accumulate seal in precommit
This commit is contained in:
parent
a12a764d6c
commit
4025645188
@ -1034,7 +1034,8 @@ impl BlockChainClient for Client {
|
|||||||
if let Ok(signature) = full_rlp.val_at::<H520>(0) {
|
if let Ok(signature) = full_rlp.val_at::<H520>(0) {
|
||||||
if let Ok(message) = full_rlp.at(1) {
|
if let Ok(message) = full_rlp.at(1) {
|
||||||
if let Ok(pub_key) = recover(&signature.into(), &message.as_raw().sha3()) {
|
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()));
|
self.notify(|notify| notify.broadcast(new_message.clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ pub use self::tendermint::Tendermint;
|
|||||||
pub use self::signed_vote::SignedVote;
|
pub use self::signed_vote::SignedVote;
|
||||||
pub use self::propose_collect::ProposeCollect;
|
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 account_provider::AccountProvider;
|
||||||
use block::ExecutedBlock;
|
use block::ExecutedBlock;
|
||||||
use spec::CommonParams;
|
use spec::CommonParams;
|
||||||
@ -138,7 +138,7 @@ pub trait Engine : Sync + Send {
|
|||||||
|
|
||||||
/// Handle any potential consensus messages;
|
/// Handle any potential consensus messages;
|
||||||
/// updating consensus state and potentially issuing a new one.
|
/// 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
|
// 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.
|
// from Spec into here and removing the Spec::builtins field.
|
||||||
|
@ -50,7 +50,7 @@ pub struct TendermintParams {
|
|||||||
enum Step {
|
enum Step {
|
||||||
Propose,
|
Propose,
|
||||||
Prevote(ProposeCollect),
|
Prevote(ProposeCollect),
|
||||||
Precommit(ProposeCollect),
|
Precommit(ProposeCollect, Vec<Bytes>),
|
||||||
Commit
|
Commit
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,7 +131,7 @@ impl Tendermint {
|
|||||||
// Move to next step is prevote is won.
|
// Move to next step is prevote is won.
|
||||||
if vote.is_won() {
|
if vote.is_won() {
|
||||||
let mut guard = self.our_params.s.write();
|
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())
|
Ok(message.as_raw().to_vec())
|
||||||
} else {
|
} else {
|
||||||
Ok(message.as_raw().to_vec())
|
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.
|
// Check if message is for correct step.
|
||||||
match *self.our_params.s.try_write().unwrap() {
|
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.
|
// Vote and accumulate seal if message is about the right block.
|
||||||
if vote.hash == try!(message.as_val()) {
|
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.
|
// Commit if precommit is won.
|
||||||
if vote.is_won() {
|
if vote.is_won() {
|
||||||
let mut guard = self.our_params.s.write();
|
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.
|
// Check if correct round.
|
||||||
if self.our_params.r != try!(message.val_at(0)) { try!(Err(EngineError::WrongRound)) }
|
if self.our_params.r != try!(message.val_at(0)) { try!(Err(EngineError::WrongRound)) }
|
||||||
// Handle according to step.
|
// Handle according to step.
|
||||||
match try!(message.val_at(1)) {
|
match try!(message.val_at(1)) {
|
||||||
0u8 if self.is_proposer(&sender) => self.propose_message(try!(message.at(2))),
|
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))),
|
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)),
|
_ => try!(Err(EngineError::UnknownStep)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -298,7 +298,7 @@ mod tests {
|
|||||||
let drain = s.out();
|
let drain = s.out();
|
||||||
let propose_rlp = UntrustedRlp::new(&drain);
|
let propose_rlp = UntrustedRlp::new(&drain);
|
||||||
|
|
||||||
engine.handle_message(proposer, propose_rlp)
|
engine.handle_message(proposer, H520::default(), propose_rlp)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
Loading…
Reference in New Issue
Block a user