From 2255cff303d2a505e335783d34181eb0fea5901f Mon Sep 17 00:00:00 2001 From: "iguerNL@Functori" Date: Thu, 22 May 2025 11:07:22 +0200 Subject: [PATCH 1/5] DAL: simplify function cells_of_level's implementation Starting from Rio, the function `cells_of_level` exposed by the DAL plugin can work with just an attestation level as an argument instead of block_info. This MR proposes to make the simplification. For Quebec, we (re)-fetch the block info locally, as its metadata is needed. This should not be an issue in practice, as Rio has been activated for almost one month (Quebec's `cells_of_level` function will likely not be called). --- src/lib_dal_node/block_handler.ml | 11 +++++------ src/lib_dal_node/block_handler.mli | 5 ++--- src/lib_dal_node/dal_plugin.ml | 2 +- src/lib_dal_node/dal_plugin.mli | 2 +- src/lib_dal_node/store_cleanup.ml | 6 +----- .../lib_dal/dal_plugin_registration.ml | 10 +++++++--- .../lib_dal/dal_plugin_registration.ml | 3 +-- src/proto_alpha/lib_dal/dal_plugin_registration.ml | 3 +-- 8 files changed, 19 insertions(+), 23 deletions(-) diff --git a/src/lib_dal_node/block_handler.ml b/src/lib_dal_node/block_handler.ml index e935a5a24666..ba8703bffa21 100644 --- a/src/lib_dal_node/block_handler.ml +++ b/src/lib_dal_node/block_handler.ml @@ -159,9 +159,9 @@ let may_update_topics ctxt proto_parameters ~block_level = (Node_context.get_gs_worker ctxt) committee -let store_skip_list_cells (type block_info) ctxt cctxt dal_constants - (block_info : block_info) block_level - (module Plugin : Dal_plugin.T with type block_info = block_info) = +(* TODO: rename block_level to attested level and add a label *) +let store_skip_list_cells ctxt cctxt dal_constants block_level + (module Plugin : Dal_plugin.T) = let open Lwt_result_syntax in let* cells_of_level = let pred_published_level = @@ -170,7 +170,7 @@ let store_skip_list_cells (type block_info) ctxt cctxt dal_constants (Int32.of_int (1 + dal_constants.Types.attestation_lag)) in Plugin.Skip_list.cells_of_level - block_info + ~attested_level:block_level cctxt ~dal_constants ~pred_publication_level_dal_constants: @@ -372,9 +372,8 @@ let process_block_data ctxt cctxt store proto_parameters block_level ctxt cctxt proto_parameters - block_info block_level - (module Plugin : Dal_plugin.T with type block_info = Plugin.block_info) + (module Plugin : Dal_plugin.T) else return_unit in let* slot_headers = Plugin.get_published_slot_headers ~block_level cctxt in diff --git a/src/lib_dal_node/block_handler.mli b/src/lib_dal_node/block_handler.mli index ad25fb66fcea..5974503440c0 100644 --- a/src/lib_dal_node/block_handler.mli +++ b/src/lib_dal_node/block_handler.mli @@ -48,7 +48,7 @@ val new_finalized_head : launch_time:float -> (unit, tztrace) result Lwt.t -(** [store_skip_list_cells ctxt cctxt proto_parameters block_info block_level +(** [store_skip_list_cells ctxt cctxt proto_parameters block_level plugin] extracts and stores the skip list cells from [block_info] at [block_level], using the encoding from the corresponding [plugin]. It is used to support DAL refutation. *) @@ -56,9 +56,8 @@ val store_skip_list_cells : Node_context.t -> Rpc_context.t -> Tezos_dal_node_services.Types.proto_parameters -> - 'block_info -> int32 -> - (module Dal_plugin.T with type block_info = 'block_info) -> + (module Dal_plugin.T) -> (unit, tztrace) result Lwt.t (** [remove_old_level_stored_data proto_parameters ctxt current_level] diff --git a/src/lib_dal_node/dal_plugin.ml b/src/lib_dal_node/dal_plugin.ml index 5d1f8447c8c7..a5942c7f546f 100644 --- a/src/lib_dal_node/dal_plugin.ml +++ b/src/lib_dal_node/dal_plugin.ml @@ -121,7 +121,7 @@ module type T = sig val cell_hash : cell -> hash val cells_of_level : - block_info -> + attested_level:int32 -> Tezos_rpc.Context.generic -> dal_constants:Tezos_dal_node_services.Types.proto_parameters -> pred_publication_level_dal_constants: diff --git a/src/lib_dal_node/dal_plugin.mli b/src/lib_dal_node/dal_plugin.mli index dcaf9662aa6f..e4bbdbdc8214 100644 --- a/src/lib_dal_node/dal_plugin.mli +++ b/src/lib_dal_node/dal_plugin.mli @@ -172,7 +172,7 @@ module type T = sig The ordering of the elements in the returned list is not relevant. *) val cells_of_level : - block_info -> + attested_level:int32 -> Tezos_rpc.Context.generic -> dal_constants:Tezos_dal_node_services.Types.proto_parameters -> pred_publication_level_dal_constants: diff --git a/src/lib_dal_node/store_cleanup.ml b/src/lib_dal_node/store_cleanup.ml index a3e3f9b76de5..56a48f63a380 100644 --- a/src/lib_dal_node/store_cleanup.ml +++ b/src/lib_dal_node/store_cleanup.ml @@ -46,9 +46,6 @@ let clean_up_store_and_catch_up_for_refutation_support ctxt cctxt let*? (module Plugin) = Node_context.get_plugin_for_level ctxt ~level:(Int32.pred level) in - let* block_info = - Plugin.block_info cctxt ~block:(`Level level) ~metadata:`Always - in let*? dal_constants = Node_context.get_proto_parameters ctxt ~level:(`Level level) in @@ -56,9 +53,8 @@ let clean_up_store_and_catch_up_for_refutation_support ctxt cctxt ctxt cctxt dal_constants - block_info level - (module Plugin : Dal_plugin.T with type block_info = Plugin.block_info) + (module Plugin : Dal_plugin.T) in let store = Node_context.get_store ctxt in let last_processed_level_store = Store.last_processed_level store in diff --git a/src/proto_021_PsQuebec/lib_dal/dal_plugin_registration.ml b/src/proto_021_PsQuebec/lib_dal/dal_plugin_registration.ml index 79de163f2bc9..3764b2f5644e 100644 --- a/src/proto_021_PsQuebec/lib_dal/dal_plugin_registration.ml +++ b/src/proto_021_PsQuebec/lib_dal/dal_plugin_registration.ml @@ -275,11 +275,15 @@ module Plugin = struct The ordering of the elements in the returned list is not relevant. *) - let cells_of_level (block_info : block_info) ctxt ~dal_constants + let cells_of_level ~attested_level ctxt ~dal_constants ~pred_publication_level_dal_constants = let open Lwt_result_syntax in - (* 0. Let's call [attested_level] the block's level. *) - let attested_level = block_info.header.shell.level in + (* 0. For Quebec, block_info is still needed to reconstruct the cells + of the skip list. Now that Rio is activated, we don't expect + [cells_of_level] to be actively called. *) + let* block_info = + block_info ctxt ~block:(`Level attested_level) ~metadata:`Never + in let published_level = Int32.sub attested_level diff --git a/src/proto_022_PsRiotum/lib_dal/dal_plugin_registration.ml b/src/proto_022_PsRiotum/lib_dal/dal_plugin_registration.ml index 818d80be104f..43ea7d56e561 100644 --- a/src/proto_022_PsRiotum/lib_dal/dal_plugin_registration.ml +++ b/src/proto_022_PsRiotum/lib_dal/dal_plugin_registration.ml @@ -301,11 +301,10 @@ module Plugin = struct cells of the skip list by calling the appropriate DAL function in the protocol. *) - let cells_of_level (block_info : block_info) ctxt ~dal_constants + let cells_of_level ~attested_level ctxt ~dal_constants ~pred_publication_level_dal_constants:_ = let open Lwt_result_syntax in let cpctxt = new Protocol_client_context.wrap_rpc_context ctxt in - let attested_level = block_info.header.shell.level in let published_level = Int32.sub attested_level diff --git a/src/proto_alpha/lib_dal/dal_plugin_registration.ml b/src/proto_alpha/lib_dal/dal_plugin_registration.ml index f3ad19ecc43b..5ef0b5929062 100644 --- a/src/proto_alpha/lib_dal/dal_plugin_registration.ml +++ b/src/proto_alpha/lib_dal/dal_plugin_registration.ml @@ -365,11 +365,10 @@ module Plugin = struct cells of the skip list by calling the appropriate DAL function in the protocol. *) - let cells_of_level (block_info : block_info) ctxt ~dal_constants + let cells_of_level ~attested_level ctxt ~dal_constants ~pred_publication_level_dal_constants:_ = let open Lwt_result_syntax in let cpctxt = new Protocol_client_context.wrap_rpc_context ctxt in - let attested_level = block_info.header.shell.level in let published_level = Int32.sub attested_level -- GitLab From 451c2f3adf91ca323e29ad4bcce0fa788ad955f0 Mon Sep 17 00:00:00 2001 From: "iguerNL@Functori" Date: Fri, 23 May 2025 10:42:01 +0200 Subject: [PATCH 2/5] DAL/Node: store_skip_list_cells takes an `~attested_level` argument --- src/lib_dal_node/block_handler.ml | 11 +++++------ src/lib_dal_node/block_handler.mli | 10 +++++----- src/lib_dal_node/store_cleanup.ml | 2 +- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/lib_dal_node/block_handler.ml b/src/lib_dal_node/block_handler.ml index ba8703bffa21..56a8ee5729c8 100644 --- a/src/lib_dal_node/block_handler.ml +++ b/src/lib_dal_node/block_handler.ml @@ -159,18 +159,17 @@ let may_update_topics ctxt proto_parameters ~block_level = (Node_context.get_gs_worker ctxt) committee -(* TODO: rename block_level to attested level and add a label *) -let store_skip_list_cells ctxt cctxt dal_constants block_level +let store_skip_list_cells ctxt cctxt dal_constants ~attested_level (module Plugin : Dal_plugin.T) = let open Lwt_result_syntax in let* cells_of_level = let pred_published_level = Int32.sub - block_level + attested_level (Int32.of_int (1 + dal_constants.Types.attestation_lag)) in Plugin.Skip_list.cells_of_level - ~attested_level:block_level + ~attested_level cctxt ~dal_constants ~pred_publication_level_dal_constants: @@ -192,7 +191,7 @@ let store_skip_list_cells ctxt cctxt dal_constants block_level cells_of_level in let store = Node_context.get_store ctxt in - Store.Skip_list_cells.insert store ~attested_level:block_level cells_of_level + Store.Skip_list_cells.insert store ~attested_level cells_of_level (* This functions counts, for each slot, the number of shards attested by the bakers. *) let attested_shards_per_slot attestations committee ~number_of_slots is_attested @@ -372,7 +371,7 @@ let process_block_data ctxt cctxt store proto_parameters block_level ctxt cctxt proto_parameters - block_level + ~attested_level:block_level (module Plugin : Dal_plugin.T) else return_unit in diff --git a/src/lib_dal_node/block_handler.mli b/src/lib_dal_node/block_handler.mli index 5974503440c0..701cfb46eea6 100644 --- a/src/lib_dal_node/block_handler.mli +++ b/src/lib_dal_node/block_handler.mli @@ -48,15 +48,15 @@ val new_finalized_head : launch_time:float -> (unit, tztrace) result Lwt.t -(** [store_skip_list_cells ctxt cctxt proto_parameters block_level - plugin] extracts and stores the skip list cells from [block_info] at - [block_level], using the encoding from the corresponding [plugin]. It is - used to support DAL refutation. *) +(** [store_skip_list_cells ctxt cctxt proto_parameters ~attested_level plugin] + extracts and stores the skip list cells from [block_info] at [block_level], + using the encoding from the corresponding [plugin]. It is used to support + DAL refutation. *) val store_skip_list_cells : Node_context.t -> Rpc_context.t -> Tezos_dal_node_services.Types.proto_parameters -> - int32 -> + attested_level:int32 -> (module Dal_plugin.T) -> (unit, tztrace) result Lwt.t diff --git a/src/lib_dal_node/store_cleanup.ml b/src/lib_dal_node/store_cleanup.ml index 56a48f63a380..2fcd0cc769df 100644 --- a/src/lib_dal_node/store_cleanup.ml +++ b/src/lib_dal_node/store_cleanup.ml @@ -53,7 +53,7 @@ let clean_up_store_and_catch_up_for_refutation_support ctxt cctxt ctxt cctxt dal_constants - level + ~attested_level:level (module Plugin : Dal_plugin.T) in let store = Node_context.get_store ctxt in -- GitLab From ab1ef2c0cf8f484535161639768dedf6db3dd35f Mon Sep 17 00:00:00 2001 From: "iguerNL@Functori" Date: Fri, 23 May 2025 10:45:45 +0200 Subject: [PATCH 3/5] DAL: explicit that block_info's metadata argument is for operations --- src/lib_dal_node/block_handler.ml | 5 ++++- src/lib_dal_node/dal_plugin.ml | 2 +- src/lib_dal_node/dal_plugin.mli | 9 +++++---- .../lib_dal/dal_plugin_registration.ml | 9 ++++++--- .../lib_dal/dal_plugin_registration.ml | 4 ++-- src/proto_alpha/lib_dal/dal_plugin_registration.ml | 4 ++-- 6 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/lib_dal_node/block_handler.ml b/src/lib_dal_node/block_handler.ml index 56a8ee5729c8..5774c872ebb4 100644 --- a/src/lib_dal_node/block_handler.ml +++ b/src/lib_dal_node/block_handler.ml @@ -363,7 +363,10 @@ let process_block_data ctxt cctxt store proto_parameters block_level (module Plugin : Dal_plugin.T) = let open Lwt_result_syntax in let* block_info = - Plugin.block_info cctxt ~block:(`Level block_level) ~metadata:`Never + Plugin.block_info + cctxt + ~block:(`Level block_level) + ~operations_metadata:`Never in let* () = if Node_context.supports_refutations ctxt then diff --git a/src/lib_dal_node/dal_plugin.ml b/src/lib_dal_node/dal_plugin.ml index a5942c7f546f..d94db2852574 100644 --- a/src/lib_dal_node/dal_plugin.ml +++ b/src/lib_dal_node/dal_plugin.ml @@ -47,7 +47,7 @@ module type T = sig val block_info : ?chain:Tezos_shell_services.Block_services.chain -> ?block:Tezos_shell_services.Block_services.block -> - metadata:[`Always | `Never] -> + operations_metadata:[`Always | `Never] -> Tezos_rpc.Context.generic -> block_info tzresult Lwt.t diff --git a/src/lib_dal_node/dal_plugin.mli b/src/lib_dal_node/dal_plugin.mli index e4bbdbdc8214..ed2d3a4523d5 100644 --- a/src/lib_dal_node/dal_plugin.mli +++ b/src/lib_dal_node/dal_plugin.mli @@ -53,14 +53,15 @@ module type T = sig type tb_slot - (** [block_info ?chain ?block ~metadata ctxt] returns the information of the - [block] in [ctxt] for the given [chain]. Block's metadata are included or - skipped depending on the value of [metadata]. This is a wrapper on top of + (** [block_info ?chain ?block ~operations_metadata ctxt] returns the + information of the [block] in [ctxt] for the given [chain]. Operations' + metadata are included or skipped depending on the value of + [operations_metadata]. This is a wrapper on top of {!Protocol_client_context.Alpha_block_services.info}. *) val block_info : ?chain:Tezos_shell_services.Block_services.chain -> ?block:Tezos_shell_services.Block_services.block -> - metadata:[`Always | `Never] -> + operations_metadata:[`Always | `Never] -> Tezos_rpc.Context.generic -> block_info tzresult Lwt.t diff --git a/src/proto_021_PsQuebec/lib_dal/dal_plugin_registration.ml b/src/proto_021_PsQuebec/lib_dal/dal_plugin_registration.ml index 3764b2f5644e..1722b9397641 100644 --- a/src/proto_021_PsQuebec/lib_dal/dal_plugin_registration.ml +++ b/src/proto_021_PsQuebec/lib_dal/dal_plugin_registration.ml @@ -96,13 +96,13 @@ module Plugin = struct (* This is supposed to be dead code, but we implement a fallback to be defensive. *) fail [DAL_accusation_not_available] - let block_info ?chain ?block ~metadata ctxt = + let block_info ?chain ?block ~operations_metadata ctxt = let cpctxt = new Protocol_client_context.wrap_rpc_context ctxt in Protocol_client_context.Alpha_block_services.info cpctxt ?chain ?block - ~metadata + ~metadata:operations_metadata () let block_shell_header (block_info : block_info) = block_info.header.shell @@ -282,7 +282,10 @@ module Plugin = struct of the skip list. Now that Rio is activated, we don't expect [cells_of_level] to be actively called. *) let* block_info = - block_info ctxt ~block:(`Level attested_level) ~metadata:`Never + block_info + ctxt + ~block:(`Level attested_level) + ~operations_metadata:`Never in let published_level = Int32.sub diff --git a/src/proto_022_PsRiotum/lib_dal/dal_plugin_registration.ml b/src/proto_022_PsRiotum/lib_dal/dal_plugin_registration.ml index 43ea7d56e561..5e54ac3c12d0 100644 --- a/src/proto_022_PsRiotum/lib_dal/dal_plugin_registration.ml +++ b/src/proto_022_PsRiotum/lib_dal/dal_plugin_registration.ml @@ -135,13 +135,13 @@ module Plugin = struct let* _op_hash = Shell_services.Injection.operation cctxt ~chain bytes in return_unit - let block_info ?chain ?block ~metadata ctxt = + let block_info ?chain ?block ~operations_metadata ctxt = let cpctxt = new Protocol_client_context.wrap_rpc_context ctxt in Protocol_client_context.Alpha_block_services.info cpctxt ?chain ?block - ~metadata + ~metadata:operations_metadata () let block_shell_header (block_info : block_info) = block_info.header.shell diff --git a/src/proto_alpha/lib_dal/dal_plugin_registration.ml b/src/proto_alpha/lib_dal/dal_plugin_registration.ml index 5ef0b5929062..c5c252097b1a 100644 --- a/src/proto_alpha/lib_dal/dal_plugin_registration.ml +++ b/src/proto_alpha/lib_dal/dal_plugin_registration.ml @@ -151,13 +151,13 @@ module Plugin = struct let* _op_hash = Shell_services.Injection.operation cctxt ~chain bytes in return_unit - let block_info ?chain ?block ~metadata ctxt = + let block_info ?chain ?block ~operations_metadata ctxt = let cpctxt = new Protocol_client_context.wrap_rpc_context ctxt in Protocol_client_context.Alpha_block_services.info cpctxt ?chain ?block - ~metadata + ~metadata:operations_metadata () let block_shell_header (block_info : block_info) = block_info.header.shell -- GitLab From a352c936cf06e828a3200d471ac9a9b4a489c41c Mon Sep 17 00:00:00 2001 From: "iguerNL@Functori" Date: Thu, 22 May 2025 11:52:56 +0200 Subject: [PATCH 4/5] DAL/Node: improve the interface when requesting cells of the skip list Explicitly return [None] if the cell associated to the given hash is not found in the sqlite backend. This translates to the use of `opt_register` on the RPC side, which returns 404 to the client if the value is [None], instead of crashing (5xx) with a Caqti error. --- src/lib_dal_node/dal_store_sqlite3.ml | 9 +++++---- src/lib_dal_node/dal_store_sqlite3.mli | 9 ++++++--- src/lib_dal_node/store.ml | 4 ++-- src/lib_dal_node/store.mli | 8 ++++---- src/lib_dal_node/test/test_storage.ml | 8 +++++--- src/proto_021_PsQuebec/lib_dal/RPC_directory.ml | 14 ++++++++------ src/proto_022_PsRiotum/lib_dal/RPC_directory.ml | 14 ++++++++------ src/proto_alpha/lib_dal/RPC_directory.ml | 14 ++++++++------ 8 files changed, 46 insertions(+), 34 deletions(-) diff --git a/src/lib_dal_node/dal_store_sqlite3.ml b/src/lib_dal_node/dal_store_sqlite3.ml index 5d526f512701..33f7b9092e2a 100644 --- a/src/lib_dal_node/dal_store_sqlite3.ml +++ b/src/lib_dal_node/dal_store_sqlite3.ml @@ -163,8 +163,9 @@ module Skip_list_cells = struct open Dal_proto_types open Tezos_dal_node_services.Types - let find : (Skip_list_hash.t, Skip_list_cell.t, [`One]) Caqti_request.t = - (skip_list_hash ->! skip_list_cell) + let find_opt : + (Skip_list_hash.t, Skip_list_cell.t, [`Zero | `One]) Caqti_request.t = + (skip_list_hash ->? skip_list_cell) @@ {sql| SELECT cell FROM skip_list_cells @@ -209,9 +210,9 @@ module Skip_list_cells = struct |sql} end - let find ?conn store skip_list_hash = + let find_opt ?conn store skip_list_hash = with_connection store conn @@ fun conn -> - Sqlite.Db.find conn Q.find skip_list_hash + Sqlite.Db.find_opt conn Q.find_opt skip_list_hash let remove ?conn store ~attested_level = let open Lwt_result_syntax in diff --git a/src/lib_dal_node/dal_store_sqlite3.mli b/src/lib_dal_node/dal_store_sqlite3.mli index 1eac89215448..991e5ff1cfb4 100644 --- a/src/lib_dal_node/dal_store_sqlite3.mli +++ b/src/lib_dal_node/dal_store_sqlite3.mli @@ -43,11 +43,14 @@ module Skip_list_cells : sig (** [use t k] executes [k] with a fresh connection to [t]. *) val use : t -> (conn -> 'a tzresult Lwt.t) -> 'a tzresult Lwt.t - (** [find ?conn store hash] returns the cell associated to [hash] in + (** [find_opt ?conn store hash] returns the cell associated to [hash] in the [store], if any. Uses the [conn] if provided (defaults to [None]). *) - val find : - ?conn:conn -> t -> Skip_list_hash.t -> Skip_list_cell.t tzresult Lwt.t + val find_opt : + ?conn:conn -> + t -> + Skip_list_hash.t -> + Skip_list_cell.t option tzresult Lwt.t (** [insert ?conn store ~attested_level values] inserts the given list of [values] associated to the given [attested_level] in the diff --git a/src/lib_dal_node/store.ml b/src/lib_dal_node/store.ml index 7b8663fee649..13f987f11731 100644 --- a/src/lib_dal_node/store.ml +++ b/src/lib_dal_node/store.ml @@ -663,8 +663,8 @@ let init_sqlite_skip_list_cells_store ?(perm = `Read_write) data_dir = () module Skip_list_cells = struct - let find ?conn t skip_list_hash = - Dal_store_sqlite3.Skip_list_cells.find + let find_opt ?conn t skip_list_hash = + Dal_store_sqlite3.Skip_list_cells.find_opt ?conn t.skip_list_cells_store skip_list_hash diff --git a/src/lib_dal_node/store.mli b/src/lib_dal_node/store.mli index 3ed576a6c97d..5bf623791c43 100644 --- a/src/lib_dal_node/store.mli +++ b/src/lib_dal_node/store.mli @@ -234,13 +234,13 @@ val add_slot_headers : module Skip_list_cells : sig open Dal_proto_types - (** [find ?conn store hash] returns the cell associated to [hash] in the [store], if - any. *) - val find : + (** [find_opt ?conn store hash] returns the cell associated to [hash] in the + [store], if any. *) + val find_opt : ?conn:Dal_store_sqlite3.conn -> t -> Skip_list_hash.t -> - Skip_list_cell.t tzresult Lwt.t + Skip_list_cell.t option tzresult Lwt.t (** [insert ?conn store ~attested_level values] inserts the given list of [values] associated to the given [attested_level] in the [store]. Any existing value diff --git a/src/lib_dal_node/test/test_storage.ml b/src/lib_dal_node/test/test_storage.ml index e645ac342b0c..c36f91ad3e80 100644 --- a/src/lib_dal_node/test/test_storage.ml +++ b/src/lib_dal_node/test/test_storage.ml @@ -312,7 +312,7 @@ let perform_sqlite store action = | Action.Insert {attested_level; payload} -> insert store ~attested_level payload | Find {skip_list_hash} -> - let* _cell = find store skip_list_hash in + let* _cell = find_opt store skip_list_hash in return_unit | Remove {attested_level} -> remove store ~attested_level @@ -337,8 +337,10 @@ let handshake state kvs_store sql_store = (fun hash -> (* The hash must exist in the stores and the associated cell must be the same. *) let* kvs_cell = Kvs_skip_list_cells_store.find kvs_store hash in - let* sql_cell = Dal_store_sqlite3.Skip_list_cells.find sql_store hash in - assert (Skip_list_cell.equal kvs_cell sql_cell) ; + let* sql_cell = + Dal_store_sqlite3.Skip_list_cells.find_opt sql_store hash + in + assert (Option.equal Skip_list_cell.equal (Some kvs_cell) sql_cell) ; return_unit) must_exist_hashes in diff --git a/src/proto_021_PsQuebec/lib_dal/RPC_directory.ml b/src/proto_021_PsQuebec/lib_dal/RPC_directory.ml index 291f6b08e925..fad35908a16a 100644 --- a/src/proto_021_PsQuebec/lib_dal/RPC_directory.ml +++ b/src/proto_021_PsQuebec/lib_dal/RPC_directory.ml @@ -17,11 +17,13 @@ module Skip_list_handlers = struct Alpha_context.Dal.Slots_history.Pointer_hash.encoding cell_hash in - let* cell = Dal_store_sqlite3.Skip_list_cells.find rpc_context hash in - return - @@ Dal_proto_types.Skip_list_cell.to_proto - Alpha_context.Dal.Slots_history.encoding - cell + let+ cell_opt = + Dal_store_sqlite3.Skip_list_cells.find_opt rpc_context hash + in + Option.map + (Dal_proto_types.Skip_list_cell.to_proto + Alpha_context.Dal.Slots_history.encoding) + cell_opt end let add_service registerer subst service handler directory = @@ -30,7 +32,7 @@ let add_service registerer subst service handler directory = let register_commitments_history ctxt directory = directory |> add_service - Tezos_rpc.Directory.register + Tezos_rpc.Directory.opt_register Tezos_rpc.Service.subst1 Dal_proto_services.Commitments_history.hash_content Skip_list_handlers.cell diff --git a/src/proto_022_PsRiotum/lib_dal/RPC_directory.ml b/src/proto_022_PsRiotum/lib_dal/RPC_directory.ml index 291f6b08e925..fad35908a16a 100644 --- a/src/proto_022_PsRiotum/lib_dal/RPC_directory.ml +++ b/src/proto_022_PsRiotum/lib_dal/RPC_directory.ml @@ -17,11 +17,13 @@ module Skip_list_handlers = struct Alpha_context.Dal.Slots_history.Pointer_hash.encoding cell_hash in - let* cell = Dal_store_sqlite3.Skip_list_cells.find rpc_context hash in - return - @@ Dal_proto_types.Skip_list_cell.to_proto - Alpha_context.Dal.Slots_history.encoding - cell + let+ cell_opt = + Dal_store_sqlite3.Skip_list_cells.find_opt rpc_context hash + in + Option.map + (Dal_proto_types.Skip_list_cell.to_proto + Alpha_context.Dal.Slots_history.encoding) + cell_opt end let add_service registerer subst service handler directory = @@ -30,7 +32,7 @@ let add_service registerer subst service handler directory = let register_commitments_history ctxt directory = directory |> add_service - Tezos_rpc.Directory.register + Tezos_rpc.Directory.opt_register Tezos_rpc.Service.subst1 Dal_proto_services.Commitments_history.hash_content Skip_list_handlers.cell diff --git a/src/proto_alpha/lib_dal/RPC_directory.ml b/src/proto_alpha/lib_dal/RPC_directory.ml index 291f6b08e925..fad35908a16a 100644 --- a/src/proto_alpha/lib_dal/RPC_directory.ml +++ b/src/proto_alpha/lib_dal/RPC_directory.ml @@ -17,11 +17,13 @@ module Skip_list_handlers = struct Alpha_context.Dal.Slots_history.Pointer_hash.encoding cell_hash in - let* cell = Dal_store_sqlite3.Skip_list_cells.find rpc_context hash in - return - @@ Dal_proto_types.Skip_list_cell.to_proto - Alpha_context.Dal.Slots_history.encoding - cell + let+ cell_opt = + Dal_store_sqlite3.Skip_list_cells.find_opt rpc_context hash + in + Option.map + (Dal_proto_types.Skip_list_cell.to_proto + Alpha_context.Dal.Slots_history.encoding) + cell_opt end let add_service registerer subst service handler directory = @@ -30,7 +32,7 @@ let add_service registerer subst service handler directory = let register_commitments_history ctxt directory = directory |> add_service - Tezos_rpc.Directory.register + Tezos_rpc.Directory.opt_register Tezos_rpc.Service.subst1 Dal_proto_services.Commitments_history.hash_content Skip_list_handlers.cell -- GitLab From fe6461dbed6720655e35bd2e8c574bf72c2b9535 Mon Sep 17 00:00:00 2001 From: "iguerNL@Functori" Date: Thu, 22 May 2025 11:37:43 +0200 Subject: [PATCH 5/5] DAL/Node: add a function find_by_slot_id_opt in skip lists' sqlite backend The internal SQL request needs a join on the cell's hash to retrieve the cell of the skip list given the slot id. Once the cell is obtained, its content could be inspected (e.g. to get the commitment hash) using the DAL plugin. --- src/lib_dal_node/dal_store_sqlite3.ml | 17 +++++++++++++++++ src/lib_dal_node/dal_store_sqlite3.mli | 10 ++++++++++ src/lib_dal_node/store.ml | 7 +++++++ src/lib_dal_node/store.mli | 10 ++++++++++ 4 files changed, 44 insertions(+) diff --git a/src/lib_dal_node/dal_store_sqlite3.ml b/src/lib_dal_node/dal_store_sqlite3.ml index 33f7b9092e2a..fbb018da624e 100644 --- a/src/lib_dal_node/dal_store_sqlite3.ml +++ b/src/lib_dal_node/dal_store_sqlite3.ml @@ -172,6 +172,19 @@ module Skip_list_cells = struct WHERE hash = $1 |sql} + let find_by_slot_id_opt : + (level * slot_index, Skip_list_cell.t, [`One | `Zero]) Caqti_request.t = + let open Caqti_type.Std in + (t2 attested_level dal_slot_index ->? skip_list_cell) + @@ {sql| + SELECT cell + FROM skip_list_cells + WHERE hash = ( + SELECT skip_list_cell_hash + FROM skip_list_slots + WHERE attested_level = $1 AND slot_index = $2 + )|sql} + let insert_skip_list_slot : (level * slot_index * Skip_list_hash.t, unit, [`Zero]) Caqti_request.t = (t3 attested_level dal_slot_index skip_list_hash ->. unit) @@ -214,6 +227,10 @@ module Skip_list_cells = struct with_connection store conn @@ fun conn -> Sqlite.Db.find_opt conn Q.find_opt skip_list_hash + let find_by_slot_id_opt ?conn store ~attested_level ~slot_index = + with_connection store conn @@ fun conn -> + Sqlite.Db.find_opt conn Q.find_by_slot_id_opt (attested_level, slot_index) + let remove ?conn store ~attested_level = let open Lwt_result_syntax in with_connection store conn @@ fun conn -> diff --git a/src/lib_dal_node/dal_store_sqlite3.mli b/src/lib_dal_node/dal_store_sqlite3.mli index 991e5ff1cfb4..b24ec12bac89 100644 --- a/src/lib_dal_node/dal_store_sqlite3.mli +++ b/src/lib_dal_node/dal_store_sqlite3.mli @@ -52,6 +52,16 @@ module Skip_list_cells : sig Skip_list_hash.t -> Skip_list_cell.t option tzresult Lwt.t + (** [find_by_slot_id_opt ?conn store ~attested_level ~slot_index] returns the cell + associated to ([attested_level], [slot_index]) in the [store], if + any. Uses the [conn] if provided (defaults to [None]). *) + val find_by_slot_id_opt : + ?conn:conn -> + t -> + attested_level:int32 -> + slot_index:int -> + Skip_list_cell.t option tzresult Lwt.t + (** [insert ?conn store ~attested_level values] inserts the given list of [values] associated to the given [attested_level] in the [store]. Any existing value is overridden. Uses the [conn] if diff --git a/src/lib_dal_node/store.ml b/src/lib_dal_node/store.ml index 13f987f11731..68a82000d6bc 100644 --- a/src/lib_dal_node/store.ml +++ b/src/lib_dal_node/store.ml @@ -669,6 +669,13 @@ module Skip_list_cells = struct t.skip_list_cells_store skip_list_hash + let find_by_slot_id_opt ?conn t ~attested_level ~slot_index = + Dal_store_sqlite3.Skip_list_cells.find_by_slot_id_opt + ?conn + t.skip_list_cells_store + ~attested_level + ~slot_index + let insert ?conn t ~attested_level items = Dal_store_sqlite3.Skip_list_cells.insert ?conn diff --git a/src/lib_dal_node/store.mli b/src/lib_dal_node/store.mli index 5bf623791c43..9ca17457fd63 100644 --- a/src/lib_dal_node/store.mli +++ b/src/lib_dal_node/store.mli @@ -242,6 +242,16 @@ module Skip_list_cells : sig Skip_list_hash.t -> Skip_list_cell.t option tzresult Lwt.t + (** [find_by_slot_id_opt ?conn store ~attested_level ~slot_index] returns the + cell associated to ([attested_level], [slot_index]) in the [store], if + any. *) + val find_by_slot_id_opt : + ?conn:Sqlite.conn -> + t -> + attested_level:int32 -> + slot_index:int -> + Dal_proto_types.Skip_list_cell.t option tzresult Lwt.t + (** [insert ?conn store ~attested_level values] inserts the given list of [values] associated to the given [attested_level] in the [store]. Any existing value is overridden. *) -- GitLab