add state_at_id and balance_at_id, integrate with RPC

This commit is contained in:
Robert Habermeier
2016-05-25 17:35:15 +02:00
parent ca008fb541
commit 2b7fae8fa6
4 changed files with 47 additions and 7 deletions

View File

@@ -346,6 +346,16 @@ impl<V> Client<V> where V: Verifier {
imported
}
/// Attempt to get a copy of a specific block's state.
///
/// This can fail (but may not) if the DB prunes state.
pub fn state_at_id(&self, id: BlockID) -> Option<State> {
self.block_header(id).map(|header| {
let db = self.state_db.lock().unwrap().boxed_clone();
State::from_existing(db, HeaderView::new(&header).state_root(), self.engine.account_start_nonce())
})
}
/// Get a copy of the best block's state.
pub fn state(&self) -> State {
State::from_existing(self.state_db.lock().unwrap().boxed_clone(), HeaderView::new(&self.best_block_header()).state_root(), self.engine.account_start_nonce())
@@ -557,6 +567,13 @@ impl<V> BlockChainClient for Client<V> where V: Verifier {
self.state().balance(address)
}
fn balance_at_id(&self, address: &Address, id: BlockID) -> Option<U256> {
match id {
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)
}

View File

@@ -74,9 +74,21 @@ pub trait BlockChainClient : Sync + Send {
/// Get address code.
fn code(&self, address: &Address) -> Option<Bytes>;
/// Get address balance.
/// Get address balance at latest state.
fn balance(&self, address: &Address) -> U256;
/// Account balance at a specific block ID.
///
/// Will fail if the block is not valid or the block's root hash has been
/// 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.
fn storage_at(&self, address: &Address, position: &H256) -> H256;