diff --git a/src/lib_store/unix/reconstruction.ml b/src/lib_store/unix/reconstruction.ml index 120b4ee2e4f96fed5abcbaa7774edbe2b5f6bfb0..4af9ff17934590a0c9a11bc35b670ab83741c5d9 100644 --- a/src/lib_store/unix/reconstruction.ml +++ b/src/lib_store/unix/reconstruction.ml @@ -28,6 +28,7 @@ type failure_kind = | Cannot_read_block_hash of Block_hash.t | Cannot_read_block_level of Int32.t | Cannot_read_resulting_context_hash of Block_hash.t + | Cannot_read_block_metadata of Block_hash.t let failure_kind_encoding = let open Data_encoding in @@ -51,6 +52,12 @@ let failure_kind_encoding = int32 (function Cannot_read_block_level l -> Some l | _ -> None) (fun l -> Cannot_read_block_level l); + case + (Tag 3) + ~title:"cannot_read_block_metadata" + Block_hash.encoding + (function Cannot_read_block_metadata h -> Some h | _ -> None) + (fun h -> Cannot_read_block_metadata h); ] let failure_kind_pp ppf = function @@ -65,6 +72,12 @@ let failure_kind_pp ppf = function "Unexpected missing resulting context hash in store for block %a" Block_hash.pp h + | Cannot_read_block_metadata h -> + Format.fprintf + ppf + "Unexpected missing block metadata in store: %a" + Block_hash.pp + h type error += Reconstruction_failure of failure_kind @@ -169,7 +182,8 @@ let compute_all_operations_metadata_hash block = let apply_context context_index chain_id ~user_activated_upgrades ~user_activated_protocol_overrides ~operation_metadata_size_limit ~predecessor_block_metadata_hash ~predecessor_ops_metadata_hash - ~predecessor_block ~expected_context_hash block = + ~predecessor_max_operations_ttl ~predecessor_block ~expected_context_hash + block = let open Lwt_result_syntax in let block_header = Store.Block.header block in let operations = Store.Block.operations block in @@ -186,8 +200,7 @@ let apply_context context_index chain_id ~user_activated_upgrades in let apply_environment = { - Block_validation.max_operations_ttl = - Int32.to_int (Store.Block.level predecessor_block); + Block_validation.max_operations_ttl = predecessor_max_operations_ttl; chain_id; predecessor_block_header; predecessor_context; @@ -313,7 +326,7 @@ let reconstruct_chunk chain_store context_index ~user_activated_upgrades ~start_level ~end_level = let open Lwt_result_syntax in let chain_id = Store.Chain.chain_id chain_store in - let rec loop level acc = + let rec loop level predecessor_max_operations_ttl acc = if level > end_level then return List.(rev acc) else let* block = @@ -340,6 +353,7 @@ let reconstruct_chunk chain_store context_index ~user_activated_upgrades reconstruct_genesis_operations_metadata chain_store else let* ( predecessor_block, + predecessor_max_operations_ttl, predecessor_block_metadata_hash, predecessor_ops_metadata_hash ) = match acc with @@ -350,8 +364,27 @@ let reconstruct_chunk chain_store context_index ~user_activated_upgrades let* predecessor_block = Store.Block.read_predecessor chain_store block in + let block_store = Store.Unsafe.get_block_store chain_store in + let cemented_block_store = + Block_store.cemented_block_store block_store + in + let* predecessor_metadata = + Cemented_block_store.read_block_metadata + cemented_block_store + (Store.Block.level predecessor_block) + in + let* predecessor_max_operations_ttl = + match predecessor_metadata with + | Some m -> return (Store.Block.max_operations_ttl m) + | None -> + tzfail + (Reconstruction_failure + (Cannot_read_block_metadata + (Store.Block.hash predecessor_block))) + in return ( predecessor_block, + predecessor_max_operations_ttl, Store.Block.block_metadata_hash predecessor_block, Store.Block.all_operations_metadata_hash predecessor_block ) @@ -363,6 +396,7 @@ let reconstruct_chunk chain_store context_index ~user_activated_upgrades let predecessor_block = Store.Unsafe.block_of_repr pred in return ( predecessor_block, + predecessor_max_operations_ttl, Block_repr.block_metadata_hash pred, compute_all_operations_metadata_hash pred ) in @@ -374,6 +408,7 @@ let reconstruct_chunk chain_store context_index ~user_activated_upgrades ~operation_metadata_size_limit ~predecessor_block_metadata_hash ~predecessor_ops_metadata_hash + ~predecessor_max_operations_ttl ~predecessor_block ~expected_context_hash:Proto.expected_context_hash block @@ -393,9 +428,12 @@ let reconstruct_chunk chain_store context_index ~user_activated_upgrades last_preserved_block_level (Store.Unsafe.repr_of_block block) in - loop (Int32.succ level) ((reconstructed_block, block_protocol_env) :: acc) + loop + (Int32.succ level) + max_operations_ttl + ((reconstructed_block, block_protocol_env) :: acc) in - loop start_level [] + loop start_level 0 [] let store_chunk cemented_store chunk = let open Lwt_result_syntax in @@ -757,6 +795,15 @@ let reconstruct_floating chain_store context_index ~user_activated_upgrades | Some b -> return (Store.Unsafe.block_of_repr b)) in + let* predecessor_block_metadata = + Store.Block.get_block_metadata + chain_store + predecessor_block + in + let predecessor_max_operations_ttl = + Store.Block.max_operations_ttl + predecessor_block_metadata + in let* res = apply_context context_index @@ -770,6 +817,7 @@ let reconstruct_floating chain_store context_index ~user_activated_upgrades ~predecessor_ops_metadata_hash: (Store.Block.all_operations_metadata_hash predecessor_block) + ~predecessor_max_operations_ttl ~predecessor_block ~expected_context_hash:Proto.expected_context_hash block diff --git a/src/lib_store/unix/reconstruction.mli b/src/lib_store/unix/reconstruction.mli index d0308d2a374a509f350cb59d9b6bc0327381d886..8db9f6f5bbd0078987db1c9a1a4920beb18b00e5 100644 --- a/src/lib_store/unix/reconstruction.mli +++ b/src/lib_store/unix/reconstruction.mli @@ -56,6 +56,7 @@ type failure_kind = | Cannot_read_block_hash of Block_hash.t | Cannot_read_block_level of Int32.t | Cannot_read_resulting_context_hash of Block_hash.t + | Cannot_read_block_metadata of Block_hash.t type error += Reconstruction_failure of failure_kind diff --git a/src/lib_store/unix/snapshots.ml b/src/lib_store/unix/snapshots.ml index cc14eed977cbca81f55377452b6ece835df12f25..fbef8aedba2e0236039c89ffa60ca3a593534f86 100644 --- a/src/lib_store/unix/snapshots.ml +++ b/src/lib_store/unix/snapshots.ml @@ -787,6 +787,7 @@ type block_data = { block_header : Block_header.t; operations : Operation.t list list; predecessor_header : Block_header.t; + predecessor_max_operations_ttl : int; predecessor_block_metadata_hash : Block_metadata_hash.t option; predecessor_ops_metadata_hash : Operation_metadata_list_list_hash.t option; resulting_context_hash : Context_hash.t; @@ -799,6 +800,7 @@ let block_data_encoding = block_header; operations; predecessor_header; + predecessor_max_operations_ttl; predecessor_block_metadata_hash; predecessor_ops_metadata_hash; resulting_context_hash; @@ -806,12 +808,14 @@ let block_data_encoding = ( operations, block_header, predecessor_header, + predecessor_max_operations_ttl, predecessor_block_metadata_hash, predecessor_ops_metadata_hash, resulting_context_hash )) (fun ( operations, block_header, predecessor_header, + predecessor_max_operations_ttl, predecessor_block_metadata_hash, predecessor_ops_metadata_hash, resulting_context_hash ) -> @@ -819,14 +823,16 @@ let block_data_encoding = block_header; operations; predecessor_header; + predecessor_max_operations_ttl; predecessor_block_metadata_hash; predecessor_ops_metadata_hash; resulting_context_hash; }) - (obj6 + (obj7 (req "operations" (list (list (dynamic_size Operation.encoding)))) (req "block_header" (dynamic_size Block_header.encoding)) (req "predecessor_header" (dynamic_size Block_header.encoding)) + (req "predecessor_max_operations_ttl" int31) (opt "predecessor_block_metadata_hash" Block_metadata_hash.encoding) (opt "predecessor_ops_metadata_hash" @@ -1439,6 +1445,7 @@ module type EXPORTER = sig val write_block_data : t -> predecessor_header:Block_header.t -> + predecessor_max_operations_ttl:int -> predecessor_block_metadata_hash:Block_metadata_hash.t option -> predecessor_ops_metadata_hash:Operation_metadata_list_list_hash.t option -> export_block:Store.Block.t -> @@ -1519,14 +1526,16 @@ module Raw_exporter : EXPORTER = struct snapshot_protocol_dir; } - let write_block_data t ~predecessor_header ~predecessor_block_metadata_hash - ~predecessor_ops_metadata_hash ~export_block ~resulting_context_hash = + let write_block_data t ~predecessor_header ~predecessor_max_operations_ttl + ~predecessor_block_metadata_hash ~predecessor_ops_metadata_hash + ~export_block ~resulting_context_hash = let open Lwt_syntax in let block_data = { block_header = Store.Block.header export_block; operations = Store.Block.operations export_block; predecessor_header; + predecessor_max_operations_ttl; predecessor_block_metadata_hash; predecessor_ops_metadata_hash; resulting_context_hash; @@ -1777,13 +1786,15 @@ module Tar_exporter : EXPORTER = struct tar; } - let write_block_data t ~predecessor_header ~predecessor_block_metadata_hash - ~predecessor_ops_metadata_hash ~export_block ~resulting_context_hash = + let write_block_data t ~predecessor_header ~predecessor_max_operations_ttl + ~predecessor_block_metadata_hash ~predecessor_ops_metadata_hash + ~export_block ~resulting_context_hash = let block_data = { block_header = Store.Block.header export_block; operations = Store.Block.operations export_block; predecessor_header; + predecessor_max_operations_ttl; predecessor_block_metadata_hash; predecessor_ops_metadata_hash; resulting_context_hash; @@ -2546,6 +2557,12 @@ module Make_snapshot_exporter (Exporter : EXPORTER) : Snapshot_exporter = struct let* resulting_context_hash = Store.Block.resulting_context_hash chain_store export_block in + let* pred_block_metadata = + Store.Block.get_block_metadata chain_store pred_block + in + let pred_max_operations_ttl = + Store.Block.max_operations_ttl pred_block_metadata + in let* () = export_context snapshot_exporter ~data_dir pred_resulting_context_hash in @@ -2554,6 +2571,7 @@ module Make_snapshot_exporter (Exporter : EXPORTER) : Snapshot_exporter = struct export_block, resulting_context_hash, pred_block, + pred_max_operations_ttl, protocol_levels, (return_unit, floating_block_stream) ) in @@ -2561,6 +2579,7 @@ module Make_snapshot_exporter (Exporter : EXPORTER) : Snapshot_exporter = struct export_block, resulting_context_hash, pred_block, + pred_max_operations_ttl, protocol_levels, (return_unit, floating_block_stream) ) = Store.Unsafe.open_for_snapshot_export @@ -2574,6 +2593,7 @@ module Make_snapshot_exporter (Exporter : EXPORTER) : Snapshot_exporter = struct export_block, resulting_context_hash, pred_block, + pred_max_operations_ttl, protocol_levels, (return_unit, floating_block_stream) ) @@ -2646,6 +2666,12 @@ module Make_snapshot_exporter (Exporter : EXPORTER) : Snapshot_exporter = struct let* resulting_context_hash = Store.Block.resulting_context_hash chain_store export_block in + let* pred_block_metadata = + Store.Block.get_block_metadata chain_store pred_block + in + let pred_max_operations_ttl = + Store.Block.max_operations_ttl pred_block_metadata + in let* () = export_context snapshot_exporter @@ -2657,6 +2683,7 @@ module Make_snapshot_exporter (Exporter : EXPORTER) : Snapshot_exporter = struct export_block, resulting_context_hash, pred_block, + pred_max_operations_ttl, protocol_levels, cemented_table, (ro_fd, rw_fd), @@ -2669,8 +2696,9 @@ module Make_snapshot_exporter (Exporter : EXPORTER) : Snapshot_exporter = struct in let* ( export_mode, export_block, - pred_block, pred_resulting_context, + pred_block, + pred_max_operations_ttl, protocol_levels, cemented_table, (floating_ro_fd, floating_rw_fd), @@ -2716,8 +2744,9 @@ module Make_snapshot_exporter (Exporter : EXPORTER) : Snapshot_exporter = struct return ( export_mode, export_block, - pred_block, pred_resulting_context, + pred_block, + pred_max_operations_ttl, protocol_levels, (reading_thread, floating_block_stream) ) @@ -2751,6 +2780,7 @@ module Make_snapshot_exporter (Exporter : EXPORTER) : Snapshot_exporter = struct export_block, resulting_context_hash, pred_block, + predecessor_max_operations_ttl, protocol_levels, (reading_thread, floating_block_stream) ) = if rolling then @@ -2783,6 +2813,7 @@ module Make_snapshot_exporter (Exporter : EXPORTER) : Snapshot_exporter = struct Exporter.write_block_data snapshot_exporter ~predecessor_header:(Store.Block.header pred_block) + ~predecessor_max_operations_ttl ~predecessor_block_metadata_hash ~predecessor_ops_metadata_hash ~export_block @@ -3767,8 +3798,9 @@ module Make_snapshot_importer (Importer : IMPORTER) : Snapshot_importer = struct let apply_context context_index ~imported_context_hash chain_id ~block_header ~operations ~predecessor_header ~predecessor_block_metadata_hash - ~predecessor_ops_metadata_hash ~user_activated_upgrades - ~user_activated_protocol_overrides ~operation_metadata_size_limit = + ~predecessor_ops_metadata_hash ~predecessor_max_operations_ttl + ~user_activated_upgrades ~user_activated_protocol_overrides + ~operation_metadata_size_limit = let open Lwt_result_syntax in let* predecessor_context = let*! o = Context_ops.checkout context_index imported_context_hash in @@ -3776,10 +3808,10 @@ module Make_snapshot_importer (Importer : IMPORTER) : Snapshot_importer = struct | Some ch -> return ch | None -> tzfail (Inconsistent_context imported_context_hash) in + let max_operations_ttl = predecessor_max_operations_ttl in let apply_environment = { - Block_validation.max_operations_ttl = - Int32.to_int predecessor_header.Block_header.shell.level; + Block_validation.max_operations_ttl; chain_id; predecessor_block_header = predecessor_header; predecessor_context; @@ -3826,6 +3858,7 @@ module Make_snapshot_importer (Importer : IMPORTER) : Snapshot_importer = struct resulting_context_hash; operations; predecessor_header; + predecessor_max_operations_ttl; predecessor_block_metadata_hash; predecessor_ops_metadata_hash; } as block_data) = @@ -3936,6 +3969,7 @@ module Make_snapshot_importer (Importer : IMPORTER) : Snapshot_importer = struct ~predecessor_header ~predecessor_block_metadata_hash ~predecessor_ops_metadata_hash + ~predecessor_max_operations_ttl ~user_activated_upgrades ~user_activated_protocol_overrides ~operation_metadata_size_limit