Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Tendermint Engine #3759

Merged
merged 201 commits into from
Dec 15, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
201 commits
Select commit Hold shift + click to select a range
8da38fa
intro simple seal bft engine
Aug 19, 2016
74939a4
fix types and lifetimes
Aug 21, 2016
a20a0de
add spec
Aug 21, 2016
2f5aeda
reusable voting on hashes
Aug 22, 2016
89011dc
fix locking patterns, add simple test
Aug 22, 2016
3515a72
proposal vote collector
Aug 22, 2016
3aa862c
add test, start tendermint
Aug 23, 2016
535c502
delete old test
Aug 23, 2016
207f9d0
Started inf networking
arkpar Aug 15, 2016
99a143e
change broadcast interface, add basic message handling
Aug 23, 2016
1cb3c16
propose step
Aug 24, 2016
77f06be
fix error propagation
Aug 24, 2016
fcae03e
propose message test
Aug 25, 2016
8bd0034
Merge remote-tracking branch 'parity/master' into bft
Aug 25, 2016
2cc2bd6
impl Hash for Signature
Aug 26, 2016
e7a9bf4
impl Clone for Signature
Aug 26, 2016
a4ba726
update Signature and ipc usage
Aug 26, 2016
f60d464
move vote with addresses, remove recover check
Aug 26, 2016
a12a764
add rounds check, simplify tests
Aug 26, 2016
4025645
accumulate seal in precommit
Aug 29, 2016
d749904
move seal into commit
Aug 29, 2016
e475d0b
initial timeouts
Aug 31, 2016
2f3d162
Merge remote-tracking branch 'parity/master' into bft
Aug 31, 2016
0fcbf8d
fix after merge
Aug 31, 2016
83c371e
add non renewing timer
Sep 1, 2016
8851ace
fix propose collect locking
Sep 5, 2016
0af4bf2
add internal timeout service, test proposer switching
Sep 5, 2016
91fbaf9
Merge remote-tracking branch 'parity/master' into bft
Sep 5, 2016
45e6b4a
seal generation and verificatio
Sep 6, 2016
ba21baf
tests and fixes
Sep 7, 2016
4ccbec1
Merge remote-tracking branch 'parity/master' into bft
Sep 7, 2016
9fe62d9
adjust default timeouts
Sep 8, 2016
fd6900b
Merge remote-tracking branch 'parity/master' into bft
Sep 27, 2016
6cbb859
add tendermint message types and deserialization
Sep 29, 2016
d085146
separate params out
Sep 29, 2016
d59e9e8
fix tests compilation
Sep 29, 2016
8a51ae0
simplify seal
Sep 30, 2016
9ca938f
Merge remote-tracking branch 'parity/master' into bft
Sep 30, 2016
76d7ec8
new block ordering engine method
Sep 30, 2016
67c24dc
use Engine to order blockchain
Oct 5, 2016
a03db2f
add is_new_best method to engines
Oct 5, 2016
64d7bcb
validators -> authorities
Oct 5, 2016
cb2c993
keep author as validator
Oct 5, 2016
096b71f
add Vote generation
Oct 5, 2016
1f56588
Merge remote-tracking branch 'parity/master' into bft
Oct 5, 2016
e343153
mixed merge and changes...
Oct 11, 2016
214916a
new vote counter
Oct 11, 2016
ea960f1
Merge remote-tracking branch 'parity/master' into bft
Nov 7, 2016
4e36550
message revamp
Nov 8, 2016
55a5402
simplify messages
Nov 15, 2016
dd8ed42
update timeouts
Nov 15, 2016
54e4956
return errors from constructor
Nov 15, 2016
ff2dc5d
vote counting
Nov 15, 2016
d19e8c5
Merge remote-tracking branch 'parity/master' into bft
Nov 15, 2016
06e5416
header fns, extra_info
Nov 15, 2016
7d0eafd
fix extra_info
Nov 15, 2016
1c95869
timeout loading
Nov 15, 2016
8ac989c
Merge remote-tracking branch 'parity/master' into bft
Nov 16, 2016
2fa34fd
step transition messaging
Nov 16, 2016
3b0d550
fix compilation
Nov 16, 2016
51bbad6
add a path to submit seal from engine
Nov 16, 2016
802d5c6
transition rules
Nov 16, 2016
45027ea
add new client messaging
Nov 17, 2016
9563ccf
message broadcasting methods
Nov 17, 2016
6cb892f
Merge remote-tracking branch 'parity/master' into bft
Nov 17, 2016
51ac383
save proposal hash
Nov 17, 2016
ce711e3
remove unused vote accumulators
Nov 17, 2016
3bac684
last_lock
Nov 17, 2016
11ccacd
dont keep account provider in miner
Nov 17, 2016
11b6578
update tests
Nov 17, 2016
a521fda
update rpc module test
Nov 17, 2016
9d8ac7a
extra line [ci skip]
Nov 17, 2016
9d61071
Merge branch 'miner-no-ap' into auth-bft
Nov 17, 2016
c62795d
ap registration
Nov 17, 2016
e90d814
lock rounds
Nov 18, 2016
2f3b801
rename transition
Nov 18, 2016
49cbd6e
unused imports, proposer_nonce
Nov 18, 2016
9456c16
Merge branch 'master' into auth-bft
Nov 18, 2016
e69be67
message serialization
Nov 21, 2016
6e0bd40
Merge branch 'master' into auth-bft
Nov 21, 2016
42ef776
delete unused message type
Nov 21, 2016
12dbdc1
dont pass ap
Nov 21, 2016
841d094
remove WithSome block hash
Nov 21, 2016
84fdaf9
correct seal verification
Nov 21, 2016
66526af
pass engine in tests
Nov 21, 2016
32bcd08
test utilities
Nov 21, 2016
340d377
Revert "dont keep account provider in miner"
Nov 22, 2016
8f6a464
new error types
Nov 22, 2016
d5b15d4
change authorities for testing
Nov 22, 2016
2073649
improve error types
Nov 24, 2016
a3730b3
change proposer address
Nov 24, 2016
38f25fc
message tests and fixes
Nov 24, 2016
8f37807
seal checks
Nov 24, 2016
04acdd6
reuse rlp generation
Nov 24, 2016
f867372
increase default proposal time
Nov 24, 2016
da499b0
self contained test proposal
Nov 24, 2016
1692c07
Merge branch 'master' into auth-bft
Nov 25, 2016
a143da2
fix complete build
Nov 25, 2016
d2099d9
derive Eq for tests
Nov 25, 2016
f59746b
order messages by signature
Nov 25, 2016
8f72017
add transition tracing
Nov 25, 2016
a7afbf4
tracing and vote test
Nov 25, 2016
89f0bd7
test whole transitioning
Nov 28, 2016
5c0e89a
Merge branch 'master' into auth-bft
Nov 28, 2016
09c2880
proper test IoHandler
Nov 28, 2016
ef4ecce
nicer vote counting + test
Nov 28, 2016
7d97ba5
seal sigs test
Nov 28, 2016
1326c6c
rebroadcast unseen messages
Nov 28, 2016
b454f7e
use Io queue for messages
Nov 28, 2016
e4ff614
remove unused tracing
Nov 28, 2016
0f1eefc
disallow None seal sigs
Nov 28, 2016
61cf8b8
vote propose
Nov 28, 2016
d0eab4a
old message removal, avoid too many recoveries
Nov 29, 2016
49b953a
order invariant seal equality
Nov 29, 2016
e784fa9
warn on double vote
Nov 29, 2016
294e89e
use EngineError instead of BlockError
Nov 29, 2016
7929a14
fix deadlock
Nov 29, 2016
95f81b2
Moved consensus networking into Parity handler
arkpar Nov 29, 2016
4ef5bad
fix parity tests merge
Nov 30, 2016
34d5017
hold password in engine, add rpc
Nov 30, 2016
155da50
Merge branch 'master' into auth-bft
Nov 30, 2016
61f1699
fix merge
Nov 30, 2016
73e7908
test password registration
Nov 30, 2016
ca87d2c
add set_sealer rpc test
Nov 30, 2016
84cf27c
Advertise protocol version 2
arkpar Nov 30, 2016
bb83474
gossip when not enough votes
Nov 30, 2016
d128c20
remove proposer_nonce
Nov 30, 2016
dbf82c2
fix tests
Nov 30, 2016
66b4f1a
remove unnecessary option
Dec 1, 2016
344999a
return signing failure error
Dec 1, 2016
4eca687
Fixed network context
arkpar Dec 1, 2016
e40e398
clean up some tracing
Dec 1, 2016
498b2fb
show verification error
Dec 1, 2016
9290fdd
fix tests
Dec 1, 2016
f1ef4a4
Import sealed block immedtiatelly
arkpar Dec 1, 2016
39ea703
vote on message generation
Dec 1, 2016
e76ead4
update tracing message
Dec 1, 2016
df1cce8
simplify seal verification
Dec 1, 2016
f0e9eae
remove difficulty check
Dec 1, 2016
2c8c090
stricter size verification
Dec 2, 2016
0eb55cb
update message test
Dec 2, 2016
e0f2fac
new error type
Dec 2, 2016
91099f6
add more gossip if step is stuck
Dec 2, 2016
c8a3db4
new error proposal test
Dec 2, 2016
ff6240e
insert block into queue when sealing
Dec 2, 2016
9084e62
lock ordering
Dec 2, 2016
f1542b5
better genesis seal rlp
Dec 3, 2016
edef7a1
remove tracing
Dec 4, 2016
f7a01b8
better gossip, better proposal collection
Dec 4, 2016
c946ffe
Merge branch 'master' into auth-bft
Dec 5, 2016
b30c1d5
fix tests
Dec 5, 2016
c39d504
Merge branch 'spec-rlp-loading' into auth-bft
Dec 5, 2016
db59bd8
update genesis seal
Dec 5, 2016
4f85764
rename set_sealer
Dec 5, 2016
6fc943c
Merge branch 'master' into auth-bft
Dec 5, 2016
8f641e6
Merge branch 'engine-password' into auth-bft
Dec 6, 2016
d9eb5e7
remove uncles
Dec 7, 2016
5c333fc
Merge branch 'engine-password' into auth-bft
Dec 7, 2016
da030fe
Merge branch 'master' into auth-bft
Dec 7, 2016
a296c5e
test client message handling
Dec 7, 2016
c582540
Merge branch 'engine-password' into auth-bft
Dec 7, 2016
6440ca2
move stuff around
Dec 7, 2016
4361cb5
Merge branch 'engine-password' into auth-bft
Dec 7, 2016
e9743a3
Merge branch 'master' into auth-bft
Dec 7, 2016
b73689f
Merge branch 'engine-password' into auth-bft
Dec 7, 2016
aa9caac
revert cli default
Dec 7, 2016
347634a
dont rebroadcast propose
Dec 7, 2016
3ebfa14
better proposal block handling
Dec 8, 2016
dca752e
docs, tweaks
Dec 8, 2016
9ecb074
fix informant
Dec 8, 2016
79ef643
remove assert
Dec 8, 2016
cc284dd
Merge branch 'master' into auth-bft
Dec 8, 2016
74770e4
better docstrings
Dec 8, 2016
7c42241
remove merge code
Dec 8, 2016
42c34b5
ignore flaky test
Dec 9, 2016
fb71caf
remove double registration
Dec 9, 2016
762e5f1
proposed block sync tests
Dec 9, 2016
475d4bc
Merge branch 'io-stop' into auth-bft
Dec 9, 2016
c7f1260
Merge branch 'io-stop' of https://github.com/ethcore/parity into auth…
Dec 9, 2016
56e9dab
add Engine stop method
Dec 9, 2016
ca74067
AuthorityRound network simulation test
arkpar Dec 6, 2016
fe27b0f
Merge pull request #3775 from ethcore/auth-bft-test
gavofyork Dec 9, 2016
08e7e79
more test
Dec 9, 2016
b15edd0
Merge branch 'auth-bft' of https://github.com/ethcore/parity into aut…
Dec 9, 2016
e5f8044
Merge branch 'master' into auth-bft
Dec 10, 2016
239ba61
move transition message to to_step
Dec 10, 2016
b9909da
move Sealing methods to MiningBlockChainClient
Dec 10, 2016
1611d19
initial tendetmint consensus test
Dec 10, 2016
f3af0f4
Merge branch 'master' into auth-bft
Dec 10, 2016
b6c7ed2
Client trait reorg
Dec 10, 2016
c777362
Sync channel for consensus test
arkpar Dec 11, 2016
d4c9493
verification cache retrieval
Dec 11, 2016
a4bf914
Merge branch 'auth-bft' of https://github.com/ethcore/parity into aut…
Dec 11, 2016
3c5d585
nicer tracing
Dec 11, 2016
8ed89bb
propagate proposal to all peers
Dec 12, 2016
f8ed5cf
finalize unit tests
Dec 12, 2016
722cd4d
AuthorityRound fork test
Dec 12, 2016
19adb84
TestNet flushing and cleanup
Dec 12, 2016
fa504e5
Merge branch 'master' into auth-bft
Dec 12, 2016
49ae375
Don't coneect peers on each sync
arkpar Dec 13, 2016
c96826b
expect instead of index
Dec 13, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions ethcore/res/tendermint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"name": "TestBFT",
"engine": {
"Tendermint": {
"params": {
"gasLimitBoundDivisor": "0x0400",
"authorities" : [
"0x82a978b3f5962a5b0957d9ee9eef472ee55b42f1",
"0x7d577a597b2742b498cb5cf0c26cdcd726d39e6e"
]
}
}
},
"params": {
"accountStartNonce": "0x0",
"maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388",
"networkID" : "0x2323"
},
"genesis": {
"seal": {
"generic": {
"rlp": "f88980b8410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f843b8410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
}
},
"difficulty": "0x20000",
"author": "0x0000000000000000000000000000000000000000",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x",
"gasLimit": "0x2fefd8"
},
"accounts": {
"0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
"0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
"0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
"0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
"9cce34f7ab185c7aba1b7c8140d620b4bda941d6": { "balance": "1606938044258990275541962092341162602522202993782792835301376" }
}
}
7 changes: 6 additions & 1 deletion ethcore/src/client/chain_notify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.

