// Copyright 2015-2018 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 .
use std::collections::BTreeMap;
use std::sync::Arc;
use itertools::Itertools;
use block::{OpenBlock, SealedBlock, ClosedBlock};
use blockchain::TreeRoute;
use client::Mode;
use encoded;
use vm::LastHashes;
use error::{Error, CallError, EthcoreResult};
use evm::Schedule;
use executive::Executed;
use filter::Filter;
use header::{BlockNumber};
use log_entry::LocalizedLogEntry;
use receipt::LocalizedReceipt;
use trace::LocalizedTrace;
use transaction::{self, LocalizedTransaction, SignedTransaction};
use verification::queue::QueueInfo as BlockQueueInfo;
use verification::queue::kind::blocks::Unverified;
use state::StateInfo;
use header::Header;
use engines::EthEngine;
use ethereum_types::{H256, U256, Address};
use ethcore_miner::pool::VerifiedTransaction;
use bytes::Bytes;
use hashdb::DBValue;
use types::ids::*;
use types::basic_account::BasicAccount;
use types::trace_filter::Filter as TraceFilter;
use types::call_analytics::CallAnalytics;
use types::blockchain_info::BlockChainInfo;
use types::block_status::BlockStatus;
use types::pruning_info::PruningInfo;
/// 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.
fn latest_state(&self) -> Self::State;
/// 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 {}
/// Provides information on a blockchain service and it's registry
pub trait RegistryInfo {
/// Get the address of a particular blockchain service, if available.
fn registry_address(&self, name: String, block: BlockId) -> Option;
}
// 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_contract` method
pub trait CallContract {
/// Like `call`, but with various defaults. Designed to be used for calling contracts.
fn call_contract(&self, id: BlockId, address: Address, data: Bytes) -> Result;
}
/// 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) -> &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