Deprecate account management (#10213)
* Extract accounts from ethcore. * Fix ethcore. * Get rid of AccountProvider in test_helpers * Fix rest of the code. * Re-use EngineSigner, fix tests. * Simplify EngineSigner to always have an Address. * Fix RPC tests. * Add deprecation notice to RPCs. * Feature to disable accounts. * extract accounts in RPC * Run with accounts in tests. * Fix RPC compilation and tests. * Fix compilation of the binary. * Fix compilation of the binary. * Fix compilation with accounts enabled. * Fix tests. * Update submodule. * Remove android. * Use derive for Default * Don't build secretstore by default. * Add link to issue. * Refresh Cargo.lock. * Fix miner tests. * Update rpc/Cargo.toml Co-Authored-By: tomusdrw <tomusdrw@users.noreply.github.com> * Fix private tests.
This commit is contained in:
committed by
Afri Schoedon
parent
8fa56add47
commit
d5c19f8719
@@ -23,11 +23,11 @@ use ansi_term::Colour;
|
||||
use bytes::Bytes;
|
||||
use call_contract::CallContract;
|
||||
use ethcore_miner::gas_pricer::GasPricer;
|
||||
use ethcore_miner::local_accounts::LocalAccounts;
|
||||
use ethcore_miner::pool::{self, TransactionQueue, VerifiedTransaction, QueueStatus, PrioritizationStrategy};
|
||||
#[cfg(feature = "work-notify")]
|
||||
use ethcore_miner::work_notify::NotifyWork;
|
||||
use ethereum_types::{H256, U256, Address};
|
||||
use ethkey::Password;
|
||||
use io::IoChannel;
|
||||
use miner::pool_client::{PoolClient, CachedNonceClient, NonceCache};
|
||||
use miner;
|
||||
@@ -46,13 +46,12 @@ use types::header::Header;
|
||||
use types::receipt::RichReceipt;
|
||||
use using_queue::{UsingQueue, GetAction};
|
||||
|
||||
use account_provider::{AccountProvider, SignError as AccountError};
|
||||
use block::{ClosedBlock, IsBlock, SealedBlock};
|
||||
use client::{
|
||||
BlockChain, ChainInfo, BlockProducer, SealedBlockImporter, Nonce, TransactionInfo, TransactionId
|
||||
};
|
||||
use client::{BlockId, ClientIoMessage};
|
||||
use engines::{EthEngine, Seal};
|
||||
use engines::{EthEngine, Seal, EngineSigner};
|
||||
use error::{Error, ErrorKind};
|
||||
use executed::ExecutionError;
|
||||
use executive::contract_address;
|
||||
@@ -140,8 +139,6 @@ pub struct MinerOptions {
|
||||
/// will be invalid if mined.
|
||||
pub infinite_pending_block: bool,
|
||||
|
||||
/// Prioritized Local Addresses
|
||||
pub tx_queue_locals: HashSet<Address>,
|
||||
/// Strategy to use for prioritizing transactions in the queue.
|
||||
pub tx_queue_strategy: PrioritizationStrategy,
|
||||
/// Simple senders penalization.
|
||||
@@ -169,7 +166,6 @@ impl Default for MinerOptions {
|
||||
work_queue_size: 20,
|
||||
enable_resubmission: true,
|
||||
infinite_pending_block: false,
|
||||
tx_queue_locals: HashSet::new(),
|
||||
tx_queue_strategy: PrioritizationStrategy::GasPriceOnly,
|
||||
tx_queue_penalization: Penalization::Disabled,
|
||||
tx_queue_no_unfamiliar_locals: false,
|
||||
@@ -200,6 +196,25 @@ pub struct AuthoringParams {
|
||||
pub extra_data: Bytes,
|
||||
}
|
||||
|
||||
/// Block sealing mechanism
|
||||
pub enum Author {
|
||||
/// Sealing block is external and we only need a reward beneficiary (i.e. PoW)
|
||||
External(Address),
|
||||
/// Sealing is done internally, we need a way to create signatures to seal block (i.e. PoA)
|
||||
Sealer(Box<EngineSigner>),
|
||||
}
|
||||
|
||||
impl Author {
|
||||
/// Get author's address.
|
||||
pub fn address(&self) -> Address {
|
||||
match *self {
|
||||
Author::External(address) => address,
|
||||
Author::Sealer(ref sealer) => sealer.address(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct SealingWork {
|
||||
queue: UsingQueue<ClosedBlock>,
|
||||
enabled: bool,
|
||||
@@ -230,7 +245,7 @@ pub struct Miner {
|
||||
// TODO [ToDr] Arc is only required because of price updater
|
||||
transaction_queue: Arc<TransactionQueue>,
|
||||
engine: Arc<EthEngine>,
|
||||
accounts: Option<Arc<AccountProvider>>,
|
||||
accounts: Arc<LocalAccounts>,
|
||||
io_channel: RwLock<Option<IoChannel<ClientIoMessage>>>,
|
||||
}
|
||||
|
||||
@@ -248,11 +263,11 @@ impl Miner {
|
||||
}
|
||||
|
||||
/// Creates new instance of miner Arc.
|
||||
pub fn new(
|
||||
pub fn new<A: LocalAccounts + 'static>(
|
||||
options: MinerOptions,
|
||||
gas_pricer: GasPricer,
|
||||
spec: &Spec,
|
||||
accounts: Option<Arc<AccountProvider>>,
|
||||
accounts: A,
|
||||
) -> Self {
|
||||
let limits = options.pool_limits.clone();
|
||||
let verifier_options = options.pool_verification_options.clone();
|
||||
@@ -275,7 +290,7 @@ impl Miner {
|
||||
nonce_cache: NonceCache::new(nonce_cache_size),
|
||||
options,
|
||||
transaction_queue: Arc::new(TransactionQueue::new(limits, verifier_options, tx_queue_strategy)),
|
||||
accounts,
|
||||
accounts: Arc::new(accounts),
|
||||
engine: spec.engine.clone(),
|
||||
io_channel: RwLock::new(None),
|
||||
}
|
||||
@@ -284,7 +299,7 @@ impl Miner {
|
||||
/// Creates new instance of miner with given spec and accounts.
|
||||
///
|
||||
/// NOTE This should be only used for tests.
|
||||
pub fn new_for_tests(spec: &Spec, accounts: Option<Arc<AccountProvider>>) -> Miner {
|
||||
pub fn new_for_tests(spec: &Spec, accounts: Option<HashSet<Address>>) -> Miner {
|
||||
let minimal_gas_price = 0.into();
|
||||
Miner::new(MinerOptions {
|
||||
pool_verification_options: pool::verifier::Options {
|
||||
@@ -295,7 +310,7 @@ impl Miner {
|
||||
},
|
||||
reseal_min_period: Duration::from_secs(0),
|
||||
..Default::default()
|
||||
}, GasPricer::new_fixed(minimal_gas_price), spec, accounts)
|
||||
}, GasPricer::new_fixed(minimal_gas_price), spec, accounts.unwrap_or_default())
|
||||
}
|
||||
|
||||
/// Sets `IoChannel`
|
||||
@@ -362,7 +377,7 @@ impl Miner {
|
||||
chain,
|
||||
&self.nonce_cache,
|
||||
&*self.engine,
|
||||
self.accounts.as_ref().map(|x| &**x),
|
||||
&*self.accounts,
|
||||
self.options.refuse_service_transactions,
|
||||
)
|
||||
}
|
||||
@@ -830,14 +845,11 @@ impl miner::MinerService for Miner {
|
||||
self.params.write().extra_data = extra_data;
|
||||
}
|
||||
|
||||
fn set_author(&self, address: Address, password: Option<Password>) -> Result<(), AccountError> {
|
||||
self.params.write().author = address;
|
||||
fn set_author(&self, author: Author) {
|
||||
self.params.write().author = author.address();
|
||||
|
||||
if self.engine.seals_internally().is_some() && password.is_some() {
|
||||
if let Some(ref ap) = self.accounts {
|
||||
let password = password.unwrap_or_else(|| Password::from(String::new()));
|
||||
// Sign test message
|
||||
ap.sign(address.clone(), Some(password.clone()), Default::default())?;
|
||||
if let Author::Sealer(signer) = author {
|
||||
if self.engine.seals_internally().is_some() {
|
||||
// Enable sealing
|
||||
self.sealing.lock().enabled = true;
|
||||
// --------------------------------------------------------------------------
|
||||
@@ -845,14 +857,10 @@ impl miner::MinerService for Miner {
|
||||
// | (some `Engine`s call `EngineClient.update_sealing()`) |
|
||||
// | Make sure to release the locks before calling that method. |
|
||||
// --------------------------------------------------------------------------
|
||||
self.engine.set_signer(ap.clone(), address, password);
|
||||
Ok(())
|
||||
self.engine.set_signer(signer);
|
||||
} else {
|
||||
warn!(target: "miner", "No account provider");
|
||||
Err(AccountError::NotFound)
|
||||
warn!("Setting an EngineSigner while Engine does not require one.");
|
||||
}
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -925,8 +933,7 @@ impl miner::MinerService for Miner {
|
||||
let sender = pending.sender();
|
||||
let treat_as_local = trusted
|
||||
|| !self.options.tx_queue_no_unfamiliar_locals
|
||||
|| self.accounts.as_ref().map(|accts| accts.has_account(sender)).unwrap_or(false)
|
||||
|| self.options.tx_queue_locals.contains(&sender);
|
||||
|| self.accounts.is_local(&sender);
|
||||
|
||||
if treat_as_local {
|
||||
self.import_own_transaction(chain, pending)
|
||||
@@ -1255,7 +1262,7 @@ impl miner::MinerService for Miner {
|
||||
chain,
|
||||
&nonce_cache,
|
||||
&*engine,
|
||||
accounts.as_ref().map(|x| &**x),
|
||||
&*accounts,
|
||||
refuse_service_transactions,
|
||||
);
|
||||
queue.cull(client);
|
||||
@@ -1292,6 +1299,7 @@ mod tests {
|
||||
use std::iter::FromIterator;
|
||||
|
||||
use super::*;
|
||||
use accounts::AccountProvider;
|
||||
use ethkey::{Generator, Random};
|
||||
use hash::keccak;
|
||||
use rustc_hex::FromHex;
|
||||
@@ -1299,7 +1307,7 @@ mod tests {
|
||||
|
||||
use client::{TestBlockChainClient, EachBlockWith, ChainInfo, ImportSealedBlock};
|
||||
use miner::{MinerService, PendingOrdering};
|
||||
use test_helpers::{generate_dummy_client, generate_dummy_client_with_spec_and_accounts};
|
||||
use test_helpers::{generate_dummy_client, generate_dummy_client_with_spec};
|
||||
use types::transaction::{Transaction};
|
||||
|
||||
#[test]
|
||||
@@ -1349,7 +1357,6 @@ mod tests {
|
||||
enable_resubmission: true,
|
||||
infinite_pending_block: false,
|
||||
tx_queue_penalization: Penalization::Disabled,
|
||||
tx_queue_locals: HashSet::new(),
|
||||
tx_queue_strategy: PrioritizationStrategy::GasPriceOnly,
|
||||
tx_queue_no_unfamiliar_locals: false,
|
||||
refuse_service_transactions: false,
|
||||
@@ -1363,7 +1370,7 @@ mod tests {
|
||||
},
|
||||
GasPricer::new_fixed(0u64.into()),
|
||||
&Spec::new_test(),
|
||||
None, // accounts provider
|
||||
::std::collections::HashSet::new(), // local accounts
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1476,8 +1483,8 @@ mod tests {
|
||||
// given
|
||||
let keypair = Random.generate().unwrap();
|
||||
let client = TestBlockChainClient::default();
|
||||
let account_provider = AccountProvider::transient_provider();
|
||||
account_provider.insert_account(keypair.secret().clone(), &"".into()).expect("can add accounts to the provider we just created");
|
||||
let mut local_accounts = ::std::collections::HashSet::new();
|
||||
local_accounts.insert(keypair.address());
|
||||
|
||||
let miner = Miner::new(
|
||||
MinerOptions {
|
||||
@@ -1486,7 +1493,7 @@ mod tests {
|
||||
},
|
||||
GasPricer::new_fixed(0u64.into()),
|
||||
&Spec::new_test(),
|
||||
Some(Arc::new(account_provider)),
|
||||
local_accounts,
|
||||
);
|
||||
let transaction = transaction();
|
||||
let best_block = 0;
|
||||
@@ -1520,22 +1527,16 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn should_prioritize_locals() {
|
||||
let keypair = Random.generate().unwrap();
|
||||
let client = TestBlockChainClient::default();
|
||||
let account_provider = AccountProvider::transient_provider();
|
||||
account_provider.insert_account(keypair.secret().clone(), &"".into())
|
||||
.expect("can add accounts to the provider we just created");
|
||||
|
||||
let transaction = transaction();
|
||||
let miner = Miner::new(
|
||||
MinerOptions {
|
||||
tx_queue_no_unfamiliar_locals: true, // should work even with this enabled
|
||||
tx_queue_locals: HashSet::from_iter(vec![transaction.sender()].into_iter()),
|
||||
..miner().options
|
||||
},
|
||||
GasPricer::new_fixed(0u64.into()),
|
||||
&Spec::new_test(),
|
||||
Some(Arc::new(account_provider)),
|
||||
HashSet::from_iter(vec![transaction.sender()].into_iter()),
|
||||
);
|
||||
let best_block = 0;
|
||||
|
||||
@@ -1587,12 +1588,19 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_fail_setting_engine_signer_without_account_provider() {
|
||||
let spec = Spec::new_instant;
|
||||
fn should_not_fail_setting_engine_signer_without_account_provider() {
|
||||
let spec = Spec::new_test_round;
|
||||
let tap = Arc::new(AccountProvider::transient_provider());
|
||||
let addr = tap.insert_account(keccak("1").into(), &"".into()).unwrap();
|
||||
let client = generate_dummy_client_with_spec_and_accounts(spec, None);
|
||||
assert!(match client.miner().set_author(addr, Some("".into())) { Err(AccountError::NotFound) => true, _ => false });
|
||||
let client = generate_dummy_client_with_spec(spec);
|
||||
let engine_signer = Box::new((tap.clone(), addr, "".into()));
|
||||
let msg = Default::default();
|
||||
assert!(client.engine().sign(msg).is_err());
|
||||
|
||||
// should set engine signer and miner author
|
||||
client.miner().set_author(Author::Sealer(engine_signer));
|
||||
assert_eq!(client.miner().authoring_params().author, addr);
|
||||
assert!(client.engine().sign(msg).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -25,7 +25,8 @@ pub mod pool_client;
|
||||
#[cfg(feature = "stratum")]
|
||||
pub mod stratum;
|
||||
|
||||
pub use self::miner::{Miner, MinerOptions, Penalization, PendingSet, AuthoringParams};
|
||||
pub use self::miner::{Miner, MinerOptions, Penalization, PendingSet, AuthoringParams, Author};
|
||||
pub use ethcore_miner::local_accounts::LocalAccounts;
|
||||
pub use ethcore_miner::pool::PendingOrdering;
|
||||
|
||||
use std::sync::Arc;
|
||||
@@ -34,7 +35,6 @@ use std::collections::{BTreeSet, BTreeMap};
|
||||
use bytes::Bytes;
|
||||
use ethcore_miner::pool::{VerifiedTransaction, QueueStatus, local_transactions};
|
||||
use ethereum_types::{H256, U256, Address};
|
||||
use ethkey::Password;
|
||||
use types::transaction::{self, UnverifiedTransaction, SignedTransaction, PendingTransaction};
|
||||
use types::BlockNumber;
|
||||
use types::block::Block;
|
||||
@@ -130,8 +130,8 @@ pub trait MinerService : Send + Sync {
|
||||
|
||||
/// Set info necessary to sign consensus messages and block authoring.
|
||||
///
|
||||
/// On PoW password is optional.
|
||||
fn set_author(&self, address: Address, password: Option<Password>) -> Result<(), ::account_provider::SignError>;
|
||||
/// On chains where sealing is done externally (e.g. PoW) we provide only reward beneficiary.
|
||||
fn set_author(&self, author: Author);
|
||||
|
||||
// Transaction Pool
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ use std::{
|
||||
};
|
||||
|
||||
use ethereum_types::{H256, U256, Address};
|
||||
use ethcore_miner::local_accounts::LocalAccounts;
|
||||
use ethcore_miner::pool;
|
||||
use ethcore_miner::pool::client::NonceClient;
|
||||
use ethcore_miner::service_transaction_checker::ServiceTransactionChecker;
|
||||
@@ -34,7 +35,6 @@ use types::transaction::{
|
||||
use types::header::Header;
|
||||
use parking_lot::RwLock;
|
||||
|
||||
use account_provider::AccountProvider;
|
||||
use call_contract::CallContract;
|
||||
use client::{TransactionId, BlockInfo, Nonce};
|
||||
use engines::EthEngine;
|
||||
@@ -73,7 +73,7 @@ pub struct PoolClient<'a, C: 'a> {
|
||||
chain: &'a C,
|
||||
cached_nonces: CachedNonceClient<'a, C>,
|
||||
engine: &'a EthEngine,
|
||||
accounts: Option<&'a AccountProvider>,
|
||||
accounts: &'a LocalAccounts,
|
||||
best_block_header: Header,
|
||||
service_transaction_checker: Option<ServiceTransactionChecker>,
|
||||
}
|
||||
@@ -92,14 +92,14 @@ impl<'a, C: 'a> Clone for PoolClient<'a, C> {
|
||||
}
|
||||
|
||||
impl<'a, C: 'a> PoolClient<'a, C> where
|
||||
C: BlockInfo + CallContract,
|
||||
C: BlockInfo + CallContract,
|
||||
{
|
||||
/// Creates new client given chain, nonce cache, accounts and service transaction verifier.
|
||||
pub fn new(
|
||||
chain: &'a C,
|
||||
cache: &'a NonceCache,
|
||||
engine: &'a EthEngine,
|
||||
accounts: Option<&'a AccountProvider>,
|
||||
accounts: &'a LocalAccounts,
|
||||
refuse_service_transactions: bool,
|
||||
) -> Self {
|
||||
let best_block_header = chain.best_block_header();
|
||||
@@ -151,7 +151,7 @@ impl<'a, C: 'a> pool::client::Client for PoolClient<'a, C> where
|
||||
pool::client::AccountDetails {
|
||||
nonce: self.cached_nonces.account_nonce(address),
|
||||
balance: self.chain.latest_balance(address),
|
||||
is_local: self.accounts.map_or(false, |accounts| accounts.has_account(*address)),
|
||||
is_local: self.accounts.is_local(address),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user