From e09de6ea3d8877cb8926dff11b9cef644ae07506 Mon Sep 17 00:00:00 2001 From: debris Date: Sat, 12 Mar 2016 19:51:24 +0100 Subject: [PATCH] added missing eth_getBalance rpc method and tests for it --- ethcore/src/client/client.rs | 4 ++++ ethcore/src/client/mod.rs | 3 +++ ethcore/src/client/test_client.rs | 11 +++++++++++ rpc/src/v1/impls/eth.rs | 5 +++++ rpc/src/v1/tests/eth.rs | 25 ++++++++++++++++++++++++- rpc/src/v1/traits/eth.rs | 2 +- 6 files changed, 48 insertions(+), 2 deletions(-) diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 4e8c34b33..a860dd752 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -449,6 +449,10 @@ impl BlockChainClient for Client where V: Verifier { self.state().code(address) } + fn balance(&self, address: &Address) -> U256 { + self.state().balance(address) + } + fn transaction(&self, id: TransactionId) -> Option { match id { TransactionId::Hash(ref hash) => self.chain.transaction_address(hash), diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index afdfb200a..af2c6ac14 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -66,6 +66,9 @@ pub trait BlockChainClient : Sync + Send { /// Get address code. fn code(&self, address: &Address) -> Option; + /// Get address balance. + fn balance(&self, address: &Address) -> U256; + /// Get transaction with given hash. fn transaction(&self, id: TransactionId) -> Option; diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index 207f1090f..cf1352bc8 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -40,6 +40,8 @@ pub struct TestBlockChainClient { pub last_hash: RwLock, /// Difficulty. pub difficulty: RwLock, + /// Balances. + pub balances: RwLock>, } #[derive(Clone)] @@ -65,12 +67,17 @@ impl TestBlockChainClient { genesis_hash: H256::new(), last_hash: RwLock::new(H256::new()), difficulty: RwLock::new(From::from(0)), + balances: RwLock::new(HashMap::new()), }; client.add_blocks(1, EachBlockWith::Nothing); // add genesis block client.genesis_hash = client.last_hash.read().unwrap().clone(); client } + pub fn set_balance(&mut self, address: Address, balance: U256) { + self.balances.write().unwrap().insert(address, balance); + } + /// Add blocks to test client. pub fn add_blocks(&mut self, count: usize, with: EachBlockWith) { let len = self.numbers.read().unwrap().len(); @@ -165,6 +172,10 @@ impl BlockChainClient for TestBlockChainClient { unimplemented!(); } + fn balance(&self, address: &Address) -> U256 { + self.balances.read().unwrap().get(address).cloned().unwrap_or_else(U256::zero) + } + fn transaction(&self, _id: TransactionId) -> Option { unimplemented!(); } diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 47b5471b3..f5159f55f 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -170,6 +170,11 @@ impl Eth for EthClient where C: BlockChainClient + 'static, S: } } + fn balance(&self, params: Params) -> Result { + from_params::<(Address, BlockNumber)>(params) + .and_then(|(address, _block_number)| to_value(&take_weak!(self.client).balance(&address))) + } + fn block_transaction_count_by_hash(&self, params: Params) -> Result { from_params::<(H256,)>(params) .and_then(|(hash,)| match take_weak!(self.client).block(BlockId::Hash(hash)) { diff --git a/rpc/src/v1/tests/eth.rs b/rpc/src/v1/tests/eth.rs index c36a9d172..320d583d1 100644 --- a/rpc/src/v1/tests/eth.rs +++ b/rpc/src/v1/tests/eth.rs @@ -17,7 +17,8 @@ use std::collections::HashMap; use std::sync::Arc; use jsonrpc_core::IoHandler; -use util::hash::{Address}; +use util::hash::Address; +use util::numbers::U256; use ethcore::client::{TestBlockChainClient, EachBlockWith}; use v1::{Eth, EthClient}; use v1::tests::helpers::{TestAccount, TestAccountProvider, TestSyncProvider, Config}; @@ -25,6 +26,7 @@ use v1::tests::helpers::{TestAccount, TestAccountProvider, TestSyncProvider, Con fn blockchain_client() -> Arc { let mut client = TestBlockChainClient::new(); client.add_blocks(10, EachBlockWith::Nothing); + client.set_balance(Address::from(1), U256::from(5)); Arc::new(client) } @@ -57,3 +59,24 @@ fn rpc_eth_accounts() { assert_eq!(io.handle_request(request), Some(response.to_owned())); } + +#[test] +fn rpc_eth_balance() { + let client = blockchain_client(); + let sync = sync_provider(); + let ap = accounts_provider(); + + let eth = EthClient::new(&client, &sync, &ap).to_delegate(); + let io = IoHandler::new(); + io.add_delegate(eth); + + let request = r#"{ + "jsonrpc": "2.0", + "method": "eth_getBalance", + "params": ["0x0000000000000000000000000000000000000001", "latest"], + "id": 1 + }"#; + let response = r#"{"jsonrpc":"2.0","result":"0x05","id":1}"#; + + assert_eq!(io.handle_request(request), Some(response.to_owned())); +} diff --git a/rpc/src/v1/traits/eth.rs b/rpc/src/v1/traits/eth.rs index 8c24dd38c..7d33cb63f 100644 --- a/rpc/src/v1/traits/eth.rs +++ b/rpc/src/v1/traits/eth.rs @@ -130,7 +130,7 @@ pub trait Eth: Sized + Send + Sync + 'static { delegate.add_method("eth_gasPrice", Eth::gas_price); delegate.add_method("eth_accounts", Eth::accounts); delegate.add_method("eth_blockNumber", Eth::block_number); - delegate.add_method("eth_balance", Eth::balance); + delegate.add_method("eth_getBalance", Eth::balance); delegate.add_method("eth_getStorageAt", Eth::storage_at); delegate.add_method("eth_getTransactionCount", Eth::transaction_count); delegate.add_method("eth_getBlockTransactionCountByHash", Eth::block_transaction_count_by_hash);