2019-01-07 11:33:07 +01:00
|
|
|
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
|
|
|
|
// This file is part of Parity Ethereum.
|
2016-07-19 09:21:41 +02:00
|
|
|
|
2019-01-07 11:33:07 +01:00
|
|
|
// Parity Ethereum is free software: you can redistribute it and/or modify
|
2016-07-19 09:21:41 +02:00
|
|
|
// 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.
|
|
|
|
|
2019-01-07 11:33:07 +01:00
|
|
|
// Parity Ethereum is distributed in the hope that it will be useful,
|
2016-07-19 09:21:41 +02:00
|
|
|
// 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
|
2019-01-07 11:33:07 +01:00
|
|
|
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
2016-07-19 09:21:41 +02:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
use std::{collections::BTreeMap, sync::Arc};
|
2018-04-13 17:34:27 +02:00
|
|
|
|
2019-01-04 14:05:46 +01:00
|
|
|
use blockchain::{BlockReceipts, TreeRoute};
|
|
|
|
use bytes::Bytes;
|
2019-01-16 19:52:21 +01:00
|
|
|
use call_contract::{CallContract, RegistryInfo};
|
2019-01-04 14:05:46 +01:00
|
|
|
use ethcore_miner::pool::VerifiedTransaction;
|
2020-08-05 06:08:03 +02:00
|
|
|
use ethereum_types::{Address, H256, U256};
|
2019-01-04 14:05:46 +01:00
|
|
|
use evm::Schedule;
|
2017-08-17 16:05:26 +02:00
|
|
|
use itertools::Itertools;
|
2019-01-04 14:05:46 +01:00
|
|
|
use kvdb::DBValue;
|
2020-08-05 06:08:03 +02:00
|
|
|
use types::{
|
|
|
|
basic_account::BasicAccount,
|
|
|
|
block_status::BlockStatus,
|
|
|
|
blockchain_info::BlockChainInfo,
|
|
|
|
call_analytics::CallAnalytics,
|
|
|
|
data_format::DataFormat,
|
|
|
|
encoded,
|
|
|
|
filter::Filter,
|
|
|
|
header::Header,
|
|
|
|
ids::*,
|
|
|
|
log_entry::LocalizedLogEntry,
|
|
|
|
pruning_info::PruningInfo,
|
|
|
|
receipt::LocalizedReceipt,
|
|
|
|
trace_filter::Filter as TraceFilter,
|
|
|
|
transaction::{self, LocalizedTransaction, SignedTransaction},
|
|
|
|
BlockNumber,
|
|
|
|
};
|
2019-01-04 14:05:46 +01:00
|
|
|
use vm::LastHashes;
|
2017-07-12 13:09:17 +02:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
use block::{ClosedBlock, OpenBlock, SealedBlock};
|
2018-06-06 14:14:45 +02:00
|
|
|
use client::Mode;
|
2019-01-04 14:05:46 +01:00
|
|
|
use engines::EthEngine;
|
|
|
|
use error::{Error, EthcoreResult};
|
|
|
|
use executed::CallError;
|
2016-07-19 09:21:41 +02:00
|
|
|
use executive::Executed;
|
2019-01-04 14:05:46 +01:00
|
|
|
use state::StateInfo;
|
2017-07-12 13:09:17 +02:00
|
|
|
use trace::LocalizedTrace;
|
2020-08-05 06:08:03 +02:00
|
|
|
use verification::queue::{kind::blocks::Unverified, QueueInfo as BlockQueueInfo};
|
2016-07-19 09:21:41 +02:00
|
|
|
|
2018-03-03 18:42:13 +01:00
|
|
|
/// State information to be used during client query
|
|
|
|
pub enum StateOrBlock {
|
2020-08-05 06:08:03 +02:00
|
|
|
/// State to be used, may be pending
|
2020-07-29 10:36:15 +02:00
|
|
|
State(Box<dyn StateInfo>),
|
2018-03-03 18:42:13 +01:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Id of an existing block from a chain to get state from
|
|
|
|
Block(BlockId),
|
2018-03-03 18:42:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<S: StateInfo + 'static> From<S> for StateOrBlock {
|
2020-08-05 06:08:03 +02:00
|
|
|
fn from(info: S) -> StateOrBlock {
|
|
|
|
StateOrBlock::State(Box::new(info) as Box<_>)
|
|
|
|
}
|
2018-03-03 18:42:13 +01:00
|
|
|
}
|
|
|
|
|
2020-07-29 10:36:15 +02:00
|
|
|
impl From<Box<dyn StateInfo>> for StateOrBlock {
|
|
|
|
fn from(info: Box<dyn StateInfo>) -> StateOrBlock {
|
2020-08-05 06:08:03 +02:00
|
|
|
StateOrBlock::State(info)
|
|
|
|
}
|
2018-03-03 18:42:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
impl From<BlockId> for StateOrBlock {
|
2020-08-05 06:08:03 +02:00
|
|
|
fn from(id: BlockId) -> StateOrBlock {
|
|
|
|
StateOrBlock::Block(id)
|
|
|
|
}
|
2018-03-03 18:42:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Provides `nonce` and `latest_nonce` methods
|
|
|
|
pub trait Nonce {
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Attempt to get address nonce at given block.
|
|
|
|
/// May not fail on BlockId::Latest.
|
|
|
|
fn nonce(&self, address: &Address, id: BlockId) -> Option<U256>;
|
|
|
|
|
|
|
|
/// Get address nonce at the latest block's state.
|
|
|
|
fn latest_nonce(&self, address: &Address) -> U256 {
|
|
|
|
self.nonce(address, BlockId::Latest).expect(
|
|
|
|
"nonce will return Some when given BlockId::Latest. nonce was given BlockId::Latest. \
|
|
|
|
Therefore nonce has returned Some; qed",
|
|
|
|
)
|
|
|
|
}
|
2018-03-03 18:42:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Provides `balance` and `latest_balance` methods
|
|
|
|
pub trait Balance {
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Get address balance at the given block's state.
|
|
|
|
///
|
|
|
|
/// May not return None if given BlockId::Latest.
|
|
|
|
/// Returns None if and only if the block's root hash has been pruned from the DB.
|
|
|
|
fn balance(&self, address: &Address, state: StateOrBlock) -> Option<U256>;
|
|
|
|
|
|
|
|
/// Get address balance at the latest block's state.
|
|
|
|
fn latest_balance(&self, address: &Address) -> U256 {
|
|
|
|
self.balance(address, BlockId::Latest.into()).expect(
|
|
|
|
"balance will return Some if given BlockId::Latest. balance was given BlockId::Latest \
|
|
|
|
Therefore balance has returned Some; qed",
|
|
|
|
)
|
|
|
|
}
|
2018-03-03 18:42:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Provides methods to access account info
|
|
|
|
pub trait AccountData: Nonce + Balance {}
|
|
|
|
|
|
|
|
/// Provides `chain_info` method
|
|
|
|
pub trait ChainInfo {
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Get blockchain information.
|
|
|
|
fn chain_info(&self) -> BlockChainInfo;
|
2018-03-03 18:42:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Provides various information on a block by it's ID
|
|
|
|
pub trait BlockInfo {
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Get raw block header data by block id.
|
|
|
|
fn block_header(&self, id: BlockId) -> Option<encoded::Header>;
|
2016-07-19 09:21:41 +02:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Get the best block header.
|
|
|
|
fn best_block_header(&self) -> Header;
|
2018-03-03 18:42:13 +01:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Get raw block data by block header hash.
|
|
|
|
fn block(&self, id: BlockId) -> Option<encoded::Block>;
|
2018-03-03 18:42:13 +01:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Get address code hash at given block's state.
|
|
|
|
fn code_hash(&self, address: &Address, id: BlockId) -> Option<H256>;
|
2018-03-03 18:42:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Provides various information on a transaction by it's ID
|
|
|
|
pub trait TransactionInfo {
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Get the hash of block that contains the transaction, if any.
|
|
|
|
fn transaction_block(&self, id: TransactionId) -> Option<H256>;
|
2018-03-03 18:42:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Provides methods to access chain state
|
|
|
|
pub trait StateClient {
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Type representing chain state
|
|
|
|
type State: StateInfo;
|
|
|
|
|
|
|
|
/// Get a copy of the best block's state and header.
|
|
|
|
fn latest_state_and_header(&self) -> (Self::State, Header);
|
|
|
|
|
|
|
|
/// Attempt to get a copy of a specific block's final state.
|
|
|
|
///
|
|
|
|
/// This will not fail if given BlockId::Latest.
|
|
|
|
/// Otherwise, this can fail (but may not) if the DB prunes state or the block
|
|
|
|
/// is unknown.
|
|
|
|
fn state_at(&self, id: BlockId) -> Option<Self::State>;
|
2018-03-03 18:42:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Provides various blockchain information, like block header, chain state etc.
|
|
|
|
pub trait BlockChain: ChainInfo + BlockInfo + TransactionInfo {}
|
|
|
|
|
|
|
|
// FIXME Why these methods belong to BlockChainClient and not MiningBlockChainClient?
|
|
|
|
/// Provides methods to import block into blockchain
|
|
|
|
pub trait ImportBlock {
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Import a block into the blockchain.
|
|
|
|
fn import_block(&self, block: Unverified) -> EthcoreResult<H256>;
|
2018-03-03 18:42:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Provides `call` and `call_many` methods
|
|
|
|
pub trait Call {
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Type representing chain state
|
|
|
|
type State: StateInfo;
|
2018-03-03 18:42:13 +01:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Makes a non-persistent transaction call.
|
|
|
|
fn call(
|
|
|
|
&self,
|
|
|
|
tx: &SignedTransaction,
|
|
|
|
analytics: CallAnalytics,
|
|
|
|
state: &mut Self::State,
|
|
|
|
header: &Header,
|
|
|
|
) -> Result<Executed, CallError>;
|
|
|
|
|
|
|
|
/// Makes multiple non-persistent but dependent transaction calls.
|
|
|
|
/// Returns a vector of successes or a failure if any of the transaction fails.
|
|
|
|
fn call_many(
|
|
|
|
&self,
|
|
|
|
txs: &[(SignedTransaction, CallAnalytics)],
|
|
|
|
state: &mut Self::State,
|
|
|
|
header: &Header,
|
|
|
|
) -> Result<Vec<Executed>, CallError>;
|
2018-03-03 18:42:13 +01:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Estimates how much gas will be necessary for a call.
|
|
|
|
fn estimate_gas(
|
|
|
|
&self,
|
|
|
|
t: &SignedTransaction,
|
|
|
|
state: &Self::State,
|
|
|
|
header: &Header,
|
|
|
|
) -> Result<U256, CallError>;
|
2018-03-03 18:42:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Provides `engine` method
|
|
|
|
pub trait EngineInfo {
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Get underlying engine object
|
2020-07-29 10:36:15 +02:00
|
|
|
fn engine(&self) -> &dyn EthEngine;
|
2018-03-03 18:42:13 +01:00
|
|
|
}
|
|
|
|
|
2018-05-09 08:49:34 +02:00
|
|
|
/// IO operations that should off-load heavy work to another thread.
|
|
|
|
pub trait IoClient: Sync + Send {
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Queue transactions for importing.
|
|
|
|
fn queue_transactions(&self, transactions: Vec<Bytes>, peer_id: usize);
|
2018-05-09 08:49:34 +02:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Queue block import with transaction receipts. Does no sealing and transaction validation.
|
|
|
|
fn queue_ancient_block(
|
|
|
|
&self,
|
|
|
|
block_bytes: Unverified,
|
|
|
|
receipts_bytes: Bytes,
|
|
|
|
) -> EthcoreResult<H256>;
|
2018-05-09 08:49:34 +02:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Queue conensus engine message.
|
|
|
|
fn queue_consensus_message(&self, message: Bytes);
|
2018-05-09 08:49:34 +02:00
|
|
|
}
|
|
|
|
|
2018-09-08 04:04:28 +02:00
|
|
|
/// Provides recently seen bad blocks.
|
|
|
|
pub trait BadBlocks {
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Returns a list of blocks that were recently not imported because they were invalid.
|
|
|
|
fn bad_blocks(&self) -> Vec<(Unverified, String)>;
|
2018-09-08 04:04:28 +02:00
|
|
|
}
|
|
|
|
|
2018-03-03 18:42:13 +01:00
|
|
|
/// Blockchain database client. Owns and manages a blockchain and a block queue.
|
2020-08-05 06:08:03 +02:00
|
|
|
pub trait BlockChainClient:
|
|
|
|
Sync
|
|
|
|
+ Send
|
|
|
|
+ AccountData
|
|
|
|
+ BlockChain
|
|
|
|
+ CallContract
|
|
|
|
+ RegistryInfo
|
|
|
|
+ ImportBlock
|
|
|
|
+ IoClient
|
|
|
|
+ BadBlocks
|
|
|
|
{
|
|
|
|
/// Look up the block number for the given block ID.
|
|
|
|
fn block_number(&self, id: BlockId) -> Option<BlockNumber>;
|
|
|
|
|
|
|
|
/// Get raw block body data by block id.
|
|
|
|
/// Block body is an RLP list of two items: uncles and transactions.
|
|
|
|
fn block_body(&self, id: BlockId) -> Option<encoded::Body>;
|
|
|
|
|
|
|
|
/// Get block status by block header hash.
|
|
|
|
fn block_status(&self, id: BlockId) -> BlockStatus;
|
|
|
|
|
|
|
|
/// Get block total difficulty.
|
|
|
|
fn block_total_difficulty(&self, id: BlockId) -> Option<U256>;
|
|
|
|
|
|
|
|
/// Attempt to get address storage root at given block.
|
|
|
|
/// May not fail on BlockId::Latest.
|
|
|
|
fn storage_root(&self, address: &Address, id: BlockId) -> Option<H256>;
|
|
|
|
|
|
|
|
/// Get block hash.
|
|
|
|
fn block_hash(&self, id: BlockId) -> Option<H256>;
|
|
|
|
|
|
|
|
/// Get address code at given block's state.
|
|
|
|
fn code(&self, address: &Address, state: StateOrBlock) -> Option<Option<Bytes>>;
|
|
|
|
|
|
|
|
/// Get address code at the latest block's state.
|
|
|
|
fn latest_code(&self, address: &Address) -> Option<Bytes> {
|
|
|
|
self.code(address, BlockId::Latest.into())
|
|
|
|
.expect("code will return Some if given BlockId::Latest; qed")
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Get address code hash at given block's state.
|
|
|
|
|
|
|
|
/// Get value of the storage at given position at the given block's state.
|
|
|
|
///
|
|
|
|
/// May not return None if given BlockId::Latest.
|
|
|
|
/// Returns None if and only if the block's root hash has been pruned from the DB.
|
|
|
|
fn storage_at(&self, address: &Address, position: &H256, state: StateOrBlock) -> Option<H256>;
|
|
|
|
|
|
|
|
/// Get value of the storage at given position at the latest block's state.
|
|
|
|
fn latest_storage_at(&self, address: &Address, position: &H256) -> H256 {
|
|
|
|
self.storage_at(address, position, BlockId::Latest.into())
|
2016-12-09 23:01:43 +01:00
|
|
|
.expect("storage_at will return Some if given BlockId::Latest. storage_at was given BlockId::Latest. \
|
2016-07-19 09:21:41 +02:00
|
|
|
Therefore storage_at has returned Some; qed")
|
2020-08-05 06:08:03 +02:00
|
|
|
}
|
2016-07-19 09:21:41 +02:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Get a list of all accounts in the block `id`, if fat DB is in operation, otherwise `None`.
|
|
|
|
/// If `after` is set the list starts with the following item.
|
|
|
|
fn list_accounts(
|
|
|
|
&self,
|
|
|
|
id: BlockId,
|
|
|
|
after: Option<&Address>,
|
|
|
|
count: u64,
|
|
|
|
) -> Option<Vec<Address>>;
|
|
|
|
|
|
|
|
/// Get a list of all storage keys in the block `id`, if fat DB is in operation, otherwise `None`.
|
|
|
|
/// If `after` is set the list starts with the following item.
|
|
|
|
fn list_storage(
|
|
|
|
&self,
|
|
|
|
id: BlockId,
|
|
|
|
account: &Address,
|
|
|
|
after: Option<&H256>,
|
|
|
|
count: u64,
|
|
|
|
) -> Option<Vec<H256>>;
|
2016-10-03 11:13:10 +02:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Get transaction with given hash.
|
|
|
|
fn transaction(&self, id: TransactionId) -> Option<LocalizedTransaction>;
|
2016-07-19 09:21:41 +02:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Get uncle with given id.
|
|
|
|
fn uncle(&self, id: UncleId) -> Option<encoded::Header>;
|
2016-07-19 09:21:41 +02:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Get transaction receipt with given hash.
|
|
|
|
fn transaction_receipt(&self, id: TransactionId) -> Option<LocalizedReceipt>;
|
2016-07-19 09:21:41 +02:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Get localized receipts for all transaction in given block.
|
|
|
|
fn localized_block_receipts(&self, id: BlockId) -> Option<Vec<LocalizedReceipt>>;
|
2018-09-25 19:06:14 +02:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Get a tree route between `from` and `to`.
|
|
|
|
/// See `BlockChain::tree_route`.
|
|
|
|
fn tree_route(&self, from: &H256, to: &H256) -> Option<TreeRoute>;
|
2016-07-19 09:21:41 +02:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Get all possible uncle hashes for a block.
|
|
|
|
fn find_uncles(&self, hash: &H256) -> Option<Vec<H256>>;
|
2016-07-19 09:21:41 +02:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Get block receipts data by block header hash.
|
|
|
|
fn block_receipts(&self, hash: &H256) -> Option<BlockReceipts>;
|
2016-07-19 09:21:41 +02:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Get block queue information.
|
|
|
|
fn queue_info(&self) -> BlockQueueInfo;
|
2016-07-19 09:21:41 +02:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Returns true if block queue is empty.
|
|
|
|
fn is_queue_empty(&self) -> bool {
|
|
|
|
self.queue_info().is_empty()
|
|
|
|
}
|
2018-11-28 11:30:05 +01:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Clear block queue and abort all import activity.
|
|
|
|
fn clear_queue(&self);
|
2016-07-19 09:21:41 +02:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Get the registrar address, if it exists.
|
|
|
|
fn additional_params(&self) -> BTreeMap<String, String>;
|
2016-08-17 19:25:02 +02:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Returns logs matching given filter. If one of the filtering block cannot be found, returns the block id that caused the error.
|
|
|
|
fn logs(&self, filter: Filter) -> Result<Vec<LocalizedLogEntry>, BlockId>;
|
2016-07-19 09:21:41 +02:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Replays a given transaction for inspection.
|
|
|
|
fn replay(&self, t: TransactionId, analytics: CallAnalytics) -> Result<Executed, CallError>;
|
2016-07-19 09:21:41 +02:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Replays all the transactions in a given block for inspection.
|
|
|
|
fn replay_block_transactions(
|
|
|
|
&self,
|
|
|
|
block: BlockId,
|
|
|
|
analytics: CallAnalytics,
|
2020-07-29 10:36:15 +02:00
|
|
|
) -> Result<Box<dyn Iterator<Item = (H256, Executed)>>, CallError>;
|
2018-01-10 11:34:34 +01:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Returns traces matching given filter.
|
|
|
|
fn filter_traces(&self, filter: TraceFilter) -> Option<Vec<LocalizedTrace>>;
|
2016-07-19 09:21:41 +02:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Returns trace with given id.
|
|
|
|
fn trace(&self, trace: TraceId) -> Option<LocalizedTrace>;
|
2016-07-19 09:21:41 +02:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Returns traces created by transaction.
|
|
|
|
fn transaction_traces(&self, trace: TransactionId) -> Option<Vec<LocalizedTrace>>;
|
2016-07-19 09:21:41 +02:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Returns traces created by transaction from block.
|
|
|
|
fn block_traces(&self, trace: BlockId) -> Option<Vec<LocalizedTrace>>;
|
2016-07-19 09:21:41 +02:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Get last hashes starting from best block.
|
|
|
|
fn last_hashes(&self) -> LastHashes;
|
2016-07-19 09:21:41 +02:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// List all ready transactions that should be propagated to other peers.
|
|
|
|
fn transactions_to_propagate(&self) -> Vec<Arc<VerifiedTransaction>>;
|
2016-07-19 09:21:41 +02:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Sorted list of transaction gas prices from at least last sample_size blocks.
|
|
|
|
fn gas_price_corpus(&self, sample_size: usize) -> ::stats::Corpus<U256> {
|
|
|
|
let mut h = self.chain_info().best_block_hash;
|
|
|
|
let mut corpus = Vec::new();
|
|
|
|
while corpus.is_empty() {
|
|
|
|
for _ in 0..sample_size {
|
|
|
|
let block = match self.block(BlockId::Hash(h)) {
|
|
|
|
Some(block) => block,
|
|
|
|
None => return corpus.into(),
|
|
|
|
};
|
2017-02-17 16:18:31 +01:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
if block.number() == 0 {
|
|
|
|
return corpus.into();
|
|
|
|
}
|
|
|
|
block
|
|
|
|
.transaction_views()
|
|
|
|
.iter()
|
|
|
|
.foreach(|t| corpus.push(t.gas_price()));
|
|
|
|
h = block.parent_hash().clone();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
corpus.into()
|
|
|
|
}
|
2016-10-31 16:58:35 +01:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Get the preferred chain ID to sign on
|
|
|
|
fn signing_chain_id(&self) -> Option<u64>;
|
2016-11-03 22:22:25 +01:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Get the mode.
|
|
|
|
fn mode(&self) -> Mode;
|
2016-10-31 16:58:35 +01:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Set the mode.
|
|
|
|
fn set_mode(&self, mode: Mode);
|
2016-11-04 17:35:02 +01:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Get the chain spec name.
|
|
|
|
fn spec_name(&self) -> String;
|
2017-03-13 12:10:53 +01:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Set the chain via a spec name.
|
|
|
|
fn set_spec_name(&self, spec_name: String) -> Result<(), ()>;
|
2017-03-13 12:10:53 +01:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Disable the client from importing blocks. This cannot be undone in this session and indicates
|
|
|
|
/// that a subsystem has reason to believe this executable incapable of syncing the chain.
|
|
|
|
fn disable(&self);
|
2016-12-11 16:52:41 +01:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Returns engine-related extra info for `BlockId`.
|
|
|
|
fn block_extra_info(&self, id: BlockId) -> Option<BTreeMap<String, String>>;
|
2016-11-04 17:35:02 +01:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Returns engine-related extra info for `UncleId`.
|
|
|
|
fn uncle_extra_info(&self, id: UncleId) -> Option<BTreeMap<String, String>>;
|
2016-11-09 23:25:54 +01:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Returns information about pruning/data availability.
|
|
|
|
fn pruning_info(&self) -> PruningInfo;
|
2016-12-10 23:58:39 +01:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Schedule state-altering transaction to be executed on the next pending block.
|
|
|
|
fn transact_contract(&self, address: Address, data: Bytes) -> Result<(), transaction::Error>;
|
2017-01-24 10:03:58 +01:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Get the address of the registry itself.
|
|
|
|
fn registrar_address(&self) -> Option<Address>;
|
2016-07-19 09:21:41 +02:00
|
|
|
}
|
|
|
|
|
2018-03-03 18:42:13 +01:00
|
|
|
/// Provides `reopen_block` method
|
|
|
|
pub trait ReopenBlock {
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Reopens an OpenBlock and updates uncles.
|
|
|
|
fn reopen_block(&self, block: ClosedBlock) -> OpenBlock;
|
2018-03-03 18:42:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Provides `prepare_open_block` method
|
|
|
|
pub trait PrepareOpenBlock {
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Returns OpenBlock prepared for closing.
|
|
|
|
fn prepare_open_block(
|
|
|
|
&self,
|
|
|
|
author: Address,
|
|
|
|
gas_range_target: (U256, U256),
|
|
|
|
extra_data: Bytes,
|
|
|
|
) -> Result<OpenBlock, Error>;
|
2018-03-03 18:42:13 +01:00
|
|
|
}
|
2017-07-10 13:36:42 +02:00
|
|
|
|
2018-03-03 18:42:13 +01:00
|
|
|
/// Provides methods used for sealing new state
|
|
|
|
pub trait BlockProducer: PrepareOpenBlock + ReopenBlock {}
|
2016-07-19 09:21:41 +02:00
|
|
|
|
2018-03-03 18:42:13 +01:00
|
|
|
/// Provides `latest_schedule` method
|
|
|
|
pub trait ScheduleInfo {
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Returns latest schedule.
|
|
|
|
fn latest_schedule(&self) -> Schedule;
|
2018-03-03 18:42:13 +01:00
|
|
|
}
|
2016-12-08 12:03:34 +01:00
|
|
|
|
2018-03-03 18:42:13 +01:00
|
|
|
///Provides `import_sealed_block` method
|
|
|
|
pub trait ImportSealedBlock {
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Import sealed block. Skips all verifications.
|
|
|
|
fn import_sealed_block(&self, block: SealedBlock) -> EthcoreResult<H256>;
|
2018-03-03 18:42:13 +01:00
|
|
|
}
|
2016-10-28 16:42:24 +02:00
|
|
|
|
2018-03-03 18:42:13 +01:00
|
|
|
/// Provides `broadcast_proposal_block` method
|
|
|
|
pub trait BroadcastProposalBlock {
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Broadcast a block proposal.
|
|
|
|
fn broadcast_proposal_block(&self, block: SealedBlock);
|
2018-03-03 18:42:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Provides methods to import sealed block and broadcast a block proposal
|
|
|
|
pub trait SealedBlockImporter: ImportSealedBlock + BroadcastProposalBlock {}
|
2017-12-21 21:42:36 +01:00
|
|
|
|
2019-11-11 21:57:38 +01:00
|
|
|
/// Do we want to force update sealing?
|
|
|
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
|
|
|
pub enum ForceUpdateSealing {
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Ideally you want to use `No` at all times as `Yes` skips `reseal_required` checks.
|
|
|
|
Yes,
|
|
|
|
/// Don't skip `reseal_required` checks
|
|
|
|
No,
|
2019-11-11 21:57:38 +01:00
|
|
|
}
|
|
|
|
|
2017-01-10 12:23:59 +01:00
|
|
|
/// Client facilities used by internally sealing Engines.
|
2018-03-03 18:42:13 +01:00
|
|
|
pub trait EngineClient: Sync + Send + ChainInfo {
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Make a new block and seal it.
|
|
|
|
fn update_sealing(&self, force: ForceUpdateSealing);
|
2017-01-10 12:23:59 +01:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Submit a seal for a block in the mining queue.
|
|
|
|
fn submit_seal(&self, block_hash: H256, seal: Vec<Bytes>);
|
2017-01-10 12:23:59 +01:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Broadcast a consensus message to the network.
|
|
|
|
fn broadcast_consensus_message(&self, message: Bytes);
|
2017-06-28 13:17:36 +02:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Get the transition to the epoch the given parent hash is part of
|
|
|
|
/// or transitions to.
|
|
|
|
/// This will give the epoch that any children of this parent belong to.
|
|
|
|
///
|
|
|
|
/// The block corresponding the the parent hash must be stored already.
|
|
|
|
fn epoch_transition_for(&self, parent_hash: H256) -> Option<::engines::EpochTransition>;
|
2017-09-05 17:54:05 +02:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Attempt to cast the engine client to a full client.
|
2020-07-29 10:36:15 +02:00
|
|
|
fn as_full_client(&self) -> Option<&dyn BlockChainClient>;
|
2017-09-05 17:54:05 +02:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Get a block number by ID.
|
|
|
|
fn block_number(&self, id: BlockId) -> Option<BlockNumber>;
|
2018-02-15 01:39:29 +01:00
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Get raw block header data by block id.
|
|
|
|
fn block_header(&self, id: BlockId) -> Option<encoded::Header>;
|
2017-01-10 12:23:59 +01:00
|
|
|
}
|
|
|
|
|
2016-12-05 16:55:33 +01:00
|
|
|
/// Extended client interface for providing proofs of the state.
|
|
|
|
pub trait ProvingBlockChainClient: BlockChainClient {
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Prove account storage at a specific block id.
|
|
|
|
///
|
|
|
|
/// Both provided keys assume a secure trie.
|
|
|
|
/// Returns a vector of raw trie nodes (in order from the root) proving the storage query.
|
|
|
|
fn prove_storage(&self, key1: H256, key2: H256, id: BlockId) -> Option<(Vec<Bytes>, H256)>;
|
|
|
|
|
|
|
|
/// Prove account existence at a specific block id.
|
|
|
|
/// The key is the keccak hash of the account's address.
|
|
|
|
/// Returns a vector of raw trie nodes (in order from the root) proving the query.
|
|
|
|
fn prove_account(&self, key1: H256, id: BlockId) -> Option<(Vec<Bytes>, BasicAccount)>;
|
|
|
|
|
|
|
|
/// Prove execution of a transaction at the given block.
|
|
|
|
/// Returns the output of the call and a vector of database items necessary
|
|
|
|
/// to reproduce it.
|
|
|
|
fn prove_transaction(
|
|
|
|
&self,
|
|
|
|
transaction: SignedTransaction,
|
|
|
|
id: BlockId,
|
|
|
|
) -> Option<(Bytes, Vec<DBValue>)>;
|
|
|
|
|
|
|
|
/// Get an epoch change signal by block hash.
|
|
|
|
fn epoch_signal(&self, hash: H256) -> Option<Vec<u8>>;
|
2016-12-10 14:56:41 +01:00
|
|
|
}
|
2019-01-16 16:37:26 +01:00
|
|
|
|
|
|
|
/// resets the blockchain
|
|
|
|
pub trait BlockChainReset {
|
2020-08-05 06:08:03 +02:00
|
|
|
/// reset to best_block - n
|
|
|
|
fn reset(&self, num: u32) -> Result<(), String>;
|
2019-01-16 16:37:26 +01:00
|
|
|
}
|
2019-11-11 21:57:38 +01:00
|
|
|
|
|
|
|
/// Provides a method for importing/exporting blocks
|
|
|
|
pub trait ImportExportBlocks {
|
|
|
|
/// Export blocks to destination, with the given from, to and format argument.
|
|
|
|
/// destination could be a file or stdout.
|
|
|
|
/// If the format is hex, each block is written on a new line.
|
|
|
|
/// For binary exports, all block data is written to the same line.
|
2020-08-05 06:08:03 +02:00
|
|
|
fn export_blocks<'a>(
|
2019-11-11 21:57:38 +01:00
|
|
|
&self,
|
|
|
|
destination: Box<dyn std::io::Write + 'a>,
|
|
|
|
from: BlockId,
|
|
|
|
to: BlockId,
|
2020-08-05 06:08:03 +02:00
|
|
|
format: Option<DataFormat>,
|
2019-11-11 21:57:38 +01:00
|
|
|
) -> Result<(), String>;
|
|
|
|
|
2020-08-05 06:08:03 +02:00
|
|
|
/// Import blocks from destination, with the given format argument
|
|
|
|
/// Source could be a file or stdout.
|
|
|
|
/// For hex format imports, it attempts to read the blocks on a line by line basis.
|
|
|
|
/// For binary format imports, reads the 8 byte RLP header in order to decode the block
|
|
|
|
/// length to be read.
|
|
|
|
fn import_blocks<'a>(
|
|
|
|
&self,
|
|
|
|
source: Box<dyn std::io::Read + 'a>,
|
|
|
|
format: Option<DataFormat>,
|
|
|
|
) -> Result<(), String>;
|
2019-11-11 21:57:38 +01:00
|
|
|
}
|