Makes eth_mining to return False if not is not allowed to seal (#581)
This commit is contained in:
parent
f703d01f23
commit
63bab44e3c
@ -1557,6 +1557,43 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mostly is the same as `fn sealing_state(&self)` except that it does not
|
||||||
|
// check whether the node is a step proposer.
|
||||||
|
fn is_allowed_to_seal(&self) -> bool {
|
||||||
|
let our_addr = match *self.signer.read() {
|
||||||
|
Some(ref signer) => signer.address(),
|
||||||
|
None => return false,
|
||||||
|
};
|
||||||
|
|
||||||
|
let client = match self.upgrade_client_or("Not preparing block") {
|
||||||
|
Ok(client) => client,
|
||||||
|
Err(_) => return false,
|
||||||
|
};
|
||||||
|
|
||||||
|
let parent = match client.as_full_client() {
|
||||||
|
Some(full_client) => full_client.best_block_header(),
|
||||||
|
None => {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let validators = if self.immediate_transitions {
|
||||||
|
CowLike::Borrowed(&*self.validators)
|
||||||
|
} else {
|
||||||
|
let mut epoch_manager = self.epoch_manager.lock();
|
||||||
|
if !epoch_manager.zoom_to_after(
|
||||||
|
&*client,
|
||||||
|
&self.machine,
|
||||||
|
&*self.validators,
|
||||||
|
parent.hash(),
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
CowLike::Owned(epoch_manager.validators().clone())
|
||||||
|
};
|
||||||
|
validators.contains(&parent.hash(), &our_addr)
|
||||||
|
}
|
||||||
|
|
||||||
fn sealing_state(&self) -> SealingState {
|
fn sealing_state(&self) -> SealingState {
|
||||||
let our_addr = match *self.signer.read() {
|
let our_addr = match *self.signer.read() {
|
||||||
Some(ref signer) => signer.address(),
|
Some(ref signer) => signer.address(),
|
||||||
|
@ -470,6 +470,14 @@ pub trait Engine<M: Machine>: Sync + Send {
|
|||||||
/// Register a component which signs consensus messages.
|
/// Register a component which signs consensus messages.
|
||||||
fn set_signer(&self, _signer: Option<Box<dyn EngineSigner>>) {}
|
fn set_signer(&self, _signer: Option<Box<dyn EngineSigner>>) {}
|
||||||
|
|
||||||
|
/// Returns whether the current node is a validator and
|
||||||
|
/// actually may seal a block if AuRa engine is used.
|
||||||
|
///
|
||||||
|
/// Used by `eth_mining` rpc call.
|
||||||
|
fn is_allowed_to_seal(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
/// Sign using the EngineSigner, to be used for consensus tx signing.
|
/// Sign using the EngineSigner, to be used for consensus tx signing.
|
||||||
fn sign(&self, _hash: H256) -> Result<Signature, M::Error> {
|
fn sign(&self, _hash: H256) -> Result<Signature, M::Error> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
|
@ -1377,7 +1377,7 @@ impl miner::MinerService for Miner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn is_currently_sealing(&self) -> bool {
|
fn is_currently_sealing(&self) -> bool {
|
||||||
self.sealing.lock().enabled
|
self.sealing.lock().enabled && self.engine.is_allowed_to_seal()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn work_package<C>(&self, chain: &C) -> Option<(H256, BlockNumber, u64, U256)>
|
fn work_package<C>(&self, chain: &C) -> Option<(H256, BlockNumber, u64, U256)>
|
||||||
@ -1608,7 +1608,9 @@ mod tests {
|
|||||||
|
|
||||||
use client::{ChainInfo, EachBlockWith, ImportSealedBlock, TestBlockChainClient};
|
use client::{ChainInfo, EachBlockWith, ImportSealedBlock, TestBlockChainClient};
|
||||||
use miner::{MinerService, PendingOrdering};
|
use miner::{MinerService, PendingOrdering};
|
||||||
use test_helpers::{generate_dummy_client, generate_dummy_client_with_spec};
|
use test_helpers::{
|
||||||
|
dummy_engine_signer_with_address, generate_dummy_client, generate_dummy_client_with_spec,
|
||||||
|
};
|
||||||
use types::transaction::{Transaction, TypedTransaction};
|
use types::transaction::{Transaction, TypedTransaction};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -2078,6 +2080,31 @@ mod tests {
|
|||||||
assert!(miner.is_currently_sealing());
|
assert!(miner.is_currently_sealing());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_not_mine_if_is_not_allowed_to_seal() {
|
||||||
|
let spec = Spec::new_test_round();
|
||||||
|
let miner = Miner::new_for_tests_force_sealing(&spec, None, true);
|
||||||
|
assert!(!miner.is_currently_sealing());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_mine_if_is_allowed_to_seal() {
|
||||||
|
let verifier: Address = [
|
||||||
|
0x7d, 0x57, 0x7a, 0x59, 0x7b, 0x27, 0x42, 0xb4, 0x98, 0xcb, 0x5c, 0xf0, 0xc2, 0x6c,
|
||||||
|
0xdc, 0xd7, 0x26, 0xd3, 0x9e, 0x6e,
|
||||||
|
]
|
||||||
|
.into();
|
||||||
|
|
||||||
|
let spec = Spec::new_test_round();
|
||||||
|
let client: Arc<dyn EngineClient> = generate_dummy_client(2);
|
||||||
|
|
||||||
|
let miner = Miner::new_for_tests_force_sealing(&spec, None, true);
|
||||||
|
miner.engine.register_client(Arc::downgrade(&client));
|
||||||
|
miner.set_author(Author::Sealer(dummy_engine_signer_with_address(verifier)));
|
||||||
|
|
||||||
|
assert!(miner.is_currently_sealing());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_set_new_minimum_gas_price() {
|
fn should_set_new_minimum_gas_price() {
|
||||||
// Creates a new GasPricer::Fixed behind the scenes
|
// Creates a new GasPricer::Fixed behind the scenes
|
||||||
|
@ -46,6 +46,8 @@ use block::{Drain, OpenBlock};
|
|||||||
use client::{
|
use client::{
|
||||||
ChainInfo, ChainMessageType, ChainNotify, Client, ClientConfig, ImportBlock, PrepareOpenBlock,
|
ChainInfo, ChainMessageType, ChainNotify, Client, ClientConfig, ImportBlock, PrepareOpenBlock,
|
||||||
};
|
};
|
||||||
|
use engines::EngineSigner;
|
||||||
|
use ethjson::crypto::publickey::{Public, Signature};
|
||||||
use factory::Factories;
|
use factory::Factories;
|
||||||
use miner::Miner;
|
use miner::Miner;
|
||||||
use spec::Spec;
|
use spec::Spec;
|
||||||
@ -644,3 +646,38 @@ impl ChainNotify for TestNotify {
|
|||||||
self.messages.write().push(data);
|
self.messages.write().push(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns engine signer with specified address
|
||||||
|
pub fn dummy_engine_signer_with_address(addr: Address) -> Box<dyn EngineSigner> {
|
||||||
|
struct TestEngineSigner(Address);
|
||||||
|
|
||||||
|
impl TestEngineSigner {
|
||||||
|
fn with_address(addr: Address) -> Self {
|
||||||
|
Self(addr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EngineSigner for TestEngineSigner {
|
||||||
|
fn sign(&self, _hash: H256) -> Result<Signature, ethjson::crypto::publickey::Error> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn address(&self) -> Address {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn decrypt(
|
||||||
|
&self,
|
||||||
|
_auth_data: &[u8],
|
||||||
|
_cipher: &[u8],
|
||||||
|
) -> Result<Vec<u8>, parity_crypto::publickey::Error> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn public(&self) -> Option<Public> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Box::new(TestEngineSigner::with_address(addr))
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user