message tests and fixes

This commit is contained in:
keorn 2016-11-24 13:57:04 +00:00
parent a3730b3042
commit 38f25fc195

View File

@ -18,7 +18,7 @@
use util::*; use util::*;
use super::{Height, Round, BlockHash, Step}; use super::{Height, Round, BlockHash, Step};
use error::Error; use error::{Error, BlockError};
use header::Header; use header::Header;
use rlp::*; use rlp::*;
use ethkey::{recover, public_to_address}; use ethkey::{recover, public_to_address};
@ -34,7 +34,8 @@ pub struct ConsensusMessage {
fn consensus_round(header: &Header) -> Result<Round, ::rlp::DecoderError> { fn consensus_round(header: &Header) -> Result<Round, ::rlp::DecoderError> {
UntrustedRlp::new(header.seal()[0].as_slice()).as_val() let round_rlp = header.seal().get(0).expect("seal passed basic verification; seal has 3 fields; qed");
UntrustedRlp::new(round_rlp.as_slice()).as_val()
} }
impl ConsensusMessage { impl ConsensusMessage {
@ -80,7 +81,7 @@ impl PartialOrd for ConsensusMessage {
} }
impl Step { impl Step {
fn number(&self) -> i8 { fn number(&self) -> u8 {
match *self { match *self {
Step::Propose => 0, Step::Propose => 0,
Step::Prevote => 1, Step::Prevote => 1,
@ -107,17 +108,17 @@ impl Ord for ConsensusMessage {
impl Decodable for Step { impl Decodable for Step {
fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder {
match try!(decoder.as_rlp().as_val()) { match try!(decoder.as_rlp().as_val()) {
0u8 => Ok(Step::Prevote), 0u8 => Ok(Step::Propose),
1 => Ok(Step::Precommit), 1 => Ok(Step::Prevote),
2 => Ok(Step::Precommit),
_ => Err(DecoderError::Custom("Invalid step.")), _ => Err(DecoderError::Custom("Invalid step.")),
} }
} }
} }
impl Encodable for Step { impl Encodable for Step {
fn rlp_append(&self, s: &mut RlpStream) { fn rlp_append(&self, s: &mut RlpStream) {
s.append(&(self.number() as u8)); s.append(&self.number());
} }
} }
@ -125,9 +126,6 @@ impl Encodable for Step {
impl Decodable for ConsensusMessage { impl Decodable for ConsensusMessage {
fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder { fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder {
let rlp = decoder.as_rlp(); let rlp = decoder.as_rlp();
if decoder.as_raw().len() != try!(rlp.payload_info()).total() {
return Err(DecoderError::RlpIsTooBig);
}
let m = try!(rlp.at(1)); let m = try!(rlp.at(1));
let block_message: H256 = try!(m.val_at(3)); let block_message: H256 = try!(m.val_at(3));
Ok(ConsensusMessage { Ok(ConsensusMessage {
@ -142,22 +140,24 @@ impl Decodable for ConsensusMessage {
}) })
} }
} }
impl Encodable for ConsensusMessage { impl Encodable for ConsensusMessage {
fn rlp_append(&self, s: &mut RlpStream) { fn rlp_append(&self, s: &mut RlpStream) {
s.begin_list(2); s.begin_list(2)
s.append(&self.signature); .append(&self.signature)
s.begin_list(4); // TODO: figure out whats wrong with nested list encoding
s.append(&self.height); .begin_list(5)
s.append(&self.round); .append(&self.height)
s.append(&self.step); .append(&self.round)
s.append(&self.block_hash.unwrap_or(H256::zero())); .append(&self.step)
.append(&self.block_hash.unwrap_or(H256::zero()));
} }
} }
pub fn message_info_rlp(height: Height, round: Round, step: Step, block_hash: Option<BlockHash>) -> Bytes { pub fn message_info_rlp(height: Height, round: Round, step: Step, block_hash: Option<BlockHash>) -> Bytes {
let mut s = RlpStream::new_list(4); // TODO: figure out whats wrong with nested list encoding
let mut s = RlpStream::new_list(5);
s.append(&height).append(&round).append(&step).append(&block_hash.unwrap_or(H256::zero())); s.append(&height).append(&round).append(&step).append(&block_hash.unwrap_or(H256::zero()));
println!("{:?}, {:?}, {:?}, {:?}", &height, &round, &step, &block_hash);
s.out() s.out()
} }
@ -170,7 +170,95 @@ pub fn message_full_rlp<F>(signer: F, height: Height, round: Round, step: Step,
let vote_info = message_info_rlp(height, round, step, block_hash); let vote_info = message_info_rlp(height, round, step, block_hash);
signer(vote_info.sha3()).map(|ref signature| { signer(vote_info.sha3()).map(|ref signature| {
let mut s = RlpStream::new_list(2); let mut s = RlpStream::new_list(2);
s.append(signature).append(&vote_info); s.append(signature).append_raw(&vote_info, 1);
s.out() s.out()
}) })
} }
#[cfg(test)]
mod tests {
use util::*;
use rlp::*;
use super::super::Step;
use super::*;
use account_provider::AccountProvider;
use header::Header;
#[test]
fn encode_decode() {
let message = ConsensusMessage {
signature: H520::default(),
height: 10,
round: 123,
step: Step::Precommit,
block_hash: Some("1".sha3())
};
let raw_rlp = ::rlp::encode(&message).to_vec();
let rlp = Rlp::new(&raw_rlp);
assert_eq!(message, rlp.as_val());
let message = ConsensusMessage {
signature: H520::default(),
height: 1314,
round: 0,
step: Step::Prevote,
block_hash: None
};
let raw_rlp = ::rlp::encode(&message);
let rlp = Rlp::new(&raw_rlp);
assert_eq!(message, rlp.as_val());
}
#[test]
fn generate_and_verify() {
let tap = Arc::new(AccountProvider::transient_provider());
let addr = tap.insert_account("0".sha3(), "0").unwrap();
tap.unlock_account_permanently(addr, "0".into()).unwrap();
let raw_rlp = message_full_rlp(
|mh| tap.sign(addr, None, mh).ok().map(H520::from),
123,
2,
Step::Precommit,
Some(H256::default())
).unwrap();
let rlp = UntrustedRlp::new(&raw_rlp);
let message: ConsensusMessage = rlp.as_val().unwrap();
match message.verify() { Ok(a) if a == addr => {}, _ => panic!(), };
}
#[test]
fn proposal_message() {
let mut header = Header::default();
let seal = vec![
::rlp::encode(&0u8).to_vec(),
::rlp::encode(&H520::default()).to_vec(),
Vec::new()
];
header.set_seal(seal);
let message = ConsensusMessage::new_proposal(&header).unwrap();
assert_eq!(
message,
ConsensusMessage {
signature: Default::default(),
height: 0,
round: 0,
step: Step::Propose,
block_hash: Some(header.bare_hash())
}
);
}
#[test]
fn message_info_from_header() {
let mut header = Header::default();
let seal = vec![
::rlp::encode(&0u8).to_vec(),
::rlp::encode(&H520::default()).to_vec(),
Vec::new()
];
header.set_seal(seal);
assert_eq!(message_info_rlp_from_header(&header).unwrap().to_vec(), vec![228, 128, 128, 2, 160, 39, 191, 179, 126, 80, 124, 233, 13, 161, 65, 48, 114, 4, 177, 198, 186, 36, 25, 67, 128, 97, 53, 144, 172, 80, 202, 75, 29, 113, 152, 255, 101]);
}
}