From 89c00a04f8dffcba2a2b2c8d7dfee16f5a9b2696 Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Fri, 25 Oct 2024 17:56:16 +0200 Subject: [PATCH 1/3] Store: expose protocol_levels --- src/lib_store/mocked/store.ml | 11 ++++++++--- src/lib_store/store.mli | 5 +++++ src/lib_store/unix/store.ml | 9 ++++++--- src/lib_store/unix/store.mli | 5 +++++ 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/lib_store/mocked/store.ml b/src/lib_store/mocked/store.ml index eb589d9f1428..47dbf31a2ee4 100644 --- a/src/lib_store/mocked/store.ml +++ b/src/lib_store/mocked/store.ml @@ -152,11 +152,14 @@ let locked_is_acceptable_block chain_state (hash, level) = Lwt.return @@ Block_hash.equal hash target_hash else Lwt.return_true +let protocol_levels chain_store = + Shared.use chain_store.chain_state (fun {protocol_levels_data; _} -> + Stored_data.get protocol_levels_data) + let find_protocol_info chain_store ~protocol_level = let open Lwt_syntax in - Shared.use chain_store.chain_state (fun {protocol_levels_data; _} -> - let* protocol_levels = Stored_data.get protocol_levels_data in - return (Protocol_levels.find protocol_level protocol_levels)) + let* protocol_levels = protocol_levels chain_store in + return (Protocol_levels.find protocol_level protocol_levels) let expect_predecessor_context_hash_exn chain_store protocol_level = let open Lwt_syntax in @@ -1570,6 +1573,8 @@ module Chain = struct in return_unit) + let protocol_levels chain_store = protocol_levels chain_store + let find_protocol_info chain_store ~protocol_level = find_protocol_info chain_store ~protocol_level diff --git a/src/lib_store/store.mli b/src/lib_store/store.mli index 41417ec790a2..e054b63cb5d7 100644 --- a/src/lib_store/store.mli +++ b/src/lib_store/store.mli @@ -879,6 +879,11 @@ module Chain : sig (** {2 Chain's protocols} *) + (** [protol_levels chain_store] return all protocols with their activation + levels. *) + val protocol_levels : + t -> Protocol_levels.protocol_info Protocol_levels.t Lwt.t + (** [find_protocol_info chain_store ~protocol_level] returns the protocol info associated to the given [protocol_level]. *) val find_protocol_info : diff --git a/src/lib_store/unix/store.ml b/src/lib_store/unix/store.ml index c38a80b604bb..14194a8223d3 100644 --- a/src/lib_store/unix/store.ml +++ b/src/lib_store/unix/store.ml @@ -187,11 +187,14 @@ let locked_is_acceptable_block chain_state (hash, level) = (* Shared protocols accessors *) +let protocol_levels chain_store = + Shared.use chain_store.chain_state (fun {protocol_levels_data; _} -> + Stored_data.get protocol_levels_data) + let find_protocol_info chain_store ~protocol_level = let open Lwt_syntax in - Shared.use chain_store.chain_state (fun {protocol_levels_data; _} -> - let* protocol_levels = Stored_data.get protocol_levels_data in - return (Protocol_levels.find protocol_level protocol_levels)) + let* protocol_levels = protocol_levels chain_store in + return (Protocol_levels.find protocol_level protocol_levels) let find_activation_block chain_store ~protocol_level = let open Lwt_syntax in diff --git a/src/lib_store/unix/store.mli b/src/lib_store/unix/store.mli index b66649502b72..69ef305ef3a3 100644 --- a/src/lib_store/unix/store.mli +++ b/src/lib_store/unix/store.mli @@ -879,6 +879,11 @@ module Chain : sig (** {2 Chain's protocols} *) + (** [protol_levels chain_store] return all protocols with their activation + levels. *) + val protocol_levels : + t -> Protocol_levels.protocol_info Protocol_levels.t Lwt.t + (** [find_protocol_info chain_store ~protocol_level] returns the protocol info associated to the given [protocol_level]. *) val find_protocol_info : -- GitLab From 2387f3565045372c40b0ddfed2c4f14330fd18e2 Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Fri, 25 Oct 2024 18:28:38 +0200 Subject: [PATCH 2/3] Shell: RPCs /chain/{chain_id}/protocols --- src/lib_shell/chain_directory.ml | 26 ++++++++++- src/lib_shell_services/chain_services.ml | 54 +++++++++++++++++++++++ src/lib_shell_services/chain_services.mli | 37 ++++++++++++++++ src/lib_store/unix/store.ml | 2 + 4 files changed, 118 insertions(+), 1 deletion(-) diff --git a/src/lib_shell/chain_directory.ml b/src/lib_shell/chain_directory.ml index fc28100e0f27..84c92fb4ea59 100644 --- a/src/lib_shell/chain_directory.ml +++ b/src/lib_shell/chain_directory.ml @@ -155,7 +155,31 @@ let rpc_directory_with_validator dir validator = | None -> Lwt.fail Not_found | Some {level; errors} -> return {hash; level; errors}) ; register1 S.Invalid_blocks.delete (fun chain_store hash () () -> - Store.Block.unmark_invalid chain_store hash) + Store.Block.unmark_invalid chain_store hash) ; + (* protocols *) + register0 dir S.Protocols.list (fun chain_store () () -> + let*! protocols = Store.Chain.protocol_levels chain_store in + Store_types.Protocol_levels.fold + (fun proto_level + Store_types.Protocol_levels.{protocol; activation_block; _} + acc -> {protocol; proto_level; activation_block} :: acc) + protocols + [] + |> List.sort (fun p1 p2 -> + Compare.Int.compare p1.proto_level p2.proto_level) + |> return) ; + register1 S.Protocols.get (fun chain_store hash () () -> + let*! protocols = Store.Chain.protocol_levels chain_store in + let exception Found of protocol_info in + try + Store_types.Protocol_levels.iter + (fun proto_level + Store_types.Protocol_levels.{protocol; activation_block; _} -> + if Protocol_hash.equal protocol hash then + raise (Found {protocol; proto_level; activation_block})) + protocols ; + raise Not_found + with Found info -> return info) (* This RPC directory is agnostic to the node internal resources. However, theses RPCs can access a data subset by reading diff --git a/src/lib_shell_services/chain_services.ml b/src/lib_shell_services/chain_services.ml index 4d2ad7b89160..2fa821761339 100644 --- a/src/lib_shell_services/chain_services.ml +++ b/src/lib_shell_services/chain_services.ml @@ -38,6 +38,12 @@ type invalid_block = {hash : Block_hash.t; level : Int32.t; errors : error list} type prefix = Block_services.chain_prefix +type protocol_info = { + protocol : Protocol_hash.t; + proto_level : int; + activation_block : Block_hash.t * int32; +} + let path = Block_services.chain_path let block_descriptor_encoding = @@ -57,6 +63,26 @@ let bootstrap_encoding = (req "bootstrapped" Encoding.bool) (req "sync_state" Chain_validator_worker_state.sync_status_encoding) +let protocol_info_encoding = + conv + (fun {protocol; proto_level; activation_block} -> + (protocol, proto_level, activation_block)) + (fun (protocol, proto_level, activation_block) -> + {protocol; proto_level; activation_block}) + @@ obj3 + (req "protocol" Protocol_hash.encoding) + (req + "proto_level" + int31 + ~description: + "Level of protocol in the sequence of protocol activations.") + (req + "activation_block" + block_descriptor_encoding + ~description: + "The activation block for a protocol is the migration block, i.e. \ + the last level of the previous protocol.") + module S = struct let path : prefix Tezos_rpc.Path.context = Tezos_rpc.Path.open_root @@ -189,6 +215,24 @@ module S = struct ~output:Data_encoding.empty Tezos_rpc.Path.(path /: Block_hash.rpc_arg) end + + module Protocols = struct + let path = Tezos_rpc.Path.(path / "protocols") + + let list = + Tezos_rpc.Service.get_service + ~description:"Lists protocols of the chain." + ~query:Tezos_rpc.Query.empty + ~output:(list protocol_info_encoding) + path + + let get = + Tezos_rpc.Service.get_service + ~description:"Information about a protocol of the chain." + ~query:Tezos_rpc.Query.empty + ~output:protocol_info_encoding + Tezos_rpc.Path.(path /: Protocol_hash.rpc_arg) + end end let make_call0 s ctxt chain q p = @@ -255,3 +299,13 @@ module Invalid_blocks = struct let f = make_call1 S.Invalid_blocks.delete ctxt in fun ?(chain = `Main) block -> f chain block () () end + +module Protocols = struct + let list ctxt = + let f = make_call0 S.Protocols.list ctxt in + fun ?(chain = `Main) () -> f chain () () + + let get ctxt = + let f = make_call1 S.Protocols.get ctxt in + fun ?(chain = `Main) proto -> f chain proto () () +end diff --git a/src/lib_shell_services/chain_services.mli b/src/lib_shell_services/chain_services.mli index 69e5a21f87ff..7028a0fa3d58 100644 --- a/src/lib_shell_services/chain_services.mli +++ b/src/lib_shell_services/chain_services.mli @@ -36,6 +36,15 @@ type invalid_block = {hash : Block_hash.t; level : Int32.t; errors : error list} type prefix = unit * chain +type protocol_info = { + protocol : Protocol_hash.t; + proto_level : int; + (* Level of protocol in the sequence of protocol activations. *) + activation_block : Block_hash.t * int32; + (* The activation block for a protocol is the migration block, i.e. the + last level of the previous protocol. *) +} + val path : (unit, prefix) Tezos_rpc.Path.path open Tezos_rpc.Context @@ -90,6 +99,14 @@ module Invalid_blocks : sig val delete : #simple -> ?chain:chain -> Block_hash.t -> unit tzresult Lwt.t end +module Protocols : sig + val list : + #simple -> ?chain:chain -> unit -> protocol_info list tzresult Lwt.t + + val get : + #simple -> ?chain:chain -> Protocol_hash.t -> protocol_info tzresult Lwt.t +end + module S : sig val chain_id : ([`GET], prefix, prefix, unit, unit, Chain_id.t) Tezos_rpc.Service.t @@ -178,4 +195,24 @@ module S : sig unit ) Tezos_rpc.Service.t end + + module Protocols : sig + val list : + ( [`GET], + prefix, + prefix, + unit, + unit, + protocol_info list ) + Tezos_rpc.Service.t + + val get : + ( [`GET], + prefix, + prefix * Protocol_hash.t, + unit, + unit, + protocol_info ) + Tezos_rpc.Service.t + end end diff --git a/src/lib_store/unix/store.ml b/src/lib_store/unix/store.ml index 14194a8223d3..63933f486b54 100644 --- a/src/lib_store/unix/store.ml +++ b/src/lib_store/unix/store.ml @@ -2722,6 +2722,8 @@ module Chain = struct (* Protocols *) + let protocol_levels chain_store = protocol_levels chain_store + let find_protocol_info chain_store ~protocol_level = find_protocol_info chain_store ~protocol_level -- GitLab From adf7f9c7f9706025fe2add8a7d8eabd3350d826b Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Fri, 25 Oct 2024 18:30:31 +0200 Subject: [PATCH 3/3] Doc: changelog --- CHANGES.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index a77073eb0e39..97f86d42e634 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -32,6 +32,10 @@ Node --status`` command. It now returns the exit code 1 when an upgrade is availalbe. 0 is returned when the storage is up to date. (MR :gl:`!TBD`) +- New RPCs ``/chain/{chain_id}/protocols`` (and + ``/chain/{chain_id}/protocols/{protocol_hash}``) to retrieve protocol + activation levels of the chain. (MR :gl:`!15447`) + Client ------ -- GitLab