diff --git a/etherlink/CHANGES_NODE.md b/etherlink/CHANGES_NODE.md index 57967cff07bf9fdf9f6f7b3c3d3dec92cb32d7fb..92845c4518773c6328752d9e21de150b1345bfd1 100644 --- a/etherlink/CHANGES_NODE.md +++ b/etherlink/CHANGES_NODE.md @@ -4,6 +4,9 @@ ### Features +- The transaction pool is now removing any transaction that was included more + than a defined thresold ago (one hour by default). (!12741) + ### Bug fixes ### Breaking changes diff --git a/etherlink/bin_node/config/configuration.ml b/etherlink/bin_node/config/configuration.ml index be1889920ed1cab99ebb85a4b64669b665da122e..73606798f8452ecc6529b291e286e7d1082202af 100644 --- a/etherlink/bin_node/config/configuration.ml +++ b/etherlink/bin_node/config/configuration.ml @@ -2,6 +2,7 @@ (* *) (* SPDX-License-Identifier: MIT *) (* Copyright (c) 2023 Nomadic Labs, *) +(* Copyright (c) 2024 Functori *) (* *) (*****************************************************************************) @@ -43,6 +44,7 @@ type t = { observer : observer option; max_active_connections : Tezos_rpc_http_server.RPC_server.Max_active_rpc_connections.t; + tx_pool_timeout_limit : int64; } let default_filter_config = @@ -82,6 +84,8 @@ let hard_maximum_number_of_chunks = let default_max_number_of_chunks = hard_maximum_number_of_chunks +let default_tx_pool_timeout_limit = Int64.of_int 3600 + let sequencer_config_dft ?preimages ?preimages_endpoint ?time_between_blocks ?max_number_of_chunks ?private_rpc_port ~rollup_node_endpoint ~sequencer () = @@ -216,27 +220,30 @@ let encoding : t Data_encoding.t = sequencer; observer; max_active_connections; + tx_pool_timeout_limit; } -> - ( rpc_addr, - rpc_port, - devmode, - cors_origins, - cors_headers, - log_filter, - proxy, - sequencer, - observer, - max_active_connections )) - (fun ( rpc_addr, - rpc_port, - devmode, - cors_origins, - cors_headers, - log_filter, - proxy, - sequencer, - observer, - max_active_connections ) -> + ( ( rpc_addr, + rpc_port, + devmode, + cors_origins, + cors_headers, + log_filter, + proxy, + sequencer, + observer, + max_active_connections ), + tx_pool_timeout_limit )) + (fun ( ( rpc_addr, + rpc_port, + devmode, + cors_origins, + cors_headers, + log_filter, + proxy, + sequencer, + observer, + max_active_connections ), + tx_pool_timeout_limit ) -> { rpc_addr; rpc_port; @@ -248,21 +255,31 @@ let encoding : t Data_encoding.t = sequencer; observer; max_active_connections; + tx_pool_timeout_limit; }) - (obj10 - (dft "rpc-addr" ~description:"RPC address" string default_rpc_addr) - (dft "rpc-port" ~description:"RPC port" uint16 default_rpc_port) - (dft "devmode" bool default_devmode) - (dft "cors_origins" (list string) default_cors_origins) - (dft "cors_headers" (list string) default_cors_headers) - (dft "log_filter" log_filter_config_encoding default_filter_config) - (opt "proxy" proxy_encoding) - (opt "sequencer" sequencer_encoding) - (opt "observer" observer_encoding) - (dft - "max_active_connections" - Tezos_rpc_http_server.RPC_server.Max_active_rpc_connections.encoding - default_max_active_connections)) + (merge_objs + (obj10 + (dft "rpc-addr" ~description:"RPC address" string default_rpc_addr) + (dft "rpc-port" ~description:"RPC port" uint16 default_rpc_port) + (dft "devmode" bool default_devmode) + (dft "cors_origins" (list string) default_cors_origins) + (dft "cors_headers" (list string) default_cors_headers) + (dft "log_filter" log_filter_config_encoding default_filter_config) + (opt "proxy" proxy_encoding) + (opt "sequencer" sequencer_encoding) + (opt "observer" observer_encoding) + (dft + "max_active_connections" + Tezos_rpc_http_server.RPC_server.Max_active_rpc_connections + .encoding + default_max_active_connections)) + (obj1 + (dft + "tx-pool-timeout-limit" + ~description: + "Transaction timeout limit inside the transaction pool" + int64 + default_tx_pool_timeout_limit))) let save ~force ~data_dir config = let open Lwt_result_syntax in @@ -296,7 +313,7 @@ let observer_config_exn {observer; _} = module Cli = struct let create ~devmode ?rpc_addr ?rpc_port ?cors_origins ?cors_headers - ?log_filter ?proxy ?sequencer ?observer () = + ?log_filter ?proxy ?sequencer ?observer ?tx_pool_timeout_limit () = { rpc_addr = Option.value ~default:default_rpc_addr rpc_addr; rpc_port = Option.value ~default:default_rpc_port rpc_port; @@ -308,10 +325,15 @@ module Cli = struct sequencer; observer; max_active_connections = default_max_active_connections; + tx_pool_timeout_limit = + Option.value + ~default:default_tx_pool_timeout_limit + tx_pool_timeout_limit; } let patch_configuration_from_args ~devmode ?rpc_addr ?rpc_port ?cors_origins - ?cors_headers ?log_filter ?proxy ?sequencer ?observer configuration = + ?cors_headers ?log_filter ?proxy ?sequencer ?observer + ?tx_pool_timeout_limit configuration = { rpc_addr = Option.value ~default:configuration.rpc_addr rpc_addr; rpc_port = Option.value ~default:configuration.rpc_port rpc_port; @@ -325,10 +347,15 @@ module Cli = struct sequencer = Option.either configuration.sequencer sequencer; observer = Option.either configuration.observer observer; max_active_connections = configuration.max_active_connections; + tx_pool_timeout_limit = + Option.value + ~default:configuration.tx_pool_timeout_limit + tx_pool_timeout_limit; } let create_or_read_config ~data_dir ~devmode ?rpc_addr ?rpc_port ?cors_origins - ?cors_headers ?log_filter ?proxy ?sequencer ?observer () = + ?cors_headers ?log_filter ?proxy ?sequencer ?observer + ?tx_pool_timeout_limit () = let open Lwt_result_syntax in let open Filename.Infix in (* Check if the data directory of the evm node is not the one of Octez @@ -360,6 +387,7 @@ module Cli = struct ?proxy ?sequencer ?observer + ?tx_pool_timeout_limit configuration in return configuration @@ -375,6 +403,7 @@ module Cli = struct ?proxy ?sequencer ?observer + ?tx_pool_timeout_limit () in return config diff --git a/etherlink/bin_node/config/configuration.mli b/etherlink/bin_node/config/configuration.mli index 5f8be6a5369dfb18ee068df9dbdfff2107b7e7e8..7994513e0eaa5b85ec7740e1d3d473beae402dac 100644 --- a/etherlink/bin_node/config/configuration.mli +++ b/etherlink/bin_node/config/configuration.mli @@ -2,6 +2,7 @@ (* *) (* SPDX-License-Identifier: MIT *) (* Copyright (c) 2023 Nomadic Labs, *) +(* Copyright (c) 2024 Functori, *) (* *) (*****************************************************************************) @@ -57,6 +58,7 @@ type t = { observer : observer option; max_active_connections : Tezos_rpc_http_server.RPC_server.Max_active_rpc_connections.t; + tx_pool_timeout_limit : int64; } (** [default_data_dir] is the default value for [data_dir]. *) @@ -119,6 +121,7 @@ module Cli : sig ?proxy:proxy -> ?sequencer:sequencer -> ?observer:observer -> + ?tx_pool_timeout_limit:int64 -> unit -> t @@ -133,6 +136,7 @@ module Cli : sig ?proxy:proxy -> ?sequencer:sequencer -> ?observer:observer -> + ?tx_pool_timeout_limit:int64 -> unit -> t tzresult Lwt.t end diff --git a/etherlink/bin_node/lib_dev/observer.ml b/etherlink/bin_node/lib_dev/observer.ml index 28d17f412a0bd519b9d229e3e2835a4575bb5718..afea15dc1011bc71a4761c89555ab1278991cd3d 100644 --- a/etherlink/bin_node/lib_dev/observer.ml +++ b/etherlink/bin_node/lib_dev/observer.ml @@ -2,6 +2,7 @@ (* *) (* SPDX-License-Identifier: MIT *) (* Copyright (c) 2024 Nomadic Labs *) +(* Copyright (c) 2024 Functori *) (* *) (*****************************************************************************) @@ -257,6 +258,7 @@ let main ?kernel_path ~rollup_node_endpoint ~evm_node_endpoint ~data_dir Tezos_crypto.Hashed.Smart_rollup_address.to_b58check smart_rollup_address; mode = Observer; + tx_timeout_limit = config.tx_pool_timeout_limit; } in diff --git a/etherlink/bin_node/lib_dev/proxy.ml b/etherlink/bin_node/lib_dev/proxy.ml index a8dc8dfb91a67cd6b1883faae9b24980b376f5d2..c9f33dd26629b5b939536abdf8c65d3460037b74 100644 --- a/etherlink/bin_node/lib_dev/proxy.ml +++ b/etherlink/bin_node/lib_dev/proxy.ml @@ -2,7 +2,7 @@ (* *) (* SPDX-License-Identifier: MIT *) (* Copyright (c) 2023 Nomadic Labs *) -(* Copyright (c) 2023 Functori *) +(* Copyright (c) 2023-2024 Functori *) (* Copyright (c) 2023 Marigold *) (* *) (*****************************************************************************) @@ -90,7 +90,7 @@ let retry_connection (f : Uri.t -> string tzresult Lwt.t) endpoint : let fetch_smart_rollup_address ~keep_alive f (endpoint : Uri.t) = if keep_alive then retry_connection f endpoint else f endpoint -let main config ~keep_alive ~rollup_node_endpoint = +let main (config : Configuration.t) ~keep_alive ~rollup_node_endpoint = let open Lwt_result_syntax in let* smart_rollup_address = fetch_smart_rollup_address @@ -109,6 +109,7 @@ let main config ~keep_alive ~rollup_node_endpoint = rollup_node = (module Rollup_node_rpc); smart_rollup_address; mode = Proxy {rollup_node_endpoint}; + tx_timeout_limit = config.tx_pool_timeout_limit; } in let () = Rollup_node_follower.start ~proxy:true ~rollup_node_endpoint in diff --git a/etherlink/bin_node/lib_dev/sequencer.ml b/etherlink/bin_node/lib_dev/sequencer.ml index f2be1200f129594a0185eab3e799cdf2d22a9240..c6ceb496199449c13a3303a9e27f85e26b58fd73 100644 --- a/etherlink/bin_node/lib_dev/sequencer.ml +++ b/etherlink/bin_node/lib_dev/sequencer.ml @@ -2,6 +2,7 @@ (* *) (* SPDX-License-Identifier: MIT *) (* Copyright (c) 2023 Nomadic Labs *) +(* Copyright (c) 2024 Functori *) (* *) (*****************************************************************************) @@ -238,7 +239,12 @@ let main ~data_dir ~rollup_node_endpoint ~max_blueprints_lag end) in let* () = Tx_pool.start - {rollup_node = (module Sequencer); smart_rollup_address; mode = Sequencer} + { + rollup_node = (module Sequencer); + smart_rollup_address; + mode = Sequencer; + tx_timeout_limit = configuration.tx_pool_timeout_limit; + } in let* () = Block_producer.start diff --git a/etherlink/bin_node/lib_dev/tx_pool.ml b/etherlink/bin_node/lib_dev/tx_pool.ml index 8405d0ce7c984b9593a373fc5a805accccacbf08..7e1bea8e69d43e582f3d19b0cc5e40ff0ff35eb7 100644 --- a/etherlink/bin_node/lib_dev/tx_pool.ml +++ b/etherlink/bin_node/lib_dev/tx_pool.ml @@ -16,6 +16,8 @@ module Pool = struct raw_tx : string; (* Current transaction. *) gas_price : Z.t; (* The maximum price the user can pay for fees. *) gas_limit : Z.t; (* The maximum limit the user can reach in terms of gas. *) + inclusion_timestamp : Time.Protocol.t; + (* Time of inclusion in the transaction pool. *) } type t = { @@ -32,9 +34,18 @@ module Pool = struct let* nonce = Ethereum_types.transaction_nonce raw_tx in let* gas_price = Ethereum_types.transaction_gas_price raw_tx in let* gas_limit = Ethereum_types.transaction_gas_limit raw_tx in + let inclusion_timestamp = Helpers.now () in (* Add the transaction to the user's transaction map *) let transactions = - let transaction = {index = global_index; raw_tx; gas_price; gas_limit} in + let transaction = + { + index = global_index; + raw_tx; + gas_price; + gas_limit; + inclusion_timestamp; + } + in Pkey_map.update pkey (function @@ -113,6 +124,7 @@ type parameters = { rollup_node : (module Services_backend_sig.S); smart_rollup_address : string; mode : mode; + tx_timeout_limit : int64; } module Types = struct @@ -121,6 +133,7 @@ module Types = struct smart_rollup_address : string; mutable pool : Pool.t; mode : mode; + tx_timeout_limit : int64; mutable locked : bool; } @@ -267,6 +280,12 @@ let can_prepay ~balance ~gas_price ~gas_limit = let can_pay_with_current_base_fee ~gas_price ~base_fee_per_gas = gas_price >= base_fee_per_gas +(** Check if a transaction timed out since the moment it was included in the + transaction pool. *) +let transaction_timed_out ~tx_timeout_limit ~current_timestamp + ~inclusion_timestamp = + Time.Protocol.diff current_timestamp inclusion_timestamp >= tx_timeout_limit + let pop_transactions state ~maximum_cumulative_size = let open Lwt_result_syntax in let Types. @@ -274,6 +293,7 @@ let pop_transactions state ~maximum_cumulative_size = rollup_node = (module Rollup_node : Services_backend_sig.S); pool; locked; + tx_timeout_limit; _; } = state @@ -293,18 +313,23 @@ let pop_transactions state ~maximum_cumulative_size = addresses in let addr_with_nonces = List.filter_ok addr_with_nonces in - (* Remove transactions with too low nonce and the ones that + (* Remove transactions with too low nonce, timed-out and the ones that can not be prepayed anymore. *) let* (Qty base_fee_per_gas) = Rollup_node.base_fee_per_gas () in + let current_timestamp = Helpers.now () in let pool = addr_with_nonces |> List.fold_left (fun pool (pkey, balance, current_nonce) -> Pool.remove pkey - (fun nonce {gas_limit; gas_price; _} -> + (fun nonce {gas_limit; gas_price; inclusion_timestamp; _} -> nonce < current_nonce - || not (can_prepay ~balance ~gas_price ~gas_limit)) + || (not (can_prepay ~balance ~gas_price ~gas_limit)) + || transaction_timed_out + ~current_timestamp + ~inclusion_timestamp + ~tx_timeout_limit) pool) pool in @@ -440,7 +465,8 @@ module Handlers = struct type launch_error = error trace let on_launch _w () - ({rollup_node; smart_rollup_address; mode} : Types.parameters) = + ({rollup_node; smart_rollup_address; mode; tx_timeout_limit} : + Types.parameters) = let state = Types. { @@ -448,6 +474,7 @@ module Handlers = struct smart_rollup_address; pool = Pool.empty; mode; + tx_timeout_limit; locked = false; } in diff --git a/etherlink/bin_node/lib_dev/tx_pool.mli b/etherlink/bin_node/lib_dev/tx_pool.mli index b9ea9394a968d48d357553894a0e62be4d5c030f..8529448cd17b519ff6ba2736f98f869ccb6709ee 100644 --- a/etherlink/bin_node/lib_dev/tx_pool.mli +++ b/etherlink/bin_node/lib_dev/tx_pool.mli @@ -2,6 +2,7 @@ (* *) (* SPDX-License-Identifier: MIT *) (* Copyright (c) 2023 Marigold *) +(* Copyright (c) 2024 Functori *) (* *) (*****************************************************************************) @@ -11,6 +12,7 @@ type parameters = { rollup_node : (module Services_backend_sig.S); (** The backend RPC module. *) smart_rollup_address : string; (** The address of the smart rollup. *) mode : mode; + tx_timeout_limit : int64; (** TTL of a transaction inside the pool. *) } (** [start parameters] starts the tx-pool *) diff --git a/etherlink/bin_node/main.ml b/etherlink/bin_node/main.ml index 403d0ed5bafbbfce7ff6da9a8ce6285086f1879c..bbad89c9e9a2e7418a2ccb13d7b1e34e40d3c122 100644 --- a/etherlink/bin_node/main.ml +++ b/etherlink/bin_node/main.ml @@ -2,7 +2,7 @@ (* *) (* Open Source License *) (* Copyright (c) 2023 Nomadic Labs *) -(* Copyright (c) 2023 Functori *) +(* Copyright (c) 2023-2024 Functori *) (* Copyright (c) 2023 Marigold *) (* *) (* Permission is hereby granted, free of charge, to any person obtaining a *) @@ -343,6 +343,14 @@ let parent_hash_arg = ~default: "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" +let tx_pool_timeout_limit_arg = + Tezos_clic.default_arg + ~long:"tx-pool-timeout-limit" + ~placeholder:"3_600" + ~default:"3_600" + ~doc:"Transaction timeout limit inside the transaction pool (in seconds)." + Params.int + let sequencer_key_arg = Tezos_clic.arg ~long:"sequencer-key" @@ -431,7 +439,7 @@ let sequencer_command = let open Lwt_result_syntax in command ~desc:"Start the EVM node in sequencer mode" - (args20 + (args21 data_dir_arg rpc_addr_arg rpc_port_arg @@ -451,6 +459,7 @@ let sequencer_command = max_number_of_chunks_arg devmode_arg wallet_dir_arg + tx_pool_timeout_limit_arg (Client_config.password_filename_arg ())) (prefixes ["run"; "sequencer"; "with"; "endpoint"] @@ param @@ -480,6 +489,7 @@ let sequencer_command = max_number_of_chunks, devmode, wallet_dir, + tx_pool_timeout_limit, password_filename ) rollup_node_endpoint sequencer_str @@ -533,6 +543,7 @@ let sequencer_command = ?rpc_port ?cors_origins ?cors_headers + ~tx_pool_timeout_limit:(Int64.of_int tx_pool_timeout_limit) ~sequencer () in diff --git a/etherlink/tezt/lib/evm_node.ml b/etherlink/tezt/lib/evm_node.ml index 9972c90bfd1bc1cbf7a9bb2f51157e92bf3d81f2..a2b0abe38f7650198c8a35b1317f37f677b812dc 100644 --- a/etherlink/tezt/lib/evm_node.ml +++ b/etherlink/tezt/lib/evm_node.ml @@ -4,6 +4,7 @@ (* Copyright (c) 2023 Nomadic Labs *) (* Copyright (c) 2023 Functori *) (* Copyright (c) 2023 Marigold *) +(* Copyright (c) 2024 Functori *) (* *) (* Permission is hereby granted, free of charge, to any person obtaining a *) (* copy of this software and associated documentation files (the "Software"),*) @@ -47,6 +48,7 @@ type mode = max_number_of_chunks : int option; devmode : bool; wallet_dir : string option; + tx_pool_timeout_limit : int option; } | Proxy of {devmode : bool} @@ -445,6 +447,7 @@ let run_args evm_node = max_number_of_chunks; devmode; wallet_dir; + tx_pool_timeout_limit; } -> [ "run"; @@ -494,6 +497,10 @@ let run_args evm_node = max_number_of_chunks @ Cli_arg.optional_switch "devmode" devmode @ Cli_arg.optional_arg "wallet-dir" Fun.id wallet_dir + @ Cli_arg.optional_arg + "tx-pool-timeout-limit" + string_of_int + tx_pool_timeout_limit | Observer {preimages_dir; initial_kernel; rollup_node_endpoint} -> [ "run"; diff --git a/etherlink/tezt/lib/evm_node.mli b/etherlink/tezt/lib/evm_node.mli index 54e175efeadae405ac1d4f0d5bea9c51f1913a14..0c2410e63ae08bb5bdf62a8d7b75ec22007fb681 100644 --- a/etherlink/tezt/lib/evm_node.mli +++ b/etherlink/tezt/lib/evm_node.mli @@ -4,6 +4,7 @@ (* Copyright (c) 2023 Nomadic Labs *) (* Copyright (c) 2023 Functori *) (* Copyright (c) 2023 Marigold *) +(* Copyright (c) 2024 Functori *) (* *) (* Permission is hereby granted, free of charge, to any person obtaining a *) (* copy of this software and associated documentation files (the "Software"),*) @@ -59,6 +60,8 @@ type mode = max_number_of_chunks : int option; devmode : bool; (** --devmode flag. *) wallet_dir : string option; (** --wallet-dir: client directory. *) + tx_pool_timeout_limit : int option; + (** --tx-pool-timeout-limit: transaction timeout inside the pool. *) } | Proxy of {devmode : bool (** --devmode flag. *)} diff --git a/etherlink/tezt/tests/evm_rollup.ml b/etherlink/tezt/tests/evm_rollup.ml index 0299efd311484b84410312a0990d10fc2193f0ae..8cc79eea6db292dd013e96a31203854703b6f61c 100644 --- a/etherlink/tezt/tests/evm_rollup.ml +++ b/etherlink/tezt/tests/evm_rollup.ml @@ -284,8 +284,8 @@ let setup_evm_kernel ?(setup_kernel_root_hash = true) ?config ?(bootstrap_accounts = Eth_account.bootstrap_accounts) ?(with_administrator = true) ?da_fee_per_byte ?minimum_base_fee_per_gas ~admin ?sequencer_admin ?commitment_period ?challenge_window ?timestamp - ?(setup_mode = Setup_proxy {devmode = true}) ?(force_install_kernel = true) - protocol = + ?tx_pool_timeout_limit ?(setup_mode = Setup_proxy {devmode = true}) + ?(force_install_kernel = true) protocol = let* node, client = setup_l1 ?commitment_period ?challenge_window ?timestamp protocol in @@ -409,6 +409,7 @@ let setup_evm_kernel ?(setup_kernel_root_hash = true) ?config max_number_of_chunks = None; devmode; wallet_dir = Some (Client.base_dir client); + tx_pool_timeout_limit; }) in let* evm_node = @@ -4519,6 +4520,7 @@ let test_migrate_proxy_to_sequencer_future = max_number_of_chunks = None; devmode = true; wallet_dir = Some (Client.base_dir client); + tx_pool_timeout_limit = None; } in Evm_node.create ~mode (Sc_rollup_node.endpoint sc_rollup_node) @@ -4681,6 +4683,7 @@ let test_migrate_proxy_to_sequencer_past = max_number_of_chunks = None; devmode = true; wallet_dir = Some (Client.base_dir client); + tx_pool_timeout_limit = None; } in Evm_node.create ~mode (Sc_rollup_node.endpoint sc_rollup_node) @@ -5179,6 +5182,104 @@ let test_outbox_size_limit_resilience ~slow = unit) else unit +let test_tx_pool_timeout = + Protocol.register_test + ~__FILE__ + ~tags:["evm"; "tx_pool"; "timeout"] + ~title:"Check that transactions correctly timeout." + ~uses:(fun _protocol -> + [ + Constant.octez_smart_rollup_node; + Constant.octez_evm_node; + Constant.smart_rollup_installer; + Constant.WASM.evm_kernel; + ]) + @@ fun protocol -> + let sequencer_admin = Constant.bootstrap1 in + let admin = Some Constant.bootstrap3 in + let setup_mode = + Setup_sequencer + { + time_between_blocks = Some Nothing; + sequencer = sequencer_admin; + devmode = true; + } + in + let ttl = 15 in + let* {evm_node = sequencer_node; _} = + setup_evm_kernel + ~sequencer_admin + ~admin + ~minimum_base_fee_per_gas:base_fee_for_hardcoded_tx + ~tx_pool_timeout_limit:ttl + ~setup_mode + protocol + in + (* We send one transaction and produce a block immediatly to check that it's included + as it should (within the TTL that was set). *) + let tx = + (* { "chainId": "1337", + "type": "LegacyTransaction", + "valid": true, + "hash": "0xb941cbf32821471381b6f003f9013b95c788ad24260d2af54848a5b504c09bb0", + "nonce": "0", + "gasPrice": "21000", + "gasLimit": "2000000", + "from": "0x6ce4d79d4E77402e1ef3417Fdda433aA744C6e1c", + "to": "0x6ce4d79d4e77402e1ef3417fdda433aa744c6e1c", + "v": "0a95", + "r": "964f3d64696410dc1054af0aca06d5a4005a3bdf3db0b919e3de207af93e1004", + "s": "3eb79935b4e15a576955c104fd6a614437dd0464d382198dde4c52a8eed4061a", + "value": "0" } *) + "f86480825208831e8480946ce4d79d4e77402e1ef3417fdda433aa744c6e1c8080820a95a0964f3d64696410dc1054af0aca06d5a4005a3bdf3db0b919e3de207af93e1004a03eb79935b4e15a576955c104fd6a614437dd0464d382198dde4c52a8eed4061a" + in + let*@ tx_hash_expected = Rpc.send_raw_transaction ~raw_tx:tx sequencer_node in + let*@ block_number = Rpc.produce_block sequencer_node in + let*@ block = + Rpc.get_block_by_number ~block:(Int.to_string block_number) sequencer_node + in + let tx_hash = + match block.transactions with + | Hash txs -> List.hd txs + | Empty -> + Test.fail + "Inspected block should contain a list of one transaction hash and \ + not be empty." + | Full _ -> + Test.fail + "Inspected block should contain a list of one transaction hash, not \ + full objects." + in + Check.((tx_hash = tx_hash_expected) string) + ~error_msg:"Expected transaction hash is %R, got %L" ; + (* We send one transaction and produce a block after the TTL to check that the + produced block is empty. *) + let tx' = + (* { "chainId": "1337", + "type": "LegacyTransaction", + "valid": true, + "hash": "0x51a24a5cf2eb3095f522e4c500b1bf5b0de6476f04a108ea1005cfef7ceec750", + "nonce": "1", + "gasPrice": "21000", + "gasLimit": "2000000", + "from": "0x6ce4d79d4E77402e1ef3417Fdda433aA744C6e1c", + "to": "0x6ce4d79d4e77402e1ef3417fdda433aa744c6e1c", + "v": "0a95", + "r": "7298a47ad7fcbe70dc9d3705af6e47147364c5ac8ede95fb561ffaa3443dd776", + "s": "7042e72941ffdef02c773b7289d7e4241a5c819e78c7bfb362c7f151b0ba3e9e", + "value": "0" } *) + "f86401825208831e8480946ce4d79d4e77402e1ef3417fdda433aa744c6e1c8080820a95a07298a47ad7fcbe70dc9d3705af6e47147364c5ac8ede95fb561ffaa3443dd776a07042e72941ffdef02c773b7289d7e4241a5c819e78c7bfb362c7f151b0ba3e9e" + in + let*@ _tx_hash' = Rpc.send_raw_transaction ~raw_tx:tx' sequencer_node in + let* () = Lwt_unix.sleep (Int.to_float ttl *. 1.5) in + let*@ block_number = Rpc.produce_block sequencer_node in + let*@ block = + Rpc.get_block_by_number ~block:(Int.to_string block_number) sequencer_node + in + match block.transactions with + | Empty -> unit + | _ -> Test.fail "Inspected block shoud be empty." + let register_evm_node ~protocols = test_originate_evm_kernel protocols ; test_kernel_root_hash_originate_absent protocols ; @@ -5273,7 +5374,8 @@ let register_evm_node ~protocols = test_blockhash_opcode protocols ; test_revert_is_correctly_propagated protocols ; test_outbox_size_limit_resilience ~slow:true protocols ; - test_outbox_size_limit_resilience ~slow:false protocols + test_outbox_size_limit_resilience ~slow:false protocols ; + test_tx_pool_timeout protocols let protocols = Protocol.all diff --git a/etherlink/tezt/tests/evm_sequencer.ml b/etherlink/tezt/tests/evm_sequencer.ml index 835b08f85e788e49a365e5ffa1fa828439d683bd..8295d2f58e54fe55a6bd51b8533350d915155557 100644 --- a/etherlink/tezt/tests/evm_sequencer.ml +++ b/etherlink/tezt/tests/evm_sequencer.ml @@ -3,6 +3,7 @@ (* SPDX-License-Identifier: MIT *) (* Copyright (c) 2023 Nomadic Labs *) (* Copyright (c) 2024 Trilitech *) +(* Copyright (c) 2024 Functori *) (* *) (*****************************************************************************) @@ -204,6 +205,7 @@ let setup_sequencer ?(devmode = true) ?config ?genesis_timestamp max_number_of_chunks; devmode; wallet_dir = Some (Client.base_dir client); + tx_pool_timeout_limit = None; } in let* sequencer =