erigon-pulse/cmd/devnet/contracts/lib/exitpayloadreader.sol
Mark Holt c51573f333
Bor eth event flow (#8068)
Implemented polygon->eth flow
2023-08-25 12:19:39 +01:00

159 lines
4.9 KiB
Solidity

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {RLPReader} from "./rlpreader.sol";
library ExitPayloadReader {
using RLPReader for bytes;
using RLPReader for RLPReader.RLPItem;
uint8 constant WORD_SIZE = 32;
struct ExitPayload {
RLPReader.RLPItem[] data;
}
struct Receipt {
RLPReader.RLPItem[] data;
bytes raw;
uint256 logIndex;
}
struct Log {
RLPReader.RLPItem data;
RLPReader.RLPItem[] list;
}
struct LogTopics {
RLPReader.RLPItem[] data;
}
// copy paste of private copy() from RLPReader to avoid changing of existing contracts
function copy(uint256 src, uint256 dest, uint256 len) private pure {
if (len == 0) return;
// copy as many word sizes as possible
for (; len >= WORD_SIZE; len -= WORD_SIZE) {
assembly {
mstore(dest, mload(src))
}
src += WORD_SIZE;
dest += WORD_SIZE;
}
if (len == 0) return;
// left over bytes. Mask is used to remove unwanted bytes from the word
uint256 mask = 256 ** (WORD_SIZE - len) - 1;
assembly {
let srcpart := and(mload(src), not(mask)) // zero out src
let destpart := and(mload(dest), mask) // retrieve the bytes
mstore(dest, or(destpart, srcpart))
}
}
function toExitPayload(bytes memory data) internal pure returns (ExitPayload memory) {
RLPReader.RLPItem[] memory payloadData = data.toRlpItem().toList();
return ExitPayload(payloadData);
}
function getHeaderNumber(ExitPayload memory payload) internal pure returns (uint256) {
return payload.data[0].toUint();
}
function getBlockProof(ExitPayload memory payload) internal pure returns (bytes memory) {
return payload.data[1].toBytes();
}
function getBlockNumber(ExitPayload memory payload) internal pure returns (uint256) {
return payload.data[2].toUint();
}
function getBlockTime(ExitPayload memory payload) internal pure returns (uint256) {
return payload.data[3].toUint();
}
function getTxRoot(ExitPayload memory payload) internal pure returns (bytes32) {
return bytes32(payload.data[4].toUint());
}
function getReceiptRoot(ExitPayload memory payload) internal pure returns (bytes32) {
return bytes32(payload.data[5].toUint());
}
function getReceipt(ExitPayload memory payload) internal pure returns (Receipt memory receipt) {
receipt.raw = payload.data[6].toBytes();
RLPReader.RLPItem memory receiptItem = receipt.raw.toRlpItem();
if (receiptItem.isList()) {
// legacy tx
receipt.data = receiptItem.toList();
} else {
// pop first byte before parsing receipt
bytes memory typedBytes = receipt.raw;
bytes memory result = new bytes(typedBytes.length - 1);
uint256 srcPtr;
uint256 destPtr;
assembly {
srcPtr := add(33, typedBytes)
destPtr := add(0x20, result)
}
copy(srcPtr, destPtr, result.length);
receipt.data = result.toRlpItem().toList();
}
receipt.logIndex = getReceiptLogIndex(payload);
return receipt;
}
function getReceiptProof(ExitPayload memory payload) internal pure returns (bytes memory) {
return payload.data[7].toBytes();
}
function getBranchMaskAsBytes(ExitPayload memory payload) internal pure returns (bytes memory) {
return payload.data[8].toBytes();
}
function getBranchMaskAsUint(ExitPayload memory payload) internal pure returns (uint256) {
return payload.data[8].toUint();
}
function getReceiptLogIndex(ExitPayload memory payload) internal pure returns (uint256) {
return payload.data[9].toUint();
}
// Receipt methods
function toBytes(Receipt memory receipt) internal pure returns (bytes memory) {
return receipt.raw;
}
function getLog(Receipt memory receipt) internal pure returns (Log memory) {
RLPReader.RLPItem memory logData = receipt.data[3].toList()[receipt.logIndex];
return Log(logData, logData.toList());
}
// Log methods
function getEmitter(Log memory log) internal pure returns (address) {
return RLPReader.toAddress(log.list[0]);
}
function getTopics(Log memory log) internal pure returns (LogTopics memory) {
return LogTopics(log.list[1].toList());
}
function getData(Log memory log) internal pure returns (bytes memory) {
return log.list[2].toBytes();
}
function toRlpBytes(Log memory log) internal pure returns (bytes memory) {
return log.data.toRlpBytes();
}
// LogTopics methods
function getField(LogTopics memory topics, uint256 index) internal pure returns (RLPReader.RLPItem memory) {
return topics.data[index];
}
}