From 00a158d971049ec0eb2ecddaaf19e6676556c6ec Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Wed, 19 Feb 2025 15:52:08 +0100 Subject: [PATCH 1/5] DAL: move Store.Traps.v to Types --- src/bin_dal_node/accuser.ml | 2 +- src/bin_dal_node/daemon.ml | 2 +- src/bin_dal_node/store.ml | 20 +++++++------------- src/bin_dal_node/store.mli | 15 +-------------- src/lib_dal_node_services/types.ml | 20 ++++++++++++++++++++ src/lib_dal_node_services/types.mli | 14 ++++++++++++++ 6 files changed, 44 insertions(+), 29 deletions(-) diff --git a/src/bin_dal_node/accuser.ml b/src/bin_dal_node/accuser.ml index 5bb5d49d9baf..03d5cd23fb85 100644 --- a/src/bin_dal_node/accuser.ml +++ b/src/bin_dal_node/accuser.ml @@ -34,7 +34,7 @@ let filter_injectable_traps ~attested_level ~published_level attestation_map let open Lwt_result_syntax in List.filter_map_s (fun trap -> - let Store.Traps.{delegate; slot_index; shard; shard_proof} = trap in + let Types.{delegate; slot_index; shard; shard_proof} = trap in let attestation_opt = Signature.Public_key_hash.Map.find delegate attestation_map in diff --git a/src/bin_dal_node/daemon.ml b/src/bin_dal_node/daemon.ml index 2037bfb03118..ee4cd0ae2c0d 100644 --- a/src/bin_dal_node/daemon.ml +++ b/src/bin_dal_node/daemon.ml @@ -505,7 +505,7 @@ module Handler = struct if published_level <= 1l then false else Store.Traps.find traps_store ~level:published_level - |> List.exists (fun Store.Traps.{delegate; slot_index; _} -> + |> List.exists (fun Types.{delegate; slot_index; _} -> index = slot_index && Signature.Public_key_hash.equal delegate pkh) in diff --git a/src/bin_dal_node/store.ml b/src/bin_dal_node/store.ml index d247052789bf..a9f6a10a7cf6 100644 --- a/src/bin_dal_node/store.ml +++ b/src/bin_dal_node/store.ml @@ -349,13 +349,6 @@ module Traps = struct type t = payload Shard_index_map.t Slot_index_map.t Level_map.t - type v = { - delegate : Signature.Public_key_hash.t; - slot_index : Types.slot_index; - shard : Cryptobox.shard; - shard_proof : Cryptobox.shard_proof; - } - let create ~capacity = Level_map.create capacity let add_slot_index t ~slot_index ~shard_index ~delegate ~share ~shard_proof = @@ -397,12 +390,13 @@ module Traps = struct let res = List.map (fun (shard_index, (delegate, share, shard_proof)) -> - { - delegate; - slot_index; - shard = Cryptobox.{index = shard_index; share}; - shard_proof; - }) + Types. + { + delegate; + slot_index; + shard = Cryptobox.{index = shard_index; share}; + shard_proof; + }) (Shard_index_map.bindings m) in res @ acc) diff --git a/src/bin_dal_node/store.mli b/src/bin_dal_node/store.mli index d58c2c637c03..30e99c5063a5 100644 --- a/src/bin_dal_node/store.mli +++ b/src/bin_dal_node/store.mli @@ -130,19 +130,6 @@ module Traps : sig in memory. *) type t - (** The type containing all elements required to - construct a trap accusation. - - [delegate]: the baker who attested, - - [slot_index]: the index of the slot containing the trap, - - [shard]: the DAL shard containing the trap share, - - [shard_proof]: proof provided for the shard. *) - type v = { - delegate : Signature.Public_key_hash.t; - slot_index : Types.slot_index; - shard : Cryptobox.shard; - shard_proof : Cryptobox.shard_proof; - } - (** [add ~slot_id ~shard_index ~delegate ~share ~shard_proof] adds trap data to the cache. The cache maintains a maximum of [Constants.traps_cache_size] levels. Data is expected to be @@ -161,7 +148,7 @@ module Traps : sig (** [find t ~level] retrieves all trap data associated with the given level. Returns an empty list if no traps exist for that level. *) - val find : t -> level:Types.level -> v list + val find : t -> level:Types.level -> Types.trap list end module Last_processed_level : Single_value_store.S with type value = int32 diff --git a/src/lib_dal_node_services/types.ml b/src/lib_dal_node_services/types.ml index 5495245c3c05..e0b61c32a0bf 100644 --- a/src/lib_dal_node_services/types.ml +++ b/src/lib_dal_node_services/types.ml @@ -363,6 +363,13 @@ type proto_parameters = { blocks_per_cycle : int32; } +type trap = { + delegate : Signature.Public_key_hash.t; + slot_index : slot_index; + shard : Cryptobox.shard; + shard_proof : Cryptobox.shard_proof; +} + (* Encodings associated to the types. *) let slot_id_encoding = @@ -554,6 +561,19 @@ let proto_parameters_encoding : proto_parameters Data_encoding.t = (req "dal_attested_slots_validity_lag" int31) (req "blocks_per_cycle" int32))) +let trap_encoding = + Data_encoding.( + conv + (fun {delegate; slot_index; shard; shard_proof} -> + (delegate, slot_index, shard, shard_proof)) + (fun (delegate, slot_index, shard, shard_proof) -> + {delegate; slot_index; shard; shard_proof}) + (obj4 + (req "delegate" Signature.Public_key_hash.encoding) + (req "slot_index" uint8) + (req "shard" Cryptobox.shard_encoding) + (req "proof" Cryptobox.shard_proof_encoding))) + module Store = struct (** Data kind stored in DAL. *) type kind = Commitment | Header_status | Slot_id | Slot | Shard | Profile diff --git a/src/lib_dal_node_services/types.mli b/src/lib_dal_node_services/types.mli index ac33835a9039..4ff14dd8fc16 100644 --- a/src/lib_dal_node_services/types.mli +++ b/src/lib_dal_node_services/types.mli @@ -274,6 +274,18 @@ type proto_parameters = { blocks_per_cycle : int32; } +(** The type contains all elements required to construct a trap accusation. + - [delegate]: the baker who attested, + - [slot_index]: the index of the slot containing the trap, + - [shard]: the DAL shard containing the trap share, + - [shard_proof]: proof provided for the shard. *) +type trap = { + delegate : Signature.Public_key_hash.t; + slot_index : slot_index; + shard : Cryptobox.shard; + shard_proof : Cryptobox.shard_proof; +} + val slot_encoding : Cryptobox.slot Data_encoding.t val slot_header_encoding : slot_header Data_encoding.t @@ -290,6 +302,8 @@ val attestable_slots_encoding : attestable_slots Data_encoding.t val proto_parameters_encoding : proto_parameters Data_encoding.t +val trap_encoding : trap Data_encoding.t + val pp_header_status : Format.formatter -> header_status -> unit module Store : sig -- GitLab From 36c490144590d2bbdaab83be599ba0e1e2736771 Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Wed, 19 Feb 2025 15:53:40 +0100 Subject: [PATCH 2/5] DAL: declare `get_traps` RPC --- src/lib_dal_node_services/services.ml | 34 ++++++++++++++++++++++++++ src/lib_dal_node_services/services.mli | 12 +++++++++ 2 files changed, 46 insertions(+) diff --git a/src/lib_dal_node_services/services.ml b/src/lib_dal_node_services/services.ml index 48ffbc88ae2a..b52e094ea49f 100644 --- a/src/lib_dal_node_services/services.ml +++ b/src/lib_dal_node_services/services.ml @@ -91,6 +91,20 @@ let level_query = let open Query in query (fun level -> level) |+ opt_field "level" Arg.int32 (fun t -> t) |> seal +let trap_query = + let open Tezos_rpc in + let open Query in + query (fun delegate slot_index -> + object + method delegate = delegate + + method slot_index = slot_index + end) + |+ opt_field "delegate" Signature.Public_key_hash.rpc_arg (fun obj -> + obj#delegate) + |+ opt_field "slot_index" Arg.int (fun obj -> obj#slot_index) + |> seal + (* Service declarations *) type 'rpc service = @@ -350,6 +364,26 @@ let get_attestable_slots : open_root / "profiles" /: Signature.Public_key_hash.rpc_arg / "attested_levels" /: Tezos_rpc.Arg.int32 / "attestable_slots") +let get_traps : + < meth : [`GET] + ; input : unit + ; output : Types.trap list + ; prefix : unit + ; params : unit * level + ; query : + < delegate : Signature.public_key_hash option + ; slot_index : slot_index option > > + service = + Tezos_rpc.Service.get_service + ~description: + "For a given published level, return all the traps known by the node. \ + Optional arguments allow to restrict the output to a given delegate or \ + slot index." + ~query:trap_query + ~output:(Data_encoding.list Types.trap_encoding) + Tezos_rpc.Path.( + open_root / "published_levels" /: Tezos_rpc.Arg.int32 / "known_traps") + let get_slot_shard : < meth : [`GET] ; input : unit diff --git a/src/lib_dal_node_services/services.mli b/src/lib_dal_node_services/services.mli index 13f8b6874ec3..089800e1a705 100644 --- a/src/lib_dal_node_services/services.mli +++ b/src/lib_dal_node_services/services.mli @@ -193,6 +193,18 @@ val get_attestable_slots : ; query : unit > service +(** For a given published level, return all the traps known by the node. *) +val get_traps : + < meth : [`GET] + ; input : unit + ; output : Types.trap list + ; prefix : unit + ; params : unit * Types.level + ; query : + < delegate : Signature.public_key_hash option + ; slot_index : Types.slot_index option > > + service + (** Return the shard associated to the given index. *) val get_slot_shard : < meth : [`GET] -- GitLab From dfce2c05a540a98a86c2fe7c2a144579cc1805c8 Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Wed, 19 Feb 2025 15:53:51 +0100 Subject: [PATCH 3/5] DAL/Node: provide `get_traps` RPC --- src/bin_dal_node/RPC_server.ml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/bin_dal_node/RPC_server.ml b/src/bin_dal_node/RPC_server.ml index e5ad4f1c6597..3c1984c5fa40 100644 --- a/src/bin_dal_node/RPC_server.ml +++ b/src/bin_dal_node/RPC_server.ml @@ -555,6 +555,26 @@ let version ctxt () () = let open Lwt_result_syntax in Node_context.version ctxt |> return +let get_traps ctxt published_level query () = + let traps_store = Node_context.get_store ctxt |> Store.traps in + let traps = Store.Traps.find traps_store ~level:published_level in + Lwt_result_syntax.return + @@ + match (query#delegate, query#slot_index) with + | None, None -> traps + | Some pkh, None -> + List.filter + (fun Types.{delegate; _} -> + Signature.Public_key_hash.equal delegate pkh) + traps + | None, Some index -> + List.filter (fun Types.{slot_index; _} -> index = slot_index) traps + | Some pkh, Some index -> + List.filter + (fun Types.{delegate; slot_index; _} -> + index = slot_index && Signature.Public_key_hash.equal delegate pkh) + traps + module P2P = struct let connect ctxt q point = Node_context.P2P.connect ctxt ?timeout:q#timeout point @@ -715,6 +735,10 @@ let register : Tezos_rpc.Directory.opt_register2 Services.get_attestable_slots (Profile_handlers.get_attestable_slots ctxt) + |> add_service + Tezos_rpc.Directory.register1 + Services.get_traps + (get_traps ctxt) |> add_service Tezos_rpc.Directory.opt_register2 Services.get_slot_pages -- GitLab From 48f8539becf8062f7234e99673b6c84900aaddb0 Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Wed, 19 Feb 2025 17:44:47 +0100 Subject: [PATCH 4/5] Changelog: add entry --- CHANGES.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index aefce0899080..6a6e4d3e99b2 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -259,6 +259,7 @@ DAL node - **Feature** A new RPC ``/p2p/gossipsub/reconnection_delays`` which provides for each unreachable point, the time remaining until the next reconnection attempt. (MR :gl:`!16767`) + - **Bugfix** From v21.2, the ``SO_KEEP_ALIVE`` socket option was used for incoming connections only. It is not used with both incoming connections and outgoing connections. @@ -325,6 +326,9 @@ DAL node - Added a new RPC ``GET /p2p/gossipsub/fanout/`` that returns the GossipSub fanout of a peer. (MR :gl:`!16764`) +- Added a new RPC ``GET /published_levels//known_traps`` that returns the + trap shards that the DAL node knows. (MR :gl:`!16870`) + Protocol ~~~~~~~~ -- GitLab From 99352f9390ce95869752c6b5939123279a9bc1d1 Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Wed, 19 Feb 2025 17:51:27 +0100 Subject: [PATCH 5/5] DAL/Tests: update regression outputs --- .../dal.ml/Alpha- Testing DAL node (dal node list RPCs).out | 5 +++++ .../dal.ml/Quebec- Testing DAL node (dal node list RPCs).out | 5 +++++ .../dal.ml/R022-- Testing DAL node (dal node list RPCs).out | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/tezt/tests/expected/dal.ml/Alpha- Testing DAL node (dal node list RPCs).out b/tezt/tests/expected/dal.ml/Alpha- Testing DAL node (dal node list RPCs).out index 848e238d2472..31f7db7831c3 100644 --- a/tezt/tests/expected/dal.ml/Alpha- Testing DAL node (dal node list RPCs).out +++ b/tezt/tests/expected/dal.ml/Alpha- Testing DAL node (dal node list RPCs).out @@ -109,6 +109,10 @@ Available services: - GET /protocol_parameters Returns the protocol parameters as known by the DAL node. An optional 'level' argument can specify for which level to retrieve them. + - GET /published_levels//known_traps + For a given published level, return all the traps known by the node. + Optional arguments allow to restrict the output to a given delegate or + slot index. - POST /slots Post a slot to the DAL node, computes its commitment and commitment proof, then computes the correspoding shards with their proof. The @@ -123,6 +127,7 @@ Available services: Dynamic parameter description: + int32 int32 A Secp256k1 of a Ed25519 public key hash (Base58Check-encoded) diff --git a/tezt/tests/expected/dal.ml/Quebec- Testing DAL node (dal node list RPCs).out b/tezt/tests/expected/dal.ml/Quebec- Testing DAL node (dal node list RPCs).out index 848e238d2472..31f7db7831c3 100644 --- a/tezt/tests/expected/dal.ml/Quebec- Testing DAL node (dal node list RPCs).out +++ b/tezt/tests/expected/dal.ml/Quebec- Testing DAL node (dal node list RPCs).out @@ -109,6 +109,10 @@ Available services: - GET /protocol_parameters Returns the protocol parameters as known by the DAL node. An optional 'level' argument can specify for which level to retrieve them. + - GET /published_levels//known_traps + For a given published level, return all the traps known by the node. + Optional arguments allow to restrict the output to a given delegate or + slot index. - POST /slots Post a slot to the DAL node, computes its commitment and commitment proof, then computes the correspoding shards with their proof. The @@ -123,6 +127,7 @@ Available services: Dynamic parameter description: + int32 int32 A Secp256k1 of a Ed25519 public key hash (Base58Check-encoded) diff --git a/tezt/tests/expected/dal.ml/R022-- Testing DAL node (dal node list RPCs).out b/tezt/tests/expected/dal.ml/R022-- Testing DAL node (dal node list RPCs).out index 848e238d2472..31f7db7831c3 100644 --- a/tezt/tests/expected/dal.ml/R022-- Testing DAL node (dal node list RPCs).out +++ b/tezt/tests/expected/dal.ml/R022-- Testing DAL node (dal node list RPCs).out @@ -109,6 +109,10 @@ Available services: - GET /protocol_parameters Returns the protocol parameters as known by the DAL node. An optional 'level' argument can specify for which level to retrieve them. + - GET /published_levels//known_traps + For a given published level, return all the traps known by the node. + Optional arguments allow to restrict the output to a given delegate or + slot index. - POST /slots Post a slot to the DAL node, computes its commitment and commitment proof, then computes the correspoding shards with their proof. The @@ -123,6 +127,7 @@ Available services: Dynamic parameter description: + int32 int32 A Secp256k1 of a Ed25519 public key hash (Base58Check-encoded) -- GitLab