docs, tweaks
This commit is contained in:
parent
3ebfa1481d
commit
dca752e9bb
@ -14,7 +14,12 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Tendermint BFT consensus engine with round robin proof-of-authority.
|
||||
/// Tendermint BFT consensus engine with round robin proof-of-authority.
|
||||
/// At each blockchain `Height` there can be multiple `Round`s of voting.
|
||||
/// Block is issued when there is enough `Precommit` votes collected on a particular block at the end of a `Round`.
|
||||
/// Signatures always sign `Height`, `Round`, `Step` and `BlockHash` which is a block hash without seal.
|
||||
/// First a block with `Seal::Proposal` is issued by the designated proposer.
|
||||
/// Once enough votes have been gathered the proposer issues that block in the `Commit` step.
|
||||
|
||||
mod message;
|
||||
mod transition;
|
||||
@ -191,10 +196,11 @@ impl Tendermint {
|
||||
}
|
||||
}
|
||||
|
||||
fn to_height(&self, height: Height) {
|
||||
debug!(target: "poa", "Transitioning to height {}.", height);
|
||||
fn to_next_height(&self, height: Height) {
|
||||
let new_height = height + 1;
|
||||
debug!(target: "poa", "Received a Commit, transitioning to height {}.", new_height);
|
||||
self.last_lock.store(0, AtomicOrdering::SeqCst);
|
||||
self.height.store(height, AtomicOrdering::SeqCst);
|
||||
self.height.store(new_height, AtomicOrdering::SeqCst);
|
||||
self.round.store(0, AtomicOrdering::SeqCst);
|
||||
*self.lock_change.write() = None;
|
||||
}
|
||||
@ -232,20 +238,21 @@ impl Tendermint {
|
||||
let height = self.height.load(AtomicOrdering::SeqCst);
|
||||
if let Some(block_hash) = *self.proposal.read() {
|
||||
// Generate seal and remove old votes.
|
||||
if self.is_proposer(&*self.authority.read()).is_ok() {
|
||||
if let Some(seal) = self.votes.seal_signatures(height, round, block_hash) {
|
||||
trace!(target: "poa", "to_step: Collected seal: {:?}", seal);
|
||||
if self.is_proposer(&*self.authority.read()).is_ok() {
|
||||
let seal = vec![
|
||||
::rlp::encode(&round).to_vec(),
|
||||
::rlp::encode(&seal.proposal).to_vec(),
|
||||
::rlp::encode(&seal.votes).to_vec()
|
||||
];
|
||||
self.submit_seal(block_hash, seal);
|
||||
}
|
||||
self.to_next_height(height);
|
||||
} else {
|
||||
warn!(target: "poa", "Proposal was not found!");
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -289,10 +296,6 @@ impl Tendermint {
|
||||
self.round.fetch_add(n, AtomicOrdering::SeqCst);
|
||||
}
|
||||
|
||||
fn new_height(&self) {
|
||||
self.to_height(self.height.load(AtomicOrdering::SeqCst) + 1);
|
||||
}
|
||||
|
||||
fn should_unlock(&self, lock_change_round: Round) -> bool {
|
||||
self.last_lock.load(AtomicOrdering::SeqCst) < lock_change_round
|
||||
&& lock_change_round < self.round.load(AtomicOrdering::SeqCst)
|
||||
@ -414,7 +417,7 @@ impl Engine for Tendermint {
|
||||
let header = block.header();
|
||||
let author = header.author();
|
||||
// Only proposer can generate seal if None was generated.
|
||||
if self.is_proposer(author).is_err() && self.proposal.read().is_none() {
|
||||
if self.is_proposer(author).is_err() || self.proposal.read().is_some() {
|
||||
return Seal::None;
|
||||
}
|
||||
|
||||
@ -428,6 +431,7 @@ impl Engine for Tendermint {
|
||||
self.votes.vote(ConsensusMessage::new(signature, height, round, Step::Propose, bh), *author);
|
||||
// Remember proposal for later seal submission.
|
||||
*self.proposal.write() = bh;
|
||||
assert!(self.is_round_proposer(height, round, author).is_ok());
|
||||
Seal::Proposal(vec![
|
||||
::rlp::encode(&round).to_vec(),
|
||||
::rlp::encode(&signature).to_vec(),
|
||||
@ -509,13 +513,8 @@ impl Engine for Tendermint {
|
||||
}
|
||||
}
|
||||
|
||||
if self.is_above_threshold(signature_count) {
|
||||
// Skip ahead if block is from the future.
|
||||
if proposal.height > self.height.load(AtomicOrdering::SeqCst) {
|
||||
self.to_height(proposal.height);
|
||||
}
|
||||
// Check if its a proposal if there is not enough precommits.
|
||||
} else {
|
||||
if !self.is_above_threshold(signature_count) {
|
||||
let signatures_len = signatures_field.len();
|
||||
// Proposal has to have an empty signature list.
|
||||
if signatures_len != 1 {
|
||||
@ -563,9 +562,9 @@ impl Engine for Tendermint {
|
||||
}
|
||||
|
||||
fn is_new_best_block(&self, _best_total_difficulty: U256, best_header: HeaderView, _parent_details: &BlockDetails, new_header: &HeaderView) -> bool {
|
||||
trace!(target: "poa", "new_header: {}, best_header: {}", new_header.number(), best_header.number());
|
||||
let new_number = new_header.number();
|
||||
let best_number = best_header.number();
|
||||
trace!(target: "poa", "new_header: {}, best_header: {}", new_number, best_number);
|
||||
if new_number != best_number {
|
||||
new_number > best_number
|
||||
} else {
|
||||
@ -586,10 +585,12 @@ impl Engine for Tendermint {
|
||||
fn is_proposal(&self, header: &Header) -> bool {
|
||||
let signatures_len = header.seal()[2].len();
|
||||
// Signatures have to be an empty list rlp.
|
||||
let proposal = ConsensusMessage::new_proposal(header).expect("block went through full verification; this Engine verifies new_proposal creation; qed");
|
||||
if signatures_len != 1 {
|
||||
// New Commit received, skip to next height.
|
||||
self.to_next_height(proposal.height);
|
||||
return false;
|
||||
}
|
||||
let proposal = ConsensusMessage::new_proposal(header).expect("block went through full verification; this Engine verifies new_proposal creation; qed");
|
||||
let proposer = proposal.verify().expect("block went through full verification; this Engine tries verify; qed");
|
||||
debug!(target: "poa", "Received a new proposal for height {}, round {} from {}.", proposal.height, proposal.round, proposer);
|
||||
if self.is_round(&proposal) {
|
||||
|
@ -106,7 +106,6 @@ impl IoHandler<Step> for TransitionHandler {
|
||||
Step::Commit => {
|
||||
trace!(target: "poa", "timeout: Commit timeout.");
|
||||
set_timeout(io, engine.our_params.timeouts.propose);
|
||||
engine.new_height();
|
||||
Some(Step::Propose)
|
||||
},
|
||||
};
|
||||
|
@ -469,9 +469,11 @@ impl Miner {
|
||||
// Save proposal for later seal submission and broadcast it.
|
||||
Seal::Proposal(seal) => {
|
||||
trace!(target: "miner", "Received a Proposal seal.");
|
||||
{
|
||||
let mut sealing_work = self.sealing_work.lock();
|
||||
sealing_work.queue.push(block.clone());
|
||||
sealing_work.queue.use_last_ref();
|
||||
}
|
||||
block
|
||||
.lock()
|
||||
.seal(&*self.engine, seal)
|
||||
|
Loading…
Reference in New Issue
Block a user