From f2c85957f2d8cc7705175d999e87ec4500ab3adb Mon Sep 17 00:00:00 2001 From: Thomas Letan Date: Tue, 2 Apr 2024 23:14:51 +0200 Subject: [PATCH] EVM Node: Fix off-by-one in the stream RPC for blueprints When an observer starts, it connects to another EVM node to fetch blueprints, starting from `next_blueprint_number'. If (1) it was in sync with its EVM node endpoint, and (2) it is just stooped and restarted, then from the current implementation of the stream RPC, it is requesting a blueprint from the future, and the RPC fails with [ { "kind": "temporary", "id": "failure", "msg": "Cannot start watching from a level in the future" } ] This patch changes the behavior to allow an observer node to wait for the next level. It is not clear why the observer node was not failing without this patch... --- etherlink/bin_node/lib_dev/evm_services.ml | 7 +++--- etherlink/tezt/tests/evm_sequencer.ml | 27 ++++++++++++++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/etherlink/bin_node/lib_dev/evm_services.ml b/etherlink/bin_node/lib_dev/evm_services.ml index 5e2213a48182..6dcdd95835d7 100644 --- a/etherlink/bin_node/lib_dev/evm_services.ml +++ b/etherlink/bin_node/lib_dev/evm_services.ml @@ -41,10 +41,9 @@ let create_blueprint_watcher_service from_level = (* input source block creating a stream to observe the events *) let* head_info = Evm_context.head_info () in let (Qty next) = head_info.next_blueprint_number in - let head_level = Z.pred next in let* () = - if Z.(Compare.(head_level < of_int64 from_level)) then - Stdlib.failwith "Cannot start watching from a level in the future" + if Z.(Compare.(next < of_int64 from_level)) then + Stdlib.failwith "Cannot start watching from a level too far in the future" else return_unit in @@ -52,7 +51,7 @@ let create_blueprint_watcher_service from_level = let next = let next_level_requested = ref Z.(of_int64 from_level) in fun () -> - if Z.Compare.(!next_level_requested <= head_level) then ( + if Z.Compare.(!next_level_requested < next) then ( let current_request = !next_level_requested in (next_level_requested := Z.(succ current_request)) ; let* blueprint = Evm_context.blueprint (Qty current_request) in diff --git a/etherlink/tezt/tests/evm_sequencer.ml b/etherlink/tezt/tests/evm_sequencer.ml index 250dd8a829a8..50dda3a10f12 100644 --- a/etherlink/tezt/tests/evm_sequencer.ml +++ b/etherlink/tezt/tests/evm_sequencer.ml @@ -1164,6 +1164,32 @@ let test_observer_applies_blueprint = unit +let test_observer_applies_blueprint_when_restarted = + Protocol.register_test + ~__FILE__ + ~tags:["evm"; "observer"] + ~title:"Can restart an Observer node" + ~uses + @@ fun protocol -> + (* Start the evm node *) + let* {sequencer; observer; _} = + setup_sequencer ~time_between_blocks:Nothing protocol + in + + (* We produce a block and check the observer applies it. *) + let* _ = Evm_node.wait_for_blueprint_applied observer 1 + and* _ = Rpc.produce_block sequencer in + + (* We restart the observer *) + let* () = Evm_node.terminate observer in + let* () = Evm_node.run observer in + + (* We produce a block and check the observer applies it. *) + let* _ = Evm_node.wait_for_blueprint_applied observer 2 + and* _ = Rpc.produce_block sequencer in + + unit + let test_observer_forwards_transaction = Protocol.register_test ~__FILE__ @@ -2726,6 +2752,7 @@ let () = test_init_from_rollup_node_data_dir protocols ; test_init_from_rollup_node_with_delayed_inbox protocols ; test_observer_applies_blueprint protocols ; + test_observer_applies_blueprint_when_restarted protocols ; test_observer_forwards_transaction protocols ; test_sequencer_is_reimbursed protocols ; test_upgrade_kernel_auto_sync protocols ; -- GitLab