From ba5dfd5fe4b79b87f4d8aed059e1caf1e5d7acc2 Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Tue, 13 Dec 2022 11:10:45 +0100 Subject: [PATCH 1/2] SCORU/Node: don't store hash->level association on disk --- .../bin_sc_rollup_node/RPC_server.ml | 16 ++--- .../bin_sc_rollup_node/commitment.ml | 34 +++++------ src/proto_alpha/bin_sc_rollup_node/daemon.ml | 2 +- .../bin_sc_rollup_node/dal_pages_request.ml | 30 ++++++---- src/proto_alpha/bin_sc_rollup_node/inbox.ml | 2 +- src/proto_alpha/bin_sc_rollup_node/outbox.ml | 6 +- .../bin_sc_rollup_node/refutation_game.ml | 4 +- src/proto_alpha/bin_sc_rollup_node/state.ml | 60 +++++++++---------- src/proto_alpha/bin_sc_rollup_node/state.mli | 27 +++++---- 9 files changed, 94 insertions(+), 87 deletions(-) diff --git a/src/proto_alpha/bin_sc_rollup_node/RPC_server.ml b/src/proto_alpha/bin_sc_rollup_node/RPC_server.ml index 4c44eb435dff..4fe448e05fb5 100644 --- a/src/proto_alpha/bin_sc_rollup_node/RPC_server.ml +++ b/src/proto_alpha/bin_sc_rollup_node/RPC_server.ml @@ -44,9 +44,9 @@ let get_finalized store = let get_last_cemented (node_ctxt : _ Node_context.t) = let open Lwt_result_syntax in protect @@ fun () -> - let*! lcc_hash = + let* lcc_hash = State.hash_of_level - node_ctxt.store + node_ctxt (Alpha_context.Raw_level.to_int32 node_ctxt.lcc.level) in return lcc_hash @@ -192,7 +192,7 @@ module Block_directory = Make_directory (struct match block with | `Head -> get_head node_ctxt.Node_context.store | `Hash b -> return b - | `Level l -> State.hash_of_level node_ctxt.store l >>= return + | `Level l -> State.hash_of_level node_ctxt l | `Finalized -> get_finalized node_ctxt.Node_context.store | `Cemented -> get_last_cemented node_ctxt in @@ -211,7 +211,7 @@ module Outbox_directory = Make_directory (struct match block with | `Head -> get_head node_ctxt.Node_context.store | `Hash b -> return b - | `Level l -> State.hash_of_level node_ctxt.store l >>= return + | `Level l -> State.hash_of_level node_ctxt l | `Finalized -> get_finalized node_ctxt.Node_context.store | `Cemented -> get_last_cemented node_ctxt in @@ -254,7 +254,7 @@ module Common = struct let () = Block_directory.register0 Sc_rollup_services.Global.Block.level - @@ fun (node_ctxt, block) () () -> State.level_of_hash node_ctxt.store block + @@ fun (node_ctxt, block) () () -> State.level_of_hash node_ctxt block let () = Block_directory.register0 Sc_rollup_services.Global.Block.inbox @@ -300,7 +300,7 @@ module Make (Simulation : Simulation.S) (Batcher : Batcher.S) = struct Some map | None -> None in - let* level = State.level_of_hash node_ctxt.store block in + let* level = State.level_of_hash node_ctxt block in let* sim = Simulation.start_simulation node_ctxt @@ -535,9 +535,9 @@ module Make (Simulation : Simulation.S) (Batcher : Batcher.S) = struct | None -> return (Sc_rollup_services.Included (info, inbox_info)) | Some commitment_level -> ( - let*! block = + let* block = State.hash_of_level - node_ctxt.store + node_ctxt (Alpha_context.Raw_level.to_int32 commitment_level) in let*! block = diff --git a/src/proto_alpha/bin_sc_rollup_node/commitment.ml b/src/proto_alpha/bin_sc_rollup_node/commitment.ml index fae9c06423e8..0c9c6fa82291 100644 --- a/src/proto_alpha/bin_sc_rollup_node/commitment.ml +++ b/src/proto_alpha/bin_sc_rollup_node/commitment.ml @@ -87,12 +87,12 @@ module Make (PVM : Pvm.S) : Commitment_sig.S with module PVM = PVM = struct module PVM = PVM let tick_of_level (node_ctxt : _ Node_context.t) inbox_level = - let open Lwt_syntax in + let open Lwt_result_syntax in let* block_hash = - State.hash_of_level node_ctxt.store (Raw_level.to_int32 inbox_level) + State.hash_of_level node_ctxt (Raw_level.to_int32 inbox_level) in - let+ block = Store.L2_blocks.get node_ctxt.store block_hash in - Sc_rollup_block.final_tick block + let*! block = Store.L2_blocks.get node_ctxt.store block_hash in + return (Sc_rollup_block.final_tick block) let build_commitment (node_ctxt : _ Node_context.t) (prev_commitment : Sc_rollup.Commitment.Hash.t) ~prev_commitment_level @@ -110,9 +110,7 @@ module Make (PVM : Pvm.S) : Commitment_sig.S with module PVM = PVM = struct in let*! compressed_state = PVM.state_hash pvm_state in let*! tick = PVM.get_tick pvm_state in - let*! prev_commitment_tick = - tick_of_level node_ctxt prev_commitment_level - in + let* prev_commitment_tick = tick_of_level node_ctxt prev_commitment_level in let number_of_ticks = Sc_rollup.Tick.distance tick prev_commitment_tick |> Z.to_int64 |> Sc_rollup.Number_of_ticks.of_value @@ -192,22 +190,25 @@ module Make (PVM : Pvm.S) : Commitment_sig.S with module PVM = PVM = struct in return_some commitment_hash - let block_of_known_level store level = + let block_of_known_level (node_ctxt : _ Node_context.t) level = let open Lwt_option_syntax in - let* head = State.last_processed_head_opt store in + let* head = State.last_processed_head_opt node_ctxt.store in if Raw_level.(head.header.level < level) then (* Level is not known yet *) fail else - let*! block_hash = State.hash_of_level store (Raw_level.to_int32 level) in - Store.L2_blocks.find store block_hash + let*! block_hash = + State.hash_of_level node_ctxt (Raw_level.to_int32 level) + in + let*? block_hash = Result.to_option block_hash in + Store.L2_blocks.find node_ctxt.store block_hash - let get_commitment_and_publish ~check_lcc_hash - ({store; _} as node_ctxt : _ Node_context.t) next_level_to_publish = + let get_commitment_and_publish ~check_lcc_hash node_ctxt next_level_to_publish + = let open Lwt_result_syntax in let*! commitment = let open Lwt_option_syntax in - let* block = block_of_known_level store next_level_to_publish in + let* block = block_of_known_level node_ctxt next_level_to_publish in let*? commitment_hash = block.header.commitment_hash in Store.Commitments.find node_ctxt.store commitment_hash in @@ -323,11 +324,10 @@ module Make (PVM : Pvm.S) : Commitment_sig.S with module PVM = PVM = struct let* _hash = Injector.add_pending_operation ~source cement_operation in return_unit - let cement_commitment_if_possible ({Node_context.store; _} as node_ctxt) - Layer1.{level = head_level; _} = + let cement_commitment_if_possible node_ctxt Layer1.{level = head_level; _} = let open Lwt_result_syntax in let next_level_to_cement = next_lcc_level node_ctxt in - let*! block = block_of_known_level store next_level_to_cement in + let*! block = block_of_known_level node_ctxt next_level_to_cement in match block with | None | Some {header = {commitment_hash = None; _}; _} -> (* Commitment not available *) diff --git a/src/proto_alpha/bin_sc_rollup_node/daemon.ml b/src/proto_alpha/bin_sc_rollup_node/daemon.ml index 8f23ed2c2740..034b3d0f5081 100644 --- a/src/proto_alpha/bin_sc_rollup_node/daemon.ml +++ b/src/proto_alpha/bin_sc_rollup_node/daemon.ml @@ -197,7 +197,7 @@ module Make (PVM : Pvm.S) = struct = let open Lwt_result_syntax in let*! () = Daemon_event.head_processing hash level ~finalized:false in - let*! () = State.set_block_level_and_hash node_ctxt.store head in + let*! () = State.save_level node_ctxt.store head in let* inbox_hash, inbox, inbox_witness, messages, ctxt = Inbox.process_head node_ctxt head in diff --git a/src/proto_alpha/bin_sc_rollup_node/dal_pages_request.ml b/src/proto_alpha/bin_sc_rollup_node/dal_pages_request.ml index 2c8002f3337a..da4c8280bd33 100644 --- a/src/proto_alpha/bin_sc_rollup_node/dal_pages_request.ml +++ b/src/proto_alpha/bin_sc_rollup_node/dal_pages_request.ml @@ -59,9 +59,9 @@ let () = (function Dal_invalid_page_for_slot page_id -> Some page_id | _ -> None) (fun page_id -> Dal_invalid_page_for_slot page_id) -let store_entry_from_published_level ~dal_attestation_lag ~published_level store - = - State.hash_of_level store +let store_entry_from_published_level ~dal_attestation_lag ~published_level + node_ctxt = + State.hash_of_level node_ctxt @@ Int32.( add (of_int dal_attestation_lag) (Raw_level.to_int32 published_level)) @@ -94,7 +94,7 @@ let check_confirmation_status_and_download ~published_in_block_hash index = let open Lwt_result_syntax in let* confirmed_in_block_level = - State.level_of_hash node_ctxt.store confirmed_in_block_hash + State.level_of_hash node_ctxt confirmed_in_block_hash in let confirmed_in_head = Layer1.{hash = confirmed_in_block_hash; level = confirmed_in_block_level} @@ -130,8 +130,11 @@ let check_confirmation_status_and_download let slot_pages ~dal_attestation_lag ({Node_context.store; _} as node_ctxt) Dal.Slot.Header.{published_level; index} = let open Lwt_result_syntax in - let*! confirmed_in_block_hash = - store_entry_from_published_level ~dal_attestation_lag ~published_level store + let* confirmed_in_block_hash = + store_entry_from_published_level + ~dal_attestation_lag + ~published_level + node_ctxt in let*! processed = Store.Dal_processed_slots.find @@ -141,8 +144,8 @@ let slot_pages ~dal_attestation_lag ({Node_context.store; _} as node_ctxt) in match processed with | None -> - let*! published_in_block_hash = - State.hash_of_level store (Raw_level.to_int32 published_level) + let* published_in_block_hash = + State.hash_of_level node_ctxt (Raw_level.to_int32 published_level) in check_confirmation_status_and_download node_ctxt @@ -170,8 +173,11 @@ let page_content ~dal_attestation_lag ({Node_context.store; _} as node_ctxt) let open Delayed_write_monad.Lwt_result_syntax in let Dal.Page.{slot_id; page_index} = page_id in let Dal.Slot.Header.{published_level; index} = slot_id in - let*! confirmed_in_block_hash = - store_entry_from_published_level ~dal_attestation_lag ~published_level store + let* confirmed_in_block_hash = + store_entry_from_published_level + ~dal_attestation_lag + ~published_level + node_ctxt in let*! processed = Store.Dal_processed_slots.find @@ -189,8 +195,8 @@ let page_content ~dal_attestation_lag ({Node_context.store; _} as node_ctxt) having this additional check in place ensures that we do not rely on the logic of that function when determining the confirmation status of a slot. *) - let*! published_in_block_hash = - State.hash_of_level store (Raw_level.to_int32 published_level) + let* published_in_block_hash = + State.hash_of_level node_ctxt (Raw_level.to_int32 published_level) in let>* pages = check_confirmation_status_and_download diff --git a/src/proto_alpha/bin_sc_rollup_node/inbox.ml b/src/proto_alpha/bin_sc_rollup_node/inbox.ml index ce186d891ef8..07aa6a1facb4 100644 --- a/src/proto_alpha/bin_sc_rollup_node/inbox.ml +++ b/src/proto_alpha/bin_sc_rollup_node/inbox.ml @@ -253,7 +253,7 @@ let process_head (node_ctxt : _ Node_context.t) let inbox_of_hash node_ctxt hash = let open Lwt_result_syntax in - let* level = State.level_of_hash node_ctxt.Node_context.store hash in + let* level = State.level_of_hash node_ctxt hash in State.inbox_of_head node_ctxt {hash; level} let inbox_of_head = State.inbox_of_head diff --git a/src/proto_alpha/bin_sc_rollup_node/outbox.ml b/src/proto_alpha/bin_sc_rollup_node/outbox.ml index 56b410ed2595..6b1c60ff71fc 100644 --- a/src/proto_alpha/bin_sc_rollup_node/outbox.ml +++ b/src/proto_alpha/bin_sc_rollup_node/outbox.ml @@ -29,10 +29,8 @@ open Protocol.Alpha_context module Make (PVM : Pvm.S) = struct let get_state_of_lcc node_ctxt = let open Lwt_result_syntax in - let*! block_hash = - State.hash_of_level - node_ctxt.store - (Raw_level.to_int32 node_ctxt.lcc.level) + let* block_hash = + State.hash_of_level node_ctxt (Raw_level.to_int32 node_ctxt.lcc.level) in let* ctxt = Node_context.checkout_context node_ctxt block_hash in let*! state = PVM.State.find ctxt in diff --git a/src/proto_alpha/bin_sc_rollup_node/refutation_game.ml b/src/proto_alpha/bin_sc_rollup_node/refutation_game.ml index b215f13c6ec8..4178c1117dc4 100644 --- a/src/proto_alpha/bin_sc_rollup_node/refutation_game.ml +++ b/src/proto_alpha/bin_sc_rollup_node/refutation_game.ml @@ -165,9 +165,7 @@ module Make (Interpreter : Interpreter.S) : let snapshot_level_int32 = Int32.pred Raw_level.(to_int32 game.start_level) in - let*! snapshot_hash = - State.hash_of_level node_ctxt.Node_context.store snapshot_level_int32 - in + let* snapshot_hash = State.hash_of_level node_ctxt snapshot_level_int32 in let snapshot_head = Layer1.{hash = snapshot_hash; level = snapshot_level_int32} in diff --git a/src/proto_alpha/bin_sc_rollup_node/state.ml b/src/proto_alpha/bin_sc_rollup_node/state.ml index 7d916f43ec26..7c189136e987 100644 --- a/src/proto_alpha/bin_sc_rollup_node/state.ml +++ b/src/proto_alpha/bin_sc_rollup_node/state.ml @@ -75,36 +75,41 @@ module Store = struct let encoding = Tezos_crypto.Block_hash.encoding end) - - (** Table from L1 blocks hashes to levels. *) - module Hashes_to_levels = - Store.Make_append_only_map - (struct - let path = ["tezos"; "blocks_hashes"] - end) - (struct - type key = Tezos_crypto.Block_hash.t - - let to_path_representation = Tezos_crypto.Block_hash.to_b58check - end) - (struct - type value = int32 - - let name = "level" - - let encoding = Data_encoding.int32 - end) end -let hash_of_level store level = Store.Levels_to_hashes.get store level +let hash_of_level_opt Node_context.{store; cctxt; _} level = + let open Lwt_syntax in + let* hash = Store.Levels_to_hashes.find store level in + match hash with + | Some hash -> return_some hash + | None -> + let+ hash = + Tezos_shell_services.Shell_services.Blocks.hash + cctxt + ~chain:cctxt#chain + ~block:(`Level level) + () + in + Result.to_option hash + +let hash_of_level node_ctxt level = + let open Lwt_result_syntax in + let*! hash = hash_of_level_opt node_ctxt level in + match hash with + | Some h -> return h + | None -> failwith "Cannot retrieve hash of level %ld" level -let level_of_hash store hash = +let level_of_hash {Node_context.l1_ctxt; store; _} hash = let open Lwt_result_syntax in - let*! level = Store.Hashes_to_levels.find store hash in - match level with + let*! block = Raw_store.L2_blocks.find store hash in + match block with + | Some {header = {level; _}; _} -> return (Raw_level.to_int32 level) | None -> - failwith "No level known for block %a" Tezos_crypto.Block_hash.pp hash - | Some l -> return l + let+ {level; _} = Layer1.fetch_tezos_shell_header l1_ctxt hash in + level + +let save_level store Layer1.{hash; level} = + Store.Levels_to_hashes.add store level hash let save_l2_block store (head : Sc_rollup_block.t) = let open Lwt_syntax in @@ -119,11 +124,6 @@ let mark_finalized_head store head = Store.Last_finalized_head.set store head let get_finalized_head_opt store = Store.Last_finalized_head.find store -let set_block_level_and_hash store Layer1.{hash; level} = - let open Lwt_syntax in - let* () = Store.Hashes_to_levels.add store hash level in - Store.Levels_to_hashes.add store level hash - (* TODO: https://gitlab.com/tezos/tezos/-/issues/4532 Make this logarithmic, by storing pointers to muliple predecessor and by dichotomy. *) diff --git a/src/proto_alpha/bin_sc_rollup_node/state.mli b/src/proto_alpha/bin_sc_rollup_node/state.mli index 9db757186c6d..3481f831c419 100644 --- a/src/proto_alpha/bin_sc_rollup_node/state.mli +++ b/src/proto_alpha/bin_sc_rollup_node/state.mli @@ -45,19 +45,24 @@ val mark_finalized_head : Store.rw -> Layer1.head -> unit Lwt.t (** [last_finalized_head_opt store] returns the last finalized head if it exists. *) val get_finalized_head_opt : _ Store.t -> Layer1.head option Lwt.t -(** [hash_of_level store level] returns the current block hash for a - given [level]. Raise [Invalid_argument] if [hash] does not belong - to [store]. *) -val hash_of_level : _ Store.t -> int32 -> Tezos_crypto.Block_hash.t Lwt.t +(** [hash_of_level node_ctxt level] returns the current block hash for a given + [level]. *) +val hash_of_level : + _ Node_context.t -> int32 -> Tezos_crypto.Block_hash.t tzresult Lwt.t -(** [level_of_hash store hash] returns the level for Tezos block hash [hash] if - it is known by the rollup node. *) -val level_of_hash : - _ Store.t -> Tezos_crypto.Block_hash.t -> int32 tzresult Lwt.t +(** [hash_of_level_opt] is like {!hash_of_level} but returns [None] if the + [level] is not known. *) +val hash_of_level_opt : + _ Node_context.t -> int32 -> Tezos_crypto.Block_hash.t option Lwt.t + +(** [save_level store head] registers the correspondences [head.level |-> + head.hash] in the store. *) +val save_level : Store.rw -> Layer1.head -> unit Lwt.t -(** [set_block_level_and_hash store head] registers the correspondences - [head.level |-> head.hash] and [head.hash |-> head.level] in the store. *) -val set_block_level_and_hash : Store.rw -> Layer1.head -> unit Lwt.t +(** [level_of_hash node_ctxt hash] returns the level for Tezos block hash [hash] + if it is known by the Tezos Layer 1 node. *) +val level_of_hash : + _ Node_context.t -> Tezos_crypto.Block_hash.t -> int32 tzresult Lwt.t (** [block_before store tick] returns the last layer 2 block whose initial tick is before [tick]. *) -- GitLab From 2bc0d1d52ffe0aa449af75f781de7877e74cf97f Mon Sep 17 00:00:00 2001 From: Valentin Chaboche Date: Mon, 16 Jan 2023 13:47:27 +0100 Subject: [PATCH 2/2] SCORU/Node: Backport !7132 to Mumbai - SCORU/Node: don't store hash->level association on disk --- .../bin_sc_rollup_node/RPC_server.ml | 16 ++--- .../bin_sc_rollup_node/commitment.ml | 34 +++++------ .../bin_sc_rollup_node/daemon.ml | 2 +- .../bin_sc_rollup_node/dal_pages_request.ml | 30 ++++++---- .../bin_sc_rollup_node/inbox.ml | 2 +- .../bin_sc_rollup_node/outbox.ml | 6 +- .../bin_sc_rollup_node/refutation_game.ml | 4 +- .../bin_sc_rollup_node/state.ml | 60 +++++++++---------- .../bin_sc_rollup_node/state.mli | 27 +++++---- 9 files changed, 94 insertions(+), 87 deletions(-) diff --git a/src/proto_016_PtMumbai/bin_sc_rollup_node/RPC_server.ml b/src/proto_016_PtMumbai/bin_sc_rollup_node/RPC_server.ml index 4c44eb435dff..4fe448e05fb5 100644 --- a/src/proto_016_PtMumbai/bin_sc_rollup_node/RPC_server.ml +++ b/src/proto_016_PtMumbai/bin_sc_rollup_node/RPC_server.ml @@ -44,9 +44,9 @@ let get_finalized store = let get_last_cemented (node_ctxt : _ Node_context.t) = let open Lwt_result_syntax in protect @@ fun () -> - let*! lcc_hash = + let* lcc_hash = State.hash_of_level - node_ctxt.store + node_ctxt (Alpha_context.Raw_level.to_int32 node_ctxt.lcc.level) in return lcc_hash @@ -192,7 +192,7 @@ module Block_directory = Make_directory (struct match block with | `Head -> get_head node_ctxt.Node_context.store | `Hash b -> return b - | `Level l -> State.hash_of_level node_ctxt.store l >>= return + | `Level l -> State.hash_of_level node_ctxt l | `Finalized -> get_finalized node_ctxt.Node_context.store | `Cemented -> get_last_cemented node_ctxt in @@ -211,7 +211,7 @@ module Outbox_directory = Make_directory (struct match block with | `Head -> get_head node_ctxt.Node_context.store | `Hash b -> return b - | `Level l -> State.hash_of_level node_ctxt.store l >>= return + | `Level l -> State.hash_of_level node_ctxt l | `Finalized -> get_finalized node_ctxt.Node_context.store | `Cemented -> get_last_cemented node_ctxt in @@ -254,7 +254,7 @@ module Common = struct let () = Block_directory.register0 Sc_rollup_services.Global.Block.level - @@ fun (node_ctxt, block) () () -> State.level_of_hash node_ctxt.store block + @@ fun (node_ctxt, block) () () -> State.level_of_hash node_ctxt block let () = Block_directory.register0 Sc_rollup_services.Global.Block.inbox @@ -300,7 +300,7 @@ module Make (Simulation : Simulation.S) (Batcher : Batcher.S) = struct Some map | None -> None in - let* level = State.level_of_hash node_ctxt.store block in + let* level = State.level_of_hash node_ctxt block in let* sim = Simulation.start_simulation node_ctxt @@ -535,9 +535,9 @@ module Make (Simulation : Simulation.S) (Batcher : Batcher.S) = struct | None -> return (Sc_rollup_services.Included (info, inbox_info)) | Some commitment_level -> ( - let*! block = + let* block = State.hash_of_level - node_ctxt.store + node_ctxt (Alpha_context.Raw_level.to_int32 commitment_level) in let*! block = diff --git a/src/proto_016_PtMumbai/bin_sc_rollup_node/commitment.ml b/src/proto_016_PtMumbai/bin_sc_rollup_node/commitment.ml index fae9c06423e8..0c9c6fa82291 100644 --- a/src/proto_016_PtMumbai/bin_sc_rollup_node/commitment.ml +++ b/src/proto_016_PtMumbai/bin_sc_rollup_node/commitment.ml @@ -87,12 +87,12 @@ module Make (PVM : Pvm.S) : Commitment_sig.S with module PVM = PVM = struct module PVM = PVM let tick_of_level (node_ctxt : _ Node_context.t) inbox_level = - let open Lwt_syntax in + let open Lwt_result_syntax in let* block_hash = - State.hash_of_level node_ctxt.store (Raw_level.to_int32 inbox_level) + State.hash_of_level node_ctxt (Raw_level.to_int32 inbox_level) in - let+ block = Store.L2_blocks.get node_ctxt.store block_hash in - Sc_rollup_block.final_tick block + let*! block = Store.L2_blocks.get node_ctxt.store block_hash in + return (Sc_rollup_block.final_tick block) let build_commitment (node_ctxt : _ Node_context.t) (prev_commitment : Sc_rollup.Commitment.Hash.t) ~prev_commitment_level @@ -110,9 +110,7 @@ module Make (PVM : Pvm.S) : Commitment_sig.S with module PVM = PVM = struct in let*! compressed_state = PVM.state_hash pvm_state in let*! tick = PVM.get_tick pvm_state in - let*! prev_commitment_tick = - tick_of_level node_ctxt prev_commitment_level - in + let* prev_commitment_tick = tick_of_level node_ctxt prev_commitment_level in let number_of_ticks = Sc_rollup.Tick.distance tick prev_commitment_tick |> Z.to_int64 |> Sc_rollup.Number_of_ticks.of_value @@ -192,22 +190,25 @@ module Make (PVM : Pvm.S) : Commitment_sig.S with module PVM = PVM = struct in return_some commitment_hash - let block_of_known_level store level = + let block_of_known_level (node_ctxt : _ Node_context.t) level = let open Lwt_option_syntax in - let* head = State.last_processed_head_opt store in + let* head = State.last_processed_head_opt node_ctxt.store in if Raw_level.(head.header.level < level) then (* Level is not known yet *) fail else - let*! block_hash = State.hash_of_level store (Raw_level.to_int32 level) in - Store.L2_blocks.find store block_hash + let*! block_hash = + State.hash_of_level node_ctxt (Raw_level.to_int32 level) + in + let*? block_hash = Result.to_option block_hash in + Store.L2_blocks.find node_ctxt.store block_hash - let get_commitment_and_publish ~check_lcc_hash - ({store; _} as node_ctxt : _ Node_context.t) next_level_to_publish = + let get_commitment_and_publish ~check_lcc_hash node_ctxt next_level_to_publish + = let open Lwt_result_syntax in let*! commitment = let open Lwt_option_syntax in - let* block = block_of_known_level store next_level_to_publish in + let* block = block_of_known_level node_ctxt next_level_to_publish in let*? commitment_hash = block.header.commitment_hash in Store.Commitments.find node_ctxt.store commitment_hash in @@ -323,11 +324,10 @@ module Make (PVM : Pvm.S) : Commitment_sig.S with module PVM = PVM = struct let* _hash = Injector.add_pending_operation ~source cement_operation in return_unit - let cement_commitment_if_possible ({Node_context.store; _} as node_ctxt) - Layer1.{level = head_level; _} = + let cement_commitment_if_possible node_ctxt Layer1.{level = head_level; _} = let open Lwt_result_syntax in let next_level_to_cement = next_lcc_level node_ctxt in - let*! block = block_of_known_level store next_level_to_cement in + let*! block = block_of_known_level node_ctxt next_level_to_cement in match block with | None | Some {header = {commitment_hash = None; _}; _} -> (* Commitment not available *) diff --git a/src/proto_016_PtMumbai/bin_sc_rollup_node/daemon.ml b/src/proto_016_PtMumbai/bin_sc_rollup_node/daemon.ml index 8ce0a211f3c6..262676f62d4c 100644 --- a/src/proto_016_PtMumbai/bin_sc_rollup_node/daemon.ml +++ b/src/proto_016_PtMumbai/bin_sc_rollup_node/daemon.ml @@ -197,7 +197,7 @@ module Make (PVM : Pvm.S) = struct = let open Lwt_result_syntax in let*! () = Daemon_event.head_processing hash level ~finalized:false in - let*! () = State.set_block_level_and_hash node_ctxt.store head in + let*! () = State.save_level node_ctxt.store head in let* inbox_hash, inbox, inbox_witness, messages, ctxt = Inbox.process_head node_ctxt head in diff --git a/src/proto_016_PtMumbai/bin_sc_rollup_node/dal_pages_request.ml b/src/proto_016_PtMumbai/bin_sc_rollup_node/dal_pages_request.ml index 2c8002f3337a..da4c8280bd33 100644 --- a/src/proto_016_PtMumbai/bin_sc_rollup_node/dal_pages_request.ml +++ b/src/proto_016_PtMumbai/bin_sc_rollup_node/dal_pages_request.ml @@ -59,9 +59,9 @@ let () = (function Dal_invalid_page_for_slot page_id -> Some page_id | _ -> None) (fun page_id -> Dal_invalid_page_for_slot page_id) -let store_entry_from_published_level ~dal_attestation_lag ~published_level store - = - State.hash_of_level store +let store_entry_from_published_level ~dal_attestation_lag ~published_level + node_ctxt = + State.hash_of_level node_ctxt @@ Int32.( add (of_int dal_attestation_lag) (Raw_level.to_int32 published_level)) @@ -94,7 +94,7 @@ let check_confirmation_status_and_download ~published_in_block_hash index = let open Lwt_result_syntax in let* confirmed_in_block_level = - State.level_of_hash node_ctxt.store confirmed_in_block_hash + State.level_of_hash node_ctxt confirmed_in_block_hash in let confirmed_in_head = Layer1.{hash = confirmed_in_block_hash; level = confirmed_in_block_level} @@ -130,8 +130,11 @@ let check_confirmation_status_and_download let slot_pages ~dal_attestation_lag ({Node_context.store; _} as node_ctxt) Dal.Slot.Header.{published_level; index} = let open Lwt_result_syntax in - let*! confirmed_in_block_hash = - store_entry_from_published_level ~dal_attestation_lag ~published_level store + let* confirmed_in_block_hash = + store_entry_from_published_level + ~dal_attestation_lag + ~published_level + node_ctxt in let*! processed = Store.Dal_processed_slots.find @@ -141,8 +144,8 @@ let slot_pages ~dal_attestation_lag ({Node_context.store; _} as node_ctxt) in match processed with | None -> - let*! published_in_block_hash = - State.hash_of_level store (Raw_level.to_int32 published_level) + let* published_in_block_hash = + State.hash_of_level node_ctxt (Raw_level.to_int32 published_level) in check_confirmation_status_and_download node_ctxt @@ -170,8 +173,11 @@ let page_content ~dal_attestation_lag ({Node_context.store; _} as node_ctxt) let open Delayed_write_monad.Lwt_result_syntax in let Dal.Page.{slot_id; page_index} = page_id in let Dal.Slot.Header.{published_level; index} = slot_id in - let*! confirmed_in_block_hash = - store_entry_from_published_level ~dal_attestation_lag ~published_level store + let* confirmed_in_block_hash = + store_entry_from_published_level + ~dal_attestation_lag + ~published_level + node_ctxt in let*! processed = Store.Dal_processed_slots.find @@ -189,8 +195,8 @@ let page_content ~dal_attestation_lag ({Node_context.store; _} as node_ctxt) having this additional check in place ensures that we do not rely on the logic of that function when determining the confirmation status of a slot. *) - let*! published_in_block_hash = - State.hash_of_level store (Raw_level.to_int32 published_level) + let* published_in_block_hash = + State.hash_of_level node_ctxt (Raw_level.to_int32 published_level) in let>* pages = check_confirmation_status_and_download diff --git a/src/proto_016_PtMumbai/bin_sc_rollup_node/inbox.ml b/src/proto_016_PtMumbai/bin_sc_rollup_node/inbox.ml index ce186d891ef8..07aa6a1facb4 100644 --- a/src/proto_016_PtMumbai/bin_sc_rollup_node/inbox.ml +++ b/src/proto_016_PtMumbai/bin_sc_rollup_node/inbox.ml @@ -253,7 +253,7 @@ let process_head (node_ctxt : _ Node_context.t) let inbox_of_hash node_ctxt hash = let open Lwt_result_syntax in - let* level = State.level_of_hash node_ctxt.Node_context.store hash in + let* level = State.level_of_hash node_ctxt hash in State.inbox_of_head node_ctxt {hash; level} let inbox_of_head = State.inbox_of_head diff --git a/src/proto_016_PtMumbai/bin_sc_rollup_node/outbox.ml b/src/proto_016_PtMumbai/bin_sc_rollup_node/outbox.ml index 56b410ed2595..6b1c60ff71fc 100644 --- a/src/proto_016_PtMumbai/bin_sc_rollup_node/outbox.ml +++ b/src/proto_016_PtMumbai/bin_sc_rollup_node/outbox.ml @@ -29,10 +29,8 @@ open Protocol.Alpha_context module Make (PVM : Pvm.S) = struct let get_state_of_lcc node_ctxt = let open Lwt_result_syntax in - let*! block_hash = - State.hash_of_level - node_ctxt.store - (Raw_level.to_int32 node_ctxt.lcc.level) + let* block_hash = + State.hash_of_level node_ctxt (Raw_level.to_int32 node_ctxt.lcc.level) in let* ctxt = Node_context.checkout_context node_ctxt block_hash in let*! state = PVM.State.find ctxt in diff --git a/src/proto_016_PtMumbai/bin_sc_rollup_node/refutation_game.ml b/src/proto_016_PtMumbai/bin_sc_rollup_node/refutation_game.ml index b215f13c6ec8..4178c1117dc4 100644 --- a/src/proto_016_PtMumbai/bin_sc_rollup_node/refutation_game.ml +++ b/src/proto_016_PtMumbai/bin_sc_rollup_node/refutation_game.ml @@ -165,9 +165,7 @@ module Make (Interpreter : Interpreter.S) : let snapshot_level_int32 = Int32.pred Raw_level.(to_int32 game.start_level) in - let*! snapshot_hash = - State.hash_of_level node_ctxt.Node_context.store snapshot_level_int32 - in + let* snapshot_hash = State.hash_of_level node_ctxt snapshot_level_int32 in let snapshot_head = Layer1.{hash = snapshot_hash; level = snapshot_level_int32} in diff --git a/src/proto_016_PtMumbai/bin_sc_rollup_node/state.ml b/src/proto_016_PtMumbai/bin_sc_rollup_node/state.ml index 7d916f43ec26..7c189136e987 100644 --- a/src/proto_016_PtMumbai/bin_sc_rollup_node/state.ml +++ b/src/proto_016_PtMumbai/bin_sc_rollup_node/state.ml @@ -75,36 +75,41 @@ module Store = struct let encoding = Tezos_crypto.Block_hash.encoding end) - - (** Table from L1 blocks hashes to levels. *) - module Hashes_to_levels = - Store.Make_append_only_map - (struct - let path = ["tezos"; "blocks_hashes"] - end) - (struct - type key = Tezos_crypto.Block_hash.t - - let to_path_representation = Tezos_crypto.Block_hash.to_b58check - end) - (struct - type value = int32 - - let name = "level" - - let encoding = Data_encoding.int32 - end) end -let hash_of_level store level = Store.Levels_to_hashes.get store level +let hash_of_level_opt Node_context.{store; cctxt; _} level = + let open Lwt_syntax in + let* hash = Store.Levels_to_hashes.find store level in + match hash with + | Some hash -> return_some hash + | None -> + let+ hash = + Tezos_shell_services.Shell_services.Blocks.hash + cctxt + ~chain:cctxt#chain + ~block:(`Level level) + () + in + Result.to_option hash + +let hash_of_level node_ctxt level = + let open Lwt_result_syntax in + let*! hash = hash_of_level_opt node_ctxt level in + match hash with + | Some h -> return h + | None -> failwith "Cannot retrieve hash of level %ld" level -let level_of_hash store hash = +let level_of_hash {Node_context.l1_ctxt; store; _} hash = let open Lwt_result_syntax in - let*! level = Store.Hashes_to_levels.find store hash in - match level with + let*! block = Raw_store.L2_blocks.find store hash in + match block with + | Some {header = {level; _}; _} -> return (Raw_level.to_int32 level) | None -> - failwith "No level known for block %a" Tezos_crypto.Block_hash.pp hash - | Some l -> return l + let+ {level; _} = Layer1.fetch_tezos_shell_header l1_ctxt hash in + level + +let save_level store Layer1.{hash; level} = + Store.Levels_to_hashes.add store level hash let save_l2_block store (head : Sc_rollup_block.t) = let open Lwt_syntax in @@ -119,11 +124,6 @@ let mark_finalized_head store head = Store.Last_finalized_head.set store head let get_finalized_head_opt store = Store.Last_finalized_head.find store -let set_block_level_and_hash store Layer1.{hash; level} = - let open Lwt_syntax in - let* () = Store.Hashes_to_levels.add store hash level in - Store.Levels_to_hashes.add store level hash - (* TODO: https://gitlab.com/tezos/tezos/-/issues/4532 Make this logarithmic, by storing pointers to muliple predecessor and by dichotomy. *) diff --git a/src/proto_016_PtMumbai/bin_sc_rollup_node/state.mli b/src/proto_016_PtMumbai/bin_sc_rollup_node/state.mli index 9db757186c6d..3481f831c419 100644 --- a/src/proto_016_PtMumbai/bin_sc_rollup_node/state.mli +++ b/src/proto_016_PtMumbai/bin_sc_rollup_node/state.mli @@ -45,19 +45,24 @@ val mark_finalized_head : Store.rw -> Layer1.head -> unit Lwt.t (** [last_finalized_head_opt store] returns the last finalized head if it exists. *) val get_finalized_head_opt : _ Store.t -> Layer1.head option Lwt.t -(** [hash_of_level store level] returns the current block hash for a - given [level]. Raise [Invalid_argument] if [hash] does not belong - to [store]. *) -val hash_of_level : _ Store.t -> int32 -> Tezos_crypto.Block_hash.t Lwt.t +(** [hash_of_level node_ctxt level] returns the current block hash for a given + [level]. *) +val hash_of_level : + _ Node_context.t -> int32 -> Tezos_crypto.Block_hash.t tzresult Lwt.t -(** [level_of_hash store hash] returns the level for Tezos block hash [hash] if - it is known by the rollup node. *) -val level_of_hash : - _ Store.t -> Tezos_crypto.Block_hash.t -> int32 tzresult Lwt.t +(** [hash_of_level_opt] is like {!hash_of_level} but returns [None] if the + [level] is not known. *) +val hash_of_level_opt : + _ Node_context.t -> int32 -> Tezos_crypto.Block_hash.t option Lwt.t + +(** [save_level store head] registers the correspondences [head.level |-> + head.hash] in the store. *) +val save_level : Store.rw -> Layer1.head -> unit Lwt.t -(** [set_block_level_and_hash store head] registers the correspondences - [head.level |-> head.hash] and [head.hash |-> head.level] in the store. *) -val set_block_level_and_hash : Store.rw -> Layer1.head -> unit Lwt.t +(** [level_of_hash node_ctxt hash] returns the level for Tezos block hash [hash] + if it is known by the Tezos Layer 1 node. *) +val level_of_hash : + _ Node_context.t -> Tezos_crypto.Block_hash.t -> int32 tzresult Lwt.t (** [block_before store tick] returns the last layer 2 block whose initial tick is before [tick]. *) -- GitLab