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 engines::{Engine, EngineError};
|
||||||
use header::Header;
|
use header::Header;
|
||||||
use error::{Error, BlockError};
|
use error::{Error, BlockError};
|
||||||
|
use blockchain::extras::BlockDetails;
|
||||||
|
use views::HeaderView;
|
||||||
use evm::Schedule;
|
use evm::Schedule;
|
||||||
use ethjson;
|
use ethjson;
|
||||||
use io::{IoContext, IoHandler, TimerToken, IoService, IoChannel};
|
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) {
|
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({
|
header.set_gas_limit({
|
||||||
let gas_limit = parent.gas_limit().clone();
|
let gas_limit = parent.gas_limit().clone();
|
||||||
let bound_divisor = self.our_params.gas_limit_bound_divisor;
|
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
|
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>) {
|
fn register_message_channel(&self, message_channel: IoChannel<ClientIoMessage>) {
|
||||||
*self.message_channel.lock() = Some(message_channel);
|
*self.message_channel.lock() = Some(message_channel);
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,16 @@ fn consensus_round(header: &Header) -> Result<Round, ::rlp::DecoderError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ConsensusMessage {
|
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> {
|
pub fn new_proposal(header: &Header) -> Result<Self, ::rlp::DecoderError> {
|
||||||
Ok(ConsensusMessage {
|
Ok(ConsensusMessage {
|
||||||
signature: try!(UntrustedRlp::new(header.seal()[1].as_slice()).as_val()),
|
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 {
|
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
|
// TODO: figure out whats wrong with nested list encoding
|
||||||
let mut s = RlpStream::new_list(5);
|
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()
|
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())))
|
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> {
|
pub fn message_full_rlp(signature: &H520, vote_info: &Bytes) -> Bytes {
|
||||||
let vote_info = message_info_rlp(height, round, step, block_hash);
|
let mut s = RlpStream::new_list(2);
|
||||||
signer(vote_info.sha3()).map(|ref signature| {
|
s.append(signature).append_raw(vote_info, 1);
|
||||||
let mut s = RlpStream::new_list(2);
|
s.out()
|
||||||
s.append(signature).append_raw(&vote_info, 1);
|
|
||||||
s.out()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -214,13 +221,9 @@ mod tests {
|
|||||||
let addr = tap.insert_account("0".sha3(), "0").unwrap();
|
let addr = tap.insert_account("0".sha3(), "0").unwrap();
|
||||||
tap.unlock_account_permanently(addr, "0".into()).unwrap();
|
tap.unlock_account_permanently(addr, "0".into()).unwrap();
|
||||||
|
|
||||||
let raw_rlp = message_full_rlp(
|
let mi = message_info_rlp(123, 2, Step::Precommit, Some(H256::default()));
|
||||||
|mh| tap.sign(addr, None, mh).map(H520::from),
|
|
||||||
123,
|
let raw_rlp = message_full_rlp(&tap.sign(addr, None, mi.sha3()).unwrap().into(), &mi);
|
||||||
2,
|
|
||||||
Step::Precommit,
|
|
||||||
Some(H256::default())
|
|
||||||
).unwrap();
|
|
||||||
|
|
||||||
let rlp = UntrustedRlp::new(&raw_rlp);
|
let rlp = UntrustedRlp::new(&raw_rlp);
|
||||||
let message: ConsensusMessage = rlp.as_val().unwrap();
|
let message: ConsensusMessage = rlp.as_val().unwrap();
|
||||||
|
@ -134,7 +134,6 @@ impl Tendermint {
|
|||||||
|
|
||||||
fn broadcast_message(&self, message: Bytes) {
|
fn broadcast_message(&self, message: Bytes) {
|
||||||
if let Some(ref channel) = *self.message_channel.lock() {
|
if let Some(ref channel) = *self.message_channel.lock() {
|
||||||
trace!(target: "poa", "broadcast_message: {:?}", &message);
|
|
||||||
match channel.send(ClientIoMessage::BroadcastMessage(message)) {
|
match channel.send(ClientIoMessage::BroadcastMessage(message)) {
|
||||||
Ok(_) => trace!(target: "poa", "broadcast_message: BroadcastMessage message sent."),
|
Ok(_) => trace!(target: "poa", "broadcast_message: BroadcastMessage message sent."),
|
||||||
Err(err) => warn!(target: "poa", "broadcast_message: Could not send a sealing message {}.", err),
|
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> {
|
fn generate_message(&self, block_hash: Option<BlockHash>) -> Option<Bytes> {
|
||||||
if let Some(ref ap) = *self.account_provider.lock() {
|
if let Some(ref ap) = *self.account_provider.lock() {
|
||||||
match message_full_rlp(
|
let h = self.height.load(AtomicOrdering::SeqCst);
|
||||||
|mh| ap.sign(*self.authority.read(), self.password.read().clone(), mh).map(H520::from),
|
let r = self.round.load(AtomicOrdering::SeqCst);
|
||||||
self.height.load(AtomicOrdering::SeqCst),
|
let s = self.step.read();
|
||||||
self.round.load(AtomicOrdering::SeqCst),
|
let vote_info = message_info_rlp(h, r, *s, block_hash);
|
||||||
*self.step.read(),
|
let authority = self.authority.read();
|
||||||
block_hash
|
match ap.sign(*authority, self.password.read().clone(), vote_info.sha3()).map(Into::into) {
|
||||||
) {
|
Ok(signature) => {
|
||||||
Ok(m) => Some(m),
|
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) => {
|
Err(e) => {
|
||||||
trace!(target: "poa", "generate_message: Could not sign the message {}", e);
|
trace!(target: "poa", "generate_message: Could not sign the message {}", e);
|
||||||
None
|
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) {
|
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({
|
header.set_gas_limit({
|
||||||
let gas_limit = parent.gas_limit().clone();
|
let gas_limit = parent.gas_limit().clone();
|
||||||
let bound_divisor = self.our_params.gas_limit_bound_divisor;
|
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);
|
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) {
|
if let Ok(signature) = ap.sign(*author, self.password.read().clone(), vote_info.sha3()).map(H520::from) {
|
||||||
// Insert Propose vote.
|
// 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.
|
// Remember proposal for later seal submission.
|
||||||
*self.proposal.write() = Some(header.bare_hash());
|
*self.proposal.write() = Some(header.bare_hash());
|
||||||
Some(vec![
|
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 {
|
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();
|
trace!(target: "poa", "new_header: {}, best_header: {}", new_header.number(), best_header.number());
|
||||||
let best_signatures = best_header.seal().get(2).expect("Tendermint seal should have three elements.").len();
|
if new_header.number() > best_header.number() {
|
||||||
new_signatures > best_signatures
|
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>) {
|
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> {
|
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();
|
engine.handle_message(UntrustedRlp::new(&m)).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user