From ae82f2b279d2a9e10a9697461b62e5cea0d3cb52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Henry?= Date: Tue, 5 Dec 2017 15:19:25 +0100 Subject: [PATCH] Shell: enforce the context hash of the block header --- lib_node_shell/block_validator.ml | 4 ++-- lib_node_shell/state.ml | 21 ++++++++++++++++++++- lib_node_shell/state.mli | 2 ++ 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/lib_node_shell/block_validator.ml b/lib_node_shell/block_validator.ml index 0c9a5f53e..6b21a97fe 100644 --- a/lib_node_shell/block_validator.ml +++ b/lib_node_shell/block_validator.ml @@ -486,8 +486,6 @@ let rec worker_loop bv = end end >>= function | Ok result -> begin - lwt_log_info "validated block %a" - Block_hash.pp_short hash >>= fun () -> Lwt_utils.protect ~canceler:bv.canceler begin fun () -> Distributed_db.commit_block net_db hash header operations result @@ -495,6 +493,8 @@ let rec worker_loop bv = | None -> assert false (* should not happen *) | Some block -> + lwt_log_info "validated block %a" + Block_hash.pp_short hash >>= fun () -> Protocol_validator.prefetch_and_compile_protocols bv.protocol_validator ?peer ~timeout:bv.protocol_timeout diff --git a/lib_node_shell/state.ml b/lib_node_shell/state.ml index 33b5c94fc..d0d901b25 100644 --- a/lib_node_shell/state.ml +++ b/lib_node_shell/state.ml @@ -441,6 +441,22 @@ module Block = struct read_exn net_state header.shell.predecessor >>= fun block -> Lwt.return (Some block) + type error += Inconsistent_hash of Context_hash.t * Context_hash.t + + let () = + Error_monad.register_error_kind + `Permanent + ~id:"inconsistentContextHash" + ~title:"Inconsistent commit hash" + ~description: + "When commiting the context of a block, the announced context \ + hash was not the one computed at commit time." + Data_encoding.(obj2 + (req "wrong_context_hash" Context_hash.encoding) + (req "expected_context_hash" Context_hash.encoding)) + (function Inconsistent_hash (got, exp) -> Some (got, exp) | _ -> None) + (fun (got, exp) -> Inconsistent_hash (got, exp)) + let store net_state block_header operations { Updater.context ; message ; max_operations_ttl ; @@ -457,6 +473,9 @@ module Block = struct else begin Context.commit ~time:block_header.shell.timestamp ?message context >>= fun commit -> + fail_unless + (Context_hash.equal block_header.shell.context commit) + (Inconsistent_hash (commit, block_header.shell.context)) >>=? fun () -> let contents = { Store.Block.header = block_header ; message ; @@ -544,7 +563,7 @@ module Block = struct let context { net_state ; hash } = Shared.use net_state.block_store begin fun block_store -> Store.Block.Contents.read_exn (block_store, hash) - end >>= fun { context = commit } -> + end >>= fun { context = commit } -> Shared.use net_state.context_index begin fun context_index -> Context.checkout_exn context_index commit end diff --git a/lib_node_shell/state.mli b/lib_node_shell/state.mli index d341410fe..fc649eacc 100644 --- a/lib_node_shell/state.mli +++ b/lib_node_shell/state.mli @@ -104,6 +104,8 @@ module Block : sig val read_opt: Net.t -> Block_hash.t -> block option Lwt.t val read_exn: Net.t -> Block_hash.t -> block Lwt.t + type error += Inconsistent_hash of Context_hash.t * Context_hash.t + val store: Net.t -> Block_header.t ->