Skip to content

Commit

Permalink
Merge 17c8e8d into d9de430
Browse files Browse the repository at this point in the history
  • Loading branch information
spalladino authored Oct 30, 2024
2 parents d9de430 + 17c8e8d commit fc57751
Show file tree
Hide file tree
Showing 75 changed files with 1,142 additions and 1,077 deletions.
10 changes: 5 additions & 5 deletions l1-contracts/src/core/FeeJuicePortal.sol
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,12 @@ contract FeeJuicePortal is IFeeJuicePortal {
* @param _to - The aztec address of the recipient
* @param _amount - The amount to deposit
* @param _secretHash - The hash of the secret consumable message. The hash should be 254 bits (so it can fit in a Field element)
* @return - The key of the entry in the Inbox
* @return - The key of the entry in the Inbox and its leaf index
*/
function depositToAztecPublic(bytes32 _to, uint256 _amount, bytes32 _secretHash)
external
override(IFeeJuicePortal)
returns (bytes32)
returns (bytes32, uint256)
{
// Preamble
address rollup = canonicalRollup();
Expand All @@ -80,11 +80,11 @@ contract FeeJuicePortal is IFeeJuicePortal {
UNDERLYING.safeTransferFrom(msg.sender, address(this), _amount);

// Send message to rollup
bytes32 key = inbox.sendL2Message(actor, contentHash, _secretHash);
(bytes32 key, uint256 index) = inbox.sendL2Message(actor, contentHash, _secretHash);

emit DepositToAztecPublic(_to, _amount, _secretHash, key);
emit DepositToAztecPublic(_to, _amount, _secretHash, key, index);

return key;
return (key, index);
}

/**
Expand Down
6 changes: 4 additions & 2 deletions l1-contracts/src/core/interfaces/IFeeJuicePortal.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@ import {IERC20} from "@oz/token/ERC20/IERC20.sol";
import {IRegistry} from "@aztec/governance/interfaces/IRegistry.sol";

interface IFeeJuicePortal {
event DepositToAztecPublic(bytes32 indexed to, uint256 amount, bytes32 secretHash, bytes32 key);
event DepositToAztecPublic(
bytes32 indexed to, uint256 amount, bytes32 secretHash, bytes32 key, uint256 index
);
event FeesDistributed(address indexed to, uint256 amount);

function initialize() external;
function distributeFees(address _to, uint256 _amount) external;
function depositToAztecPublic(bytes32 _to, uint256 _amount, bytes32 _secretHash)
external
returns (bytes32);
returns (bytes32, uint256);
function canonicalRollup() external view returns (address);

function UNDERLYING() external view returns (IERC20);
Expand Down
4 changes: 2 additions & 2 deletions l1-contracts/src/core/interfaces/messagebridge/IInbox.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ interface IInbox {
* @param _recipient - The recipient of the message
* @param _content - The content of the message (application specific)
* @param _secretHash - The secret hash of the message (make it possible to hide when a specific message is consumed on L2)
* @return The key of the message in the set
* @return The key of the message in the set and its leaf index in the tree
*/
function sendL2Message(
DataStructures.L2Actor memory _recipient,
bytes32 _content,
bytes32 _secretHash
) external returns (bytes32);
) external returns (bytes32, uint256);
// docs:end:send_l1_to_l2_message

// docs:start:consume
Expand Down
2 changes: 2 additions & 0 deletions l1-contracts/src/core/libraries/DataStructures.sol
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,14 @@ library DataStructures {
* @param recipient - The recipient of the message
* @param content - The content of the message (application specific) padded to bytes32 or hashed if larger.
* @param secretHash - The secret hash of the message (make it possible to hide when a specific message is consumed on L2).
* @param index - Global leaf index on the L1 to L2 messages tree.
*/
struct L1ToL2Msg {
L1Actor sender;
L2Actor recipient;
bytes32 content;
bytes32 secretHash;
uint256 index;
}
// docs:end:l1_to_l2_msg

Expand Down
4 changes: 3 additions & 1 deletion l1-contracts/src/core/libraries/crypto/Hash.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ library Hash {
*/
function sha256ToField(DataStructures.L1ToL2Msg memory _message) internal pure returns (bytes32) {
return sha256ToField(
abi.encode(_message.sender, _message.recipient, _message.content, _message.secretHash)
abi.encode(
_message.sender, _message.recipient, _message.content, _message.secretHash, _message.index
)
);
}

Expand Down
20 changes: 11 additions & 9 deletions l1-contracts/src/core/messagebridge/Inbox.sol
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,13 @@ contract Inbox is IInbox {
* @param _content - The content of the message (application specific)
* @param _secretHash - The secret hash of the message (make it possible to hide when a specific message is consumed on L2)
*
* @return Hash of the sent message.
* @return Hash of the sent message and its leaf index in the tree.
*/
function sendL2Message(
DataStructures.L2Actor memory _recipient,
bytes32 _content,
bytes32 _secretHash
) external override(IInbox) returns (bytes32) {
) external override(IInbox) returns (bytes32, uint256) {
require(
uint256(_recipient.actor) <= Constants.MAX_FIELD_VALUE,
Errors.Inbox__ActorTooLarge(_recipient.actor)
Expand All @@ -81,23 +81,25 @@ contract Inbox is IInbox {
currentTree = trees[inProgress];
}

// this is the global leaf index and not index in the l2Block subtree
// such that users can simply use it and don't need access to a node if they are to consume it in public.
// trees are constant size so global index = tree number * size + subtree index
uint256 index = (inProgress - Constants.INITIAL_L2_BLOCK_NUM) * SIZE + currentTree.nextIndex;

DataStructures.L1ToL2Msg memory message = DataStructures.L1ToL2Msg({
sender: DataStructures.L1Actor(msg.sender, block.chainid),
recipient: _recipient,
content: _content,
secretHash: _secretHash
secretHash: _secretHash,
index: index
});

bytes32 leaf = message.sha256ToField();
// this is the global leaf index and not index in the l2Block subtree
// such that users can simply use it and don't need access to a node if they are to consume it in public.
// trees are constant size so global index = tree number * size + subtree index
uint256 index =
(inProgress - Constants.INITIAL_L2_BLOCK_NUM) * SIZE + currentTree.insertLeaf(leaf);
currentTree.insertLeaf(leaf);
totalMessagesInserted++;
emit MessageSent(inProgress, index, leaf);

return leaf;
return (leaf, index);
}

/**
Expand Down
9 changes: 7 additions & 2 deletions l1-contracts/src/mock/MockFeeJuicePortal.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,13 @@ contract MockFeeJuicePortal is IFeeJuicePortal {

function distributeFees(address, uint256) external override {}

function depositToAztecPublic(bytes32, uint256, bytes32) external pure override returns (bytes32) {
return bytes32(0);
function depositToAztecPublic(bytes32, uint256, bytes32)
external
pure
override
returns (bytes32, uint256)
{
return (bytes32(0), 0);
}

function canonicalRollup() external pure override returns (address) {
Expand Down
36 changes: 24 additions & 12 deletions l1-contracts/test/Inbox.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,16 @@ contract InboxTest is Test {
version: version
}),
content: 0x2000000000000000000000000000000000000000000000000000000000000000,
secretHash: 0x3000000000000000000000000000000000000000000000000000000000000000
secretHash: 0x3000000000000000000000000000000000000000000000000000000000000000,
index: 0x01
});
}

function _divideAndRoundUp(uint256 a, uint256 b) internal pure returns (uint256) {
return (a + b - 1) / b;
}

function _boundMessage(DataStructures.L1ToL2Msg memory _message)
function _boundMessage(DataStructures.L1ToL2Msg memory _message, uint256 _globalLeafIndex)
internal
view
returns (DataStructures.L1ToL2Msg memory)
Expand All @@ -61,6 +62,8 @@ contract InboxTest is Test {
_message.secretHash = bytes32(uint256(_message.secretHash) % Constants.P);
// update version
_message.recipient.version = version;
// set leaf index
_message.index = _globalLeafIndex;

return _message;
}
Expand All @@ -84,32 +87,40 @@ contract InboxTest is Test {
}

function testFuzzInsert(DataStructures.L1ToL2Msg memory _message) public checkInvariant {
DataStructures.L1ToL2Msg memory message = _boundMessage(_message);
uint256 globalLeafIndex = (FIRST_REAL_TREE_NUM - 1) * SIZE;
DataStructures.L1ToL2Msg memory message = _boundMessage(_message, globalLeafIndex);

bytes32 leaf = message.sha256ToField();
vm.expectEmit(true, true, true, true);
// event we expect
uint256 globalLeafIndex = (FIRST_REAL_TREE_NUM - 1) * SIZE;
emit IInbox.MessageSent(FIRST_REAL_TREE_NUM, globalLeafIndex, leaf);
// event we will get
bytes32 insertedLeaf =
(bytes32 insertedLeaf, uint256 insertedIndex) =
inbox.sendL2Message(message.recipient, message.content, message.secretHash);

assertEq(insertedLeaf, leaf);
assertEq(insertedIndex, globalLeafIndex);
}

function testSendDuplicateL2Messages() public checkInvariant {
DataStructures.L1ToL2Msg memory message = _fakeMessage();
bytes32 leaf1 = inbox.sendL2Message(message.recipient, message.content, message.secretHash);
bytes32 leaf2 = inbox.sendL2Message(message.recipient, message.content, message.secretHash);
bytes32 leaf3 = inbox.sendL2Message(message.recipient, message.content, message.secretHash);
(bytes32 leaf1, uint256 index1) =
inbox.sendL2Message(message.recipient, message.content, message.secretHash);
(bytes32 leaf2, uint256 index2) =
inbox.sendL2Message(message.recipient, message.content, message.secretHash);
(bytes32 leaf3, uint256 index3) =
inbox.sendL2Message(message.recipient, message.content, message.secretHash);

// Only 1 tree should be non-zero
assertEq(inbox.getNumTrees(), 1);

// All the leaves should be the same
assertEq(leaf1, leaf2);
assertEq(leaf2, leaf3);
// All the leaves should be different since the index gets mixed in
assertNotEq(leaf1, leaf2);
assertNotEq(leaf2, leaf3);

// Check indices
assertEq(index1 + 1, index2);
assertEq(index1 + 2, index3);
}

function testRevertIfActorTooLarge() public {
Expand Down Expand Up @@ -161,7 +172,8 @@ contract InboxTest is Test {

// We send the messages and then check that toConsume root did not change.
for (uint256 i = 0; i < _messages.length; i++) {
DataStructures.L1ToL2Msg memory message = _boundMessage(_messages[i]);
DataStructures.L1ToL2Msg memory message =
_boundMessage(_messages[i], inbox.getNextMessageIndex());

// We check whether a new tree is correctly initialized when the one in progress is full
uint256 numTrees = inbox.getNumTrees();
Expand Down
12 changes: 7 additions & 5 deletions l1-contracts/test/fee_portal/depositToAztecPublic.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,14 @@ contract DepositToAztecPublic is Test {
bytes32 to = bytes32(0x0);
bytes32 secretHash = bytes32(uint256(0x01));
uint256 amount = 100 ether;
uint256 expectedIndex = 2 ** Constants.L1_TO_L2_MSG_SUBTREE_HEIGHT;

DataStructures.L1ToL2Msg memory message = DataStructures.L1ToL2Msg({
sender: DataStructures.L1Actor(address(feeJuicePortal), block.chainid),
recipient: DataStructures.L2Actor(feeJuicePortal.L2_TOKEN_ADDRESS(), 1 + numberOfRollups),
content: Hash.sha256ToField(abi.encodeWithSignature("claim(bytes32,uint256)", to, amount)),
secretHash: secretHash
secretHash: secretHash,
index: expectedIndex
});

bytes32 expectedKey = message.sha256ToField();
Expand All @@ -92,16 +94,16 @@ contract DepositToAztecPublic is Test {

Inbox inbox = Inbox(address(Rollup(address(registry.getRollup())).INBOX()));
assertEq(inbox.totalMessagesInserted(), 0);
uint256 index = 2 ** Constants.L1_TO_L2_MSG_SUBTREE_HEIGHT;

vm.expectEmit(true, true, true, true, address(inbox));
emit IInbox.MessageSent(2, index, expectedKey);
emit IInbox.MessageSent(2, expectedIndex, expectedKey);
vm.expectEmit(true, true, true, true, address(feeJuicePortal));
emit IFeeJuicePortal.DepositToAztecPublic(to, amount, secretHash, expectedKey);
emit IFeeJuicePortal.DepositToAztecPublic(to, amount, secretHash, expectedKey, expectedIndex);

bytes32 key = feeJuicePortal.depositToAztecPublic(to, amount, secretHash);
(bytes32 key, uint256 index) = feeJuicePortal.depositToAztecPublic(to, amount, secretHash);

assertEq(inbox.totalMessagesInserted(), 1);
assertEq(key, expectedKey);
assertEq(index, expectedIndex);
}
}
16 changes: 8 additions & 8 deletions l1-contracts/test/fixtures/empty_block_1.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
"l2ToL1Messages": []
},
"block": {
"archive": "0x18589e53843baf9415aa9a4943bd4d8fa19b318329604f51a4ac0b8e7eb8e155",
"blockHash": "0x2662dae080808aceafe3377c439d8bea968d5ea74c98643adf5c2ea805f72c0c",
"archive": "0x04f48997a6e0472d7919af16c50859f86c041ef9aefceba4be94657943618ac1",
"blockHash": "0x2f3394755802dfe8105c0e7a5a7733970b59d83f6b9bd6eb754317f4d6a73c0f",
"body": "0x00000000",
"txsEffectsHash": "0x00e994e16b3763fd5039413cf99c2b3c378e2bab939e7992a77bd201b28160d6",
"decodedHeader": {
Expand All @@ -21,12 +21,12 @@
},
"globalVariables": {
"blockNumber": 1,
"slotNumber": "0x0000000000000000000000000000000000000000000000000000000000000011",
"slotNumber": "0x0000000000000000000000000000000000000000000000000000000000000012",
"chainId": 31337,
"timestamp": 1728563130,
"timestamp": 1730234580,
"version": 1,
"coinbase": "0xd498444361455d5099a036e93f395a584cf085c6",
"feeRecipient": "0x07c66a9b410a7e26824d677a12d8af977c0db64e5fcdfc8ad704c71c0267d649",
"coinbase": "0x2590e3544a7e2e7d736649fefc72ea5ad1d6efc3",
"feeRecipient": "0x2146e005e28b76eedc61edeff431b412b5ece74a5818080051832d286795ce2e",
"gasFees": {
"feePerDaGas": 0,
"feePerL2Gas": 0
Expand Down Expand Up @@ -57,8 +57,8 @@
}
}
},
"header": "0x1200a06aae1368abe36530b585bd7a4d2ba4de5037b82076412691a187d7621e00000001000000000000000000000000000000000000000000000000000000000000000200e994e16b3763fd5039413cf99c2b3c378e2bab939e7992a77bd201b28160d600089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c00f5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb14f44d672eb357739e42463497f9fdac46623af863eea4d947ca00a497dcdeb3000000100b59baa35b9dc267744f0ccb4e3b0255c1fc512460d91130c6bc19fb2668568d0000008019a8c197c12bb33da6314c4ef4f8f6fcb9e25250c085df8672adf67c8f1e3dbc0000010023c08a6b1297210c5e24c76b9a936250a1ce2721576c26ea797c7ec35f9e46a9000001000000000000000000000000000000000000000000000000000000000000007a69000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000011000000000000000000000000000000000000000000000000000000006707c7bad498444361455d5099a036e93f395a584cf085c607c66a9b410a7e26824d677a12d8af977c0db64e5fcdfc8ad704c71c0267d649000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"publicInputsHash": "0x00e081da850e07688f3b8eac898caaeb80fabf215e1c87bbecc180d88a19f34e",
"header": "0x1200a06aae1368abe36530b585bd7a4d2ba4de5037b82076412691a187d7621e00000001000000000000000000000000000000000000000000000000000000000000000200e994e16b3763fd5039413cf99c2b3c378e2bab939e7992a77bd201b28160d600089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c00f5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb14f44d672eb357739e42463497f9fdac46623af863eea4d947ca00a497dcdeb3000000100b59baa35b9dc267744f0ccb4e3b0255c1fc512460d91130c6bc19fb2668568d0000008019a8c197c12bb33da6314c4ef4f8f6fcb9e25250c085df8672adf67c8f1e3dbc0000010023c08a6b1297210c5e24c76b9a936250a1ce2721576c26ea797c7ec35f9e46a9000001000000000000000000000000000000000000000000000000000000000000007a6900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000672148d42590e3544a7e2e7d736649fefc72ea5ad1d6efc32146e005e28b76eedc61edeff431b412b5ece74a5818080051832d286795ce2e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"publicInputsHash": "0x0086289eca84479d5e34db9c4548bdd156af80fb725c51219650aa4460c80240",
"numTxs": 0
}
}
18 changes: 9 additions & 9 deletions l1-contracts/test/fixtures/empty_block_2.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
"l2ToL1Messages": []
},
"block": {
"archive": "0x1d3dc82359e412945750080a10eede5c3ee3cb9360dc3ca35dda2c5f2e296c52",
"blockHash": "0x15fb8c7900432692f9f4e590e6df42d6fff4ce24f0b720514d6bc30ba234d548",
"archive": "0x07d7359b2b2922b8126019bef4f2d5698f25226f5f2270a79d1105503727dd6e",
"blockHash": "0x1836f56b16db44064b3231102c84c6eaf3327d0204a5171f65b3019fc79c2b5e",
"body": "0x00000000",
"txsEffectsHash": "0x00e994e16b3763fd5039413cf99c2b3c378e2bab939e7992a77bd201b28160d6",
"decodedHeader": {
Expand All @@ -21,20 +21,20 @@
},
"globalVariables": {
"blockNumber": 2,
"slotNumber": "0x0000000000000000000000000000000000000000000000000000000000000012",
"slotNumber": "0x0000000000000000000000000000000000000000000000000000000000000013",
"chainId": 31337,
"timestamp": 1728563154,
"timestamp": 1730234604,
"version": 1,
"coinbase": "0xd498444361455d5099a036e93f395a584cf085c6",
"feeRecipient": "0x07c66a9b410a7e26824d677a12d8af977c0db64e5fcdfc8ad704c71c0267d649",
"coinbase": "0x2590e3544a7e2e7d736649fefc72ea5ad1d6efc3",
"feeRecipient": "0x2146e005e28b76eedc61edeff431b412b5ece74a5818080051832d286795ce2e",
"gasFees": {
"feePerDaGas": 0,
"feePerL2Gas": 0
}
},
"lastArchive": {
"nextAvailableLeafIndex": 2,
"root": "0x18589e53843baf9415aa9a4943bd4d8fa19b318329604f51a4ac0b8e7eb8e155"
"root": "0x04f48997a6e0472d7919af16c50859f86c041ef9aefceba4be94657943618ac1"
},
"stateReference": {
"l1ToL2MessageTree": {
Expand All @@ -57,8 +57,8 @@
}
}
},
"header": "0x18589e53843baf9415aa9a4943bd4d8fa19b318329604f51a4ac0b8e7eb8e15500000002000000000000000000000000000000000000000000000000000000000000000200e994e16b3763fd5039413cf99c2b3c378e2bab939e7992a77bd201b28160d600089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c00f5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb14f44d672eb357739e42463497f9fdac46623af863eea4d947ca00a497dcdeb3000000200b59baa35b9dc267744f0ccb4e3b0255c1fc512460d91130c6bc19fb2668568d0000010019a8c197c12bb33da6314c4ef4f8f6fcb9e25250c085df8672adf67c8f1e3dbc0000018023c08a6b1297210c5e24c76b9a936250a1ce2721576c26ea797c7ec35f9e46a9000001800000000000000000000000000000000000000000000000000000000000007a69000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000006707c7d2d498444361455d5099a036e93f395a584cf085c607c66a9b410a7e26824d677a12d8af977c0db64e5fcdfc8ad704c71c0267d649000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"publicInputsHash": "0x00815a814be4b3e0ac1a671e1a0321c231ac90e23ef7b2b1e411d32a2fb1948d",
"header": "0x04f48997a6e0472d7919af16c50859f86c041ef9aefceba4be94657943618ac100000002000000000000000000000000000000000000000000000000000000000000000200e994e16b3763fd5039413cf99c2b3c378e2bab939e7992a77bd201b28160d600089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c00f5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb14f44d672eb357739e42463497f9fdac46623af863eea4d947ca00a497dcdeb3000000200b59baa35b9dc267744f0ccb4e3b0255c1fc512460d91130c6bc19fb2668568d0000010019a8c197c12bb33da6314c4ef4f8f6fcb9e25250c085df8672adf67c8f1e3dbc0000018023c08a6b1297210c5e24c76b9a936250a1ce2721576c26ea797c7ec35f9e46a9000001800000000000000000000000000000000000000000000000000000000000007a6900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001300000000000000000000000000000000000000000000000000000000672148ec2590e3544a7e2e7d736649fefc72ea5ad1d6efc32146e005e28b76eedc61edeff431b412b5ece74a5818080051832d286795ce2e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"publicInputsHash": "0x009727b9d0f6c22ea711c2e31249776bd687ffa0eaf97b54120af68c96da0eda",
"numTxs": 0
}
}
Loading

0 comments on commit fc57751

Please sign in to comment.