Merge pull request #723 from ethcore/rpc_tests
another batch of rpc tests
This commit is contained in:
commit
7628df6fe6
@ -87,22 +87,22 @@ impl TestBlockChainClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Set the balance of account `address` to `balance`.
|
/// Set the balance of account `address` to `balance`.
|
||||||
pub fn set_balance(&mut self, address: Address, balance: U256) {
|
pub fn set_balance(&self, address: Address, balance: U256) {
|
||||||
self.balances.write().unwrap().insert(address, balance);
|
self.balances.write().unwrap().insert(address, balance);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set `code` at `address`.
|
/// Set `code` at `address`.
|
||||||
pub fn set_code(&mut self, address: Address, code: Bytes) {
|
pub fn set_code(&self, address: Address, code: Bytes) {
|
||||||
self.code.write().unwrap().insert(address, code);
|
self.code.write().unwrap().insert(address, code);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set storage `position` to `value` for account `address`.
|
/// Set storage `position` to `value` for account `address`.
|
||||||
pub fn set_storage(&mut self, address: Address, position: H256, value: H256) {
|
pub fn set_storage(&self, address: Address, position: H256, value: H256) {
|
||||||
self.storage.write().unwrap().insert((address, position), value);
|
self.storage.write().unwrap().insert((address, position), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add blocks to test client.
|
/// Add blocks to test client.
|
||||||
pub fn add_blocks(&mut self, count: usize, with: EachBlockWith) {
|
pub fn add_blocks(&self, count: usize, with: EachBlockWith) {
|
||||||
let len = self.numbers.read().unwrap().len();
|
let len = self.numbers.read().unwrap().len();
|
||||||
for n in len..(len + count) {
|
for n in len..(len + count) {
|
||||||
let mut header = BlockHeader::new();
|
let mut header = BlockHeader::new();
|
||||||
|
@ -223,6 +223,11 @@ impl<'a> BlockView<'a> {
|
|||||||
pub fn uncle_hashes(&self) -> Vec<H256> {
|
pub fn uncle_hashes(&self) -> Vec<H256> {
|
||||||
self.rlp.at(2).iter().map(|rlp| rlp.as_raw().sha3()).collect()
|
self.rlp.at(2).iter().map(|rlp| rlp.as_raw().sha3()).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return nth uncle.
|
||||||
|
pub fn uncle_at(&self, index: usize) -> Option<Header> {
|
||||||
|
self.rlp.at(2).iter().nth(index).map(|rlp| rlp.as_val())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Hashable for BlockView<'a> {
|
impl<'a> Hashable for BlockView<'a> {
|
||||||
|
59
rpc/src/v1/helpers/external_miner.rs
Normal file
59
rpc/src/v1/helpers/external_miner.rs
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::sync::RwLock;
|
||||||
|
use util::numbers::U256;
|
||||||
|
use util::hash::H256;
|
||||||
|
|
||||||
|
/// External miner interface.
|
||||||
|
pub trait ExternalMinerService: Send + Sync {
|
||||||
|
/// Submit hashrate for given miner.
|
||||||
|
fn submit_hashrate(&self, hashrate: U256, id: H256);
|
||||||
|
|
||||||
|
/// Total hashrate.
|
||||||
|
fn hashrate(&self) -> U256;
|
||||||
|
|
||||||
|
/// Returns true if external miner is mining.
|
||||||
|
fn is_mining(&self) -> bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// External Miner.
|
||||||
|
pub struct ExternalMiner {
|
||||||
|
hashrates: RwLock<HashMap<H256, U256>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ExternalMiner {
|
||||||
|
fn default() -> Self {
|
||||||
|
ExternalMiner {
|
||||||
|
hashrates: RwLock::new(HashMap::new()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExternalMinerService for ExternalMiner {
|
||||||
|
fn submit_hashrate(&self, hashrate: U256, id: H256) {
|
||||||
|
self.hashrates.write().unwrap().insert(id, hashrate);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hashrate(&self) -> U256 {
|
||||||
|
self.hashrates.read().unwrap().iter().fold(U256::from(0), |sum, (_, v)| sum + *v)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_mining(&self) -> bool {
|
||||||
|
!self.hashrates.read().unwrap().is_empty()
|
||||||
|
}
|
||||||
|
}
|
@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
mod poll_manager;
|
mod poll_manager;
|
||||||
mod poll_filter;
|
mod poll_filter;
|
||||||
|
pub mod external_miner;
|
||||||
|
|
||||||
pub use self::poll_manager::PollManager;
|
pub use self::poll_manager::PollManager;
|
||||||
pub use self::poll_filter::PollFilter;
|
pub use self::poll_filter::PollFilter;
|
||||||
|
pub use self::external_miner::{ExternalMinerService, ExternalMiner};
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
//! Eth rpc implementation.
|
//! Eth rpc implementation.
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::HashSet;
|
||||||
use std::sync::{Arc, Weak, Mutex, RwLock};
|
use std::sync::{Arc, Weak, Mutex};
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use ethsync::{SyncProvider, SyncState};
|
use ethsync::{SyncProvider, SyncState};
|
||||||
use ethminer::{MinerService};
|
use ethminer::{MinerService};
|
||||||
@ -25,42 +25,59 @@ use util::numbers::*;
|
|||||||
use util::sha3::*;
|
use util::sha3::*;
|
||||||
use util::rlp::encode;
|
use util::rlp::encode;
|
||||||
use ethcore::client::*;
|
use ethcore::client::*;
|
||||||
use ethcore::block::{IsBlock};
|
use ethcore::block::IsBlock;
|
||||||
use ethcore::views::*;
|
use ethcore::views::*;
|
||||||
use ethcore::ethereum::Ethash;
|
use ethcore::ethereum::Ethash;
|
||||||
use ethcore::ethereum::denominations::shannon;
|
use ethcore::ethereum::denominations::shannon;
|
||||||
use ethcore::transaction::Transaction as EthTransaction;
|
use ethcore::transaction::Transaction as EthTransaction;
|
||||||
use v1::traits::{Eth, EthFilter};
|
use v1::traits::{Eth, EthFilter};
|
||||||
use v1::types::{Block, BlockTransactions, BlockNumber, Bytes, SyncStatus, SyncInfo, Transaction, TransactionRequest, OptionalValue, Index, Filter, Log};
|
use v1::types::{Block, BlockTransactions, BlockNumber, Bytes, SyncStatus, SyncInfo, Transaction, TransactionRequest, OptionalValue, Index, Filter, Log};
|
||||||
use v1::helpers::{PollFilter, PollManager};
|
use v1::helpers::{PollFilter, PollManager, ExternalMinerService, ExternalMiner};
|
||||||
use util::keys::store::AccountProvider;
|
use util::keys::store::AccountProvider;
|
||||||
|
|
||||||
/// Eth rpc implementation.
|
/// Eth rpc implementation.
|
||||||
pub struct EthClient<C, S, A, M>
|
pub struct EthClient<C, S, A, M, EM = ExternalMiner>
|
||||||
where C: BlockChainClient,
|
where C: BlockChainClient,
|
||||||
S: SyncProvider,
|
S: SyncProvider,
|
||||||
A: AccountProvider,
|
A: AccountProvider,
|
||||||
M: MinerService {
|
M: MinerService,
|
||||||
|
EM: ExternalMinerService {
|
||||||
client: Weak<C>,
|
client: Weak<C>,
|
||||||
sync: Weak<S>,
|
sync: Weak<S>,
|
||||||
accounts: Weak<A>,
|
accounts: Weak<A>,
|
||||||
miner: Weak<M>,
|
miner: Weak<M>,
|
||||||
hashrates: RwLock<HashMap<H256, u64>>,
|
external_miner: EM,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, S, A, M> EthClient<C, S, A, M>
|
impl<C, S, A, M> EthClient<C, S, A, M, ExternalMiner>
|
||||||
where C: BlockChainClient,
|
where C: BlockChainClient,
|
||||||
S: SyncProvider,
|
S: SyncProvider,
|
||||||
A: AccountProvider,
|
A: AccountProvider,
|
||||||
M: MinerService {
|
M: MinerService {
|
||||||
|
|
||||||
/// Creates new EthClient.
|
/// Creates new EthClient.
|
||||||
pub fn new(client: &Arc<C>, sync: &Arc<S>, accounts: &Arc<A>, miner: &Arc<M>) -> Self {
|
pub fn new(client: &Arc<C>, sync: &Arc<S>, accounts: &Arc<A>, miner: &Arc<M>) -> Self {
|
||||||
|
EthClient::new_with_external_miner(client, sync, accounts, miner, ExternalMiner::default())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl<C, S, A, M, EM> EthClient<C, S, A, M, EM>
|
||||||
|
where C: BlockChainClient,
|
||||||
|
S: SyncProvider,
|
||||||
|
A: AccountProvider,
|
||||||
|
M: MinerService,
|
||||||
|
EM: ExternalMinerService {
|
||||||
|
|
||||||
|
/// Creates new EthClient with custom external miner.
|
||||||
|
pub fn new_with_external_miner(client: &Arc<C>, sync: &Arc<S>, accounts: &Arc<A>, miner: &Arc<M>, em: EM)
|
||||||
|
-> EthClient<C, S, A, M, EM> {
|
||||||
EthClient {
|
EthClient {
|
||||||
client: Arc::downgrade(client),
|
client: Arc::downgrade(client),
|
||||||
sync: Arc::downgrade(sync),
|
sync: Arc::downgrade(sync),
|
||||||
miner: Arc::downgrade(miner),
|
miner: Arc::downgrade(miner),
|
||||||
accounts: Arc::downgrade(accounts),
|
accounts: Arc::downgrade(accounts),
|
||||||
hashrates: RwLock::new(HashMap::new()),
|
external_miner: em,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,13 +125,19 @@ impl<C, S, A, M> EthClient<C, S, A, M>
|
|||||||
None => Ok(Value::Null)
|
None => Ok(Value::Null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn uncle(&self, _block: BlockId, _index: usize) -> Result<Value, Error> {
|
||||||
|
// TODO: implement!
|
||||||
|
Ok(Value::Null)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, S, A, M> Eth for EthClient<C, S, A, M>
|
impl<C, S, A, M, EM> Eth for EthClient<C, S, A, M, EM>
|
||||||
where C: BlockChainClient + 'static,
|
where C: BlockChainClient + 'static,
|
||||||
S: SyncProvider + 'static,
|
S: SyncProvider + 'static,
|
||||||
A: AccountProvider + 'static,
|
A: AccountProvider + 'static,
|
||||||
M: MinerService + 'static {
|
M: MinerService + 'static,
|
||||||
|
EM: ExternalMinerService + 'static {
|
||||||
|
|
||||||
fn protocol_version(&self, params: Params) -> Result<Value, Error> {
|
fn protocol_version(&self, params: Params) -> Result<Value, Error> {
|
||||||
match params {
|
match params {
|
||||||
@ -152,7 +175,7 @@ impl<C, S, A, M> Eth for EthClient<C, S, A, M>
|
|||||||
// TODO: return real value of mining once it's implemented.
|
// TODO: return real value of mining once it's implemented.
|
||||||
fn is_mining(&self, params: Params) -> Result<Value, Error> {
|
fn is_mining(&self, params: Params) -> Result<Value, Error> {
|
||||||
match params {
|
match params {
|
||||||
Params::None => to_value(&!self.hashrates.read().unwrap().is_empty()),
|
Params::None => to_value(&self.external_miner.is_mining()),
|
||||||
_ => Err(Error::invalid_params())
|
_ => Err(Error::invalid_params())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -160,7 +183,7 @@ impl<C, S, A, M> Eth for EthClient<C, S, A, M>
|
|||||||
// TODO: return real hashrate once we have mining
|
// TODO: return real hashrate once we have mining
|
||||||
fn hashrate(&self, params: Params) -> Result<Value, Error> {
|
fn hashrate(&self, params: Params) -> Result<Value, Error> {
|
||||||
match params {
|
match params {
|
||||||
Params::None => to_value(&self.hashrates.read().unwrap().iter().fold(0u64, |sum, (_, v)| sum + v)),
|
Params::None => to_value(&self.external_miner.hashrate()),
|
||||||
_ => Err(Error::invalid_params())
|
_ => Err(Error::invalid_params())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -267,6 +290,16 @@ impl<C, S, A, M> Eth for EthClient<C, S, A, M>
|
|||||||
.and_then(|(number, index)| self.transaction(TransactionId::Location(number.into(), index.value())))
|
.and_then(|(number, index)| self.transaction(TransactionId::Location(number.into(), index.value())))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn uncle_by_block_hash_and_index(&self, params: Params) -> Result<Value, Error> {
|
||||||
|
from_params::<(H256, Index)>(params)
|
||||||
|
.and_then(|(hash, index)| self.uncle(BlockId::Hash(hash), index.value()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn uncle_by_block_number_and_index(&self, params: Params) -> Result<Value, Error> {
|
||||||
|
from_params::<(BlockNumber, Index)>(params)
|
||||||
|
.and_then(|(number, index)| self.uncle(number.into(), index.value()))
|
||||||
|
}
|
||||||
|
|
||||||
fn compilers(&self, params: Params) -> Result<Value, Error> {
|
fn compilers(&self, params: Params) -> Result<Value, Error> {
|
||||||
match params {
|
match params {
|
||||||
Params::None => to_value(&vec![] as &Vec<String>),
|
Params::None => to_value(&vec![] as &Vec<String>),
|
||||||
@ -318,8 +351,8 @@ impl<C, S, A, M> Eth for EthClient<C, S, A, M>
|
|||||||
|
|
||||||
fn submit_hashrate(&self, params: Params) -> Result<Value, Error> {
|
fn submit_hashrate(&self, params: Params) -> Result<Value, Error> {
|
||||||
// TODO: Index should be U256.
|
// TODO: Index should be U256.
|
||||||
from_params::<(Index, H256)>(params).and_then(|(rate, id)| {
|
from_params::<(U256, H256)>(params).and_then(|(rate, id)| {
|
||||||
self.hashrates.write().unwrap().insert(id, rate.value() as u64);
|
self.external_miner.submit_hashrate(rate, id);
|
||||||
to_value(&true)
|
to_value(&true)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -15,20 +15,16 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::Arc;
|
use std::sync::{Arc, RwLock};
|
||||||
use jsonrpc_core::IoHandler;
|
use jsonrpc_core::IoHandler;
|
||||||
use util::hash::{Address, H256};
|
use util::hash::{Address, H256};
|
||||||
use util::numbers::U256;
|
use util::numbers::U256;
|
||||||
use ethcore::client::{TestBlockChainClient, EachBlockWith};
|
use ethcore::client::{TestBlockChainClient, EachBlockWith};
|
||||||
use v1::{Eth, EthClient};
|
use v1::{Eth, EthClient};
|
||||||
use v1::tests::helpers::{TestAccount, TestAccountProvider, TestSyncProvider, Config, TestMinerService};
|
use v1::tests::helpers::{TestAccount, TestAccountProvider, TestSyncProvider, Config, TestMinerService, TestExternalMiner};
|
||||||
|
|
||||||
fn blockchain_client() -> Arc<TestBlockChainClient> {
|
fn blockchain_client() -> Arc<TestBlockChainClient> {
|
||||||
let mut client = TestBlockChainClient::new();
|
let client = TestBlockChainClient::new();
|
||||||
client.add_blocks(10, EachBlockWith::Nothing);
|
|
||||||
client.set_balance(Address::from(1), U256::from(5));
|
|
||||||
client.set_storage(Address::from(1), H256::from(4), H256::from(7));
|
|
||||||
client.set_code(Address::from(1), vec![0xff, 0x21]);
|
|
||||||
Arc::new(client)
|
Arc::new(client)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,10 +47,11 @@ fn miner_service() -> Arc<TestMinerService> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct EthTester {
|
struct EthTester {
|
||||||
_client: Arc<TestBlockChainClient>,
|
client: Arc<TestBlockChainClient>,
|
||||||
_sync: Arc<TestSyncProvider>,
|
_sync: Arc<TestSyncProvider>,
|
||||||
_accounts_provider: Arc<TestAccountProvider>,
|
_accounts_provider: Arc<TestAccountProvider>,
|
||||||
_miner: Arc<TestMinerService>,
|
_miner: Arc<TestMinerService>,
|
||||||
|
hashrates: Arc<RwLock<HashMap<H256, U256>>>,
|
||||||
pub io: IoHandler,
|
pub io: IoHandler,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,15 +61,18 @@ impl Default for EthTester {
|
|||||||
let sync = sync_provider();
|
let sync = sync_provider();
|
||||||
let ap = accounts_provider();
|
let ap = accounts_provider();
|
||||||
let miner = miner_service();
|
let miner = miner_service();
|
||||||
let eth = EthClient::new(&client, &sync, &ap, &miner).to_delegate();
|
let hashrates = Arc::new(RwLock::new(HashMap::new()));
|
||||||
|
let external_miner = TestExternalMiner::new(hashrates.clone());
|
||||||
|
let eth = EthClient::new_with_external_miner(&client, &sync, &ap, &miner, external_miner).to_delegate();
|
||||||
let io = IoHandler::new();
|
let io = IoHandler::new();
|
||||||
io.add_delegate(eth);
|
io.add_delegate(eth);
|
||||||
EthTester {
|
EthTester {
|
||||||
_client: client,
|
client: client,
|
||||||
_sync: sync,
|
_sync: sync,
|
||||||
_accounts_provider: ap,
|
_accounts_provider: ap,
|
||||||
_miner: miner,
|
_miner: miner,
|
||||||
io: io
|
io: io,
|
||||||
|
hashrates: hashrates,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -92,9 +92,35 @@ fn rpc_eth_syncing() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[ignore]
|
|
||||||
fn rpc_eth_hashrate() {
|
fn rpc_eth_hashrate() {
|
||||||
unimplemented!()
|
let tester = EthTester::default();
|
||||||
|
tester.hashrates.write().unwrap().insert(H256::from(0), U256::from(0xfffa));
|
||||||
|
tester.hashrates.write().unwrap().insert(H256::from(0), U256::from(0xfffb));
|
||||||
|
tester.hashrates.write().unwrap().insert(H256::from(1), U256::from(0x1));
|
||||||
|
|
||||||
|
let request = r#"{"jsonrpc": "2.0", "method": "eth_hashrate", "params": [], "id": 1}"#;
|
||||||
|
let response = r#"{"jsonrpc":"2.0","result":"0xfffc","id":1}"#;
|
||||||
|
|
||||||
|
assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rpc_eth_submit_hashrate() {
|
||||||
|
let tester = EthTester::default();
|
||||||
|
|
||||||
|
let request = r#"{
|
||||||
|
"jsonrpc": "2.0",
|
||||||
|
"method": "eth_submitHashrate",
|
||||||
|
"params": [
|
||||||
|
"0x0000000000000000000000000000000000000000000000000000000000500000",
|
||||||
|
"0x59daa26581d0acd1fce254fb7e85952f4c09d0915afd33d3886cd914bc7d283c"],
|
||||||
|
"id": 1
|
||||||
|
}"#;
|
||||||
|
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||||
|
|
||||||
|
assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
|
||||||
|
assert_eq!(tester.hashrates.read().unwrap().get(&H256::from("0x59daa26581d0acd1fce254fb7e85952f4c09d0915afd33d3886cd914bc7d283c")).cloned(),
|
||||||
|
Some(U256::from(0x500_000)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -104,9 +130,18 @@ fn rpc_eth_author() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[ignore]
|
|
||||||
fn rpc_eth_mining() {
|
fn rpc_eth_mining() {
|
||||||
unimplemented!()
|
let tester = EthTester::default();
|
||||||
|
|
||||||
|
let request = r#"{"jsonrpc": "2.0", "method": "eth_mining", "params": [], "id": 1}"#;
|
||||||
|
let response = r#"{"jsonrpc":"2.0","result":false,"id":1}"#;
|
||||||
|
assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
|
||||||
|
|
||||||
|
tester.hashrates.write().unwrap().insert(H256::from(1), U256::from(0x1));
|
||||||
|
|
||||||
|
let request = r#"{"jsonrpc": "2.0", "method": "eth_mining", "params": [], "id": 1}"#;
|
||||||
|
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||||
|
assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -127,14 +162,20 @@ fn rpc_eth_accounts() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_eth_block_number() {
|
fn rpc_eth_block_number() {
|
||||||
|
let tester = EthTester::default();
|
||||||
|
tester.client.add_blocks(10, EachBlockWith::Nothing);
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "eth_blockNumber", "params": [], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "eth_blockNumber", "params": [], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":"0x0a","id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":"0x0a","id":1}"#;
|
||||||
|
|
||||||
assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
|
assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_eth_balance() {
|
fn rpc_eth_balance() {
|
||||||
|
let tester = EthTester::default();
|
||||||
|
tester.client.set_balance(Address::from(1), U256::from(5));
|
||||||
|
|
||||||
let request = r#"{
|
let request = r#"{
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
"method": "eth_getBalance",
|
"method": "eth_getBalance",
|
||||||
@ -143,11 +184,14 @@ fn rpc_eth_balance() {
|
|||||||
}"#;
|
}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":"0x05","id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":"0x05","id":1}"#;
|
||||||
|
|
||||||
assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
|
assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_eth_storage_at() {
|
fn rpc_eth_storage_at() {
|
||||||
|
let tester = EthTester::default();
|
||||||
|
tester.client.set_storage(Address::from(1), H256::from(4), H256::from(7));
|
||||||
|
|
||||||
let request = r#"{
|
let request = r#"{
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
"method": "eth_getStorageAt",
|
"method": "eth_getStorageAt",
|
||||||
@ -156,7 +200,7 @@ fn rpc_eth_storage_at() {
|
|||||||
}"#;
|
}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":"0x07","id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":"0x07","id":1}"#;
|
||||||
|
|
||||||
assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
|
assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -226,6 +270,9 @@ fn rpc_eth_uncle_count_by_block_number() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_eth_code() {
|
fn rpc_eth_code() {
|
||||||
|
let tester = EthTester::default();
|
||||||
|
tester.client.set_code(Address::from(1), vec![0xff, 0x21]);
|
||||||
|
|
||||||
let request = r#"{
|
let request = r#"{
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
"method": "eth_getCode",
|
"method": "eth_getCode",
|
||||||
@ -234,7 +281,7 @@ fn rpc_eth_code() {
|
|||||||
}"#;
|
}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":"0xff21","id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":"0xff21","id":1}"#;
|
||||||
|
|
||||||
assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
|
assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -275,5 +322,29 @@ fn rpc_eth_compilers() {
|
|||||||
assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
|
assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rpc_eth_compile_lll() {
|
||||||
|
let request = r#"{"jsonrpc": "2.0", "method": "eth_compileLLL", "params": [], "id": 1}"#;
|
||||||
|
let response = r#"{"jsonrpc":"2.0","error":{"code":-32603,"message":"Internal error","data":null},"id":1}"#;
|
||||||
|
|
||||||
|
assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rpc_eth_compile_solidity() {
|
||||||
|
let request = r#"{"jsonrpc": "2.0", "method": "eth_compileSolidity", "params": [], "id": 1}"#;
|
||||||
|
let response = r#"{"jsonrpc":"2.0","error":{"code":-32603,"message":"Internal error","data":null},"id":1}"#;
|
||||||
|
|
||||||
|
assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rpc_eth_compile_serpent() {
|
||||||
|
let request = r#"{"jsonrpc": "2.0", "method": "eth_compileSerpent", "params": [], "id": 1}"#;
|
||||||
|
let response = r#"{"jsonrpc":"2.0","error":{"code":-32603,"message":"Internal error","data":null},"id":1}"#;
|
||||||
|
|
||||||
|
assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
48
rpc/src/v1/tests/helpers/external_miner.rs
Normal file
48
rpc/src/v1/tests/helpers/external_miner.rs
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::sync::{Arc, RwLock};
|
||||||
|
use util::numbers::U256;
|
||||||
|
use util::hash::H256;
|
||||||
|
use v1::helpers::ExternalMinerService;
|
||||||
|
|
||||||
|
/// Test ExternalMinerService;
|
||||||
|
pub struct TestExternalMiner {
|
||||||
|
pub hashrates: Arc<RwLock<HashMap<H256, U256>>>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestExternalMiner {
|
||||||
|
pub fn new(hashrates: Arc<RwLock<HashMap<H256, U256>>>) -> Self {
|
||||||
|
TestExternalMiner {
|
||||||
|
hashrates: hashrates,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExternalMinerService for TestExternalMiner {
|
||||||
|
fn submit_hashrate(&self, hashrate: U256, id: H256) {
|
||||||
|
self.hashrates.write().unwrap().insert(id, hashrate);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hashrate(&self) -> U256 {
|
||||||
|
self.hashrates.read().unwrap().iter().fold(U256::from(0), |sum, (_, v)| sum + *v)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_mining(&self) -> bool {
|
||||||
|
!self.hashrates.read().unwrap().is_empty()
|
||||||
|
}
|
||||||
|
}
|
@ -17,7 +17,9 @@
|
|||||||
mod account_provider;
|
mod account_provider;
|
||||||
mod sync_provider;
|
mod sync_provider;
|
||||||
mod miner_service;
|
mod miner_service;
|
||||||
|
mod external_miner;
|
||||||
|
|
||||||
pub use self::account_provider::{TestAccount, TestAccountProvider};
|
pub use self::account_provider::{TestAccount, TestAccountProvider};
|
||||||
pub use self::sync_provider::{Config, TestSyncProvider};
|
pub use self::sync_provider::{Config, TestSyncProvider};
|
||||||
pub use self::miner_service::{TestMinerService};
|
pub use self::miner_service::{TestMinerService};
|
||||||
|
pub use self::external_miner::TestExternalMiner;
|
||||||
|
@ -102,7 +102,10 @@ pub trait Eth: Sized + Send + Sync + 'static {
|
|||||||
fn transaction_receipt(&self, _: Params) -> Result<Value, Error> { rpc_unimplemented!() }
|
fn transaction_receipt(&self, _: Params) -> Result<Value, Error> { rpc_unimplemented!() }
|
||||||
|
|
||||||
/// Returns an uncles at given block and index.
|
/// Returns an uncles at given block and index.
|
||||||
fn uncle_at(&self, _: Params) -> Result<Value, Error> { rpc_unimplemented!() }
|
fn uncle_by_block_hash_and_index(&self, _: Params) -> Result<Value, Error> { rpc_unimplemented!() }
|
||||||
|
|
||||||
|
/// Returns an uncles at given block and index.
|
||||||
|
fn uncle_by_block_number_and_index(&self, _: Params) -> Result<Value, Error> { rpc_unimplemented!() }
|
||||||
|
|
||||||
/// Returns available compilers.
|
/// Returns available compilers.
|
||||||
fn compilers(&self, _: Params) -> Result<Value, Error> { rpc_unimplemented!() }
|
fn compilers(&self, _: Params) -> Result<Value, Error> { rpc_unimplemented!() }
|
||||||
@ -158,8 +161,8 @@ pub trait Eth: Sized + Send + Sync + 'static {
|
|||||||
delegate.add_method("eth_getTransactionByBlockHashAndIndex", Eth::transaction_by_block_hash_and_index);
|
delegate.add_method("eth_getTransactionByBlockHashAndIndex", Eth::transaction_by_block_hash_and_index);
|
||||||
delegate.add_method("eth_getTransactionByBlockNumberAndIndex", Eth::transaction_by_block_number_and_index);
|
delegate.add_method("eth_getTransactionByBlockNumberAndIndex", Eth::transaction_by_block_number_and_index);
|
||||||
delegate.add_method("eth_getTransactionReceipt", Eth::transaction_receipt);
|
delegate.add_method("eth_getTransactionReceipt", Eth::transaction_receipt);
|
||||||
delegate.add_method("eth_getUncleByBlockHashAndIndex", Eth::uncle_at);
|
delegate.add_method("eth_getUncleByBlockHashAndIndex", Eth::uncle_by_block_hash_and_index);
|
||||||
delegate.add_method("eth_getUncleByBlockNumberAndIndex", Eth::uncle_at);
|
delegate.add_method("eth_getUncleByBlockNumberAndIndex", Eth::uncle_by_block_number_and_index);
|
||||||
delegate.add_method("eth_getCompilers", Eth::compilers);
|
delegate.add_method("eth_getCompilers", Eth::compilers);
|
||||||
delegate.add_method("eth_compileLLL", Eth::compile_lll);
|
delegate.add_method("eth_compileLLL", Eth::compile_lll);
|
||||||
delegate.add_method("eth_compileSolidity", Eth::compile_solidity);
|
delegate.add_method("eth_compileSolidity", Eth::compile_solidity);
|
||||||
|
Loading…
Reference in New Issue
Block a user