// Copyright 2015-2020 Parity Technologies (UK) Ltd.
// This file is part of Open Ethereum.
// Open 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.
// Open 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 Open Ethereum. If not, see .
use std::{
collections::BTreeMap,
sync::Arc,
};
use account_state::state::StateInfo;
use blockchain::BlockProvider;
use bytes::Bytes;
use call_contract::CallContract;
use registrar::RegistrarClient;
use common_types::{
basic_account::BasicAccount,
block_status::BlockStatus,
blockchain_info::BlockChainInfo,
BlockNumber,
call_analytics::CallAnalytics,
chain_notify::{NewBlocks, ChainMessageType},
client_types::Mode,
encoded,
engines::{epoch::Transition as EpochTransition, machine::Executed},
errors::{EthcoreError, EthcoreResult},
filter::Filter,
header::Header,
ids::{BlockId, TransactionId, TraceId, UncleId},
log_entry::LocalizedLogEntry,
pruning_info::PruningInfo,
receipt::LocalizedReceipt,
trace_filter::Filter as TraceFilter,
transaction::{self, Action, LocalizedTransaction, CallError, SignedTransaction, UnverifiedTransaction},
tree_route::TreeRoute,
verification::{VerificationQueueInfo, Unverified},
};
use ethereum_types::{Address, H256, U256};
use ethcore_db::keys::BlockReceipts;
use ethcore_miner::pool::VerifiedTransaction;
use kvdb::DBValue;
use stats;
use trace::{
FlatTrace,
localized::LocalizedTrace,
VMTrace,
};
use common_types::{
data_format::DataFormat,
client_types::StateResult
};
use vm::{LastHashes, Schedule};
/// 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: 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: Send + Sync {
/// 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 various blockchain information, like block header, chain state etc.
pub trait BlockChain: ChainInfo + BlockInfo + TransactionInfo {}
/// Do we want to force update sealing?
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum ForceUpdateSealing {
/// Ideally you want to use `No` at all times as `Yes` skips `reseal_required` checks.
Yes,
/// Don't skip `reseal_required` checks
No
}
/// Client facilities used by internally sealing Engines.
pub trait EngineClient: Sync + Send + ChainInfo {
/// Make a new block and seal it.
fn update_sealing(&self, force: ForceUpdateSealing);
/// Submit a seal for a block in the mining queue.
fn submit_seal(&self, block_hash: H256, seal: Vec);
/// Broadcast a consensus message to the network.
fn broadcast_consensus_message(&self, message: Bytes);
/// 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;
/// Attempt to cast the engine client to a full client.
fn as_full_client(&self) -> Option<&dyn BlockChainClient>;
/// Get a block number by ID.
fn block_number(&self, id: BlockId) -> Option;
/// Get raw block header data by block id.
fn block_header(&self, id: BlockId) -> Option;
}
/// Provides methods to import block into blockchain
pub trait ImportBlock {
/// Import a block into the blockchain.
fn import_block(&self, block: Unverified) -> EthcoreResult;
/// Triggered by a message from a block queue when the block is ready for insertion.
/// Returns the number of blocks imported.
fn import_verified_blocks(&self) -> usize;
}
/// 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 consensus engine message.
fn queue_consensus_message(&self, message: Bytes);
}
/// Implement this for clients that need logic to decide when/how to advance.
pub trait Tick {
/// Tick the client
fn tick(&self, _prevent_sleep: bool) {}
}
impl Tick for () {}
/// 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 + RegistrarClient
+ 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) -> StateResult