From fcae03e55fe0f302b58e949f3839159e6b556f16 Mon Sep 17 00:00:00 2001 From: keorn Date: Thu, 25 Aug 2016 19:22:10 +0200 Subject: [PATCH] propose message test --- ethcore/res/tendermint.json | 42 +++++++++++++++++++++++++++++++ ethcore/src/client/client.rs | 1 + ethcore/src/client/test_client.rs | 2 +- ethcore/src/engines/mod.rs | 2 +- ethcore/src/engines/tendermint.rs | 38 ++++++++++++++++++++-------- 5 files changed, 73 insertions(+), 12 deletions(-) create mode 100644 ethcore/res/tendermint.json diff --git a/ethcore/res/tendermint.json b/ethcore/res/tendermint.json new file mode 100644 index 000000000..126761233 --- /dev/null +++ b/ethcore/res/tendermint.json @@ -0,0 +1,42 @@ +{ + "name": "TestBFT", + "engine": { + "Tendermint": { + "params": { + "gasLimitBoundDivisor": "0x0400", + "durationLimit": "0x0d", + "validators" : [ + "0x7d577a597b2742b498cb5cf0c26cdcd726d39e6e", + "0x82a978b3f5962a5b0957d9ee9eef472ee55b42f1" + ] + } + } + }, + "params": { + "accountStartNonce": "0x0100000", + "maximumExtraDataSize": "0x20", + "minGasLimit": "0x1388", + "networkID" : "0x69" + }, + "genesis": { + "seal": { + "generic": { + "fields": 1, + "rlp": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa" + } + }, + "difficulty": "0x20000", + "author": "0x0000000000000000000000000000000000000000", + "timestamp": "0x00", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "extraData": "0x", + "gasLimit": "0x2fefd8" + }, + "accounts": { + "0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, + "0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, + "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, + "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, + "9cce34f7ab185c7aba1b7c8140d620b4bda941d6": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" } + } +} diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 87367bf98..721a31548 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -1022,6 +1022,7 @@ impl BlockChainClient for Client { self.miner.pending_transactions() } + // TODO: Make it an actual queue, return errors. fn queue_infinity_message(&self, message: Bytes) { let full_rlp = UntrustedRlp::new(&message); if let Ok(signature) = full_rlp.val_at(0) { diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index a7d710da3..8852448cc 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -38,7 +38,7 @@ use spec::Spec; use block_queue::BlockQueueInfo; use block::{OpenBlock, SealedBlock}; use executive::Executed; -use error::{Error, CallError}; +use error::CallError; use trace::LocalizedTrace; /// Test client. diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index 07d17399a..d27bd97a1 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -134,7 +134,7 @@ pub trait Engine : Sync + Send { /// Handle any potential consensus messages; /// updating consensus state and potentially issuing a new one. - fn handle_message(&self, sender: Address, message: UntrustedRlp) -> Result { Err(EngineError::UnexpectedMessage.into()) } + fn handle_message(&self, _sender: Address, _message: UntrustedRlp) -> Result { Err(EngineError::UnexpectedMessage.into()) } // 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. diff --git a/ethcore/src/engines/tendermint.rs b/ethcore/src/engines/tendermint.rs index bc865ce2d..e5c46c65a 100644 --- a/ethcore/src/engines/tendermint.rs +++ b/ethcore/src/engines/tendermint.rs @@ -16,6 +16,7 @@ //! Tendermint BFT consensus engine with round robin proof-of-authority. +use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering}; use common::*; use account_provider::AccountProvider; use block::*; @@ -40,7 +41,7 @@ pub struct TendermintParams { /// Consensus step. s: RwLock, /// Used to swith proposer. - proposer_nonce: usize + proposer_nonce: AtomicUsize } #[derive(Debug)] @@ -62,7 +63,7 @@ impl From for TendermintParams { validator_n: val_n, r: 0, s: RwLock::new(Step::Propose), - proposer_nonce: 0 + proposer_nonce: AtomicUsize::new(0) } } } @@ -86,7 +87,7 @@ impl Tendermint { fn proposer(&self) -> Address { let ref p = self.our_params; - p.validators.get(p.proposer_nonce%p.validator_n).unwrap().clone() + p.validators.get(p.proposer_nonce.load(AtomicOrdering::Relaxed)%p.validator_n).unwrap().clone() } fn propose_message(&self, message: UntrustedRlp) -> Result { @@ -94,7 +95,8 @@ impl Tendermint { Step::Propose => (), _ => try!(Err(EngineError::WrongStep)), } - let proposal = try!(message.val_at(0)); + let proposal = try!(message.as_val()); + self.our_params.proposer_nonce.fetch_add(1, AtomicOrdering::Relaxed); let vote = ProposeCollect::new(proposal, self.our_params.validators.iter().cloned().collect(), self.threshold()); @@ -164,8 +166,8 @@ impl Engine for Tendermint { fn handle_message(&self, sender: Address, message: UntrustedRlp) -> Result { match try!(message.val_at(0)) { - 0u8 if sender == self.proposer() => self.propose_message(message), - 1 => self.prevote_message(sender, message), + 0u8 if sender == self.proposer() => self.propose_message(try!(message.at(1))), + 1 => self.prevote_message(sender, try!(message.at(1))), _ => try!(Err(EngineError::UnknownStep)), } } @@ -222,8 +224,10 @@ mod tests { use tests::helpers::*; use account_provider::AccountProvider; use spec::Spec; + use super::Step; /// Create a new test chain spec with `Tendermint` consensus engine. + /// Account "0".sha3() and "1".sha3() are a validators. fn new_test_tendermint() -> Spec { Spec::load(include_bytes!("../../res/tendermint.json")) } #[test] @@ -299,12 +303,26 @@ mod tests { } #[test] - fn propose_step(){ + fn propose_step() { let engine = new_test_tendermint().engine; let tap = AccountProvider::transient_provider(); - let addr = tap.insert_account("1".sha3(), "1").unwrap(); - println!("{:?}", addr); - false; + let mut s = RlpStream::new_list(2); + let header = Header::default(); + s.append(&0u8).append(&header.bare_hash()); + let drain = s.out(); + let propose_rlp = UntrustedRlp::new(&drain); + + let not_validator_addr = tap.insert_account("101".sha3(), "101").unwrap(); + assert!(engine.handle_message(not_validator_addr, propose_rlp.clone()).is_err()); + + let not_proposer_addr = tap.insert_account("0".sha3(), "0").unwrap(); + assert!(engine.handle_message(not_proposer_addr, propose_rlp.clone()).is_err()); + + let proposer_addr = tap.insert_account("1".sha3(), "1").unwrap(); + assert_eq!(vec![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], + engine.handle_message(proposer_addr, propose_rlp.clone()).unwrap()); + + assert!(engine.handle_message(not_proposer_addr, propose_rlp).is_err()); } #[test]