Errors & warnings for inappropriate RPCs (#6029)
* Clarify function name Function checks if sealing is currently underway, not to be confused with checking whether the engine performs internal sealing. * Error when work called on internal sealing engine * Error submitting work for internal sealing engine * Fix inverted bool and style grumbles * Add can_produce_work_package to TestMinerService * Error when setting engine signer on PoW chain * Unit tests for engine signing Setting engine signer should fail if chain does not seal internally or client lacks account provider. * Tweak TestMinerService * Fix minor style grumbles
This commit is contained in:
@@ -64,7 +64,9 @@ pub enum SignError {
|
||||
/// Low-level hardware device error.
|
||||
Hardware(HardwareError),
|
||||
/// Low-level error from store
|
||||
SStore(SSError)
|
||||
SStore(SSError),
|
||||
/// Inappropriate chain
|
||||
InappropriateChain,
|
||||
}
|
||||
|
||||
impl fmt::Display for SignError {
|
||||
@@ -74,6 +76,7 @@ impl fmt::Display for SignError {
|
||||
SignError::NotFound => write!(f, "Account does not exist"),
|
||||
SignError::Hardware(ref e) => write!(f, "{}", e),
|
||||
SignError::SStore(ref e) => write!(f, "{}", e),
|
||||
SignError::InappropriateChain => write!(f, "Inappropriate chain"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -804,9 +804,15 @@ impl MinerService for Miner {
|
||||
// | Make sure to release the locks before calling that method. |
|
||||
// --------------------------------------------------------------------------
|
||||
self.engine.set_signer(ap.clone(), address, password);
|
||||
Ok(())
|
||||
} else {
|
||||
warn!(target: "miner", "No account provider");
|
||||
Err(AccountError::NotFound)
|
||||
}
|
||||
} else {
|
||||
warn!(target: "miner", "Cannot set engine signer on a PoW chain.");
|
||||
Err(AccountError::InappropriateChain)
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_extra_data(&self, extra_data: Bytes) {
|
||||
@@ -1085,6 +1091,10 @@ impl MinerService for Miner {
|
||||
self.transaction_queue.read().last_nonce(address)
|
||||
}
|
||||
|
||||
fn can_produce_work_package(&self) -> bool {
|
||||
self.engine.seals_internally().is_none()
|
||||
}
|
||||
|
||||
/// Update sealing if required.
|
||||
/// Prepare the block and work if the Engine does not seal internally.
|
||||
fn update_sealing(&self, chain: &MiningBlockChainClient) {
|
||||
@@ -1113,7 +1123,7 @@ impl MinerService for Miner {
|
||||
}
|
||||
}
|
||||
|
||||
fn is_sealing(&self) -> bool {
|
||||
fn is_currently_sealing(&self) -> bool {
|
||||
self.sealing_work.lock().queue.is_in_use()
|
||||
}
|
||||
|
||||
@@ -1272,7 +1282,7 @@ mod tests {
|
||||
use header::BlockNumber;
|
||||
use types::transaction::{SignedTransaction, Transaction, PendingTransaction, Action};
|
||||
use spec::Spec;
|
||||
use tests::helpers::{generate_dummy_client};
|
||||
use tests::helpers::{generate_dummy_client, generate_dummy_client_with_spec_and_accounts};
|
||||
|
||||
#[test]
|
||||
fn should_prepare_block_to_seal() {
|
||||
@@ -1440,4 +1450,22 @@ mod tests {
|
||||
assert!(miner.pending_block().is_none());
|
||||
assert_eq!(client.chain_info().best_block_number, 4 as BlockNumber);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_fail_setting_engine_signer_on_pow() {
|
||||
let spec = Spec::new_pow_test_spec;
|
||||
let tap = Arc::new(AccountProvider::transient_provider());
|
||||
let addr = tap.insert_account("1".sha3().into(), "").unwrap();
|
||||
let client = generate_dummy_client_with_spec_and_accounts(spec, Some(tap.clone()));
|
||||
assert!(match client.miner().set_engine_signer(addr, "".into()) { Err(AccountError::InappropriateChain) => true, _ => false })
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_fail_setting_engine_signer_without_account_provider() {
|
||||
let spec = Spec::new_instant;
|
||||
let tap = Arc::new(AccountProvider::transient_provider());
|
||||
let addr = tap.insert_account("1".sha3().into(), "").unwrap();
|
||||
let client = generate_dummy_client_with_spec_and_accounts(spec, None);
|
||||
assert!(match client.miner().set_engine_signer(addr, "".into()) { Err(AccountError::NotFound) => true, _ => false });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,6 +136,9 @@ pub trait MinerService : Send + Sync {
|
||||
/// Called when blocks are imported to chain, updates transactions queue.
|
||||
fn chain_new_blocks(&self, chain: &MiningBlockChainClient, imported: &[H256], invalid: &[H256], enacted: &[H256], retracted: &[H256]);
|
||||
|
||||
/// PoW chain - can produce work package
|
||||
fn can_produce_work_package(&self) -> bool;
|
||||
|
||||
/// New chain head event. Restart mining operation.
|
||||
fn update_sealing(&self, chain: &MiningBlockChainClient);
|
||||
|
||||
@@ -176,7 +179,7 @@ pub trait MinerService : Send + Sync {
|
||||
fn last_nonce(&self, address: &Address) -> Option<U256>;
|
||||
|
||||
/// Is it currently sealing?
|
||||
fn is_sealing(&self) -> bool;
|
||||
fn is_currently_sealing(&self) -> bool;
|
||||
|
||||
/// Suggested gas price.
|
||||
fn sensible_gas_price(&self) -> U256;
|
||||
|
||||
@@ -451,6 +451,9 @@ impl Spec {
|
||||
/// Create a new Spec with BasicAuthority which uses multiple validator sets changing with height.
|
||||
/// Account with secrets "0".sha3() is the validator for block 1 and with "1".sha3() onwards.
|
||||
pub fn new_validator_multi() -> Self { load_bundled!("validator_multi") }
|
||||
|
||||
/// Create a new spec for a PoW chain
|
||||
pub fn new_pow_test_spec() -> Self { load_bundled!("ethereum/olympic") }
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
Reference in New Issue
Block a user