// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity Ethereum.
// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see .
use std::{collections::BTreeMap, sync::Arc};
use blockchain::{BlockReceipts, TreeRoute};
use bytes::Bytes;
use call_contract::{CallContract, RegistryInfo};
use ethcore_miner::pool::VerifiedTransaction;
use ethereum_types::{Address, H256, U256};
use evm::Schedule;
use itertools::Itertools;
use kvdb::DBValue;
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,
};
use vm::LastHashes;
use block::{ClosedBlock, OpenBlock, SealedBlock};
use client::Mode;
use engines::EthEngine;
use error::{Error, EthcoreResult};
use executed::CallError;
use executive::Executed;
use state::StateInfo;
use trace::LocalizedTrace;
use verification::queue::{kind::blocks::Unverified, QueueInfo as BlockQueueInfo};
/// State information to be used during client query
pub enum StateOrBlock {
/// State to be used, may be pending
State(Box),
/// Id of an existing block from a chain to get state from
Block(BlockId),
}
impl From for StateOrBlock {
fn from(info: S) -> StateOrBlock {
StateOrBlock::State(Box::new(info) as Box<_>)
}
}
impl From> for StateOrBlock {
fn from(info: Box) -> StateOrBlock {
StateOrBlock::State(info)
}
}
impl From for StateOrBlock {
fn from(id: BlockId) -> StateOrBlock {
StateOrBlock::Block(id)
}
}
/// Provides `nonce` and `latest_nonce` methods
pub trait Nonce {
/// Attempt to get address nonce at given block.
/// May not fail on BlockId::Latest.
fn nonce(&self, address: &Address, id: BlockId) -> Option;
/// 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",
)
}
}
/// Provides `balance` and `latest_balance` methods
pub trait Balance {
/// 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;
/// 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",
)
}
}
/// Provides methods to access account info
pub trait AccountData: Nonce + Balance {}
/// Provides `chain_info` method
pub trait ChainInfo {
/// Get blockchain information.
fn chain_info(&self) -> BlockChainInfo;
}
/// Provides various information on a block by it's ID
pub trait BlockInfo {
/// Get raw block header data by block id.
fn block_header(&self, id: BlockId) -> Option;
/// Get the best block header.
fn best_block_header(&self) -> Header;
/// Get raw block data by block header hash.
fn block(&self, id: BlockId) -> Option;
/// Get address code hash at given block's state.
fn code_hash(&self, address: &Address, id: BlockId) -> Option;
}
/// Provides various information on a transaction by it's ID
pub trait TransactionInfo {
/// Get the hash of block that contains the transaction, if any.
fn transaction_block(&self, id: TransactionId) -> Option;
}
/// Provides methods to access chain state
pub trait StateClient {
/// 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;
}
/// 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 {
/// Import a block into the blockchain.
fn import_block(&self, block: Unverified) -> EthcoreResult;
}
/// Provides `call` and `call_many` methods
pub trait Call {
/// Type representing chain state
type State: StateInfo;
/// Makes a non-persistent transaction call.
fn call(
&self,
tx: &SignedTransaction,
analytics: CallAnalytics,
state: &mut Self::State,
header: &Header,
) -> Result;
/// 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, CallError>;
/// Estimates how much gas will be necessary for a call.
fn estimate_gas(
&self,
t: &SignedTransaction,
state: &Self::State,
header: &Header,
) -> Result;
}
/// Provides `engine` method
pub trait EngineInfo {
/// Get underlying engine object
fn engine(&self) -> &dyn EthEngine;
}
/// IO operations that should off-load heavy work to another thread.
pub trait IoClient: Sync + Send {
/// Queue transactions for importing.
fn queue_transactions(&self, transactions: Vec, peer_id: usize);
/// Queue block import with transaction receipts. Does no sealing and transaction validation.
fn queue_ancient_block(
&self,
block_bytes: Unverified,
receipts_bytes: Bytes,
) -> EthcoreResult;
/// Queue conensus engine message.
fn queue_consensus_message(&self, message: Bytes);
}
/// Provides recently seen bad blocks.
pub trait BadBlocks {
/// Returns a list of blocks that were recently not imported because they were invalid.
fn bad_blocks(&self) -> Vec<(Unverified, String)>;
}
/// Blockchain database client. Owns and manages a blockchain and a block queue.
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;
/// 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;
/// 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;
/// Attempt to get address storage root at given block.
/// May not fail on BlockId::Latest.
fn storage_root(&self, address: &Address, id: BlockId) -> Option;
/// Get block hash.
fn block_hash(&self, id: BlockId) -> Option;
/// Get address code at given block's state.
fn code(&self, address: &Address, state: StateOrBlock) -> Option