From 9a2c001b8f7ddc37f91cc96e67c39ab5e1a30af9 Mon Sep 17 00:00:00 2001 From: arnaud Date: Mon, 2 Jun 2025 10:11:20 +0200 Subject: [PATCH 1/5] Tezlink/Backend: Rename header into block As this function returns a block and will be used by multiple RPCs others than header --- etherlink/bin_node/lib_dev/tezlink/tezlink_backend_sig.ml | 2 +- etherlink/bin_node/lib_dev/tezlink/tezos_services.ml | 4 ++-- etherlink/bin_node/lib_dev/tezlink_services_impl.ml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/etherlink/bin_node/lib_dev/tezlink/tezlink_backend_sig.ml b/etherlink/bin_node/lib_dev/tezlink/tezlink_backend_sig.ml index f862f82aa481..4f62a4cb54d3 100644 --- a/etherlink/bin_node/lib_dev/tezlink/tezlink_backend_sig.ml +++ b/etherlink/bin_node/lib_dev/tezlink/tezlink_backend_sig.ml @@ -28,7 +28,7 @@ module type S = sig val counter : [`Main] -> block_param -> Tezos_types.Contract.t -> Z.t tzresult Lwt.t - val header : [`Main] -> block_param -> L2_types.Tezos_block.t tzresult Lwt.t + val block : [`Main] -> block_param -> L2_types.Tezos_block.t tzresult Lwt.t val bootstrapped : unit -> (Ethereum_types.block_hash * Time.Protocol.t) tzresult Lwt.t diff --git a/etherlink/bin_node/lib_dev/tezlink/tezos_services.ml b/etherlink/bin_node/lib_dev/tezlink/tezos_services.ml index 44074a22f8b8..915a92405099 100644 --- a/etherlink/bin_node/lib_dev/tezlink/tezos_services.ml +++ b/etherlink/bin_node/lib_dev/tezlink/tezos_services.ml @@ -534,8 +534,8 @@ let register_block_services ~l2_chain_id ~impl:(fun {chain; block} () () -> let*? chain = check_chain chain in let*? block = check_block block in - let* header = Backend.header chain block in - Lwt_result_syntax.return (header, chain)) + let* tezlink_block = Backend.block chain block in + Lwt_result_syntax.return (tezlink_block, chain)) ~convert_output: (Protocol_types.Block_header.tezlink_block_to_block_header ~l2_chain_id) diff --git a/etherlink/bin_node/lib_dev/tezlink_services_impl.ml b/etherlink/bin_node/lib_dev/tezlink_services_impl.ml index d103d355b365..f1abaf1fbd49 100644 --- a/etherlink/bin_node/lib_dev/tezlink_services_impl.ml +++ b/etherlink/bin_node/lib_dev/tezlink_services_impl.ml @@ -112,7 +112,7 @@ module Make (Backend : Backend) (Block_storage : Tezlink_block_storage_sig.S) : let `Main = chain in Tezlink_durable_storage.counter (read ~block) c - let header chain block = + let block chain block = let open Lwt_result_syntax in let `Main = chain in let* block_number = shell_block_param_to_block_number block in -- GitLab From 832985adf2e0033244c64571a27cc9e4d7269887 Mon Sep 17 00:00:00 2001 From: arnaud Date: Wed, 28 May 2025 14:04:51 +0200 Subject: [PATCH 2/5] Tezlink/Node: Import block info service --- etherlink/bin_node/lib_dev/tezlink/tezos_services.ml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/etherlink/bin_node/lib_dev/tezlink/tezos_services.ml b/etherlink/bin_node/lib_dev/tezlink/tezos_services.ml index 915a92405099..744922bb871f 100644 --- a/etherlink/bin_node/lib_dev/tezlink/tezos_services.ml +++ b/etherlink/bin_node/lib_dev/tezlink/tezos_services.ml @@ -424,6 +424,18 @@ module Imported_services = struct Block_hash.t * Block_header.t ) Tezos_rpc.Service.t = Tezos_shell_services.Monitor_services.S.heads + + let _block_info : + ( [`GET], + tezlink_rpc_context, + tezlink_rpc_context, + < force_metadata : bool + ; metadata : [`Always | `Never] option + ; version : Tezlink_protocols.Shell_impl.version >, + unit, + Tezlink_protocols.Shell_impl.version * Block_services.block_info ) + Tezos_rpc.Service.t = + import_service Block_services.S.info end let chain_directory_path = Tezos_shell_services.Chain_services.path -- GitLab From b35541b6917e4e90416a5e117cee382668962c73 Mon Sep 17 00:00:00 2001 From: arnaud Date: Wed, 28 May 2025 14:51:46 +0200 Subject: [PATCH 3/5] Tezlink/Node: Introduce conversion function for blocks informations --- .../lib_dev/tezlink/tezos_services.ml | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/etherlink/bin_node/lib_dev/tezlink/tezos_services.ml b/etherlink/bin_node/lib_dev/tezlink/tezos_services.ml index 744922bb871f..ce63d3104038 100644 --- a/etherlink/bin_node/lib_dev/tezlink/tezos_services.ml +++ b/etherlink/bin_node/lib_dev/tezlink/tezos_services.ml @@ -145,6 +145,29 @@ module Protocol_types = struct {chain_id; hash; shell; protocol_data} in return block_header + + let tezlink_block_to_raw_block_header block = + let open Result_syntax in + let* protocol_data = Protocol_data.get_mock_protocol_data in + let* shell = tezlink_block_to_shell_header block in + let raw_block_header : Block_services.raw_block_header = + {shell; protocol_data} + in + return raw_block_header + end + + module Block = struct + let _tezlink_block_to_block_info ~l2_chain_id (version, block, chain) = + let open Result_syntax in + let* chain_id = tezlink_to_tezos_chain_id ~l2_chain_id chain in + let* hash = + ethereum_to_tezos_block_hash block.L2_types.Tezos_block.hash + in + let* header = Block_header.tezlink_block_to_raw_block_header block in + let block_info : Block_services.block_info = + {chain_id; hash; header; metadata = None; operations = []} + in + return (version, block_info) end module Level = struct -- GitLab From 6f4b47afd8c924d807086e6eaa43345dd38f1041 Mon Sep 17 00:00:00 2001 From: arnaud Date: Wed, 28 May 2025 18:29:48 +0200 Subject: [PATCH 4/5] Tezlink/Node: RPC block implementation --- .../bin_node/lib_dev/tezlink/tezos_services.ml | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/etherlink/bin_node/lib_dev/tezlink/tezos_services.ml b/etherlink/bin_node/lib_dev/tezlink/tezos_services.ml index ce63d3104038..ccf82c362323 100644 --- a/etherlink/bin_node/lib_dev/tezlink/tezos_services.ml +++ b/etherlink/bin_node/lib_dev/tezlink/tezos_services.ml @@ -157,7 +157,7 @@ module Protocol_types = struct end module Block = struct - let _tezlink_block_to_block_info ~l2_chain_id (version, block, chain) = + let tezlink_block_to_block_info ~l2_chain_id (version, block, chain) = let open Result_syntax in let* chain_id = tezlink_to_tezos_chain_id ~l2_chain_id chain in let* hash = @@ -448,7 +448,7 @@ module Imported_services = struct Tezos_rpc.Service.t = Tezos_shell_services.Monitor_services.S.heads - let _block_info : + let block_info : ( [`GET], tezlink_rpc_context, tezlink_rpc_context, @@ -593,6 +593,17 @@ let register_block_services ~l2_chain_id _chain_id, _operation_inclusion_latency ) -> return (operation.protocol_data, Mock.receipts)) + (* TODO: https://gitlab.com/tezos/tezos/-/issues/7993 *) + (* RPCs at directory level doesn't appear properly in the describe RPC *) + |> register_with_conversion + ~service:Imported_services.block_info + ~impl:(fun {block; chain} q () -> + let*? chain = check_chain chain in + let*? block = check_block block in + let* tezlink_block = Backend.block chain block in + Lwt_result_syntax.return (q#version, tezlink_block, chain)) + ~convert_output: + (Protocol_types.Block.tezlink_block_to_block_info ~l2_chain_id) in Tezos_rpc.Directory.prefix block_directory_path -- GitLab From e9bc4af38c88a77e884e6dadc295beec2e1ec218 Mon Sep 17 00:00:00 2001 From: arnaud Date: Mon, 2 Jun 2025 11:09:48 +0200 Subject: [PATCH 5/5] Tezlink/RPC/Tezt: Test th block_info rpc consistency --- etherlink/tezt/lib/test_helpers.ml | 29 +++++++++++++++++ etherlink/tezt/lib/test_helpers.mli | 9 +++++ etherlink/tezt/tests/evm_sequencer.ml | 47 +++++++++++++++++++++++++-- 3 files changed, 82 insertions(+), 3 deletions(-) diff --git a/etherlink/tezt/lib/test_helpers.ml b/etherlink/tezt/lib/test_helpers.ml index 8daacb3f73d1..40e3ae1f24a6 100644 --- a/etherlink/tezt/lib/test_helpers.ml +++ b/etherlink/tezt/lib/test_helpers.ml @@ -152,6 +152,35 @@ let check_header ~previous_header ~current_header ~chain_id ~current_timestamp = "Expected the timestamp of the current_block to be %R, but got %L" | _ -> () +(* Block info contains a raw header that differs slightly from the header returned by + the header RPC. + We need to append the hash and chain_id fields to our raw_header so that the function + check_header doesn't fail. *) +let block_info_to_header block_info = + let raw_header = JSON.(block_info |-> "header") in + let hash_raw_header = JSON.(put ("hash", block_info |-> "hash") raw_header) in + let header = + JSON.(put ("chain_id", block_info |-> "chain_id") hash_raw_header) + in + header + +let check_block_info ~previous_block_info ~current_block_info ~chain_id + ~current_timestamp = + let () = + check_header + ~previous_header:(block_info_to_header previous_block_info) + ~current_header:(block_info_to_header current_block_info) + ~chain_id + ~current_timestamp + in + (* For now operations are converted to dummy string as the list should be empty. + We convert to string operations to use the Check module *) + let operations = + JSON.(current_block_info |-> "operations" |> as_list |> List.map as_string) + in + Check.((operations = []) (list string)) + ~error_msg:"List of operations is expected to be empty for now" + let next_evm_level ~evm_node ~sc_rollup_node ~client = match Evm_node.mode evm_node with | Proxy -> diff --git a/etherlink/tezt/lib/test_helpers.mli b/etherlink/tezt/lib/test_helpers.mli index 76d41ec1ecca..6a5330deb163 100644 --- a/etherlink/tezt/lib/test_helpers.mli +++ b/etherlink/tezt/lib/test_helpers.mli @@ -87,6 +87,15 @@ val check_header : current_timestamp:string option -> unit +(** [check_block_info ~previous_block_info ~current_block_info] checks that two + consecutive block's info are consistent. *) +val check_block_info : + previous_block_info:JSON.t -> + current_block_info:JSON.t -> + chain_id:int option -> + current_timestamp:string option -> + unit + (** [next_evm_level ~evm_node ~sc_rollup_node ~client] moves [evm_node] to the next L2 level. *) val next_evm_level : diff --git a/etherlink/tezt/tests/evm_sequencer.ml b/etherlink/tezt/tests/evm_sequencer.ml index 4a3cd0de94d5..0cb9c92f7324 100644 --- a/etherlink/tezt/tests/evm_sequencer.ml +++ b/etherlink/tezt/tests/evm_sequencer.ml @@ -767,7 +767,7 @@ let test_tezlink_header = let endpoint = Client.( Foreign_endpoint - {(Evm_node.rpc_endpoint_record sequencer) with path = "tezlink"}) + {(Evm_node.rpc_endpoint_record sequencer) with path = "/tezlink"}) in let*@ n = Rpc.produce_block sequencer in @@ -793,6 +793,46 @@ let test_tezlink_header = ~chain_id ~current_timestamp:(Some current_timestamp) +let test_tezlink_block_info = + register_tezlink_test + ~title:"Test of the block_info rpc" + ~tags:["rpc"; "block_info"] + @@ fun {sequencer; client; l2_chains; _} _protocol -> + let chain_id = + match l2_chains with + | [l2_chain] -> Some l2_chain.l2_chain_id + | _ -> Test.fail ~__LOC__ "Expected one l2 chain" + in + + let endpoint = + Client.( + Foreign_endpoint + {(Evm_node.rpc_endpoint_record sequencer) with path = "/tezlink"}) + in + + let*@ n = Rpc.produce_block sequencer in + let* () = Evm_node.wait_for_blueprint_applied sequencer n in + let current_timestamp = + Tezos_base.Time.( + System.now () |> System.to_protocol |> Protocol.to_notation) + in + let*@ n = Rpc.produce_block ~timestamp:current_timestamp sequencer in + let* () = Evm_node.wait_for_blueprint_applied sequencer n in + let* block_1 = + Client.RPC.call ~hooks ~endpoint client + @@ RPC.get_chain_block ~block:"head~1" () + in + let* block_2 = + Client.RPC.call ~hooks ~endpoint client @@ RPC.get_chain_block () + in + + return + @@ check_block_info + ~previous_block_info:block_1 + ~current_block_info:block_2 + ~chain_id + ~current_timestamp:(Some current_timestamp) + let test_tezlink_bootstrapped = register_tezlink_test ~title:"Test of the bootstrapped rpc" @@ -841,7 +881,7 @@ let test_tezlink_monitor_heads = let open Lwt.Syntax in (* Prepare the RPC endpoint *) let rpc_info = Evm_node.rpc_endpoint_record sequencer in - let endpoint = Client.Foreign_endpoint {rpc_info with path = "tezlink"} in + let endpoint = Client.Foreign_endpoint {rpc_info with path = "/tezlink"} in let total_headers = 4 in @@ -13777,4 +13817,5 @@ let () = test_tezlink_chain_id [Alpha] ; test_tezlink_bootstrapped [Alpha] ; test_fa_deposit_can_be_claimed [Alpha] ; - test_eip2930_storage_access [Alpha] + test_eip2930_storage_access [Alpha] ; + test_tezlink_block_info [Alpha] -- GitLab