consolidate [balance/storage]_at and _at_id functionality
This commit is contained in:
parent
3405f3eab1
commit
86eab79d9d
@ -349,7 +349,12 @@ impl<V> Client<V> where V: Verifier {
|
|||||||
/// Attempt to get a copy of a specific block's state.
|
/// Attempt to get a copy of a specific block's state.
|
||||||
///
|
///
|
||||||
/// This can fail (but may not) if the DB prunes state.
|
/// This can fail (but may not) if the DB prunes state.
|
||||||
pub fn state_at_id(&self, id: BlockID) -> Option<State> {
|
pub fn state_at(&self, id: BlockID) -> Option<State> {
|
||||||
|
// fast path for latest state.
|
||||||
|
if let BlockID::Latest = id.clone() {
|
||||||
|
return Some(self.state())
|
||||||
|
}
|
||||||
|
|
||||||
self.block_header(id).map(|header| {
|
self.block_header(id).map(|header| {
|
||||||
let db = self.state_db.lock().unwrap().boxed_clone();
|
let db = self.state_db.lock().unwrap().boxed_clone();
|
||||||
State::from_existing(db, HeaderView::new(&header).state_root(), self.engine.account_start_nonce())
|
State::from_existing(db, HeaderView::new(&header).state_root(), self.engine.account_start_nonce())
|
||||||
@ -563,26 +568,12 @@ impl<V> BlockChainClient for Client<V> where V: Verifier {
|
|||||||
self.state().code(address)
|
self.state().code(address)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn balance(&self, address: &Address) -> U256 {
|
fn balance(&self, address: &Address, id: BlockID) -> Option<U256> {
|
||||||
self.state().balance(address)
|
self.state_at(id).map(|s| s.balance(address))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn balance_at_id(&self, address: &Address, id: BlockID) -> Option<U256> {
|
fn storage_at(&self, address: &Address, position: &H256, id: BlockID) -> Option<H256> {
|
||||||
match id {
|
self.state_at(id).map(|s| s.storage_at(address, position))
|
||||||
BlockID::Latest => Some(self.balance(address)),
|
|
||||||
id => self.state_at_id(id).map(|s| s.balance(address)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn storage_at(&self, address: &Address, position: &H256) -> H256 {
|
|
||||||
self.state().storage_at(address, position)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn storage_at_id(&self, address: &Address, position: &H256, id: BlockID) -> Option<H256> {
|
|
||||||
match id {
|
|
||||||
BlockID::Latest => Some(self.storage_at(address, position)),
|
|
||||||
id => self.state_at_id(id).map(|s| s.storage_at(address, position)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transaction(&self, id: TransactionID) -> Option<LocalizedTransaction> {
|
fn transaction(&self, id: TransactionID) -> Option<LocalizedTransaction> {
|
||||||
|
@ -74,33 +74,15 @@ pub trait BlockChainClient : Sync + Send {
|
|||||||
/// Get address code.
|
/// Get address code.
|
||||||
fn code(&self, address: &Address) -> Option<Bytes>;
|
fn code(&self, address: &Address) -> Option<Bytes>;
|
||||||
|
|
||||||
/// Get address balance at latest state.
|
/// Get address balance at the given block's state.
|
||||||
fn balance(&self, address: &Address) -> U256;
|
|
||||||
|
|
||||||
/// Account balance at a specific block ID.
|
|
||||||
///
|
///
|
||||||
/// Must not fail if `id` is `BlockID::Latest`.
|
/// Returns None if and only if the block's root hash has been pruned from the DB.
|
||||||
/// Will fail if the block is not valid or the block's root hash has been
|
fn balance(&self, address: &Address, id: BlockID) -> Option<U256>;
|
||||||
/// pruned from the DB.
|
|
||||||
fn balance_at_id(&self, address: &Address, id: BlockID) -> Option<U256> {
|
|
||||||
if let BlockID::Latest = id {
|
|
||||||
Some(self.balance(address))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get value of the storage at given position from the latest state.
|
/// Get value of the storage at given position at the given block.
|
||||||
fn storage_at(&self, address: &Address, position: &H256) -> H256;
|
///
|
||||||
|
/// Returns None if and only if the block's root hash has been pruned from the DB.
|
||||||
/// Get value of the storage at given position form the latest state.
|
fn storage_at(&self, address: &Address, position: &H256, id: BlockID) -> Option<H256>;
|
||||||
fn storage_at_id(&self, address: &Address, position: &H256, id: BlockID) -> Option<H256> {
|
|
||||||
if let BlockID::Latest = id {
|
|
||||||
Some(self.storage_at(address, position))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get transaction with given hash.
|
/// Get transaction with given hash.
|
||||||
fn transaction(&self, id: TransactionID) -> Option<LocalizedTransaction>;
|
fn transaction(&self, id: TransactionID) -> Option<LocalizedTransaction>;
|
||||||
|
@ -253,12 +253,20 @@ impl BlockChainClient for TestBlockChainClient {
|
|||||||
self.code.read().unwrap().get(address).cloned()
|
self.code.read().unwrap().get(address).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn balance(&self, address: &Address) -> U256 {
|
fn balance(&self, address: &Address, id: BlockID) -> Option<U256> {
|
||||||
self.balances.read().unwrap().get(address).cloned().unwrap_or_else(U256::zero)
|
if let BlockID::Latest = id {
|
||||||
|
Some(self.balances.read().unwrap().get(address).cloned().unwrap_or_else(U256::zero))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn storage_at(&self, address: &Address, position: &H256) -> H256 {
|
fn storage_at(&self, address: &Address, position: &H256, id: BlockID) -> Option<H256> {
|
||||||
self.storage.read().unwrap().get(&(address.clone(), position.clone())).cloned().unwrap_or_else(H256::new)
|
if let BlockID::Latest = id {
|
||||||
|
Some(self.storage.read().unwrap().get(&(address.clone(), position.clone())).cloned().unwrap_or_else(H256::new))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transaction(&self, _id: TransactionID) -> Option<LocalizedTransaction> {
|
fn transaction(&self, _id: TransactionID) -> Option<LocalizedTransaction> {
|
||||||
|
@ -168,7 +168,7 @@ impl Miner {
|
|||||||
let mut queue = self.transaction_queue.lock().unwrap();
|
let mut queue = self.transaction_queue.lock().unwrap();
|
||||||
let fetch_account = |a: &Address| AccountDetails {
|
let fetch_account = |a: &Address| AccountDetails {
|
||||||
nonce: chain.nonce(a),
|
nonce: chain.nonce(a),
|
||||||
balance: chain.balance(a),
|
balance: chain.balance(a, BlockID::Latest).unwrap(),
|
||||||
};
|
};
|
||||||
for hash in invalid_transactions.into_iter() {
|
for hash in invalid_transactions.into_iter() {
|
||||||
queue.remove_invalid(&hash, &fetch_account);
|
queue.remove_invalid(&hash, &fetch_account);
|
||||||
@ -290,12 +290,18 @@ impl MinerService for Miner {
|
|||||||
|
|
||||||
fn balance(&self, chain: &BlockChainClient, address: &Address) -> U256 {
|
fn balance(&self, chain: &BlockChainClient, address: &Address) -> U256 {
|
||||||
let sealing_work = self.sealing_work.lock().unwrap();
|
let sealing_work = self.sealing_work.lock().unwrap();
|
||||||
sealing_work.peek_last_ref().map_or_else(|| chain.balance(address), |b| b.block().fields().state.balance(address))
|
sealing_work.peek_last_ref().map_or_else(
|
||||||
|
|| chain.balance(address, BlockID::Latest).unwrap(),
|
||||||
|
|b| b.block().fields().state.balance(address)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn storage_at(&self, chain: &BlockChainClient, address: &Address, position: &H256) -> H256 {
|
fn storage_at(&self, chain: &BlockChainClient, address: &Address, position: &H256) -> H256 {
|
||||||
let sealing_work = self.sealing_work.lock().unwrap();
|
let sealing_work = self.sealing_work.lock().unwrap();
|
||||||
sealing_work.peek_last_ref().map_or_else(|| chain.storage_at(address, position), |b| b.block().fields().state.storage_at(address, position))
|
sealing_work.peek_last_ref().map_or_else(
|
||||||
|
|| chain.storage_at(address, position, BlockID::Latest).unwrap(),
|
||||||
|
|b| b.block().fields().state.storage_at(address, position)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn nonce(&self, chain: &BlockChainClient, address: &Address) -> U256 {
|
fn nonce(&self, chain: &BlockChainClient, address: &Address) -> U256 {
|
||||||
@ -546,7 +552,7 @@ impl MinerService for Miner {
|
|||||||
}
|
}
|
||||||
let _ = self.import_transactions(txs, |a| AccountDetails {
|
let _ = self.import_transactions(txs, |a| AccountDetails {
|
||||||
nonce: chain.nonce(a),
|
nonce: chain.nonce(a),
|
||||||
balance: chain.balance(a),
|
balance: chain.balance(a, BlockID::Latest).unwrap(),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ use util::numbers::*;
|
|||||||
use util::sha3::*;
|
use util::sha3::*;
|
||||||
use util::bytes::ToPretty;
|
use util::bytes::ToPretty;
|
||||||
use util::rlp::{encode, decode, UntrustedRlp, View};
|
use util::rlp::{encode, decode, UntrustedRlp, View};
|
||||||
use ethcore::client::{self, BlockChainClient, BlockID, TransactionID, UncleID};
|
use ethcore::client::{BlockChainClient, BlockID, TransactionID, UncleID};
|
||||||
use ethcore::block::IsBlock;
|
use ethcore::block::IsBlock;
|
||||||
use ethcore::views::*;
|
use ethcore::views::*;
|
||||||
use ethcore::ethereum::Ethash;
|
use ethcore::ethereum::Ethash;
|
||||||
@ -200,7 +200,7 @@ impl<C, S, A, M, EM> EthClient<C, S, A, M, EM> where
|
|||||||
miner.import_own_transaction(client.deref(), signed_transaction, |a: &Address| {
|
miner.import_own_transaction(client.deref(), signed_transaction, |a: &Address| {
|
||||||
AccountDetails {
|
AccountDetails {
|
||||||
nonce: client.nonce(&a),
|
nonce: client.nonce(&a),
|
||||||
balance: client.balance(&a),
|
balance: client.balance(&a, BlockID::Latest).unwrap(),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
@ -352,9 +352,8 @@ impl<C, S, A, M, EM> Eth for EthClient<C, S, A, M, EM> where
|
|||||||
fn balance(&self, params: Params) -> Result<Value, Error> {
|
fn balance(&self, params: Params) -> Result<Value, Error> {
|
||||||
from_params_default_second(params)
|
from_params_default_second(params)
|
||||||
.and_then(|(address, block_number,)| match block_number {
|
.and_then(|(address, block_number,)| match block_number {
|
||||||
BlockNumber::Latest => to_value(&take_weak!(self.client).balance(&address)),
|
|
||||||
BlockNumber::Pending => to_value(&take_weak!(self.miner).balance(take_weak!(self.client).deref(), &address)),
|
BlockNumber::Pending => to_value(&take_weak!(self.miner).balance(take_weak!(self.client).deref(), &address)),
|
||||||
id => to_value(&try!(take_weak!(self.client).balance_at_id(&address, id.into()).ok_or_else(make_unsupported_err))),
|
id => to_value(&try!(take_weak!(self.client).balance(&address, id.into()).ok_or_else(make_unsupported_err))),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -362,8 +361,10 @@ impl<C, S, A, M, EM> Eth for EthClient<C, S, A, M, EM> where
|
|||||||
from_params_default_third::<Address, U256>(params)
|
from_params_default_third::<Address, U256>(params)
|
||||||
.and_then(|(address, position, block_number,)| match block_number {
|
.and_then(|(address, position, block_number,)| match block_number {
|
||||||
BlockNumber::Pending => to_value(&U256::from(take_weak!(self.miner).storage_at(&*take_weak!(self.client), &address, &H256::from(position)))),
|
BlockNumber::Pending => to_value(&U256::from(take_weak!(self.miner).storage_at(&*take_weak!(self.client), &address, &H256::from(position)))),
|
||||||
BlockNumber::Latest => to_value(&U256::from(take_weak!(self.client).storage_at(&address, &H256::from(position)))),
|
id => match take_weak!(self.client).storage_at(&address, &H256::from(position), id.into()) {
|
||||||
id => to_value(&try!(take_weak!(self.client).storage_at_id(&address, &H256::from(position), id.into()).ok_or_else(make_unsupported_err))),
|
Some(s) => to_value(&U256::from(s)),
|
||||||
|
None => Err(make_unsupported_err()), // None is only returned on unsupported requests.
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -901,7 +901,7 @@ impl ChainSync {
|
|||||||
let chain = io.chain();
|
let chain = io.chain();
|
||||||
let fetch_account = |a: &Address| AccountDetails {
|
let fetch_account = |a: &Address| AccountDetails {
|
||||||
nonce: chain.nonce(a),
|
nonce: chain.nonce(a),
|
||||||
balance: chain.balance(a),
|
balance: chain.balance(a, BlockID::Latest).unwrap(),
|
||||||
};
|
};
|
||||||
let _ = self.miner.import_transactions(transactions, fetch_account);
|
let _ = self.miner.import_transactions(transactions, fetch_account);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
Loading…
Reference in New Issue
Block a user