openethereum/rpc/src/v1/impls/light/parity.rs

449 lines
13 KiB
Rust
Raw Normal View History

2017-02-17 21:38:43 +01:00
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Parity-specific rpc implementation.
use std::sync::Arc;
use std::collections::{BTreeMap, HashSet};
use version::version_data;
2017-02-17 21:38:43 +01:00
use crypto::DEFAULT_MAC;
use ethkey::{crypto::ecies, Brain, Generator};
2017-02-17 21:38:43 +01:00
use ethstore::random_phrase;
2018-04-10 12:13:49 +02:00
use sync::LightSyncProvider;
2017-02-17 21:38:43 +01:00
use ethcore::account_provider::AccountProvider;
use ethcore_logger::RotatingLogger;
use node_health::{NodeHealth, Health};
`Client` refactoring (#7038) * Improves `BestBlock` comment * Improves `TraceDB` comment * Improves `journaldb::Algorithm` comment. Probably the whole enum should be renamed to `Strategy` or something alike. * Comments some of the `Client`'s fields * Deglobs client imports * Fixes comments * Extracts `import_lock` to `Importer` struct * Extracts `verifier` to `Importer` struct * Extracts `block_queue` to `Importer` struct * Extracts `miner` to `Importer` struct * Extracts `ancient_verifier` to `Importer` struct * Extracts `rng` to `Importer` struct * Extracts `import_old_block` to `Importer` struct * Adds `Nonce` trait * Adds `Balance` trait * Adds `ChainInfo` trait * Fixes imports for tests using `chain_info` method * Adds `BlockInfo` trait * Adds more `ChainInfo` imports * Adds `BlockInfo` imports * Adds `ReopenBlock` trait * Adds `PrepareOpenBlock` trait * Fixes import in tests * Adds `CallContract` trait * Fixes imports in tests using `call_contract` method * Adds `TransactionInfo` trait * Adds `RegistryInfo` trait * Fixes imports in tests using `registry_address` method * Adds `ScheduleInfo` trait * Adds `ImportSealedBlock` trait * Fixes imports in test using `import_sealed_block` method * Adds `BroadcastProposalBlock` trait * Migrates `Miner` to static dispatch * Fixes tests * Moves `calculate_enacted_retracted` to `Importer` * Moves import-related methods to `Importer` * Removes redundant `import_old_block` wrapper * Extracts `import_block*` into separate trait * Fixes tests * Handles `Pending` in `LightFetch` * Handles `Pending` in filters * Handles `Pending` in `ParityClient` * Handles `Pending` in `EthClient` * Removes `BlockId::Pending`, partly refactors dependent code * Adds `StateInfo` trait * Exports `StateOrBlock` and `BlockChain` types from `client` module * Refactors `balance` RPC using generic API * Refactors `storage_at` RPC using generic API * Makes `MinerService::pending_state`'s return type dynamic * Adds `StateOrBlock` and `BlockChain` types * Adds impl of `client::BlockChain` for `Client` * Exports `StateInfo` trait from `client` module * Missing `self` use To be fixed up to "Adds impl of `client::BlockChain` for `Client`" * Adds `number_to_id` and refactors dependent RPC methods * Refactors `code_at` using generic API * Adds `StateClient` trait * Refactors RPC to use `StateClient` trait * Reverts `client::BlockChain` trait stuff, refactors methods to accept `StateOrBlock` * Refactors TestClient * Adds helper function `block_number_to_id` * Uses `block_number_to_id` instead of local function * Handles `Pending` in `list_accounts` and `list_storage_keys` * Attempt to use associated types for state instead of trait objects * Simplifies `state_at_beginning` * Extracts `call` and `call_many` into separate trait * Refactors `build_last_hashes` to accept reference * Exports `Call` type from the module * Refactors `call` and `call_many` to accept state and header * Exports `state_at` in `StateClient` * Exports `pending_block_header` from `MinerService` * Refactors RPC `call` method using new API * Adds missing parentheses * Refactors `parity::call` to use new call API * Update .gitlab-ci.yml fix gitlab lint * Fixes error handling * Refactors `traces::call` and `call_many` to use new call API * Refactors `call_contract` * Refactors `block_header` * Refactors internal RPC method `block` * Moves `estimate_gas` to `Call` trait, refactors parameters * Refactors `estimate_gas` in RPC * Refactors `uncle` * Refactors RPC `transaction` * Covers missing branches * Makes it all compile, fixes compiler grumbles * Adds casts in `blockchain` module * Fixes `PendingBlock` tests, work on `MinerService` * Adds test stubs for StateClient and EngineInfo * Makes `state_db` public * Adds missing impls for `TestBlockChainClient` * Adds trait documentation * Adds missing docs to the `state_db` module * Fixes trivial compilation errors * Moves `code_hash` method to a `BlockInfo` trait * Refactors `Verifier` to be generic over client * Refactors `TransactionFilter` to be generic over client * Refactors `Miner` and `Client` to reflect changes in verifier and txfilter API * Moves `ServiceTransactionChecker` back to `ethcore` * Fixes trait bounds in `Miner` API * Fixes `Client` * Fixes lifetime bound in `FullFamilyParams` * Adds comments to `FullFamilyParams` * Fixes imports in `ethcore` * Fixes BlockNumber handling in `code_at` and `replay_block_transactions` * fix compile issues * First step to redundant trait merge * Fixes compilation error in RPC tests * Adds mock `State` as a stub for `TestClient` * Handles `StateOrBlock::State` in `TestBlockChainClient::balance` * Fixes `transaction_count` RPC * Fixes `transaction_count` * Moves `service_transaction.json` to the `contracts` subfolder * Fixes compilation errors in tests * Refactors client to use `AccountData` * Refactors client to use `BlockChain` * Refactors miner to use aggregate traits * Adds `SealedBlockImporter` trait * Refactors miner to use `SealedBlockImporter` trait * Removes unused imports * Simplifies `RegistryInfo::registry_address` * Fixes indentation * Removes commented out trait bound
2018-03-03 18:42:13 +01:00
use ethcore::ids::BlockId;
2017-02-17 21:38:43 +01:00
use light::client::LightChainClient;
2017-02-17 21:38:43 +01:00
2017-11-14 11:38:17 +01:00
use jsonrpc_core::{Result, BoxFuture};
use jsonrpc_core::futures::Future;
2017-02-17 21:38:43 +01:00
use jsonrpc_macros::Trailing;
use v1::helpers::{self, errors, ipfs, SigningQueue, SignerService, NetworkSettings};
Secretstore RPCs + integration (#5439) * ECDKG protocol prototype * added test for enc/dec math * get rid of decryption_session * added licenses * fix after merge * get rid of unused serde dependency * doc * decryption session [without commutative enc] * failed_dec_session * fixed tests * added commen * added more decryption session tests * helper to localize an issue * more computations to localize error * decryption_session::SessionParams * added tests for EC math to localize problem * secretstore network transport * encryption_session_works_over_network * network errors processing * connecting to KeyServer * licenses * get rid of debug println-s * fixed secretstore args * encryption results are stored in KS database * decryption protocol works over network * enc/dec Session traits * fixing warnings * fix after merge * on-chain ACL checker proto * fixed compilation * fixed compilation * finally fixed <odd>-of-N-scheme * temporary commented test * 1-of-N works in math * scheme 1-of-N works * updated AclStorage with real contract ABI * remove unnecessary unsafety * fixed grumbles * wakeup on access denied * encrypt secretstore messages * 'shadow' decryption * fix grumbles * lost files * secretstore cli-options * decryption seccion when ACL check failed on master * disallow regenerating key for existing document * removed obsolete TODO * fix after merge * switched to tokio_io * fix after merge * fix after merge * fix after merge * fix after merge * fix after merge * fixed test * fix after merge * encryption session errors are now fatal * session timeouts * autorestart decryption session * remove sessions on completion * exclude disconnected nodes from decryption session * test for enc/dec session over network with 1 node * remove debug printlns * fixed 1-of-1 scheme * drop for KeyServerHttpListener * Use standard encryption and decryption (as in RPC) * added some tests * moved DEFAULT_MAC to ethcrypto * rpc_secretstore_encrypt_and_decrypt * serialization with "0x" prefix (RPC compatibility) * secretstore RPC API * fix after merge * fixed typo * secretstore_shadowDecrypt RPC * enable secretstore RPCs by default * fixed test * SecStore RPCs available without SecStore feature * fixed grumbles * lost files * added password argument to Parity RPCs * update docs * lost file
2017-05-05 15:57:29 +02:00
use v1::helpers::dispatch::LightDispatcher;
use v1::helpers::light_fetch::LightFetch;
2017-02-17 21:38:43 +01:00
use v1::metadata::Metadata;
use v1::traits::Parity;
use v1::types::{
Bytes, U256, U64, H160, H256, H512, CallRequest,
2017-02-17 21:38:43 +01:00
Peers, Transaction, RpcSettings, Histogram,
TransactionStats, LocalTransactionStatus,
BlockNumber, ConsensusCapability, VersionInfo,
OperationsInfo, DappId, ChainStatus,
AccountInfo, HwAccountInfo, Header, RichHeader,
2017-02-17 21:38:43 +01:00
};
2017-09-21 14:52:44 +02:00
use Host;
2017-02-17 21:38:43 +01:00
/// Parity implementation for light client.
pub struct ParityClient {
client: Arc<LightChainClient>,
2017-02-17 21:38:43 +01:00
light_dispatch: Arc<LightDispatcher>,
accounts: Arc<AccountProvider>,
logger: Arc<RotatingLogger>,
settings: Arc<NetworkSettings>,
health: NodeHealth,
2017-02-17 21:38:43 +01:00
signer: Option<Arc<SignerService>>,
2017-09-21 14:52:44 +02:00
dapps_address: Option<Host>,
ws_address: Option<Host>,
eip86_transition: u64,
gas_price_percentile: usize,
2017-02-17 21:38:43 +01:00
}
impl ParityClient {
/// Creates new `ParityClient`.
pub fn new(
client: Arc<LightChainClient>,
2017-02-17 21:38:43 +01:00
light_dispatch: Arc<LightDispatcher>,
accounts: Arc<AccountProvider>,
logger: Arc<RotatingLogger>,
settings: Arc<NetworkSettings>,
health: NodeHealth,
2017-02-17 21:38:43 +01:00
signer: Option<Arc<SignerService>>,
2017-09-21 14:52:44 +02:00
dapps_address: Option<Host>,
ws_address: Option<Host>,
gas_price_percentile: usize,
2017-02-17 21:38:43 +01:00
) -> Self {
ParityClient {
light_dispatch,
accounts,
logger,
settings,
health,
signer,
dapps_address,
ws_address,
eip86_transition: client.eip86_transition(),
client,
gas_price_percentile,
2017-02-17 21:38:43 +01:00
}
}
/// Create a light blockchain data fetcher.
fn fetcher(&self) -> LightFetch {
LightFetch {
client: self.light_dispatch.client.clone(),
on_demand: self.light_dispatch.on_demand.clone(),
sync: self.light_dispatch.sync.clone(),
cache: self.light_dispatch.cache.clone(),
gas_price_percentile: self.gas_price_percentile,
}
}
2017-02-17 21:38:43 +01:00
}
impl Parity for ParityClient {
type Metadata = Metadata;
2017-11-14 11:38:17 +01:00
fn accounts_info(&self, dapp: Trailing<DappId>) -> Result<BTreeMap<H160, AccountInfo>> {
let dapp = dapp.unwrap_or_default();
2017-02-17 21:38:43 +01:00
let store = &self.accounts;
let dapp_accounts = store
.note_dapp_used(dapp.clone().into())
2017-02-20 18:01:29 +01:00
.and_then(|_| store.dapp_addresses(dapp.into()))
.map_err(|e| errors::account("Could not fetch accounts.", e))?
2017-02-17 21:38:43 +01:00
.into_iter().collect::<HashSet<_>>();
let info = store.accounts_info().map_err(|e| errors::account("Could not fetch account info.", e))?;
let other = store.addresses_info();
Ok(info
.into_iter()
.chain(other.into_iter())
.filter(|&(ref a, _)| dapp_accounts.contains(a))
.map(|(a, v)| (H160::from(a), AccountInfo { name: v.name }))
.collect()
)
}
2017-11-14 11:38:17 +01:00
fn hardware_accounts_info(&self) -> Result<BTreeMap<H160, HwAccountInfo>> {
2017-02-17 21:38:43 +01:00
let store = &self.accounts;
let info = store.hardware_accounts_info().map_err(|e| errors::account("Could not fetch account info.", e))?;
Ok(info
.into_iter()
.map(|(a, v)| (H160::from(a), HwAccountInfo { name: v.name, manufacturer: v.meta }))
.collect()
)
}
2017-11-14 11:38:17 +01:00
fn locked_hardware_accounts_info(&self) -> Result<Vec<String>> {
Trezor Support (#6403) * Copy modal from keepkey branch and generalize The keepkey PinMatrix modal needs to be the same for Trezor, but we should probably try to keep it general since it can be used for both. * Add trezor communication code This is a result of much trial-and-error and a couple of dead-ends in how to communicate and wire everything up. Code here is still a bit WIP with lots of debug prints and stuff. The test works though, it is possible to sign a transaction. * Extend the basic lib to allow Trezor This is kind of ugly and needs some cleanup and generalization. I’ve just copy-pasted some things to bring in the trezor wallets. I’ve also had to add a lock to the USB API so that only one thing talks to the USB at once. * Add RPC plumbing needed We need to be able to get “locked” devices from the frontend to figure out if we’re going to display the PinMatrix or not. Then we need to be able to send a pin to a device. * Add logic to query backend for Trezor and display PinMatrix There’s a bug somewhere here because signing a transaction fails if you take too long to press the confirm button on the device. * Change back to paritytech branch As my fork has been merged in. * Converting spaces to tabs, as it should be * Incorporate correct handling of EIP-155 Turns out the Trezor was adjusting the v part of the signature, and we’re already doing that so it was done twice. * Some circular logic here that was incorrect BE-encoded U256 is almost the same as RLP encoded without the size-byte, except for <u8 sized values. What’s really done is BE-encoded U256 and then left-trimmed to the smallest size. Kind of obvious in hindsight. * Resolve issue where not clicking fast enough fails The device will not repeat a ButtonRequest when you read from it, so you need to have a blocking `read` for whatever amount of time that you want to give the user to click. You could also have a shorter timeout but keep retrying for some amount of time, but it would amount to the same thing. * Scan after pin entry to make accepting it faster * Remove ability to cancel pin request * Some slight cleanup * Probe for the correct HID Version to determine padding * Move the PinMatrix from Accounts to Application * Removing unused dependencies * Mistake in copying over stuff from keepkey branch * Simplify FormattedMessage * Move generated code to external crate * Remove ethcore-util dependency * Fix broken import in test This test is useless without a connected Trezor, not sure how to make it useful without one. * Merge branch 'master' into fh-4500-trezor-support # Conflicts: # rpc/src/v1/helpers/dispatch.rs * Ignore test that can't be run without trezor device * Fixing grumbles * Avoiding owning data in RPC method * Checking for overflow in v part of signature * s/network_id/chain_id * Propagating an error from the HID Api * Condensing code a little bit * Fixing UI. * Debugging trezor. * Minor styling tweak * Make message type into an actual type This makes the message type that the RPC message accepts into an actual type as opposed to just a string, based on feedback. Although I’m not 100% sure this has actually improved the situation. Overall I think the hardware wallet interface needs some refactoring love. * Split the trezor RPC endpoint It’s split into two more generic endpoints that should be suitable for any hardware wallets with the same behavior to sit behind. * Reflect RPC method split in javascript * Fix bug with pin entry * Fix deadlock for Ledger * Avoid having a USB lock in just listing locked wallets * Fix javascript issue (see #6509) * Replace Mutex with RwLock * Update Ledger test * Fix typo causing faulty signatures (sometimes) * *Actually* fix tests * Update git submodule Needed to make tests pass * Swap line orders to prevent possible deadlock * Make setPinMatrixRequest an @action
2017-09-14 19:28:43 +02:00
let store = &self.accounts;
Ok(store.locked_hardware_accounts().map_err(|e| errors::account("Error communicating with hardware wallet.", e))?)
}
2017-11-14 11:38:17 +01:00
fn default_account(&self, meta: Self::Metadata) -> Result<H160> {
2017-02-17 21:38:43 +01:00
let dapp_id = meta.dapp_id();
Ok(self.accounts
2017-02-20 18:01:29 +01:00
.dapp_addresses(dapp_id.into())
.ok()
.and_then(|accounts| accounts.get(0).cloned())
.map(|acc| acc.into())
.unwrap_or_default())
2017-02-17 21:38:43 +01:00
}
2017-11-14 11:38:17 +01:00
fn transactions_limit(&self) -> Result<usize> {
2017-02-17 21:38:43 +01:00
Ok(usize::max_value())
}
2017-11-14 11:38:17 +01:00
fn min_gas_price(&self) -> Result<U256> {
2017-02-17 21:38:43 +01:00
Ok(U256::default())
}
2017-11-14 11:38:17 +01:00
fn extra_data(&self) -> Result<Bytes> {
2017-02-17 21:38:43 +01:00
Ok(Bytes::default())
}
2017-11-14 11:38:17 +01:00
fn gas_floor_target(&self) -> Result<U256> {
2017-02-17 21:38:43 +01:00
Ok(U256::default())
}
2017-11-14 11:38:17 +01:00
fn gas_ceil_target(&self) -> Result<U256> {
2017-02-17 21:38:43 +01:00
Ok(U256::default())
}
2017-11-14 11:38:17 +01:00
fn dev_logs(&self) -> Result<Vec<String>> {
2017-02-17 21:38:43 +01:00
let logs = self.logger.logs();
Ok(logs.as_slice().to_owned())
}
2017-11-14 11:38:17 +01:00
fn dev_logs_levels(&self) -> Result<String> {
2017-02-17 21:38:43 +01:00
Ok(self.logger.levels().to_owned())
}
2017-11-14 11:38:17 +01:00
fn net_chain(&self) -> Result<String> {
2017-02-17 21:38:43 +01:00
Ok(self.settings.chain.clone())
}
2017-11-14 11:38:17 +01:00
fn net_peers(&self) -> Result<Peers> {
2017-02-17 21:38:43 +01:00
let peers = self.light_dispatch.sync.peers().into_iter().map(Into::into).collect();
let peer_numbers = self.light_dispatch.sync.peer_numbers();
Ok(Peers {
active: peer_numbers.active,
connected: peer_numbers.connected,
max: peer_numbers.max as u32,
peers: peers,
})
}
2017-11-14 11:38:17 +01:00
fn net_port(&self) -> Result<u16> {
2017-02-17 21:38:43 +01:00
Ok(self.settings.network_port)
}
2017-11-14 11:38:17 +01:00
fn node_name(&self) -> Result<String> {
2017-02-17 21:38:43 +01:00
Ok(self.settings.name.clone())
}
2017-11-14 11:38:17 +01:00
fn registry_address(&self) -> Result<Option<H160>> {
let reg = self.light_dispatch.client.engine().params().registrar;
if reg == Default::default() {
Ok(None)
} else {
Ok(Some(reg.into()))
}
2017-02-17 21:38:43 +01:00
}
2017-11-14 11:38:17 +01:00
fn rpc_settings(&self) -> Result<RpcSettings> {
2017-02-17 21:38:43 +01:00
Ok(RpcSettings {
enabled: self.settings.rpc_enabled,
interface: self.settings.rpc_interface.clone(),
port: self.settings.rpc_port as u64,
})
}
2017-11-14 11:38:17 +01:00
fn default_extra_data(&self) -> Result<Bytes> {
2017-02-17 21:38:43 +01:00
Ok(Bytes::new(version_data()))
}
2017-11-14 11:38:17 +01:00
fn gas_price_histogram(&self) -> BoxFuture<Histogram> {
Box::new(self.light_dispatch.gas_price_corpus()
2017-02-17 21:38:43 +01:00
.and_then(|corpus| corpus.histogram(10).ok_or_else(errors::not_enough_data))
.map(Into::into))
2017-02-17 21:38:43 +01:00
}
2017-11-14 11:38:17 +01:00
fn unsigned_transactions_count(&self) -> Result<usize> {
2017-02-17 21:38:43 +01:00
match self.signer {
None => Err(errors::signer_disabled()),
Some(ref signer) => Ok(signer.len()),
}
}
2017-11-14 11:38:17 +01:00
fn generate_secret_phrase(&self) -> Result<String> {
2017-02-17 21:38:43 +01:00
Ok(random_phrase(12))
}
2017-11-14 11:38:17 +01:00
fn phrase_to_address(&self, phrase: String) -> Result<H160> {
2017-02-17 21:38:43 +01:00
Ok(Brain::new(phrase).generate().unwrap().address().into())
}
2017-11-14 11:38:17 +01:00
fn list_accounts(&self, _: u64, _: Option<H160>, _: Trailing<BlockNumber>) -> Result<Option<Vec<H160>>> {
2017-02-17 21:38:43 +01:00
Err(errors::light_unimplemented(None))
}
2017-11-14 11:38:17 +01:00
fn list_storage_keys(&self, _: H160, _: u64, _: Option<H256>, _: Trailing<BlockNumber>) -> Result<Option<Vec<H256>>> {
2017-02-17 21:38:43 +01:00
Err(errors::light_unimplemented(None))
}
2017-11-14 11:38:17 +01:00
fn encrypt_message(&self, key: H512, phrase: Bytes) -> Result<Bytes> {
2017-02-17 21:38:43 +01:00
ecies::encrypt(&key.into(), &DEFAULT_MAC, &phrase.0)
.map_err(errors::encryption)
2017-02-17 21:38:43 +01:00
.map(Into::into)
}
2017-11-14 11:38:17 +01:00
fn pending_transactions(&self) -> Result<Vec<Transaction>> {
2017-02-17 21:38:43 +01:00
let txq = self.light_dispatch.transaction_queue.read();
let chain_info = self.light_dispatch.client.chain_info();
Ok(
txq.ready_transactions(chain_info.best_block_number, chain_info.best_block_timestamp)
.into_iter()
.map(|tx| Transaction::from_pending(tx, chain_info.best_block_number, self.eip86_transition))
New Transaction Queue implementation (#8074) * Implementation of Verifier, Scoring and Ready. * Queue in progress. * TransactionPool. * Prepare for txpool release. * Miner refactor [WiP] * WiP reworking miner. * Make it compile. * Add some docs. * Split blockchain access to a separate file. * Work on miner API. * Fix ethcore tests. * Refactor miner interface for sealing/work packages. * Implement next nonce. * RPC compiles. * Implement couple of missing methdods for RPC. * Add transaction queue listeners. * Compiles! * Clean-up and parallelize. * Get rid of RefCell in header. * Revert "Get rid of RefCell in header." This reverts commit 0f2424c9b7319a786e1565ea2a8a6d801a21b4fb. * Override Sync requirement. * Fix status display. * Unify logging. * Extract some cheap checks. * Measurements and optimizations. * Fix scoring bug, heap size of bug and add cache * Disable tx queueing and parallel verification. * Make ethcore and ethcore-miner compile again. * Make RPC compile again. * Bunch of txpool tests. * Migrate transaction queue tests. * Nonce Cap * Nonce cap cache and tests. * Remove stale future transactions from the queue. * Optimize scoring and write some tests. * Simple penalization. * Clean up and support for different scoring algorithms. * Add CLI parameters for the new queue. * Remove banning queue. * Disable debug build. * Change per_sender limit to be 1% instead of 5% * Avoid cloning when propagating transactions. * Remove old todo. * Post-review fixes. * Fix miner options default. * Implement back ready transactions for light client. * Get rid of from_pending_block * Pass rejection reason. * Add more details to drop. * Rollback heap size of. * Avoid cloning hashes when propagating and include more details on rejection. * Fix tests. * Introduce nonces cache. * Remove uneccessary hashes allocation. * Lower the mem limit. * Re-enable parallel verification. * Add miner log. Don't check the type if not below min_gas_price. * Add more traces, fix disabling miner. * Fix creating pending blocks twice on AuRa authorities. * Fix tests. * re-use pending blocks in AuRa * Use reseal_min_period to prevent too frequent update_sealing. * Fix log to contain hash not sender. * Optimize local transactions. * Fix aura tests. * Update locks comments. * Get rid of unsafe Sync impl. * Review fixes. * Remove excessive matches. * Fix compilation errors. * Use new pool in private transactions. * Fix private-tx test. * Fix secret store tests. * Actually use gas_floor_target * Fix config tests. * Fix pool tests. * Address grumbles.
2018-04-13 17:34:27 +02:00
.collect::<Vec<_>>()
)
}
fn all_transactions(&self) -> Result<Vec<Transaction>> {
let txq = self.light_dispatch.transaction_queue.read();
let chain_info = self.light_dispatch.client.chain_info();
let current = txq.ready_transactions(chain_info.best_block_number, chain_info.best_block_timestamp);
let future = txq.future_transactions(chain_info.best_block_number, chain_info.best_block_timestamp);
Ok(
current
.into_iter()
.chain(future.into_iter())
.map(|tx| Transaction::from_pending(tx, chain_info.best_block_number, self.eip86_transition))
2017-02-17 21:38:43 +01:00
.collect::<Vec<_>>()
)
}
2017-11-14 11:38:17 +01:00
fn future_transactions(&self) -> Result<Vec<Transaction>> {
2017-02-17 21:38:43 +01:00
let txq = self.light_dispatch.transaction_queue.read();
let chain_info = self.light_dispatch.client.chain_info();
Ok(
txq.future_transactions(chain_info.best_block_number, chain_info.best_block_timestamp)
.into_iter()
.map(|tx| Transaction::from_pending(tx, chain_info.best_block_number, self.eip86_transition))
2017-02-17 21:38:43 +01:00
.collect::<Vec<_>>()
)
}
2017-11-14 11:38:17 +01:00
fn pending_transactions_stats(&self) -> Result<BTreeMap<H256, TransactionStats>> {
2017-02-17 21:38:43 +01:00
let stats = self.light_dispatch.sync.transactions_stats();
Ok(stats.into_iter()
.map(|(hash, stats)| (hash.into(), stats.into()))
.collect()
)
}
2017-11-14 11:38:17 +01:00
fn local_transactions(&self) -> Result<BTreeMap<H256, LocalTransactionStatus>> {
2017-02-17 21:38:43 +01:00
let mut map = BTreeMap::new();
let chain_info = self.light_dispatch.client.chain_info();
let (best_num, best_tm) = (chain_info.best_block_number, chain_info.best_block_timestamp);
let txq = self.light_dispatch.transaction_queue.read();
for pending in txq.ready_transactions(best_num, best_tm) {
map.insert(pending.hash().into(), LocalTransactionStatus::Pending);
}
for future in txq.future_transactions(best_num, best_tm) {
map.insert(future.hash().into(), LocalTransactionStatus::Future);
}
// TODO: other types?
Ok(map)
}
2017-11-14 11:38:17 +01:00
fn dapps_url(&self) -> Result<String> {
helpers::to_url(&self.dapps_address)
2017-02-17 21:38:43 +01:00
.ok_or_else(|| errors::dapps_disabled())
}
2017-11-14 11:38:17 +01:00
fn ws_url(&self) -> Result<String> {
helpers::to_url(&self.ws_address)
.ok_or_else(|| errors::ws_disabled())
2017-02-17 21:38:43 +01:00
}
2017-11-14 11:38:17 +01:00
fn next_nonce(&self, address: H160) -> BoxFuture<U256> {
Box::new(self.light_dispatch.next_nonce(address.into()).map(Into::into))
2017-02-17 21:38:43 +01:00
}
2017-11-14 11:38:17 +01:00
fn mode(&self) -> Result<String> {
2017-02-17 21:38:43 +01:00
Err(errors::light_unimplemented(None))
}
2017-11-14 11:38:17 +01:00
fn chain_id(&self) -> Result<Option<U64>> {
Ok(self.client.signing_chain_id().map(U64::from))
}
2017-11-14 11:38:17 +01:00
fn chain(&self) -> Result<String> {
Ok(self.settings.chain.clone())
}
2017-11-14 11:38:17 +01:00
fn enode(&self) -> Result<String> {
2017-02-17 21:38:43 +01:00
self.light_dispatch.sync.enode().ok_or_else(errors::network_disabled)
}
2017-11-14 11:38:17 +01:00
fn consensus_capability(&self) -> Result<ConsensusCapability> {
2017-02-17 21:38:43 +01:00
Err(errors::light_unimplemented(None))
}
2017-11-14 11:38:17 +01:00
fn version_info(&self) -> Result<VersionInfo> {
2017-02-17 21:38:43 +01:00
Err(errors::light_unimplemented(None))
}
2017-11-14 11:38:17 +01:00
fn releases_info(&self) -> Result<Option<OperationsInfo>> {
2017-02-17 21:38:43 +01:00
Err(errors::light_unimplemented(None))
}
2017-11-14 11:38:17 +01:00
fn chain_status(&self) -> Result<ChainStatus> {
2017-02-17 21:38:43 +01:00
let chain_info = self.light_dispatch.client.chain_info();
let gap = chain_info.ancient_block_number.map(|x| U256::from(x + 1))
.and_then(|first| chain_info.first_block_number.map(|last| (first, U256::from(last))));
Ok(ChainStatus {
block_gap: gap.map(|(x, y)| (x.into(), y.into())),
})
}
2017-11-14 11:38:17 +01:00
fn node_kind(&self) -> Result<::v1::types::NodeKind> {
use ::v1::types::{NodeKind, Availability, Capability};
Ok(NodeKind {
availability: Availability::Personal,
capability: Capability::Light,
})
}
2017-11-14 11:38:17 +01:00
fn block_header(&self, number: Trailing<BlockNumber>) -> BoxFuture<RichHeader> {
use ethcore::encoded;
let engine = self.light_dispatch.client.engine().clone();
let from_encoded = move |encoded: encoded::Header| {
let header = encoded.decode();
let extra_info = engine.extra_info(&header);
RichHeader {
inner: Header {
hash: Some(header.hash().into()),
size: Some(encoded.rlp().as_raw().len().into()),
parent_hash: header.parent_hash().clone().into(),
uncles_hash: header.uncles_hash().clone().into(),
author: header.author().clone().into(),
miner: header.author().clone().into(),
state_root: header.state_root().clone().into(),
transactions_root: header.transactions_root().clone().into(),
receipts_root: header.receipts_root().clone().into(),
number: Some(header.number().into()),
gas_used: header.gas_used().clone().into(),
gas_limit: header.gas_limit().clone().into(),
logs_bloom: header.log_bloom().clone().into(),
timestamp: header.timestamp().into(),
difficulty: header.difficulty().clone().into(),
seal_fields: header.seal().iter().cloned().map(Into::into).collect(),
extra_data: Bytes::new(header.extra_data().clone()),
},
extra_info: extra_info,
}
};
`Client` refactoring (#7038) * Improves `BestBlock` comment * Improves `TraceDB` comment * Improves `journaldb::Algorithm` comment. Probably the whole enum should be renamed to `Strategy` or something alike. * Comments some of the `Client`'s fields * Deglobs client imports * Fixes comments * Extracts `import_lock` to `Importer` struct * Extracts `verifier` to `Importer` struct * Extracts `block_queue` to `Importer` struct * Extracts `miner` to `Importer` struct * Extracts `ancient_verifier` to `Importer` struct * Extracts `rng` to `Importer` struct * Extracts `import_old_block` to `Importer` struct * Adds `Nonce` trait * Adds `Balance` trait * Adds `ChainInfo` trait * Fixes imports for tests using `chain_info` method * Adds `BlockInfo` trait * Adds more `ChainInfo` imports * Adds `BlockInfo` imports * Adds `ReopenBlock` trait * Adds `PrepareOpenBlock` trait * Fixes import in tests * Adds `CallContract` trait * Fixes imports in tests using `call_contract` method * Adds `TransactionInfo` trait * Adds `RegistryInfo` trait * Fixes imports in tests using `registry_address` method * Adds `ScheduleInfo` trait * Adds `ImportSealedBlock` trait * Fixes imports in test using `import_sealed_block` method * Adds `BroadcastProposalBlock` trait * Migrates `Miner` to static dispatch * Fixes tests * Moves `calculate_enacted_retracted` to `Importer` * Moves import-related methods to `Importer` * Removes redundant `import_old_block` wrapper * Extracts `import_block*` into separate trait * Fixes tests * Handles `Pending` in `LightFetch` * Handles `Pending` in filters * Handles `Pending` in `ParityClient` * Handles `Pending` in `EthClient` * Removes `BlockId::Pending`, partly refactors dependent code * Adds `StateInfo` trait * Exports `StateOrBlock` and `BlockChain` types from `client` module * Refactors `balance` RPC using generic API * Refactors `storage_at` RPC using generic API * Makes `MinerService::pending_state`'s return type dynamic * Adds `StateOrBlock` and `BlockChain` types * Adds impl of `client::BlockChain` for `Client` * Exports `StateInfo` trait from `client` module * Missing `self` use To be fixed up to "Adds impl of `client::BlockChain` for `Client`" * Adds `number_to_id` and refactors dependent RPC methods * Refactors `code_at` using generic API * Adds `StateClient` trait * Refactors RPC to use `StateClient` trait * Reverts `client::BlockChain` trait stuff, refactors methods to accept `StateOrBlock` * Refactors TestClient * Adds helper function `block_number_to_id` * Uses `block_number_to_id` instead of local function * Handles `Pending` in `list_accounts` and `list_storage_keys` * Attempt to use associated types for state instead of trait objects * Simplifies `state_at_beginning` * Extracts `call` and `call_many` into separate trait * Refactors `build_last_hashes` to accept reference * Exports `Call` type from the module * Refactors `call` and `call_many` to accept state and header * Exports `state_at` in `StateClient` * Exports `pending_block_header` from `MinerService` * Refactors RPC `call` method using new API * Adds missing parentheses * Refactors `parity::call` to use new call API * Update .gitlab-ci.yml fix gitlab lint * Fixes error handling * Refactors `traces::call` and `call_many` to use new call API * Refactors `call_contract` * Refactors `block_header` * Refactors internal RPC method `block` * Moves `estimate_gas` to `Call` trait, refactors parameters * Refactors `estimate_gas` in RPC * Refactors `uncle` * Refactors RPC `transaction` * Covers missing branches * Makes it all compile, fixes compiler grumbles * Adds casts in `blockchain` module * Fixes `PendingBlock` tests, work on `MinerService` * Adds test stubs for StateClient and EngineInfo * Makes `state_db` public * Adds missing impls for `TestBlockChainClient` * Adds trait documentation * Adds missing docs to the `state_db` module * Fixes trivial compilation errors * Moves `code_hash` method to a `BlockInfo` trait * Refactors `Verifier` to be generic over client * Refactors `TransactionFilter` to be generic over client * Refactors `Miner` and `Client` to reflect changes in verifier and txfilter API * Moves `ServiceTransactionChecker` back to `ethcore` * Fixes trait bounds in `Miner` API * Fixes `Client` * Fixes lifetime bound in `FullFamilyParams` * Adds comments to `FullFamilyParams` * Fixes imports in `ethcore` * Fixes BlockNumber handling in `code_at` and `replay_block_transactions` * fix compile issues * First step to redundant trait merge * Fixes compilation error in RPC tests * Adds mock `State` as a stub for `TestClient` * Handles `StateOrBlock::State` in `TestBlockChainClient::balance` * Fixes `transaction_count` RPC * Fixes `transaction_count` * Moves `service_transaction.json` to the `contracts` subfolder * Fixes compilation errors in tests * Refactors client to use `AccountData` * Refactors client to use `BlockChain` * Refactors miner to use aggregate traits * Adds `SealedBlockImporter` trait * Refactors miner to use `SealedBlockImporter` trait * Removes unused imports * Simplifies `RegistryInfo::registry_address` * Fixes indentation * Removes commented out trait bound
2018-03-03 18:42:13 +01:00
// Note: Here we treat `Pending` as `Latest`.
// Since light clients don't produce pending blocks
// (they don't have state) we can safely fallback to `Latest`.
let id = match number.unwrap_or_default() {
BlockNumber::Num(n) => BlockId::Number(n),
BlockNumber::Earliest => BlockId::Earliest,
BlockNumber::Latest | BlockNumber::Pending => BlockId::Latest,
};
Box::new(self.fetcher().header(id).map(from_encoded))
}
2017-11-14 11:38:17 +01:00
fn ipfs_cid(&self, content: Bytes) -> Result<String> {
ipfs::cid(content)
}
2017-11-14 11:38:17 +01:00
fn call(&self, _meta: Self::Metadata, _requests: Vec<CallRequest>, _block: Trailing<BlockNumber>) -> Result<Vec<Bytes>> {
Err(errors::light_unimplemented(None))
}
2017-11-14 11:38:17 +01:00
fn node_health(&self) -> BoxFuture<Health> {
Box::new(self.health.health()
.map_err(|err| errors::internal("Health API failure.", err)))
}
2017-02-17 21:38:43 +01:00
}