message serialization

This commit is contained in:
keorn 2016-11-21 11:36:07 +00:00
parent 9456c160c2
commit e69be670de
2 changed files with 23 additions and 22 deletions

View File

@ -30,21 +30,6 @@ pub struct ConsensusMessage {
}
impl ConsensusMessage {
pub fn new_rlp<F>(signer: F, height: Height, round: Round, step: Step, block_hash: Option<BlockHash>) -> Option<Bytes> where F: FnOnce(H256) -> Option<H520> {
let mut s = RlpStream::new_list(4);
s.append(&height);
s.append(&round);
s.append(&step);
s.append(&block_hash.unwrap_or(H256::zero()));
let block_info = s.out();
signer(block_info.sha3()).map(|ref signature| {
let mut s = RlpStream::new_list(2);
s.append(signature);
s.append(&block_info);
s.out()
})
}
pub fn is_height(&self, height: Height) -> bool {
self.height == height
}
@ -143,3 +128,18 @@ impl Encodable for ConsensusMessage {
s.append(&self.block_hash.unwrap_or(H256::zero()));
}
}
pub fn message_info_rlp(height: Height, round: Round, step: Step, block_hash: Option<BlockHash>) -> Bytes {
let mut s = RlpStream::new_list(4);
s.append(&height).append(&round).append(&step).append(&block_hash.unwrap_or(H256::zero()));
s.out()
}
pub fn message_full_rlp<F>(signer: F, height: Height, round: Round, step: Step, block_hash: Option<BlockHash>) -> Option<Bytes> where F: FnOnce(H256) -> Option<H520> {
let vote_info = message_info_rlp(height, round, step, block_hash);
signer(vote_info.sha3()).map(|ref signature| {
let mut s = RlpStream::new_list(2);
s.append(signature).append(&vote_info);
s.out()
})
}

View File

@ -40,7 +40,7 @@ use views::HeaderView;
use evm::Schedule;
use io::{IoService, IoChannel};
use service::ClientIoMessage;
use self::message::ConsensusMessage;
use self::message::{ConsensusMessage, message_info_rlp, message_full_rlp};
use self::transition::TransitionHandler;
use self::params::TendermintParams;
use self::vote_collector::VoteCollector;
@ -148,7 +148,7 @@ impl Tendermint {
fn generate_message(&self, block_hash: Option<BlockHash>) -> Option<Bytes> {
if let Some(ref ap) = *self.account_provider.lock() {
ConsensusMessage::new_rlp(
message_full_rlp(
|mh| ap.sign(*self.authority.read(), None, mh).ok().map(H520::from),
self.height.load(AtomicOrdering::SeqCst),
self.round.load(AtomicOrdering::SeqCst),
@ -335,7 +335,8 @@ impl Engine for Tendermint {
if let Some(ref ap) = *self.account_provider.lock() {
let header = block.header();
let author = header.author();
if let Ok(signature) = ap.sign(*author, None, block_hash(header)) {
let vote_info = message_info_rlp(header.number() as Height, self.round.load(AtomicOrdering::SeqCst), Step::Propose, Some(block_hash(header)));
if let Ok(signature) = ap.sign(*author, None, vote_info.sha3()) {
*self.proposal.write() = Some(header.bare_hash());
Some(vec![
::rlp::encode(&self.round.load(AtomicOrdering::SeqCst)).to_vec(),
@ -418,10 +419,6 @@ impl Engine for Tendermint {
/// Also transitions to Prevote if verifying Proposal.
fn verify_block_unordered(&self, header: &Header, _block: Option<&[u8]>) -> Result<(), Error> {
let signature = try!(proposer_signature(header));
let proposer = public_to_address(&try!(recover(&signature.into(), &block_hash(header))));
if !self.is_proposer(&proposer) {
try!(Err(BlockError::InvalidSeal))
}
let proposal = ConsensusMessage {
signature: signature,
height: header.number() as Height,
@ -429,6 +426,10 @@ impl Engine for Tendermint {
step: Step::Propose,
block_hash: Some(block_hash(header))
};
let proposer = public_to_address(&try!(recover(&signature.into(), &::rlp::encode(&proposal))));
if !self.is_proposer(&proposer) {
try!(Err(BlockError::InvalidSeal))
}
self.votes.vote(proposal, proposer);
let votes_rlp = UntrustedRlp::new(&header.seal()[2]);
for rlp in votes_rlp.iter() {