From a0a2d6b004cd5c4435a7e0c116cfc6ed5fdffaf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Henry?= Date: Sat, 5 May 2018 20:25:57 +0200 Subject: [PATCH] Shell: filter out future block --- src/lib_shell/bootstrap_pipeline.ml | 10 ++++++ src/lib_shell/distributed_db.ml | 38 +++++++++++++++------ src/lib_shell_services/validation_errors.ml | 1 + 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/src/lib_shell/bootstrap_pipeline.ml b/src/lib_shell/bootstrap_pipeline.ml index 75f52912a..5c3f702b8 100644 --- a/src/lib_shell/bootstrap_pipeline.ml +++ b/src/lib_shell/bootstrap_pipeline.ml @@ -61,6 +61,9 @@ let fetch_step pipeline (step : Block_locator.step) = pipeline.chain_db ~peer:pipeline.peer_id hash () end >>=? fun header -> + fail_unless + (Time.(now () >= header.shell.timestamp)) + (Future_block_header hash) >>=? fun () -> lwt_debug "fetched block header %a from peer %a." Block_hash.pp_short hash P2p_peer.Id.pp_short pipeline.peer_id >>= fun () -> @@ -99,6 +102,12 @@ let headers_fetch_worker_loop pipeline = P2p_peer.Id.pp_short pipeline.peer_id >>= fun () -> Lwt_canceler.cancel pipeline.canceler >>= fun () -> Lwt.return_unit + | Error [ Future_block_header bh ] -> + lwt_log_notice "Block locator %a from peer %a contains future blocks." + Block_hash.pp_short bh + P2p_peer.Id.pp_short pipeline.peer_id >>= fun () -> + Lwt_canceler.cancel pipeline.canceler >>= fun () -> + Lwt.return_unit | Error err -> pipeline.errors <- pipeline.errors @ err ; lwt_log_error "@[Unexpected error (headers fetch):@ %a@]" @@ -214,6 +223,7 @@ let create Lwt_canceler.on_cancel pipeline.canceler begin fun () -> Lwt_pipe.close fetched_blocks ; Lwt_pipe.close fetched_headers ; + (* TODO proper cleanup of ressources... *) Lwt.return_unit end ; let head, _ = (pipeline.locator : Block_locator.t :> _ * _) in diff --git a/src/lib_shell/distributed_db.ml b/src/lib_shell/distributed_db.ml index 67d3cd59c..d77eea659 100644 --- a/src/lib_shell/distributed_db.ml +++ b/src/lib_shell/distributed_db.ml @@ -490,12 +490,20 @@ module P2p_reader = struct Lwt_list.exists_p (State.Block.known_invalid chain_db.chain_state) (Block_header.hash head :: hist) >>= fun known_invalid -> - if not known_invalid then - chain_db.callback.notify_branch state.gid locator - else - (* Kickban *) - P2p.greylist_peer global_db.p2p state.gid; - Lwt.return_unit + if known_invalid then begin + (* TODO Kick *) + P2p.greylist_peer global_db.p2p state.gid ; + Lwt.return_unit + end else if Time.(now () < head.shell.timestamp) then begin + (* TODO some penalty *) + lwt_log_notice "Received future block %a from peer %a." + Block_hash.pp_short (Block_header.hash head) + P2p_peer.Id.pp_short state.gid >>= fun () -> + Lwt.return_unit + end else begin + chain_db.callback.notify_branch state.gid locator ; + Lwt.return_unit + end | Deactivate chain_id -> may_handle state chain_id @@ fun chain_db -> @@ -533,12 +541,20 @@ module P2p_reader = struct so the message is ignored. This should probably warrant a reduction of the sender's score. *) in - if not known_invalid then - chain_db.callback.notify_head state.gid header mempool - else - (* Kickban *) + if known_invalid then begin + (* TODO Kick *) P2p.greylist_peer global_db.p2p state.gid ; - Lwt.return_unit + Lwt.return_unit + end else if Time.(now () < header.shell.timestamp) then begin + (* TODO some penalty *) + lwt_log_notice "Received future block %a from peer %a." + Block_hash.pp_short head + P2p_peer.Id.pp_short state.gid >>= fun () -> + Lwt.return_unit + end else begin + chain_db.callback.notify_head state.gid header mempool ; + Lwt.return_unit + end | Get_block_headers hashes -> Lwt_list.iter_p diff --git a/src/lib_shell_services/validation_errors.ml b/src/lib_shell_services/validation_errors.ml index e38f617fc..5331ea787 100644 --- a/src/lib_shell_services/validation_errors.ml +++ b/src/lib_shell_services/validation_errors.ml @@ -12,6 +12,7 @@ type error += Parse_error type error += Too_many_operations type error += Oversized_operation of { size: int ; max: int } +type error += Future_block_header of Block_hash.t let () = (* Parse error *)