accumulate seal in precommit

This commit is contained in:
keorn 2016-08-29 12:09:51 +02:00
parent a12a764d6c
commit 4025645188
3 changed files with 12 additions and 11 deletions

View File

@ -1034,7 +1034,8 @@ impl BlockChainClient for Client {
if let Ok(signature) = full_rlp.val_at::<H520>(0) {
if let Ok(message) = full_rlp.at(1) {
if let Ok(pub_key) = recover(&signature.into(), &message.as_raw().sha3()) {
if let Ok(new_message) = self.engine.handle_message(pub_key.sha3().into(), message) {
if let Ok(new_message) = self.engine.handle_message(pub_key.sha3().into(), signature, message)
{
self.notify(|notify| notify.broadcast(new_message.clone()));
}
}

View File

@ -30,7 +30,7 @@ pub use self::tendermint::Tendermint;
pub use self::signed_vote::SignedVote;
pub use self::propose_collect::ProposeCollect;
use common::{HashMap, SemanticVersion, Header, EnvInfo, Address, Builtin, BTreeMap, U256, Bytes, SignedTransaction, Error, UntrustedRlp};
use common::{HashMap, SemanticVersion, Header, EnvInfo, Address, Builtin, BTreeMap, U256, Bytes, SignedTransaction, Error, UntrustedRlp, H520};
use account_provider::AccountProvider;
use block::ExecutedBlock;
use spec::CommonParams;
@ -138,7 +138,7 @@ pub trait Engine : Sync + Send {
/// Handle any potential consensus messages;
/// updating consensus state and potentially issuing a new one.
fn handle_message(&self, _sender: Address, _message: UntrustedRlp) -> Result<Bytes, Error> { Err(EngineError::UnexpectedMessage.into()) }
fn handle_message(&self, _sender: Address, _signature: H520, _message: UntrustedRlp) -> Result<Bytes, Error> { Err(EngineError::UnexpectedMessage.into()) }
// TODO: builtin contract routing - to do this properly, it will require removing the built-in configuration-reading logic
// from Spec into here and removing the Spec::builtins field.

View File

@ -50,7 +50,7 @@ pub struct TendermintParams {
enum Step {
Propose,
Prevote(ProposeCollect),
Precommit(ProposeCollect),
Precommit(ProposeCollect, Vec<Bytes>),
Commit
}
@ -131,7 +131,7 @@ impl Tendermint {
// Move to next step is prevote is won.
if vote.is_won() {
let mut guard = self.our_params.s.write();
*guard = Step::Precommit(self.new_vote(vote.hash));
*guard = Step::Precommit(self.new_vote(vote.hash), Vec::new());
Ok(message.as_raw().to_vec())
} else {
Ok(message.as_raw().to_vec())
@ -144,13 +144,13 @@ impl Tendermint {
}
}
fn precommit_message(&self, sender: Address, message: UntrustedRlp) -> Result<Bytes, Error> {
fn precommit_message(&self, sender: Address, signature: H520, message: UntrustedRlp) -> Result<Bytes, Error> {
// Check if message is for correct step.
match *self.our_params.s.try_write().unwrap() {
Step::Prevote(ref mut vote) => {
Step::Precommit(ref mut vote, ref mut seal) => {
// Vote and accumulate seal if message is about the right block.
if vote.hash == try!(message.as_val()) {
vote.vote(sender);
if vote.vote(sender) { seal.push(encode(&signature).to_vec()); }
// Commit if precommit is won.
if vote.is_won() {
let mut guard = self.our_params.s.write();
@ -222,14 +222,14 @@ impl Engine for Tendermint {
})
}
fn handle_message(&self, sender: Address, message: UntrustedRlp) -> Result<Bytes, Error> {
fn handle_message(&self, sender: Address, signature: H520, message: UntrustedRlp) -> Result<Bytes, Error> {
// Check if correct round.
if self.our_params.r != try!(message.val_at(0)) { try!(Err(EngineError::WrongRound)) }
// Handle according to step.
match try!(message.val_at(1)) {
0u8 if self.is_proposer(&sender) => self.propose_message(try!(message.at(2))),
1 if self.is_validator(&sender) => self.prevote_message(sender, try!(message.at(2))),
2 if self.is_validator(&sender) => self.precommit_message(sender, try!(message.at(2))),
2 if self.is_validator(&sender) => self.precommit_message(sender, signature, try!(message.at(2))),
_ => try!(Err(EngineError::UnknownStep)),
}
}
@ -298,7 +298,7 @@ mod tests {
let drain = s.out();
let propose_rlp = UntrustedRlp::new(&drain);
engine.handle_message(proposer, propose_rlp)
engine.handle_message(proposer, H520::default(), propose_rlp)
}
#[test]