This repository has been archived by the owner on Mar 1, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 505
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #366 from maticnetwork/typed-transactions
Typed transactions
- Loading branch information
Showing
11 changed files
with
255 additions
and
77 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
pragma solidity 0.5.17; | ||
|
||
import {RLPReader} from "solidity-rlp/contracts/RLPReader.sol"; | ||
import {BytesLib} from "./BytesLib.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; | ||
} | ||
|
||
function toExitPayload(bytes memory data) | ||
internal | ||
pure | ||
returns (ExitPayload memory) | ||
{ | ||
RLPReader.RLPItem[] memory payloadData = data | ||
.toRlpItem() | ||
.toList(); | ||
|
||
return ExitPayload(payloadData); | ||
} | ||
|
||
function copy(uint src, uint dest, uint 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; | ||
} | ||
|
||
// left over bytes. Mask is used to remove unwanted bytes from the word | ||
uint 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 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 parsting 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(); | ||
} | ||
|
||
function getTx(ExitPayload memory payload) internal pure returns(bytes memory) { | ||
return payload.data[10].toBytes(); | ||
} | ||
|
||
function getTxProof(ExitPayload memory payload) internal pure returns(bytes memory) { | ||
return payload.data[11].toBytes(); | ||
} | ||
|
||
// 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]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.