* fix: refactor return type of `BlockChainClient::code` * Add TODO move to `common-types` Co-Authored-By: David <dvdplm@gmail.com>
This commit is contained in:
parent
0bd2979c04
commit
0c0f965354
@ -67,6 +67,16 @@ pub enum StateOrBlock {
|
||||
Block(BlockId)
|
||||
}
|
||||
|
||||
/// Result to be used during get address code at given block's state
|
||||
// todo[botika] move to `common-types`
|
||||
pub enum StateResult<T> {
|
||||
/// State is missing
|
||||
Missing,
|
||||
|
||||
/// State is some
|
||||
Some(T),
|
||||
}
|
||||
|
||||
impl From<Box<dyn StateInfo>> for StateOrBlock {
|
||||
fn from(info: Box<dyn StateInfo>) -> StateOrBlock {
|
||||
StateOrBlock::State(info)
|
||||
@ -231,12 +241,14 @@ pub trait BlockChainClient : Sync + Send + AccountData + BlockChain + CallContra
|
||||
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>>;
|
||||
fn code(&self, address: &Address, state: StateOrBlock) -> StateResult<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")
|
||||
match self.code(address, BlockId::Latest.into()) {
|
||||
StateResult::Missing => panic!("code will return Some if given BlockId::Latest; qed"),
|
||||
StateResult::Some(t) => t,
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a reference to the `BlockProvider`.
|
||||
|
@ -77,6 +77,7 @@ use client_traits::{
|
||||
ScheduleInfo,
|
||||
StateClient,
|
||||
StateOrBlock,
|
||||
StateResult,
|
||||
Tick,
|
||||
TransactionInfo
|
||||
};
|
||||
@ -1758,14 +1759,14 @@ impl BlockChainClient for Client {
|
||||
Self::block_hash(&chain, id)
|
||||
}
|
||||
|
||||
fn code(&self, address: &Address, state: StateOrBlock) -> Option<Option<Bytes>> {
|
||||
fn code(&self, address: &Address, state: StateOrBlock) -> StateResult<Option<Bytes>> {
|
||||
let result = match state {
|
||||
StateOrBlock::State(s) => s.code(address).ok(),
|
||||
StateOrBlock::Block(id) => self.state_at(id).and_then(|s| s.code(address).ok())
|
||||
};
|
||||
|
||||
// Converting from `Option<Option<Arc<Bytes>>>` to `Option<Option<Bytes>>`
|
||||
result.map(|c| c.map(|c| (&*c).clone()))
|
||||
// Converting from `Option<Option<Arc<Bytes>>>` to `StateResult<Option<Bytes>>`
|
||||
result.map_or(StateResult::Missing, |c| StateResult::Some(c.map(|c| (&*c).clone())))
|
||||
}
|
||||
|
||||
fn storage_at(&self, address: &Address, position: &H256, state: StateOrBlock) -> Option<H256> {
|
||||
|
@ -71,7 +71,7 @@ use client::{
|
||||
use client_traits::{
|
||||
BlockInfo, Nonce, Balance, ChainInfo, TransactionInfo, BlockChainClient, ImportBlock,
|
||||
AccountData, BlockChain, IoClient, BadBlocks, ScheduleInfo, StateClient, ProvingBlockChainClient,
|
||||
StateOrBlock
|
||||
StateOrBlock, StateResult
|
||||
};
|
||||
use engine::Engine;
|
||||
use machine::executed::Executed;
|
||||
@ -702,10 +702,10 @@ impl BlockChainClient for TestBlockChainClient {
|
||||
None
|
||||
}
|
||||
|
||||
fn code(&self, address: &Address, state: StateOrBlock) -> Option<Option<Bytes>> {
|
||||
fn code(&self, address: &Address, state: StateOrBlock) -> StateResult<Option<Bytes>> {
|
||||
match state {
|
||||
StateOrBlock::Block(BlockId::Latest) => Some(self.code.read().get(address).cloned()),
|
||||
_ => None,
|
||||
StateOrBlock::Block(BlockId::Latest) => StateResult::Some(self.code.read().get(address).cloned()),
|
||||
_ => StateResult::Missing,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ use hash::{keccak, KECCAK_NULL_RLP};
|
||||
use ethereum_types::{U256, H256, Address};
|
||||
use bytes::ToPretty;
|
||||
use rlp::PayloadInfo;
|
||||
use client_traits::{BlockChainReset, Nonce, Balance, BlockChainClient, ImportExportBlocks};
|
||||
use client_traits::{BlockChainReset, Nonce, Balance, BlockChainClient, ImportExportBlocks, StateResult};
|
||||
use ethcore::{
|
||||
client::{DatabaseCompactionProfile, VMType},
|
||||
miner::Miner,
|
||||
@ -592,7 +592,10 @@ fn execute_export_state(cmd: ExportState) -> Result<(), String> {
|
||||
out.write(b",").expect("Write error");
|
||||
}
|
||||
out.write_fmt(format_args!("\n\"0x{:x}\": {{\"balance\": \"{:x}\", \"nonce\": \"{:x}\"", account, balance, client.nonce(&account, at).unwrap_or_else(U256::zero))).expect("Write error");
|
||||
let code = client.code(&account, at.into()).unwrap_or(None).unwrap_or_else(Vec::new);
|
||||
let code = match client.code(&account, at.into()) {
|
||||
StateResult::Missing => Vec::new(),
|
||||
StateResult::Some(t) => t.unwrap_or_else(Vec::new),
|
||||
};
|
||||
if !code.is_empty() {
|
||||
out.write_fmt(format_args!(", \"code_hash\": \"0x{:x}\"", keccak(&code))).expect("Write error");
|
||||
if cmd.code {
|
||||
|
@ -25,7 +25,7 @@ use ethereum_types::{Address, H64, H160, H256, U64, U256, BigEndianHash};
|
||||
use parking_lot::Mutex;
|
||||
|
||||
use account_state::state::StateInfo;
|
||||
use client_traits::{BlockChainClient, StateClient, ProvingBlockChainClient, StateOrBlock};
|
||||
use client_traits::{BlockChainClient, StateClient, ProvingBlockChainClient, StateOrBlock, StateResult};
|
||||
use ethash::{self, SeedHashCompute};
|
||||
use ethcore::client::{Call, EngineInfo};
|
||||
use ethcore::miner::{self, MinerService};
|
||||
@ -742,8 +742,8 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
|
||||
try_bf!(check_known(&*self.client, num.clone()));
|
||||
|
||||
let res = match self.client.code(&address, self.get_state(num)) {
|
||||
Some(code) => Ok(code.map_or_else(Bytes::default, Bytes::new)),
|
||||
None => Err(errors::state_pruned()),
|
||||
StateResult::Some(code) => Ok(code.map_or_else(Bytes::default, Bytes::new)),
|
||||
StateResult::Missing => Err(errors::state_pruned()),
|
||||
};
|
||||
|
||||
Box::new(future::done(res))
|
||||
|
Loading…
Reference in New Issue
Block a user