From 275d08678ddec7193238c4cc7217877d09f172bc Mon Sep 17 00:00:00 2001 From: Andreas Fackler Date: Thu, 15 Aug 2019 10:17:53 +0200 Subject: [PATCH] Rename parameter to two_thirds_majority_transition. --- .../src/engines/authority_round/finality.rs | 12 +++---- ethcore/src/engines/authority_round/mod.rs | 34 +++++++++++-------- json/src/spec/authority_round.rs | 2 +- 3 files changed, 26 insertions(+), 22 deletions(-) diff --git a/ethcore/src/engines/authority_round/finality.rs b/ethcore/src/engines/authority_round/finality.rs index 01244ecd38c..76b086efccc 100644 --- a/ethcore/src/engines/authority_round/finality.rs +++ b/ethcore/src/engines/authority_round/finality.rs @@ -36,19 +36,19 @@ pub struct RollingFinality { sign_count: HashMap, last_pushed: Option, /// First block for which a 2/3 quorum (instead of 1/2) is required. - quorum_2_3_transition: BlockNumber, + two_thirds_majority_transition: BlockNumber, } impl RollingFinality { /// Create a blank finality checker under the given validator set. - pub fn blank(signers: Vec
, quorum_2_3_transition: BlockNumber) -> Self { + pub fn blank(signers: Vec
, two_thirds_majority_transition: BlockNumber) -> Self { trace!(target: "finality", "Instantiating blank RollingFinality with {} signers: {:?}", signers.len(), signers); RollingFinality { headers: VecDeque::new(), signers: SimpleList::new(signers), sign_count: HashMap::new(), last_pushed: None, - quorum_2_3_transition, + two_thirds_majority_transition, } } @@ -133,15 +133,15 @@ impl RollingFinality { } /// Returns the first block for which a 2/3 quorum (instead of 1/2) is required. - pub fn quorum_2_3_transition(&self) -> BlockNumber { - self.quorum_2_3_transition + pub fn two_thirds_majority_transition(&self) -> BlockNumber { + self.two_thirds_majority_transition } /// Returns whether the first entry in `self.headers` is finalized. fn is_finalized(&self) -> bool { match self.headers.front() { None => false, - Some((_, number, _)) if *number < self.quorum_2_3_transition => { + Some((_, number, _)) if *number < self.two_thirds_majority_transition => { self.sign_count.len() * 2 > self.signers.len() } Some((_, _, _)) => { diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index 2b54930fa59..a670149e6fc 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -15,6 +15,10 @@ // along with Parity Ethereum. If not, see . //! A blockchain engine that supports a non-instant BFT proof-of-authority. +//! +//! It is recommended to use the `two_thirds_majority_transition` option, to defend against the +//! ["Attack of the Clones"](https://arxiv.org/pdf/1902.10244.pdf). Newly started networks can +//! set this option to `0`, to use a 2/3 quorum from the beginning. use std::collections::{BTreeMap, BTreeSet, HashSet}; use std::{cmp, fmt}; @@ -94,7 +98,7 @@ pub struct AuthorityRoundParams { /// Empty step messages transition block. pub empty_steps_transition: u64, /// First block for which a 2/3 quorum (instead of 1/2) is required. - pub quorum_2_3_transition: BlockNumber, + pub two_thirds_majority_transition: BlockNumber, /// Number of accepted empty steps. pub maximum_empty_steps: usize, /// Transition block to strict empty steps validation. @@ -128,7 +132,7 @@ impl From for AuthorityRoundParams { maximum_uncle_count: p.maximum_uncle_count.map_or(0, Into::into), empty_steps_transition: p.empty_steps_transition.map_or(u64::max_value(), |n| ::std::cmp::max(n.into(), 1)), maximum_empty_steps: p.maximum_empty_steps.map_or(0, Into::into), - quorum_2_3_transition: p.quorum_2_3_transition.map_or_else(BlockNumber::max_value, Into::into), + two_thirds_majority_transition: p.two_thirds_majority_transition.map_or_else(BlockNumber::max_value, Into::into), strict_empty_steps_transition: p.strict_empty_steps_transition.map_or(0, Into::into), } } @@ -224,11 +228,11 @@ struct EpochManager { } impl EpochManager { - fn blank(quorum_2_3_transition: BlockNumber) -> Self { + fn blank(two_thirds_majority_transition: BlockNumber) -> Self { EpochManager { epoch_transition_hash: H256::zero(), epoch_transition_number: 0, - finality_checker: RollingFinality::blank(Vec::new(), quorum_2_3_transition), + finality_checker: RollingFinality::blank(Vec::new(), two_thirds_majority_transition), force: true, } } @@ -292,8 +296,8 @@ impl EpochManager { }) .expect("proof produced by this engine; therefore it is valid; qed"); - let quorum_2_3_transition = self.finality_checker.quorum_2_3_transition(); - self.finality_checker = RollingFinality::blank(epoch_set, quorum_2_3_transition); + let two_thirds_majority_transition = self.finality_checker.two_thirds_majority_transition(); + self.finality_checker = RollingFinality::blank(epoch_set, two_thirds_majority_transition); } self.epoch_transition_hash = last_transition.block_hash; @@ -456,7 +460,7 @@ pub struct AuthorityRound { maximum_uncle_count: usize, empty_steps_transition: u64, strict_empty_steps_transition: u64, - quorum_2_3_transition: BlockNumber, + two_thirds_majority_transition: BlockNumber, maximum_empty_steps: usize, machine: Machine, } @@ -467,7 +471,7 @@ struct EpochVerifier { subchain_validators: SimpleList, empty_steps_transition: u64, /// First block for which a 2/3 quorum (instead of 1/2) is required. - quorum_2_3_transition: BlockNumber, + two_thirds_majority_transition: BlockNumber, } impl engine::EpochVerifier for EpochVerifier { @@ -481,7 +485,7 @@ impl engine::EpochVerifier for EpochVerifier { fn check_finality_proof(&self, proof: &[u8]) -> Option> { let signers = self.subchain_validators.clone().into_inner(); - let mut finality_checker = RollingFinality::blank(signers, self.quorum_2_3_transition); + let mut finality_checker = RollingFinality::blank(signers, self.two_thirds_majority_transition); let mut finalized = Vec::new(); let headers: Vec
= Rlp::new(proof).as_list().ok()?; @@ -717,7 +721,7 @@ impl AuthorityRound { validate_score_transition: our_params.validate_score_transition, validate_step_transition: our_params.validate_step_transition, empty_steps: Default::default(), - epoch_manager: Mutex::new(EpochManager::blank(our_params.quorum_2_3_transition)), + epoch_manager: Mutex::new(EpochManager::blank(our_params.two_thirds_majority_transition)), immediate_transitions: our_params.immediate_transitions, block_reward: our_params.block_reward, block_reward_contract_transition: our_params.block_reward_contract_transition, @@ -726,7 +730,7 @@ impl AuthorityRound { maximum_uncle_count: our_params.maximum_uncle_count, empty_steps_transition: our_params.empty_steps_transition, maximum_empty_steps: our_params.maximum_empty_steps, - quorum_2_3_transition: our_params.quorum_2_3_transition, + two_thirds_majority_transition: our_params.two_thirds_majority_transition, strict_empty_steps_transition: our_params.strict_empty_steps_transition, machine, }); @@ -1267,8 +1271,8 @@ impl Engine for AuthorityRound { ) -> Result<(), Error> { let mut beneficiaries = Vec::new(); - if block.header.number() == self.quorum_2_3_transition { - info!(target: "engine", "Block {}: Transitioning to 2/3 quorum.", self.quorum_2_3_transition); + if block.header.number() == self.two_thirds_majority_transition { + info!(target: "engine", "Block {}: Transitioning to 2/3 quorum.", self.two_thirds_majority_transition); } if block.header.number() >= self.empty_steps_transition { @@ -1583,7 +1587,7 @@ impl Engine for AuthorityRound { step: self.step.clone(), subchain_validators: list, empty_steps_transition: self.empty_steps_transition, - quorum_2_3_transition: self.quorum_2_3_transition, + two_thirds_majority_transition: self.two_thirds_majority_transition, }); match finalize { @@ -1683,7 +1687,7 @@ mod tests { block_reward_contract_transition: 0, block_reward_contract: Default::default(), strict_empty_steps_transition: 0, - quorum_2_3_transition: 0, + two_thirds_majority_transition: 0, }; // mutate aura params diff --git a/json/src/spec/authority_round.rs b/json/src/spec/authority_round.rs index ad31ee727fc..7432ab88b94 100644 --- a/json/src/spec/authority_round.rs +++ b/json/src/spec/authority_round.rs @@ -59,7 +59,7 @@ pub struct AuthorityRoundParams { /// Strict validation of empty steps transition block. pub strict_empty_steps_transition: Option, /// First block for which a 2/3 quorum (instead of 1/2) is required. - pub quorum_2_3_transition: Option, + pub two_thirds_majority_transition: Option, } /// Authority engine deserialization.