From 795701608c22170bd4874bbc0ed7c89773ee1baf Mon Sep 17 00:00:00 2001 From: Gavin Wood <gavin@parity.io> Date: Fri, 22 Nov 2019 13:05:52 +0100 Subject: [PATCH] grandpa: voting rules shouldn't restrict past round base (#4155) * grandpa: voting rules shouldn't restrict past round base * grandpa: fix lower bound on vote restriction. add test --- .../client/finality-grandpa/src/environment.rs | 12 +++++++++++- substrate/client/finality-grandpa/src/tests.rs | 13 +++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/substrate/client/finality-grandpa/src/environment.rs b/substrate/client/finality-grandpa/src/environment.rs index 883dc0e35c0..b0eaf298b5a 100644 --- a/substrate/client/finality-grandpa/src/environment.rs +++ b/substrate/client/finality-grandpa/src/environment.rs @@ -34,7 +34,7 @@ use client_api::{ utils::is_descendent_of, }; use client::{ - apply_aux, Client, + apply_aux, Client, }; use grandpa::{ BlockNumberOps, Equivocation, Error as GrandpaError, round::State as RoundState, @@ -497,8 +497,18 @@ where // note that we pass the original `best_header`, i.e. before the // authority set limit filter, which can be considered a // mandatory/implicit voting rule. + // + // we also make sure that the restricted vote is higher than the + // round base (i.e. last finalized), otherwise the value + // returned by the given voting rule is ignored and the original + // target is used instead. self.voting_rule .restrict_vote(&*self.client, &base_header, &best_header, target_header) + .filter(|(_, restricted_number)| { + // we can only restrict votes within the interval [base, target] + restricted_number >= base_header.number() && + restricted_number < target_header.number() + }) .or(Some((target_header.hash(), *target_header.number()))) }, Ok(None) => { diff --git a/substrate/client/finality-grandpa/src/tests.rs b/substrate/client/finality-grandpa/src/tests.rs index 6d4d439a9fb..abcd44635cc 100644 --- a/substrate/client/finality-grandpa/src/tests.rs +++ b/substrate/client/finality-grandpa/src/tests.rs @@ -1660,6 +1660,19 @@ fn grandpa_environment_respects_voting_rules() { ).unwrap().1, 19, ); + + // we finalize block 20 with block 20 being the best block + peer.client().finalize_block(BlockId::Number(20), None, false).unwrap(); + + // even though the default environment will always try to not vote on the + // best block, there's a hard rule that we can't cast any votes lower than + // the given base (#20). + assert_eq!( + default_env.best_chain_containing( + peer.client().info().chain.finalized_hash + ).unwrap().1, + 20, + ); } #[test] -- GitLab