Shell: early detection of incompatible new heads and branches.

This commit is contained in:
Grégoire Henry 2018-05-10 16:59:48 +02:00 committed by Benjamin Canou
parent 96dd65e36d
commit 6170ae2246

View File

@ -123,16 +123,6 @@ let bootstrap_new_branch w _ancestor _head unknown_prefix =
let validate_new_head w hash (header : Block_header.t) =
let pv = Worker.state w in
let chain_state = Distributed_db.chain_state pv.parameters.chain_db in
State.Block.known chain_state header.shell.predecessor >>= function
| false ->
debug w
"missing predecessor for new head %a from peer %a"
Block_hash.pp_short hash
P2p_peer.Id.pp_short pv.peer_id ;
Distributed_db.Request.current_branch pv.parameters.chain_db ~peer:pv.peer_id () ;
return ()
| true ->
debug w
"fetching operations for new head %a from peer %a"
Block_hash.pp_short hash
@ -177,13 +167,23 @@ let only_if_fitness_increases w distant_header cont =
return ()
end else cont ()
let may_validate_new_head w hash header =
let assert_acceptable_head w hash (header: Block_header.t) =
let pv = Worker.state w in
let chain_state = Distributed_db.chain_state pv.parameters.chain_db in
State.Block.known chain_state hash >>= function
| true -> begin
State.Block.known_valid chain_state hash >>= function
| true ->
State.Chain.acceptable_block chain_state hash header >>= fun acceptable ->
fail_unless acceptable
(Validation_errors.Checkpoint_error (hash, Some pv.peer_id))
let may_validate_new_head w hash (header : Block_header.t) =
let pv = Worker.state w in
let chain_state = Distributed_db.chain_state pv.parameters.chain_db in
State.Block.known_valid chain_state hash >>= fun valid_block ->
State.Block.known_invalid chain_state hash >>= fun invalid_block ->
State.Block.known_valid chain_state
header.shell.predecessor >>= fun valid_predecessor ->
State.Block.known_invalid chain_state
header.shell.predecessor >>= fun invalid_predecessor ->
if valid_block then begin
debug w
"ignoring previously validated block %a from peer %a"
Block_hash.pp_short hash
@ -191,21 +191,40 @@ let may_validate_new_head w hash header =
set_bootstrapped pv ;
pv.last_validated_head <- header ;
return ()
| false ->
end else if invalid_block then begin
debug w
"ignoring known invalid block %a from peer %a"
Block_hash.pp_short hash
P2p_peer.Id.pp_short pv.peer_id ;
fail Validation_errors.Known_invalid
end
| false ->
end else if invalid_predecessor then begin
debug w
"ignoring known invalid block %a from peer %a"
Block_hash.pp_short hash
P2p_peer.Id.pp_short pv.peer_id ;
Distributed_db.commit_invalid_block pv.parameters.chain_db
hash header [Validation_errors.Known_invalid] >>=? fun _ ->
fail Validation_errors.Known_invalid
end else if not valid_predecessor then begin
debug w
"missing predecessor for new head %a from peer %a"
Block_hash.pp_short hash
P2p_peer.Id.pp_short pv.peer_id ;
Distributed_db.Request.current_branch
pv.parameters.chain_db ~peer:pv.peer_id () ;
return ()
end else begin
only_if_fitness_increases w header @@ fun () ->
assert_acceptable_head w hash header >>=? fun () ->
validate_new_head w hash header
end
let may_validate_new_branch w distant_hash locator =
let pv = Worker.state w in
let distant_header, _ = (locator : Block_locator.t :> Block_header.t * _) in
only_if_fitness_increases w distant_header @@ fun () ->
assert_acceptable_head w
(Block_header.hash distant_header) distant_header >>=? fun () ->
let chain_state = Distributed_db.chain_state pv.parameters.chain_db in
State.Block.known_ancestor chain_state locator >>= function
| None ->