use ipc::IpcConfig;
use util::H256;
use util::{H256, Bytes};

/// Represents what has to be handled by actor listening to chain events
#[ipc]
Expand All @@ -27,6 +27,8 @@ pub trait ChainNotify : Send + Sync {
_enacted: Vec<H256>,
_retracted: Vec<H256>,
_sealed: Vec<H256>,
// Block bytes.
_proposed: Vec<Bytes>,
_duration: u64) {
// does nothing by default
}
Expand All @@ -41,6 +43,9 @@ pub trait ChainNotify : Send + Sync {
// does nothing by default
}

/// fires when chain broadcasts a message
fn broadcast(&self, _data: Vec<u8>) {}

/// fires when new transactions are received from a peer
fn transactions_received(&self,
_hashes: Vec<H256>,
Expand Down
72 changes: 61 additions & 11 deletions ethcore/src/client/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ use time::precise_time_ns;
// util
use util::{Bytes, PerfTimer, Itertools, Mutex, RwLock, Hashable};
use util::{journaldb, TrieFactory, Trie};
use util::trie::TrieSpec;
use util::{U256, H256, Address, H2048, Uint, FixedHash};
use util::trie::TrieSpec;
use util::kvdb::*;

// other
Expand Down Expand Up @@ -396,9 +396,10 @@ impl Client {
/// This is triggered by a message coming from a block queue when the block is ready for insertion
pub fn import_verified_blocks(&self) -> usize {
let max_blocks_to_import = 4;
let (imported_blocks, import_results, invalid_blocks, imported, duration, is_empty) = {
let (imported_blocks, import_results, invalid_blocks, imported, proposed_blocks, duration, is_empty) = {
let mut imported_blocks = Vec::with_capacity(max_blocks_to_import);
let mut invalid_blocks = HashSet::new();
let mut proposed_blocks = Vec::with_capacity(max_blocks_to_import);
let mut import_results = Vec::with_capacity(max_blocks_to_import);

let _import_lock = self.import_lock.lock();
Expand All @@ -417,12 +418,17 @@ impl Client {
continue;
}
if let Ok(closed_block) = self.check_and_close_block(&block) {
imported_blocks.push(header.hash());
if self.engine.is_proposal(&block.header) {
self.block_queue.mark_as_good(&[header.hash()]);
proposed_blocks.push(block.bytes);
} else {
imported_blocks.push(header.hash());

let route = self.commit_block(closed_block, &header.hash(), &block.bytes);
import_results.push(route);
let route = self.commit_block(closed_block, &header.hash(), &block.bytes);
import_results.push(route);

self.report.write().accrue_block(&block);
self.report.write().accrue_block(&block);
}
} else {
invalid_blocks.insert(header.hash());
}
Expand All @@ -436,7 +442,7 @@ impl Client {
}
let is_empty = self.block_queue.mark_as_good(&imported_blocks);
let duration_ns = precise_time_ns() - start;
(imported_blocks, import_results, invalid_blocks, imported, duration_ns, is_empty)
(imported_blocks, import_results, invalid_blocks, imported, proposed_blocks, duration_ns, is_empty)
};

{
Expand All @@ -454,6 +460,7 @@ impl Client {
enacted.clone(),
retracted.clone(),
Vec::new(),
proposed_blocks.clone(),
duration,
);
});
Expand Down Expand Up @@ -577,9 +584,10 @@ impl Client {
self.miner.clone()
}

/// Used by PoA to try sealing on period change.
pub fn update_sealing(&self) {
self.miner.update_sealing(self)

/// Replace io channel. Useful for testing.
pub fn set_io_channel(&self, io_channel: IoChannel<ClientIoMessage>) {
*self.io_channel.lock() = io_channel;
}

/// Attempt to get a copy of a specific block's final state.
Expand Down Expand Up @@ -1290,6 +1298,18 @@ impl BlockChainClient for Client {
self.miner.pending_transactions(self.chain.read().best_block_number())
}

fn queue_consensus_message(&self, message: Bytes) {
let channel = self.io_channel.lock().clone();
if let Err(e) = channel.send(ClientIoMessage::NewMessage(message)) {
debug!("Ignoring the message, error queueing: {}", e);
}
}

fn broadcast_consensus_message(&self, message: Bytes) {
self.notify(|notify| notify.broadcast(message.clone()));
}


fn signing_network_id(&self) -> Option<u64> {
self.engine.signing_network_id(&self.latest_env_info())
}
Expand All @@ -1314,7 +1334,6 @@ impl BlockChainClient for Client {
}

impl MiningBlockChainClient for Client {

fn latest_schedule(&self) -> Schedule {
self.engine.schedule(&self.latest_env_info())
}
Expand Down Expand Up @@ -1357,6 +1376,30 @@ impl MiningBlockChainClient for Client {
&self.factories.vm
}

fn update_sealing(&self) {
self.miner.update_sealing(self)
}

fn submit_seal(&self, block_hash: H256, seal: Vec<Bytes>) {
if self.miner.submit_seal(self, block_hash, seal).is_err() {
warn!(target: "poa", "Wrong internal seal submission!")
}
}

fn broadcast_proposal_block(&self, block: SealedBlock) {
self.notify(|notify| {
notify.new_blocks(
vec![],
vec![],
vec![],
vec![],
vec![],
vec![block.rlp_bytes()],
0,
);
});
}

fn import_sealed_block(&self, block: SealedBlock) -> ImportResult {
let h = block.header().hash();
let start = precise_time_ns();
Expand All @@ -1381,6 +1424,7 @@ impl MiningBlockChainClient for Client {
enacted.clone(),
retracted.clone(),
vec![h.clone()],
vec![],
precise_time_ns() - start,
);
});
Expand Down Expand Up @@ -1416,6 +1460,12 @@ impl ::client::ProvingBlockChainClient for Client {
}
}

impl Drop for Client {
fn drop(&mut self) {
self.engine.stop();
}
}

#[cfg(test)]
mod tests {

Expand Down
18 changes: 18 additions & 0 deletions ethcore/src/client/test_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,18 @@ impl MiningBlockChainClient for TestBlockChainClient {
fn import_sealed_block(&self, _block: SealedBlock) -> ImportResult {
Ok(H256::default())
}

fn broadcast_proposal_block(&self, _block: SealedBlock) {}

fn update_sealing(&self) {
self.miner.update_sealing(self)
}

fn submit_seal(&self, block_hash: H256, seal: Vec<Bytes>) {
if self.miner.submit_seal(self, block_hash, seal).is_err() {
warn!(target: "poa", "Wrong internal seal submission!")
}
}
}

impl BlockChainClient for TestBlockChainClient {
Expand Down Expand Up @@ -663,6 +675,12 @@ impl BlockChainClient for TestBlockChainClient {
self.miner.import_external_transactions(self, txs);
}

fn queue_consensus_message(&self, message: Bytes) {
self.spec.engine.handle_message(&message).unwrap();
}

fn broadcast_consensus_message(&self, _message: Bytes) {}

fn pending_transactions(&self) -> Vec<SignedTransaction> {
self.miner.pending_transactions(self.chain_info().best_block_number)
}
Expand Down
15 changes: 15 additions & 0 deletions ethcore/src/client/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,12 @@ pub trait BlockChainClient : Sync + Send {
/// Queue transactions for importing.
fn queue_transactions(&self, transactions: Vec<Bytes>, peer_id: usize);

/// Queue conensus engine message.
fn queue_consensus_message(&self, message: Bytes);

/// Used by PoA to communicate with peers.
fn broadcast_consensus_message(&self, message: Bytes);

/// list all transactions
fn pending_transactions(&self) -> Vec<SignedTransaction>;

Expand Down Expand Up @@ -273,6 +279,15 @@ pub trait MiningBlockChainClient: BlockChainClient {
/// Returns EvmFactory.
fn vm_factory(&self) -> &EvmFactory;

/// Used by PoA to try sealing on period change.
fn update_sealing(&self);

/// Used by PoA to submit gathered signatures.
fn submit_seal(&self, block_hash: H256, seal: Vec<Bytes>);

/// Broadcast a block proposal.
fn broadcast_proposal_block(&self, block: SealedBlock);

/// Import sealed block. Skips all verifications.
fn import_sealed_block(&self, block: SealedBlock) -> ImportResult;

Expand Down
22 changes: 12 additions & 10 deletions ethcore/src/engines/authority_round.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use rlp::{UntrustedRlp, Rlp, View, encode};
use account_provider::AccountProvider;
use block::*;
use spec::CommonParams;
use engines::Engine;
use engines::{Engine, Seal, EngineError};
use header::Header;
use error::{Error, BlockError};
use blockchain::extras::BlockDetails;
Expand Down Expand Up @@ -225,8 +225,8 @@ impl Engine for AuthorityRound {
///
/// This operation is synchronous and may (quite reasonably) not be available, in which `false` will
/// be returned.
fn generate_seal(&self, block: &ExecutedBlock) -> Option<Vec<Bytes>> {
if self.proposed.load(AtomicOrdering::SeqCst) { return None; }
fn generate_seal(&self, block: &ExecutedBlock) -> Seal {
if self.proposed.load(AtomicOrdering::SeqCst) { return Seal::None; }
let header = block.header();
let step = self.step();
if self.is_step_proposer(step, header.author()) {
Expand All @@ -235,7 +235,8 @@ impl Engine for AuthorityRound {
if let Ok(signature) = ap.sign(*header.author(), self.password.read().clone(), header.bare_hash()) {
trace!(target: "poa", "generate_seal: Issuing a block for step {}.", step);
self.proposed.store(true, AtomicOrdering::SeqCst);
return Some(vec![encode(&step).to_vec(), encode(&(&*signature as &[u8])).to_vec()]);
let rlps = vec![encode(&step).to_vec(), encode(&(&*signature as &[u8])).to_vec()];
return Seal::Regular(rlps);
} else {
warn!(target: "poa", "generate_seal: FAIL: Accounts secret key unavailable.");
}
Expand All @@ -245,7 +246,7 @@ impl Engine for AuthorityRound {
} else {
trace!(target: "poa", "generate_seal: Not a proposer for step {}.", step);
}
None
Seal::None
}

/// Check the number of seal fields.
Expand Down Expand Up @@ -288,7 +289,7 @@ impl Engine for AuthorityRound {
// Check if parent is from a previous step.
if step == try!(header_step(parent)) {
trace!(target: "poa", "Multiple blocks proposed for step {}.", step);
try!(Err(BlockError::DoubleVote(header.author().clone())));
try!(Err(EngineError::DoubleVote(header.author().clone())));
}

let gas_limit_divisor = self.our_params.gas_limit_bound_divisor;
Expand Down Expand Up @@ -347,6 +348,7 @@ mod tests {
use tests::helpers::*;
use account_provider::AccountProvider;
use spec::Spec;
use engines::Seal;

#[test]
fn has_valid_metadata() {
Expand Down Expand Up @@ -416,17 +418,17 @@ mod tests {
let b2 = b2.close_and_lock();

engine.set_signer(addr1, "1".into());
if let Some(seal) = engine.generate_seal(b1.block()) {
if let Seal::Regular(seal) = engine.generate_seal(b1.block()) {
assert!(b1.clone().try_seal(engine, seal).is_ok());
// Second proposal is forbidden.
assert!(engine.generate_seal(b1.block()).is_none());
assert!(engine.generate_seal(b1.block()) == Seal::None);
}

engine.set_signer(addr2, "2".into());
if let Some(seal) = engine.generate_seal(b2.block()) {
if let Seal::Regular(seal) = engine.generate_seal(b2.block()) {
assert!(b2.clone().try_seal(engine, seal).is_ok());
// Second proposal is forbidden.
assert!(engine.generate_seal(b2.block()).is_none());
assert!(engine.generate_seal(b2.block()) == Seal::None);
}
}

Expand Down
Loading