diff --git a/etherlink/bin_node/lib_dev/tezlink/tezlink_directory.ml b/etherlink/bin_node/lib_dev/tezlink/tezlink_directory.ml index 9be4bf299ad517e99ccb444a04fa1d7de17a23a5..aaca3d877acc02454988fda5e0bfe18d57bd90d5 100644 --- a/etherlink/bin_node/lib_dev/tezlink/tezlink_directory.ml +++ b/etherlink/bin_node/lib_dev/tezlink/tezlink_directory.ml @@ -303,6 +303,28 @@ let build_block_static_directory ~l2_chain_id ops in Lwt_result_syntax.return (param#version, receipts)) + |> register + ~service:Tezos_services.raw_json_cycle + ~impl:(fun ({block; chain}, _cycle) () () -> + let open Tezlink_mock in + let*? _chain = check_chain chain in + let*? _block = check_block block in + let consensus_pk = + Imported_protocol.Raw_context. + { + delegate = public_key_hash; + consensus_pk = public_key; + consensus_pkh = public_key_hash; + } + in + let delegate_sampler_state = + Storage_repr.Cycle.create_sample_state + ~consensus_pks:[(consensus_pk, 200000000000L)] + in + let selected_stake_distribution = [] in + Lwt_result.return + Storage_repr.Cycle. + {delegate_sampler_state; selected_stake_distribution}) let register_block_info ~l2_chain_id (module Backend : Tezlink_backend_sig.S) (module Block_header : HEADER) base_dir = diff --git a/etherlink/bin_node/lib_dev/tezlink/tezlink_mock.ml b/etherlink/bin_node/lib_dev/tezlink/tezlink_mock.ml index de140fe6bd85ff3211853631a35c8f3f90abeaa3..e998d7a2be263b12d079d0d1d488d52ebce1b5ab 100644 --- a/etherlink/bin_node/lib_dev/tezlink/tezlink_mock.ml +++ b/etherlink/bin_node/lib_dev/tezlink/tezlink_mock.ml @@ -34,6 +34,19 @@ let fitness = being replaced by actual data. *) let context = Context_hash.of_bytes_exn (Bytes.make 32 '\255') +let public_key_internal = + let pk_opt = + Tezos_crypto.Signature.Ed25519.Public_key.of_bytes_without_validation + (Bytes.make 32 '\000') + in + match pk_opt with None -> (* Unreachable *) assert false | Some pk -> pk + +let public_key : Imported_protocol.Alpha_context.public_key = + Ed25519 public_key_internal + +let public_key_hash : Imported_protocol.Alpha_context.public_key_hash = + Ed25519 (Tezos_crypto.Signature.Ed25519.Public_key.hash public_key_internal) + let contents : Alpha_context.Block_header.contents = { payload_hash = Imported_protocol.Block_payload_hash.zero; @@ -235,3 +248,69 @@ let version = network_version = Network_version.Internal_for_tests.mock (); commit_info = Some {commit_hash = ""; commit_date = ""}; } + +(* This module is a fake storage representation, the raw services gives access to the + real context. Unfortunately, some values are useless for Tezlink, so we don't want + to store them in the durable storage. So let's do their mock here *) +module Storage_repr = struct + module Cycle = struct + let delegate_sampler_state_encoding = + Imported_protocol.Sampler.encoding + Imported_protocol.Raw_context.consensus_pk_encoding + + let create_sample_state ~consensus_pks = + Imported_protocol.Sampler.create consensus_pks + + let selected_stake_distribution_encoding = + Data_encoding.( + Variable.list + (obj2 + (req "baker" Signature.Public_key_hash.encoding) + (req "active_stake" Imported_protocol.Stake_repr.encoding))) + + type storage_cycle = { + selected_stake_distribution : + (Signature.public_key_hash * Imported_protocol.Stake_repr.t) list; + delegate_sampler_state : + Imported_protocol.Raw_context.consensus_pk Imported_protocol.Sampler.t; + } + + let sampler_encoding = + let open Data_encoding in + conv + (fun {delegate_sampler_state; selected_stake_distribution} -> + ( (), + (), + delegate_sampler_state, + (), + (), + (), + (), + selected_stake_distribution, + () )) + (fun ( (), + (), + delegate_sampler_state, + (), + (), + (), + (), + selected_stake_distribution, + () ) -> {delegate_sampler_state; selected_stake_distribution}) + (obj9 + (req "already_denounced" empty) + (req "dal_already_denounced" empty) + (req "delegate_sampler_state" delegate_sampler_state_encoding) + (req "nonces" empty) + (req "pending_consensus_keys" empty) + (req "pending_staking_parameters" empty) + (req + "random_seed" + (constant + "0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8")) + (req + "selected_stake_distribution" + selected_stake_distribution_encoding) + (req "total_active_stake" empty)) + end +end diff --git a/etherlink/bin_node/lib_dev/tezlink/tezos_services.ml b/etherlink/bin_node/lib_dev/tezlink/tezos_services.ml index 0c0cc6ef35f3343dbb8dcbb3d9e32e4e56b4cad0..25710f73b7c9e2e01e26dc7ff3c3be69f1d9edbb 100644 --- a/etherlink/bin_node/lib_dev/tezlink/tezos_services.ml +++ b/etherlink/bin_node/lib_dev/tezlink/tezos_services.ml @@ -6,6 +6,7 @@ (*****************************************************************************) include Tezlink_imports +open Tezlink_mock (** We add to Imported_protocol the mocked protocol data used in headers *) module Imported_protocol = struct @@ -165,6 +166,11 @@ let wrap conv impl p q i = types in the signature of the service [s]. *) let import_service s = Tezos_rpc.Service.subst0 s +(** [import_service_with_arg s] makes it possible to substitute new [prefix] + types in the signature of the service [s]. It also substitute the [param] + but keeps the last arg of the n-uplet intact. *) +let import_service_with_arg s = Tezos_rpc.Service.subst1 s + type block = Tezos_shell_services.Block_services.block type chain = Tezos_shell_services.Chain_services.chain @@ -300,6 +306,25 @@ module Adaptive_issuance_services = struct expected_issuance_path end +(* Raw services normally represents the context of the Tezos blockchain. + But because context in Tezlink is different, we need to mock some rpcs + to make Tzkt indexing works. *) +module Raw_services = struct + let custom_root : tezlink_rpc_context Tezos_rpc.Path.context = + Tezos_rpc.Path.(open_root / "context" / "raw" / "json") + + let cycle = + let open Tezos_rpc in + Service.get_service + ~description: + "Returns the cycle . This RPC is a mock as there's no cycle notion \ + in Tezlink and doesn't represent what's in the context of a block" + ~query:Query.empty + ~output:Storage_repr.Cycle.sampler_encoding + Imported_env.RPC_path.( + custom_root / "cycle" /: Imported_protocol.Cycle_repr.rpc_arg) +end + (* This is where we import service declarations from the protocol. *) module Protocol_plugin_services = Imported_protocol_plugin.RPC.S @@ -344,7 +369,7 @@ let contract_info : unit, Imported_protocol_plugin.Contract_services.info ) Tezos_rpc.Service.t = - Tezos_rpc.Service.subst1 Imported_protocol_plugin.Contract_services.S.info + import_service_with_arg Imported_protocol_plugin.Contract_services.S.info let balance : ( [`GET], @@ -354,7 +379,7 @@ let balance : unit, Tezos_types.Tez.t ) Tezos_rpc.Service.t = - Tezos_rpc.Service.subst1 Imported_protocol_plugin.Contract_services.S.balance + import_service_with_arg Imported_protocol_plugin.Contract_services.S.balance let manager_key : ( [`GET], @@ -364,8 +389,8 @@ let manager_key : unit, Protocol_types.Alpha_context.public_key option ) Tezos_rpc.Service.t = - let open Tezos_rpc in - Service.subst1 Imported_protocol_plugin.Contract_services.S.manager_key + import_service_with_arg + Imported_protocol_plugin.Contract_services.S.manager_key let counter : ( [`GET], @@ -375,8 +400,7 @@ let counter : unit, Protocol_types.Counter.t ) Tezos_rpc.Service.t = - let open Tezos_rpc in - Service.subst1 Imported_protocol_plugin.Contract_services.S.counter + import_service_with_arg Imported_protocol_plugin.Contract_services.S.counter let constants : ( [`GET], @@ -455,7 +479,7 @@ let get_storage_normalized : Imported_protocol.Script_ir_unparser.unparsing_mode, Alpha_context.Script.expr option ) Tezos_rpc.Service.t = - Tezos_rpc.Service.subst1 + import_service_with_arg Imported_protocol_plugin.RPC.Contract.S.get_storage_normalized let injection_operation : @@ -480,3 +504,13 @@ let preapply_operations : list ) Tezos_rpc.Service.t = import_service Block_services.S.Helpers.Preapply.operations + +let raw_json_cycle : + ( [`GET], + tezlink_rpc_context, + tezlink_rpc_context * Imported_protocol.Cycle_repr.t, + unit, + unit, + Storage_repr.Cycle.storage_cycle ) + Tezos_rpc.Service.t = + import_service_with_arg Raw_services.cycle diff --git a/etherlink/tezt/tests/evm_sequencer.ml b/etherlink/tezt/tests/evm_sequencer.ml index a481635f72682dba5b8873c1929e9a7de6d6d762..7260f939cd1b16b21ca30afd03e4fde22b3fef1d 100644 --- a/etherlink/tezt/tests/evm_sequencer.ml +++ b/etherlink/tezt/tests/evm_sequencer.ml @@ -1454,6 +1454,33 @@ let test_tezlink_hash_rpc = ~error_msg:"Block hash should be different") ; unit +let test_tezlink_raw_json_cycle = + register_tezlink_test + ~title:"Test Tezlink raw json cycle rpc" + ~tags:["rpc"; "cycle"; "raw"] + @@ fun {sequencer; _} _protocol -> + let path_head = "/tezlink/chains/main/blocks/head/" in + let rpc_raw_json_cycle () = + let* res = + Curl.get_raw + ~args:["-v"] + (Evm_node.endpoint sequencer ^ path_head ^ "context/raw/json/cycle/0") + |> Runnable.run + in + return @@ JSON.parse ~origin:"curl_hash" res + in + let*@ _ = produce_block sequencer in + let* cycle_0 = rpc_raw_json_cycle () in + (* 0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8 is the mock value + used for the ranom seed and never changes *) + Check.( + JSON.( + cycle_0 |-> "random_seed" |> as_string + = "0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8") + string + ~error_msg:"Unexpected random_seed field") ; + unit + module Protocol = struct include Protocol @@ -14078,6 +14105,7 @@ let () = test_tezlink_constants [Alpha] ; test_tezlink_produceBlock [Alpha] ; test_tezlink_hash_rpc [Alpha] ; + test_tezlink_raw_json_cycle [Alpha] ; test_tezlink_chain_id [Alpha] ; test_tezlink_bootstrapped [Alpha] ; test_fa_deposit_can_be_claimed [Alpha] ; diff --git a/etherlink/tezt/tests/expected/evm_sequencer.ml/Alpha- Test the -describe endpoint.out b/etherlink/tezt/tests/expected/evm_sequencer.ml/Alpha- Test the -describe endpoint.out index 3c830feef5ad73ac8ec512a41dd4a4672c806675..627d94184ac4ddee44499157cdfed0a68051b980 100644 --- a/etherlink/tezt/tests/expected/evm_sequencer.ml/Alpha- Test the -describe endpoint.out +++ b/etherlink/tezt/tests/expected/evm_sequencer.ml/Alpha- Test the -describe endpoint.out @@ -163,6 +163,10 @@ Available services: - GET /chains/main/blocks/head/context/issuance/expected_issuance Returns the expected issued tez for the provided block and the next 'consensus_rights_delay' cycles (in mutez) + - GET /chains/main/blocks/head/context/raw/json/cycle/ + Returns the cycle . This RPC is a mock as there's no cycle + notion in Tezlink and doesn't represent what's in the context of a + block - GET /chains/main/blocks/head/hash The block's hash, its unique identifier. - GET /chains/main/blocks/head/header @@ -189,6 +193,8 @@ Available services: Dynamic parameter description: + + A cycle integer A contract identifier encoded in b58check.