vote on message generation
This commit is contained in:
parent
f1ef4a4935
commit
39ea703c69
@ -28,6 +28,8 @@ use spec::CommonParams;
|
||||
use engines::{Engine, EngineError};
|
||||
use header::Header;
|
||||
use error::{Error, BlockError};
|
||||
use blockchain::extras::BlockDetails;
|
||||
use views::HeaderView;
|
||||
use evm::Schedule;
|
||||
use ethjson;
|
||||
use io::{IoContext, IoHandler, TimerToken, IoService, IoChannel};
|
||||
@ -196,7 +198,6 @@ impl Engine for AuthorityRound {
|
||||
}
|
||||
|
||||
fn populate_from_parent(&self, header: &mut Header, parent: &Header, gas_floor_target: U256, _gas_ceil_target: U256) {
|
||||
header.set_difficulty(parent.difficulty().clone());
|
||||
header.set_gas_limit({
|
||||
let gas_limit = parent.gas_limit().clone();
|
||||
let bound_divisor = self.our_params.gas_limit_bound_divisor;
|
||||
@ -308,6 +309,10 @@ impl Engine for AuthorityRound {
|
||||
t.sender().map(|_|()) // Perform EC recovery and cache sender
|
||||
}
|
||||
|
||||
fn is_new_best_block(&self, _best_total_difficulty: U256, best_header: HeaderView, _parent_details: &BlockDetails, new_header: &HeaderView) -> bool {
|
||||
new_header.number() > best_header.number()
|
||||
}
|
||||
|
||||
fn register_message_channel(&self, message_channel: IoChannel<ClientIoMessage>) {
|
||||
*self.message_channel.lock() = Some(message_channel);
|
||||
}
|
||||
|
@ -39,6 +39,16 @@ fn consensus_round(header: &Header) -> Result<Round, ::rlp::DecoderError> {
|
||||
}
|
||||
|
||||
impl ConsensusMessage {
|
||||
pub fn new(signature: H520, height: Height, round: Round, step: Step, block_hash: Option<BlockHash>) -> Self {
|
||||
ConsensusMessage {
|
||||
signature: signature,
|
||||
height: height,
|
||||
round: round,
|
||||
step: step,
|
||||
block_hash: block_hash
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_proposal(header: &Header) -> Result<Self, ::rlp::DecoderError> {
|
||||
Ok(ConsensusMessage {
|
||||
signature: try!(UntrustedRlp::new(header.seal()[1].as_slice()).as_val()),
|
||||
@ -156,7 +166,7 @@ impl Encodable for ConsensusMessage {
|
||||
pub fn message_info_rlp(height: Height, round: Round, step: Step, block_hash: Option<BlockHash>) -> Bytes {
|
||||
// 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_else(H256::zero));
|
||||
s.out()
|
||||
}
|
||||
|
||||
@ -165,13 +175,10 @@ pub fn message_info_rlp_from_header(header: &Header) -> Result<Bytes, ::rlp::Dec
|
||||
Ok(message_info_rlp(header.number() as Height, round, Step::Precommit, Some(header.bare_hash())))
|
||||
}
|
||||
|
||||
pub fn message_full_rlp<F>(signer: F, height: Height, round: Round, step: Step, block_hash: Option<BlockHash>) -> Result<Bytes, ::account_provider::Error> where F: FnOnce(H256) -> Result<H520, ::account_provider::Error> {
|
||||
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_raw(&vote_info, 1);
|
||||
s.out()
|
||||
})
|
||||
pub fn message_full_rlp(signature: &H520, vote_info: &Bytes) -> Bytes {
|
||||
let mut s = RlpStream::new_list(2);
|
||||
s.append(signature).append_raw(vote_info, 1);
|
||||
s.out()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -214,13 +221,9 @@ mod tests {
|
||||
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).map(H520::from),
|
||||
123,
|
||||
2,
|
||||
Step::Precommit,
|
||||
Some(H256::default())
|
||||
).unwrap();
|
||||
let mi = message_info_rlp(123, 2, Step::Precommit, Some(H256::default()));
|
||||
|
||||
let raw_rlp = message_full_rlp(&tap.sign(addr, None, mi.sha3()).unwrap().into(), &mi);
|
||||
|
||||
let rlp = UntrustedRlp::new(&raw_rlp);
|
||||
let message: ConsensusMessage = rlp.as_val().unwrap();
|
||||
|
@ -134,7 +134,6 @@ impl Tendermint {
|
||||
|
||||
fn broadcast_message(&self, message: Bytes) {
|
||||
if let Some(ref channel) = *self.message_channel.lock() {
|
||||
trace!(target: "poa", "broadcast_message: {:?}", &message);
|
||||
match channel.send(ClientIoMessage::BroadcastMessage(message)) {
|
||||
Ok(_) => trace!(target: "poa", "broadcast_message: BroadcastMessage message sent."),
|
||||
Err(err) => warn!(target: "poa", "broadcast_message: Could not send a sealing message {}.", err),
|
||||
@ -146,14 +145,17 @@ impl Tendermint {
|
||||
|
||||
fn generate_message(&self, block_hash: Option<BlockHash>) -> Option<Bytes> {
|
||||
if let Some(ref ap) = *self.account_provider.lock() {
|
||||
match message_full_rlp(
|
||||
|mh| ap.sign(*self.authority.read(), self.password.read().clone(), mh).map(H520::from),
|
||||
self.height.load(AtomicOrdering::SeqCst),
|
||||
self.round.load(AtomicOrdering::SeqCst),
|
||||
*self.step.read(),
|
||||
block_hash
|
||||
) {
|
||||
Ok(m) => Some(m),
|
||||
let h = self.height.load(AtomicOrdering::SeqCst);
|
||||
let r = self.round.load(AtomicOrdering::SeqCst);
|
||||
let s = self.step.read();
|
||||
let vote_info = message_info_rlp(h, r, *s, block_hash);
|
||||
let authority = self.authority.read();
|
||||
match ap.sign(*authority, self.password.read().clone(), vote_info.sha3()).map(Into::into) {
|
||||
Ok(signature) => {
|
||||
let message_rlp = message_full_rlp(&signature, &vote_info);
|
||||
self.votes.vote(ConsensusMessage::new(signature, h, r, *s, block_hash), *authority);
|
||||
Some(message_rlp)
|
||||
},
|
||||
Err(e) => {
|
||||
trace!(target: "poa", "generate_message: Could not sign the message {}", e);
|
||||
None
|
||||
@ -309,7 +311,6 @@ impl Engine for Tendermint {
|
||||
}
|
||||
|
||||
fn populate_from_parent(&self, header: &mut Header, parent: &Header, gas_floor_target: U256, _gas_ceil_target: U256) {
|
||||
header.set_difficulty(parent.difficulty().clone());
|
||||
header.set_gas_limit({
|
||||
let gas_limit = parent.gas_limit().clone();
|
||||
let bound_divisor = self.our_params.gas_limit_bound_divisor;
|
||||
@ -344,7 +345,7 @@ impl Engine for Tendermint {
|
||||
let vote_info = message_info_rlp(height, round, Step::Propose, bh);
|
||||
if let Ok(signature) = ap.sign(*author, self.password.read().clone(), vote_info.sha3()).map(H520::from) {
|
||||
// Insert Propose vote.
|
||||
self.votes.vote(ConsensusMessage { signature: signature, height: height, round: round, step: Step::Propose, block_hash: bh }, *author);
|
||||
self.votes.vote(ConsensusMessage::new(signature, height, round, Step::Propose, bh), *author);
|
||||
// Remember proposal for later seal submission.
|
||||
*self.proposal.write() = Some(header.bare_hash());
|
||||
Some(vec![
|
||||
@ -489,9 +490,14 @@ impl Engine for Tendermint {
|
||||
}
|
||||
|
||||
fn is_new_best_block(&self, _best_total_difficulty: U256, best_header: HeaderView, _parent_details: &BlockDetails, new_header: &HeaderView) -> bool {
|
||||
let new_signatures = new_header.seal().get(2).expect("Tendermint seal should have three elements.").len();
|
||||
let best_signatures = best_header.seal().get(2).expect("Tendermint seal should have three elements.").len();
|
||||
new_signatures > best_signatures
|
||||
trace!(target: "poa", "new_header: {}, best_header: {}", new_header.number(), best_header.number());
|
||||
if new_header.number() > best_header.number() {
|
||||
true
|
||||
} else {
|
||||
let new_signatures = new_header.seal().get(2).expect("Tendermint seal should have three elements.").len();
|
||||
let best_signatures = best_header.seal().get(2).expect("Tendermint seal should have three elements.").len();
|
||||
new_signatures > best_signatures
|
||||
}
|
||||
}
|
||||
|
||||
fn register_message_channel(&self, message_channel: IoChannel<ClientIoMessage>) {
|
||||
@ -544,7 +550,8 @@ mod tests {
|
||||
}
|
||||
|
||||
fn vote<F>(engine: &Arc<Engine>, signer: F, height: usize, round: usize, step: Step, block_hash: Option<H256>) where F: FnOnce(H256) -> Result<H520, ::account_provider::Error> {
|
||||
let m = message_full_rlp(signer, height, round, step, block_hash).unwrap();
|
||||
let mi = message_info_rlp(height, round, step, block_hash);
|
||||
let m = message_full_rlp(&signer(mi.sha3()).unwrap().into(), &mi);
|
||||
engine.handle_message(UntrustedRlp::new(&m)).unwrap();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user