[light/jsonrpc] Provide the actual account for `eth_coinbase` RPC and unify error handeling for light and full client (#9383)

* Provide the actual `account` for eth_coinbase

The previous implementation always provided the `zero address` on
`eth_coinbase` RPC. Now, instead the actual address is returned on
success or an error when no account(s) is found!

* full client `eth_coinbase` return err

In the full-client return an error when no account is found instead of
returning the `zero address`

* Remove needless blocks on single import

* Remove needless `static` lifetime on const

* Fix `rpc_eth_author` test
This commit is contained in:
Niklas Adolfsson 2018-09-05 19:21:08 +02:00 committed by cheme
parent ab9843cb00
commit dca88ff85c
3 changed files with 22 additions and 12 deletions

View File

@ -33,7 +33,7 @@ use ethcore::log_entry::LogEntry;
use ethcore::miner::{self, MinerService};
use ethcore::snapshot::SnapshotService;
use ethcore::encoded;
use sync::{SyncProvider};
use sync::SyncProvider;
use miner::external::ExternalMinerService;
use transaction::{SignedTransaction, LocalizedTransaction};
@ -52,7 +52,7 @@ use v1::types::{
};
use v1::metadata::Metadata;
const EXTRA_INFO_PROOF: &'static str = "Object exists in blockchain (fetched earlier), extra_info is always available if object exists; qed";
const EXTRA_INFO_PROOF: &str = "Object exists in blockchain (fetched earlier), extra_info is always available if object exists; qed";
/// Eth RPC options
pub struct EthClientOptions {
@ -500,12 +500,16 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
}
fn author(&self) -> Result<RpcH160> {
let mut miner = self.miner.authoring_params().author;
let miner = self.miner.authoring_params().author;
if miner == 0.into() {
miner = self.accounts.accounts().ok().and_then(|a| a.get(0).cloned()).unwrap_or_default();
self.accounts.accounts()
.ok()
.and_then(|a| a.first().cloned())
.map(From::from)
.ok_or_else(|| errors::account("No accounts were found", ""))
} else {
Ok(RpcH160::from(miner))
}
Ok(RpcH160::from(miner))
}
fn is_mining(&self) -> Result<bool> {

View File

@ -252,7 +252,11 @@ impl<T: LightChainClient + 'static> Eth for EthClient<T> {
}
fn author(&self) -> Result<RpcH160> {
Ok(Default::default())
self.accounts.accounts()
.ok()
.and_then(|a| a.first().cloned())
.map(From::from)
.ok_or_else(|| errors::account("No accounts were found", ""))
}
fn is_mining(&self) -> Result<bool> {

View File

@ -359,25 +359,27 @@ fn rpc_eth_author() {
let make_res = |addr| r#"{"jsonrpc":"2.0","result":""#.to_owned() + &format!("0x{:x}", addr) + r#"","id":1}"#;
let tester = EthTester::default();
let req = r#"{
let request = r#"{
"jsonrpc": "2.0",
"method": "eth_coinbase",
"params": [],
"id": 1
}"#;
// No accounts - returns zero
assert_eq!(tester.io.handle_request_sync(req), Some(make_res(Address::zero())));
let response = r#"{"jsonrpc":"2.0","error":{"code":-32023,"message":"No accounts were found","data":"\"\""},"id":1}"#;
// No accounts - returns an error indicating that no accounts were found
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_string()));
// Account set - return first account
let addr = tester.accounts_provider.new_account(&"123".into()).unwrap();
assert_eq!(tester.io.handle_request_sync(req), Some(make_res(addr)));
assert_eq!(tester.io.handle_request_sync(request), Some(make_res(addr)));
for i in 0..20 {
let addr = tester.accounts_provider.new_account(&format!("{}", i).into()).unwrap();
tester.miner.set_author(addr.clone(), None).unwrap();
assert_eq!(tester.io.handle_request_sync(req), Some(make_res(addr)));
assert_eq!(tester.io.handle_request_sync(request), Some(make_res(addr)));
}
}