From 830c1bd40d6c0cbe6b8f207715ad8e79b1ab1be7 Mon Sep 17 00:00:00 2001 From: Valentin Chaboche Date: Fri, 25 Oct 2024 15:59:44 +0200 Subject: [PATCH 1/3] EVM/Node: estimate gas uses minimum base fee per gas for DA fees --- etherlink/bin_node/lib_dev/durable_storage_path.ml | 2 ++ etherlink/bin_node/lib_dev/durable_storage_path.mli | 2 ++ etherlink/bin_node/lib_dev/simulator.ml | 6 ++---- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/etherlink/bin_node/lib_dev/durable_storage_path.ml b/etherlink/bin_node/lib_dev/durable_storage_path.ml index afe94fde54bf..6aef664287da 100644 --- a/etherlink/bin_node/lib_dev/durable_storage_path.ml +++ b/etherlink/bin_node/lib_dev/durable_storage_path.ml @@ -30,6 +30,8 @@ end let chain_id = EVM.make "/chain_id" +let minimum_base_fee_per_gas = World_state.make "/fees/minimum_base_fee_per_gas" + let base_fee_per_gas = World_state.make "/fees/base_fee_per_gas" let da_fee_per_byte = World_state.make "/fees/da_fee_per_byte" diff --git a/etherlink/bin_node/lib_dev/durable_storage_path.mli b/etherlink/bin_node/lib_dev/durable_storage_path.mli index 919a8f50b644..d490a39ad07b 100644 --- a/etherlink/bin_node/lib_dev/durable_storage_path.mli +++ b/etherlink/bin_node/lib_dev/durable_storage_path.mli @@ -18,6 +18,8 @@ val evm_node_flag : path val chain_id : path +val minimum_base_fee_per_gas : path + val base_fee_per_gas : path val da_fee_per_byte : path diff --git a/etherlink/bin_node/lib_dev/simulator.ml b/etherlink/bin_node/lib_dev/simulator.ml index 878d6e1c9037..de1bf019d7ab 100644 --- a/etherlink/bin_node/lib_dev/simulator.ml +++ b/etherlink/bin_node/lib_dev/simulator.ml @@ -130,13 +130,11 @@ module Make (SimulationBackend : SimulationBackend) = struct in let* da_fee_per_byte = read_qty Durable_storage_path.da_fee_per_byte in let* (Qty gas_price) = - let path = Durable_storage_path.base_fee_per_gas in + let path = Durable_storage_path.minimum_base_fee_per_gas in let* gas_price_opt = read_qty path in match gas_price_opt with | None -> - (* Base fee per gas is supposed to be updated in the storage after - every block. *) - failwith "Internal error: base fee per gas is not found at %s" path + return (Ethereum_types.quantity_of_z (Z.of_string "1_000_000_000")) | Some gas_price -> return gas_price in let da_fee = Fees.gas_for_fees ?da_fee_per_byte ~gas_price tx_data in -- GitLab From 9653ffdd5861318421a3369b5c0adf01ba625205 Mon Sep 17 00:00:00 2001 From: Valentin Chaboche Date: Fri, 25 Oct 2024 15:59:59 +0200 Subject: [PATCH 2/3] EVM/Tezt: regression test --- .../kernel_evm/solidity_examples/batcher.sol | 13 ++++ etherlink/tezt/lib/evm_node.mli | 3 + etherlink/tezt/lib/solidity_contracts.ml | 7 ++ etherlink/tezt/tests/evm_sequencer.ml | 75 ++++++++++++++++++- 4 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 etherlink/kernel_evm/solidity_examples/batcher.sol diff --git a/etherlink/kernel_evm/solidity_examples/batcher.sol b/etherlink/kernel_evm/solidity_examples/batcher.sol new file mode 100644 index 000000000000..4a727dac51ca --- /dev/null +++ b/etherlink/kernel_evm/solidity_examples/batcher.sol @@ -0,0 +1,13 @@ +pragma solidity ^0.8.0; + +contract Batcher { + + function batchXTZ(uint256 n, uint256 amount) external { + uint256 i = 0; + for (i; i < n; i++) { + address f = 0xcD496958e71093470dA7D16C460b62dEbeD738Bc; + (bool success, ) = f.call{value: amount}(""); + require(success, "Transfer failed."); + } + } +} \ No newline at end of file diff --git a/etherlink/tezt/lib/evm_node.mli b/etherlink/tezt/lib/evm_node.mli index a23d061bcb84..261af6c7d51c 100644 --- a/etherlink/tezt/lib/evm_node.mli +++ b/etherlink/tezt/lib/evm_node.mli @@ -285,6 +285,9 @@ val spawn_run : ?extra_arguments:string list -> t -> Process.t Default [timeout] is 30 seconds, after which SIGKILL is sent. *) val terminate : ?timeout:float -> t -> unit Lwt.t +val resolve_or_timeout : + ?timeout:float -> t -> name:string -> 'a Lwt.t -> 'a Lwt.t + (** The same exact behavior as {!Sc_rollup_node.wait_for} but for the EVM node. *) val wait_for : ?where:string -> t -> string -> (JSON.t -> 'a option) -> 'a Lwt.t diff --git a/etherlink/tezt/lib/solidity_contracts.ml b/etherlink/tezt/lib/solidity_contracts.ml index 57fd7b08d7d5..2331fcc8267d 100644 --- a/etherlink/tezt/lib/solidity_contracts.ml +++ b/etherlink/tezt/lib/solidity_contracts.ml @@ -387,3 +387,10 @@ let state_override_tester_readable () = ~label:"state_override_tester_readable" ~contract:"StateOverrideTester" ~evm_version:"shanghai" + +let batcher () = + compile_contract + ~source:(solidity_contracts_path ^ "/batcher.sol") + ~label:"batcher" + ~contract:"Batcher" + ~evm_version:"shanghai" diff --git a/etherlink/tezt/tests/evm_sequencer.ml b/etherlink/tezt/tests/evm_sequencer.ml index 8ece6e4e5b89..31a1dc6075b4 100644 --- a/etherlink/tezt/tests/evm_sequencer.ml +++ b/etherlink/tezt/tests/evm_sequencer.ml @@ -6884,6 +6884,78 @@ let test_configuration_service = unit +let test_inconsistent_da_fees = + register_all + ~kernels:Kernel.all + ~tags:["evm"; "rpc"; "estimate_gas"; "da_fees"] + ~title:"Regression: da fees are inconsistent if gas price is provided" + ~time_between_blocks:Nothing + ~da_fee:(Wei.of_string "4_000_000_000") + @@ fun {sequencer; _} _protocol -> + (* There is an inconsistency in the gas estimation observed when the fee model + kicks in, i.e. minimum_base_fee_per_gas and base_fee_per_gas are different. + + The test serves as a non regression test. + *) + let* batcher = Solidity_contracts.batcher () in + let* () = Eth_cli.add_abi ~label:batcher.label ~abi:batcher.abi () in + let* batcher_contract, _tx_hash = + send_transaction_to_sequencer + (fun () -> + Eth_cli.deploy + ~source_private_key:Eth_account.bootstrap_accounts.(0).private_key + ~endpoint:(Evm_node.endpoint sequencer) + ~abi:batcher.abi + ~bin:batcher.bin) + sequencer + in + let* _tx = + send_transaction_to_sequencer + (Eth_cli.contract_send + ~source_private_key:Eth_account.bootstrap_accounts.(0).private_key + ~endpoint:(Evm_node.endpoint sequencer) + ~abi_label:batcher.label + ~address:batcher_contract + ~method_call:"batchXTZ(565, 0)") + sequencer + in + + let wait_for = + (* This event is emitted on invalid node DA fees. *) + Evm_node.( + resolve_or_timeout ~timeout:10. sequencer ~name:"wait_for_node_da_fees" + @@ wait_for sequencer "node_da_fees.v0" + @@ Fun.const (Some ())) + in + + let*@ _ = + Rpc.estimate_gas + [ + ( "data", + `String + "0x0b7d796e00000000000000000000000000000000000000000000000000000000000186a0" + ); + ("to", `String "0xCF02B9Ca488f8F6F4E28e37AA1bDD16b3F1b2aD8"); + ] + sequencer + in + let timeout = ref false in + let* () = + Lwt.catch + (fun () -> + let* () = wait_for in + unit) + (fun _exn -> + timeout := true ; + unit) + in + Check.is_true + !timeout + ~error_msg: + "The event should not be emitted, the wait_for_event is supposed to \ + timeout" ; + unit + let protocols = Protocol.all let () = @@ -6983,4 +7055,5 @@ let () = test_da_fees_after_execution protocols ; test_trace_transaction_calltracer_failed_create protocols ; test_configuration_service [Protocol.Alpha] ; - test_overwrite_simulation_tick_limit protocols + test_overwrite_simulation_tick_limit protocols ; + test_inconsistent_da_fees protocols -- GitLab From 992464d3a8cb94fcc25a1506c77cd76c25958c03 Mon Sep 17 00:00:00 2001 From: Valentin Chaboche Date: Fri, 25 Oct 2024 14:35:18 +0200 Subject: [PATCH 3/3] EVM/Tezt: foo or not to foo --- etherlink/tezt/tests/evm_sequencer.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etherlink/tezt/tests/evm_sequencer.ml b/etherlink/tezt/tests/evm_sequencer.ml index 31a1dc6075b4..26f51e648ccf 100644 --- a/etherlink/tezt/tests/evm_sequencer.ml +++ b/etherlink/tezt/tests/evm_sequencer.ml @@ -6800,7 +6800,7 @@ let test_tx_pool_replacing_transactions_on_limit () = let test_da_fees_after_execution = register_all ~time_between_blocks:Nothing - ~tags:["evm"; "da_fees"; "foo"] + ~tags:["evm"; "da_fees"] ~da_fee:(Wei.of_string "4_000_000_000_000") ~title:"da fees test" @@ fun {sequencer; _} _protocol -> -- GitLab