Skip to content

Commit

Permalink
revised tx types on bundle protocol (#33)
Browse files Browse the repository at this point in the history
* remove unused url from bundle struct

* fix failing test

* fix failing test

* split tx struct into tx & request, rename to EIP155
  • Loading branch information
zeroXbrock authored Jan 19, 2024
1 parent 20bd687 commit d12fe35
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 16 deletions.
72 changes: 63 additions & 9 deletions src/Transactions.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,30 @@ library Transactions {
using RLPReader for RLPReader.Iterator;
using RLPReader for bytes;

struct Legacy {
struct EIP155 {
address to;
uint64 gas;
uint64 gasPrice;
uint64 value;
uint64 nonce;
uint256 gas;
uint256 gasPrice;
uint256 value;
uint256 nonce;
bytes data;
uint64 chainId;
uint256 chainId;
bytes r;
bytes s;
bytes v;
}

function encodeRLP(Legacy memory txStruct) internal pure returns (bytes memory) {
struct EIP155Request {
address to;
uint256 gas;
uint256 gasPrice;
uint256 value;
uint256 nonce;
bytes data;
uint256 chainId;
}

function encodeRLP(EIP155 memory txStruct) internal pure returns (bytes memory) {
bytes[] memory items = new bytes[](9);

items[0] = RLPWriter.writeUint(txStruct.nonce);
Expand All @@ -43,8 +53,29 @@ library Transactions {
return RLPWriter.writeList(items);
}

function decodeRLP(bytes memory rlp) internal pure returns (Legacy memory) {
Legacy memory txStruct;
function encodeRLP(EIP155Request memory txStruct) internal pure returns (bytes memory) {
bytes[] memory items = new bytes[](9);

items[0] = RLPWriter.writeUint(txStruct.nonce);
items[1] = RLPWriter.writeUint(txStruct.gasPrice);
items[2] = RLPWriter.writeUint(txStruct.gas);

if (txStruct.to == address(0)) {
items[3] = RLPWriter.writeBytes(bytes(""));
} else {
items[3] = RLPWriter.writeAddress(txStruct.to);
}
items[4] = RLPWriter.writeUint(txStruct.value);
items[5] = RLPWriter.writeBytes(txStruct.data);
items[6] = RLPWriter.writeUint(txStruct.chainId);
items[7] = RLPWriter.writeBytes("");
items[8] = RLPWriter.writeBytes("");

return RLPWriter.writeList(items);
}

function decodeRLP_EIP155(bytes memory rlp) internal pure returns (EIP155 memory) {
EIP155 memory txStruct;

RLPReader.RLPItem[] memory ls = rlp.toRlpItem().toList();
require(ls.length == 9, "invalid transaction");
Expand All @@ -67,4 +98,27 @@ library Transactions {

return txStruct;
}

function decodeRLP_EIP155Request(bytes memory rlp) internal pure returns (EIP155Request memory) {
EIP155Request memory txStruct;

RLPReader.RLPItem[] memory ls = rlp.toRlpItem().toList();
require(ls.length == 9, "invalid transaction");

txStruct.nonce = ls[0].toUint();
txStruct.gasPrice = ls[1].toUint();
txStruct.gas = ls[2].toUint();

if (ls[3].toRlpBytes().length == 1) {
txStruct.to = address(0);
} else {
txStruct.to = ls[3].toAddress();
}

txStruct.value = ls[4].toUint();
txStruct.data = ls[5].toBytes();
txStruct.chainId = uint64(ls[6].toUint());

return txStruct;
}
}
14 changes: 7 additions & 7 deletions test/Transactions.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import "src/Transactions.sol";
contract TestTransactions is Test {
using Transactions for *;

function testLegacyTransactionRLPEncoding() public {
Transactions.Legacy memory txnWithToAddress = Transactions.Legacy({
function testEIP155TransactionRLPEncoding() public {
Transactions.EIP155 memory txnWithToAddress = Transactions.EIP155({
to: address(0x095E7BAea6a6c7c4c2DfeB977eFac326aF552d87),
gas: 50000,
gasPrice: 10,
Expand All @@ -24,9 +24,9 @@ contract TestTransactions is Test {
bytes memory expected = abi.encodePacked(
hex"f85f800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba09bea4c4daac7c7c52e093e6a4c35dbbcf8856f1af7b059ba20253e70848d094fa08a8fae537ce25ed8cb5af9adac3f141af69bd515bd2ba031522df09b97dd72b1"
);
_testLegacyTransaction(txnWithToAddress, expected);
_testEIP155Transaction(txnWithToAddress, expected);

Transactions.Legacy memory txnWithoutToAddress = Transactions.Legacy({
Transactions.EIP155 memory txnWithoutToAddress = Transactions.EIP155({
to: address(0),
gas: 50000,
gasPrice: 10,
Expand All @@ -42,14 +42,14 @@ contract TestTransactions is Test {
expected = abi.encodePacked(
hex"f84b010a82c350800a021ba0754a33a9c37cfcf61cd61939fd93f5fe194b7d1ee6ef07490e8c880f3bd0d87da0715bd50fa2c24e2ce0ea595025a44a39ac238558882f9f07dd885ddc51839419"
);
_testLegacyTransaction(txnWithoutToAddress, expected);
_testEIP155Transaction(txnWithoutToAddress, expected);
}

function _testLegacyTransaction(Transactions.Legacy memory legacyTxn, bytes memory expectedRlp) public {
function _testEIP155Transaction(Transactions.EIP155 memory legacyTxn, bytes memory expectedRlp) public {
bytes memory rlp = Transactions.encodeRLP(legacyTxn);
assertEq0(rlp, expectedRlp);

Transactions.Legacy memory legacyTxn1 = Transactions.decodeRLP(rlp);
Transactions.EIP155 memory legacyTxn1 = Transactions.decodeRLP_EIP155(rlp);

// re-encode to validate that the decoding was correct
bytes memory rlp1 = Transactions.encodeRLP(legacyTxn1);
Expand Down

0 comments on commit d12fe35

Please sign in to comment.