From 8892a88bbad08604ab4f3562db864e3608613dcf Mon Sep 17 00:00:00 2001 From: Zehui Zheng Date: Wed, 24 Jan 2024 20:28:03 +0800 Subject: [PATCH] feat!: include chain ID in `EvmAdvance` input --- .../rollups/.changeset/shaggy-queens-kneel.md | 5 +++++ onchain/rollups/contracts/common/Inputs.sol | 2 ++ onchain/rollups/contracts/inputs/InputBox.sol | 10 +++++++++- .../rollups/test/foundry/inputs/InputBox.t.sol | 16 ++++++++++++---- .../foundry/relays/ApplicationAddressRelay.t.sol | 5 ++++- .../test/foundry/util/EvmAdvanceEncoder.sol | 11 ++++++++++- 6 files changed, 42 insertions(+), 7 deletions(-) create mode 100644 onchain/rollups/.changeset/shaggy-queens-kneel.md diff --git a/onchain/rollups/.changeset/shaggy-queens-kneel.md b/onchain/rollups/.changeset/shaggy-queens-kneel.md new file mode 100644 index 00000000..41941fa2 --- /dev/null +++ b/onchain/rollups/.changeset/shaggy-queens-kneel.md @@ -0,0 +1,5 @@ +--- +"@cartesi/rollups": major +--- + +Include chain ID in `EvmAdvance` input. diff --git a/onchain/rollups/contracts/common/Inputs.sol b/onchain/rollups/contracts/common/Inputs.sol index a4a6134d..bd416f07 100644 --- a/onchain/rollups/contracts/common/Inputs.sol +++ b/onchain/rollups/contracts/common/Inputs.sol @@ -7,6 +7,7 @@ pragma solidity ^0.8.8; /// @notice Defines the signatures of inputs. interface Inputs { /// @notice An advance request from an EVM-compatible blockchain to a Cartesi Machine. + /// @param chainId The chain ID /// @param app The application address /// @param sender The address of whoever sent the input /// @param blockNumber The number of the block in which the input was added @@ -14,6 +15,7 @@ interface Inputs { /// @param index The input index /// @param payload The payload provided by the sender function EvmAdvance( + uint256 chainId, address app, address sender, uint256 blockNumber, diff --git a/onchain/rollups/contracts/inputs/InputBox.sol b/onchain/rollups/contracts/inputs/InputBox.sol index f16c9654..8c1ece1a 100644 --- a/onchain/rollups/contracts/inputs/InputBox.sol +++ b/onchain/rollups/contracts/inputs/InputBox.sol @@ -22,7 +22,15 @@ contract InputBox is IInputBox { bytes memory input = abi.encodeCall( Inputs.EvmAdvance, - (app, msg.sender, block.number, block.timestamp, index, payload) + ( + block.chainid, + app, + msg.sender, + block.number, + block.timestamp, + index, + payload + ) ); if (input.length > CanonicalMachine.INPUT_MAX_SIZE) { diff --git a/onchain/rollups/test/foundry/inputs/InputBox.t.sol b/onchain/rollups/test/foundry/inputs/InputBox.t.sol index 26561894..d479b3d0 100644 --- a/onchain/rollups/test/foundry/inputs/InputBox.t.sol +++ b/onchain/rollups/test/foundry/inputs/InputBox.t.sol @@ -22,7 +22,7 @@ contract InputBoxTest is Test { assertEq(_inputBox.getNumberOfInputs(app), 0); } - function testAddLargeInput() public { + function testAddLargeInput(uint64 chainId) public { address app = vm.addr(1); uint256 max = _getMaxInputPayloadLength(); @@ -30,7 +30,7 @@ contract InputBoxTest is Test { bytes memory largePayload = new bytes(max + 1); uint256 largeLength = EvmAdvanceEncoder - .encode(app, address(this), 1, largePayload) + .encode(chainId, app, address(this), 1, largePayload) .length; vm.expectRevert( abi.encodeWithSelector( @@ -43,7 +43,13 @@ contract InputBoxTest is Test { _inputBox.addInput(app, largePayload); } - function testAddInput(address app, bytes[] calldata payloads) public { + function testAddInput( + uint64 chainId, + address app, + bytes[] calldata payloads + ) public { + vm.chainId(chainId); // foundry limits chain id to be less than 2^64 - 1 + uint256 numPayloads = payloads.length; bytes32[] memory returnedValues = new bytes32[](numPayloads); uint256 year2022 = 1641070800; // Unix Timestamp for 2022 @@ -61,6 +67,7 @@ contract InputBoxTest is Test { vm.expectEmit(true, true, false, true, address(_inputBox)); bytes memory input = EvmAdvanceEncoder.encode( + chainId, app, address(this), i, @@ -79,6 +86,7 @@ contract InputBoxTest is Test { abi.encodeCall( Inputs.EvmAdvance, ( + chainId, app, address(this), i, // block.number @@ -98,7 +106,7 @@ contract InputBoxTest is Test { function _getMaxInputPayloadLength() internal pure returns (uint256) { bytes memory blob = abi.encodeCall( Inputs.EvmAdvance, - (address(0), address(0), 0, 0, 0, new bytes(32)) + (0, address(0), address(0), 0, 0, 0, new bytes(32)) ); // number of bytes in input blob excluding input payload uint256 extraBytes = blob.length - 32; diff --git a/onchain/rollups/test/foundry/relays/ApplicationAddressRelay.t.sol b/onchain/rollups/test/foundry/relays/ApplicationAddressRelay.t.sol index 9380631a..d48f7080 100644 --- a/onchain/rollups/test/foundry/relays/ApplicationAddressRelay.t.sol +++ b/onchain/rollups/test/foundry/relays/ApplicationAddressRelay.t.sol @@ -44,13 +44,16 @@ contract ApplicationAddressRelayTest is Test { assertEq(address(_relay.getInputBox()), address(_inputBox)); } - function testRelayApplicationAddress(address app) public { + function testRelayApplicationAddress(uint64 chainId, address app) public { + vm.chainId(chainId); // foundry limits chain id to be less than 2^64 - 1 + // Check the application's input box before assertEq(_inputBox.getNumberOfInputs(app), 0); // Construct the application address relay input bytes memory payload = abi.encodePacked(app); bytes memory input = EvmAdvanceEncoder.encode( + chainId, app, address(_relay), 0, diff --git a/onchain/rollups/test/foundry/util/EvmAdvanceEncoder.sol b/onchain/rollups/test/foundry/util/EvmAdvanceEncoder.sol index e7c95eec..6d327e53 100644 --- a/onchain/rollups/test/foundry/util/EvmAdvanceEncoder.sol +++ b/onchain/rollups/test/foundry/util/EvmAdvanceEncoder.sol @@ -8,6 +8,7 @@ import {Inputs} from "contracts/common/Inputs.sol"; library EvmAdvanceEncoder { function encode( + uint256 chainId, address app, address sender, uint256 index, @@ -16,7 +17,15 @@ library EvmAdvanceEncoder { return abi.encodeCall( Inputs.EvmAdvance, - (app, sender, block.number, block.timestamp, index, payload) + ( + chainId, + app, + sender, + block.number, + block.timestamp, + index, + payload + ) ); } }