diff --git a/src/kernel_evm/CHANGES.md b/src/kernel_evm/CHANGES.md index bd951ea58f552acdfde1dddcbc333ff856909711..0bee527e52b03c576fb0cd36ed598caf11a78d9d 100644 --- a/src/kernel_evm/CHANGES.md +++ b/src/kernel_evm/CHANGES.md @@ -12,6 +12,7 @@ L1 smart contract. It will consider upgrades messages coming from a specific address defined in its storage. (!9927) - Adds a new type of message in simulation mode, to verify that a transaction is valid by checking if the nonce is neither too low nor too high. (!9679) +- Simulate if a transaction has a correct chain id. (!9752) ### EVM Node @@ -20,6 +21,7 @@ - Add an optional `mode` argument to switch from the proxy on production to the one on development. (!9940) - `eth_sendRawTransaction` checks that the nonce of the transaction is neither too low nor too high. (!9679) +- `eth_sendRawTransaction` checks if the chain id is correct. (!9752) ### Bug fixes diff --git a/src/kernel_evm/kernel/src/error.rs b/src/kernel_evm/kernel/src/error.rs index 3424289d793451c042b277f6548c92d56f16f1b8..a75a5b2e259add3023a67a3590e05589185209c5 100644 --- a/src/kernel_evm/kernel/src/error.rs +++ b/src/kernel_evm/kernel/src/error.rs @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: 2023 Nomadic Labs // SPDX-FileCopyrightText: 2023 Functori // SPDX-FileCopyrightText: 2023 Trilitech +// SPDX-FileCopyrightText: 2023 Marigold // // SPDX-License-Identifier: MIT use core::str::Utf8Error; @@ -26,6 +27,8 @@ pub enum TransferError { CumulativeGasUsedOverflow, #[error("Transaction error: invalid address format {0}")] InvalidAddressFormat(Utf8Error), + #[error("Transaction error: invalid chain id {expected} but got {actual}")] + InvalidChainId { expected: U256, actual: U256 }, } #[derive(Error, Debug, Eq, PartialEq)] diff --git a/src/kernel_evm/kernel/src/simulation.rs b/src/kernel_evm/kernel/src/simulation.rs index 63a981a931f425066aae2b7c5b9e73131a9a3686..5b8d74f38810bc3609a2b6e018817cbf18c26c1e 100644 --- a/src/kernel_evm/kernel/src/simulation.rs +++ b/src/kernel_evm/kernel/src/simulation.rs @@ -156,6 +156,7 @@ enum TxValidationOutcome { NonceTooLow, NonceTooHigh, NotCorrectSignature, + InvalidChainId, } impl TxValidation { @@ -176,6 +177,8 @@ impl TxValidation { Some(account) => account.nonce(host)?, None => U256::zero(), }; + // Get the chain_id + let chain_id = storage::read_chain_id(host)?; // Check if nonce is too low if tx.nonce < caller_nonce { return Ok(TxValidationOutcome::NonceTooLow); @@ -184,6 +187,10 @@ impl TxValidation { if tx.nonce > caller_nonce { return Ok(TxValidationOutcome::NonceTooHigh); } + // Check if the chain id is correct + if tx.chain_id != chain_id { + return Ok(TxValidationOutcome::InvalidChainId); + } Ok(TxValidationOutcome::Valid) } } @@ -339,6 +346,10 @@ fn store_tx_validation_outcome( storage::store_simulation_status(host, false)?; storage::store_simulation_result(host, Some(b"Incorrect signature.".to_vec())) } + TxValidationOutcome::InvalidChainId => { + storage::store_simulation_status(host, false)?; + storage::store_simulation_result(host, Some(b"Invalid chain id.".to_vec())) + } } } diff --git a/tezt/tests/evm_rollup.ml b/tezt/tests/evm_rollup.ml index f0b82fc707a82e162c47ee1180c686eadd66b023..af08a32bdb145aaba0085f083ccea0e5de931273 100644 --- a/tezt/tests/evm_rollup.ml +++ b/tezt/tests/evm_rollup.ml @@ -2478,6 +2478,24 @@ let test_block_storage_before_and_after_migration = in gen_kernel_migration_test ~scenario_prior ~scenario_after protocol +let test_rpc_sendRawTransaction_invalid_chain_id = + Protocol.register_test + ~__FILE__ + ~tags:["evm"; "chain_id"] + ~title:"Returns an error if the chainId is not correct." + @@ fun protocol -> + let* {evm_proxy_server; _} = setup_past_genesis ~admin:None protocol in + (* Nonce: 0, chainId: 4242*) + let raw_tx = + "0xf86a8080831e8480940000000000000000000000000000000000000000888ac7230489e8000080822148a0e09f1fb4920f2e64a274b83d925890dd0b109fdf31f2811a781e918118daf34aa00f425e9a93bd92d710d3d323998b093a8c7d497d2af688c062a8099b076813e8" + in + let* result = send_raw_transaction evm_proxy_server raw_tx in + let error_message = Result.get_error result in + Check.( + ((error_message = "Invalid chain id.") string) + ~error_msg:"The transaction should fail") ; + unit + let register_evm_migration ~protocols = test_kernel_migration protocols ; test_deposit_before_and_after_migration protocols ; @@ -2523,7 +2541,8 @@ let register_evm_proxy_server ~protocols = test_rpc_sendRawTransaction protocols ; test_deposit_dailynet protocols ; test_rpc_sendRawTransaction_nonce_too_low protocols ; - test_rpc_sendRawTransaction_nonce_too_high protocols + test_rpc_sendRawTransaction_nonce_too_high protocols ; + test_rpc_sendRawTransaction_invalid_chain_id protocols let register ~protocols = register_evm_proxy_server ~protocols ;