diff --git a/op-e2e/e2eutils/interop/contracts/bindings/inbox/inbox.go b/op-e2e/e2eutils/interop/contracts/bindings/inbox/inbox.go index f73fd56355e..e9381f631df 100644 --- a/op-e2e/e2eutils/interop/contracts/bindings/inbox/inbox.go +++ b/op-e2e/e2eutils/interop/contracts/bindings/inbox/inbox.go @@ -188,27 +188,6 @@ func (_Inbox *InboxTransactorRaw) Transact(opts *bind.TransactOpts, method strin return _Inbox.Contract.contract.Transact(opts, method, params...) } -// ExecuteMessage is a paid mutator transaction binding the contract method 0x5984c53e. -// -// Solidity: function executeMessage((address,uint256,uint256,uint256,uint256) _id, address _target, bytes _message) payable returns() -func (_Inbox *InboxTransactor) ExecuteMessage(opts *bind.TransactOpts, _id Identifier, _target common.Address, _message []byte) (*types.Transaction, error) { - return _Inbox.contract.Transact(opts, "executeMessage", _id, _target, _message) -} - -// ExecuteMessage is a paid mutator transaction binding the contract method 0x5984c53e. -// -// Solidity: function executeMessage((address,uint256,uint256,uint256,uint256) _id, address _target, bytes _message) payable returns() -func (_Inbox *InboxSession) ExecuteMessage(_id Identifier, _target common.Address, _message []byte) (*types.Transaction, error) { - return _Inbox.Contract.ExecuteMessage(&_Inbox.TransactOpts, _id, _target, _message) -} - -// ExecuteMessage is a paid mutator transaction binding the contract method 0x5984c53e. -// -// Solidity: function executeMessage((address,uint256,uint256,uint256,uint256) _id, address _target, bytes _message) payable returns() -func (_Inbox *InboxTransactorSession) ExecuteMessage(_id Identifier, _target common.Address, _message []byte) (*types.Transaction, error) { - return _Inbox.Contract.ExecuteMessage(&_Inbox.TransactOpts, _id, _target, _message) -} - // ValidateMessage is a paid mutator transaction binding the contract method 0xab4d6f75. // // Solidity: function validateMessage((address,uint256,uint256,uint256,uint256) _id, bytes32 _msgHash) returns() diff --git a/op-e2e/interop/interop_test.go b/op-e2e/interop/interop_test.go index 1df24c2b8f3..c6daf0e7903 100644 --- a/op-e2e/interop/interop_test.go +++ b/op-e2e/interop/interop_test.go @@ -298,18 +298,17 @@ func TestInteropBlockBuilding(t *testing.T) { t.Log("Testing invalid message") { - bobAddr := s2.Address(chainA, "Bob") // direct it to a random account without code ctx, cancel := context.WithTimeout(context.Background(), time.Second*15) defer cancel() - // Send an executing message, but with different payload. + // Emitting an executing message, but with different payload. if s2.(*interopE2ESystem).config.mempoolFiltering { // We expect the traqnsaction to be filtered out by the mempool if mempool filtering is enabled. - // ExecuteMessage the ErrTxFilteredOut error is checked when sending the tx. - _, err := s2.ExecuteMessage(ctx, chainB, "Alice", identifier, bobAddr, invalidPayload, gethCore.ErrTxFilteredOut) + // ValidateMessage the ErrTxFilteredOut error is checked when sending the tx. + _, err := s2.ValidateMessage(ctx, chainB, "Alice", identifier, invalidPayloadHash, gethCore.ErrTxFilteredOut) require.ErrorContains(t, err, gethCore.ErrTxFilteredOut.Error()) } else { // We expect the miner to be unable to include this tx, and confirmation to thus time out, if mempool filtering is disabled. - _, err := s2.ExecuteMessage(ctx, chainB, "Alice", identifier, bobAddr, invalidPayload, nil) + _, err := s2.ValidateMessage(ctx, chainB, "Alice", identifier, invalidPayloadHash, nil) require.ErrorIs(t, err, ctx.Err()) require.ErrorIs(t, ctx.Err(), context.DeadlineExceeded) } @@ -317,11 +316,10 @@ func TestInteropBlockBuilding(t *testing.T) { t.Log("Testing valid message now") { - bobAddr := s2.Address(chainA, "Bob") // direct it to a random account without code ctx, cancel := context.WithTimeout(context.Background(), time.Second*15) defer cancel() - // Send an executing message with the correct identifier / payload - rec, err := s2.ExecuteMessage(ctx, chainB, "Alice", identifier, bobAddr, msgPayload, nil) + // Emit an executing message with the correct identifier / payload + rec, err := s2.ValidateMessage(ctx, chainB, "Alice", identifier, payloadHash, nil) require.NoError(t, err, "expecting tx to be confirmed") t.Logf("confirmed executing msg in block %s", rec.BlockNumber) } diff --git a/op-e2e/interop/supersystem.go b/op-e2e/interop/supersystem.go index b7c8f28a655..3abbc29ebc5 100644 --- a/op-e2e/interop/supersystem.go +++ b/op-e2e/interop/supersystem.go @@ -106,14 +106,13 @@ type SuperSystem interface { EmitData(ctx context.Context, network string, username string, data string) *types.Receipt // AddDependency adds a dependency (by chain ID) to the given chain AddDependency(ctx context.Context, network string, dep *big.Int) *types.Receipt - // ExecuteMessage calls the CrossL2Inbox executeMessage function - ExecuteMessage( + // ValidateMessage calls the CrossL2Inbox ValidateMessage function + ValidateMessage( ctx context.Context, id string, sender string, msgIdentifier supervisortypes.Identifier, - target common.Address, - message []byte, + msgHash [32]byte, expectedError error, ) (*types.Receipt, error) // Access a contract on a network by name @@ -733,17 +732,16 @@ func (s *interopE2ESystem) SendL2Tx( newApply) } -// ExecuteMessage calls the CrossL2Inbox executeMessage function +// ValidateMessage calls the CrossL2Inbox ValidateMessage function // it uses the L2's chain ID, username key, and geth client. -// expectedError represents the error returned by `ExecuteMessage` if it is expected. +// expectedError represents the error returned by `ValidateMessage` if it is expected. // the returned err is related to `WaitMined` -func (s *interopE2ESystem) ExecuteMessage( +func (s *interopE2ESystem) ValidateMessage( ctx context.Context, id string, sender string, msgIdentifier supervisortypes.Identifier, - target common.Address, - message []byte, + msgHash [32]byte, expectedError error, ) (*types.Receipt, error) { secret := s.UserKey(id, sender) @@ -762,14 +760,14 @@ func (s *interopE2ESystem) ExecuteMessage( Timestamp: new(big.Int).SetUint64(msgIdentifier.Timestamp), ChainId: msgIdentifier.ChainID.ToBig(), } - tx, err := contract.InboxTransactor.ExecuteMessage(auth, identifier, target, message) + tx, err := contract.InboxTransactor.ValidateMessage(auth, identifier, msgHash) if expectedError != nil { require.ErrorContains(s.t, err, expectedError.Error()) return nil, err } else { require.NoError(s.t, err) } - s.logger.Info("Executing message", "tx", tx.Hash(), "to", tx.To(), "target", target, "data", hexutil.Bytes(tx.Data())) + s.logger.Info("Validating message", "tx", tx.Hash(), "to", tx.To(), "data", hexutil.Bytes(tx.Data())) return bind.WaitMined(ctx, s.L2GethClient(id), tx) } diff --git a/op-supervisor/supervisor/backend/processors/executing_message_test.go b/op-supervisor/supervisor/backend/processors/executing_message_test.go index 6badeb20167..6f5a9c59363 100644 --- a/op-supervisor/supervisor/backend/processors/executing_message_test.go +++ b/op-supervisor/supervisor/backend/processors/executing_message_test.go @@ -43,8 +43,7 @@ func TestDecodeExecutingMessageLog(t *testing.T) { // uint256 timestamp; // uint256 chainId; // } - // function executeMessage(Identifier calldata _id, - // address _target, bytes calldata _message) external payable; + // event ExecutingMessage(bytes32 indexed msgHash, Identifier id); originAddr := common.HexToAddress("0x5fbdb2315678afecb367f032d93f642f64180aa3") payloadHash := common.HexToHash("0xc3f57e1f0dd62a4f77787d834029bfeaab8894022c47edbe13b044fb658c9190") diff --git a/packages/contracts-bedrock/interfaces/L2/ICrossL2Inbox.sol b/packages/contracts-bedrock/interfaces/L2/ICrossL2Inbox.sol index 0a80c29d7ac..8b486cc7073 100644 --- a/packages/contracts-bedrock/interfaces/L2/ICrossL2Inbox.sol +++ b/packages/contracts-bedrock/interfaces/L2/ICrossL2Inbox.sol @@ -23,12 +23,6 @@ interface ICrossL2Inbox { /// @notice Thrown when a non-written transient storage slot is attempted to be read from. error NotEntered(); - /// @notice Thrown when trying to execute a cross chain message with an invalid Identifier timestamp. - error InvalidTimestamp(); - - /// @notice Thrown when trying to execute a cross chain message with an invalid Identifier chain ID. - error InvalidChainId(); - /// @notice Thrown when trying to execute a cross chain message on a deposit transaction. error NoExecutingDeposits(); diff --git a/packages/contracts-bedrock/src/L2/CrossL2Inbox.sol b/packages/contracts-bedrock/src/L2/CrossL2Inbox.sol index 69bc23f53df..6b4fdbb2288 100644 --- a/packages/contracts-bedrock/src/L2/CrossL2Inbox.sol +++ b/packages/contracts-bedrock/src/L2/CrossL2Inbox.sol @@ -19,12 +19,6 @@ error InteropStartAlreadySet(); /// @notice Thrown when a non-written transient storage slot is attempted to be read from. error NotEntered(); -/// @notice Thrown when trying to execute a cross chain message with an invalid Identifier timestamp. -error InvalidTimestamp(); - -/// @notice Thrown when trying to execute a cross chain message with an invalid Identifier chain ID. -error InvalidChainId(); - /// @notice Thrown when trying to execute a cross chain message on a deposit transaction. error NoExecutingDeposits(); @@ -143,23 +137,9 @@ contract CrossL2Inbox is ISemver, TransientReentrancyAware { // We need to know if this is being called on a depositTx if (IL1BlockInterop(Predeploys.L1_BLOCK_ATTRIBUTES).isDeposit()) revert NoExecutingDeposits(); - // Check the Identifier. - _checkIdentifier(_id); - emit ExecutingMessage(_msgHash, _id); } - /// @notice Validates that for a given cross chain message identifier, - /// it's timestamp is not in the future and the source chainId - /// is in the destination chain's dependency set. - /// @param _id Identifier of the message. - function _checkIdentifier(Identifier calldata _id) internal view { - if (_id.timestamp > block.timestamp || _id.timestamp <= interopStart()) revert InvalidTimestamp(); - if (!IDependencySet(Predeploys.L1_BLOCK_ATTRIBUTES).isInDependencySet(_id.chainId)) { - revert InvalidChainId(); - } - } - /// @notice Stores the Identifier in transient storage. /// @param _id Identifier to store. function _storeIdentifier(Identifier calldata _id) internal { diff --git a/packages/contracts-bedrock/test/L2/CrossL2Inbox.t.sol b/packages/contracts-bedrock/test/L2/CrossL2Inbox.t.sol index 5f4bd92f01b..69501625467 100644 --- a/packages/contracts-bedrock/test/L2/CrossL2Inbox.t.sol +++ b/packages/contracts-bedrock/test/L2/CrossL2Inbox.t.sol @@ -14,8 +14,6 @@ import { Identifier, NotEntered, NoExecutingDeposits, - InvalidTimestamp, - InvalidChainId, NotDepositor, InteropStartAlreadySet } from "src/L2/CrossL2Inbox.sol"; @@ -180,92 +178,6 @@ contract CrossL2InboxTest is Test { crossL2Inbox.validateMessage(_id, _messageHash); } - /// @dev Tests that the `validateMessage` function reverts when called with an identifier with a timestamp later - /// than current block.timestamp. - function testFuzz_validateMessage_invalidTimestamp_reverts( - Identifier memory _id, - bytes32 _messageHash - ) - external - setInteropStart - { - // Ensure is not a deposit transaction - vm.mockCall({ - callee: Predeploys.L1_BLOCK_ATTRIBUTES, - data: abi.encodeCall(IL1BlockInterop.isDeposit, ()), - returnData: abi.encode(false) - }); - - // Ensure that the id's timestamp is invalid (greater than the current block timestamp) - _id.timestamp = bound(_id.timestamp, block.timestamp + 1, type(uint256).max); - - // Expect a revert with the InvalidTimestamp selector - vm.expectRevert(InvalidTimestamp.selector); - - // Call the validateMessage function - crossL2Inbox.validateMessage(_id, _messageHash); - } - - /// @dev Tests that the `validateMessage` function reverts when called with an identifier with a timestamp earlier - /// than INTEROP_START timestamp - function testFuzz_validateMessage_invalidTimestampInteropStart_reverts( - Identifier memory _id, - bytes32 _messageHash - ) - external - setInteropStart - { - // Ensure that the id's timestamp is invalid (less than or equal to interopStartTime) - _id.timestamp = bound(_id.timestamp, 0, crossL2Inbox.interopStart()); - - // Ensure is not a deposit transaction - vm.mockCall({ - callee: Predeploys.L1_BLOCK_ATTRIBUTES, - data: abi.encodeCall(IL1BlockInterop.isDeposit, ()), - returnData: abi.encode(false) - }); - - // Expect a revert with the InvalidTimestamp selector - vm.expectRevert(InvalidTimestamp.selector); - - // Call the validateMessage function - crossL2Inbox.validateMessage(_id, _messageHash); - } - - /// @dev Tests that the `validateMessage` function reverts when called with an identifier with a chain ID not in the - /// dependency set. - function testFuzz_validateMessage_invalidChainId_reverts( - Identifier memory _id, - bytes32 _messageHash - ) - external - setInteropStart - { - // Ensure that the timestamp is valid (less than or equal to the current block timestamp and greater than - // interopStartTime) - _id.timestamp = bound(_id.timestamp, interopStartTime + 1, block.timestamp); - - // Ensure that the chain ID is NOT in the dependency set. - vm.mockCall({ - callee: Predeploys.L1_BLOCK_ATTRIBUTES, - data: abi.encodeCall(IL1BlockInterop.isInDependencySet, (_id.chainId)), - returnData: abi.encode(false) - }); - - // Ensure is not a deposit transaction - vm.mockCall({ - callee: Predeploys.L1_BLOCK_ATTRIBUTES, - data: abi.encodeCall(IL1BlockInterop.isDeposit, ()), - returnData: abi.encode(false) - }); - - // Expect a revert with the InvalidChainId selector - vm.expectRevert(InvalidChainId.selector); - - // Call the validateMessage function - crossL2Inbox.validateMessage(_id, _messageHash); - } - /// @dev Tests that the `origin` function returns the correct value. function testFuzz_origin_succeeds(address _origin) external { // Increment the call depth to prevent NotEntered revert