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 {
|
||||
let our_addr = match *self.signer.read() {
|
||||
Some(ref signer) => signer.address(),
|
||||
|
@ -470,6 +470,14 @@ pub trait Engine<M: Machine>: Sync + Send {
|
||||
/// Register a component which signs consensus messages.
|
||||
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.
|
||||
fn sign(&self, _hash: H256) -> Result<Signature, M::Error> {
|
||||
unimplemented!()
|
||||
|
@ -1377,7 +1377,7 @@ impl miner::MinerService for Miner {
|
||||
}
|
||||
|
||||
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)>
|
||||
@ -1608,7 +1608,9 @@ mod tests {
|
||||
|
||||
use client::{ChainInfo, EachBlockWith, ImportSealedBlock, TestBlockChainClient};
|
||||
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};
|
||||
|
||||
#[test]
|
||||
@ -2078,6 +2080,31 @@ mod tests {
|
||||
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]
|
||||
fn should_set_new_minimum_gas_price() {
|
||||
// Creates a new GasPricer::Fixed behind the scenes
|
||||
|
@ -46,6 +46,8 @@ use block::{Drain, OpenBlock};
|
||||
use client::{
|
||||
ChainInfo, ChainMessageType, ChainNotify, Client, ClientConfig, ImportBlock, PrepareOpenBlock,
|
||||
};
|
||||
use engines::EngineSigner;
|
||||
use ethjson::crypto::publickey::{Public, Signature};
|
||||
use factory::Factories;
|
||||
use miner::Miner;
|
||||
use spec::Spec;
|
||||
@ -644,3 +646,38 @@ impl ChainNotify for TestNotify {
|
||||
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