Skip to content
This repository was archived by the owner on Nov 6, 2020. It is now read-only.

Commit

Permalink
Merge pull request #723 from ethcore/rpc_tests
Browse files Browse the repository at this point in the history
another batch of rpc tests
  • Loading branch information
gavofyork committed Mar 14, 2016
2 parents ffbc6f5 + 9b241fa commit 7628df6
Show file tree
Hide file tree
Showing 9 changed files with 265 additions and 42 deletions.
8 changes: 4 additions & 4 deletions ethcore/src/client/test_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,22 +87,22 @@ impl TestBlockChainClient {
}

/// 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);
}

/// 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);
}

/// 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);
}

/// 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();
for n in len..(len + count) {
let mut header = BlockHeader::new();
Expand Down
7 changes: 6 additions & 1 deletion ethcore/src/views.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,11 @@ impl<'a> BlockView<'a> {
pub fn uncle_hashes(&self) -> Vec<H256> {
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> {
Expand Down Expand Up @@ -280,7 +285,7 @@ impl<'a> HeaderView<'a> {

/// Returns block number.
pub fn number(&self) -> BlockNumber { self.rlp.val_at(8) }

/// Returns block gas limit.
pub fn gas_limit(&self) -> U256 { self.rlp.val_at(9) }

Expand Down
59 changes: 59 additions & 0 deletions rpc/src/v1/helpers/external_miner.rs
Original file line number Diff line number Diff line change
@@ -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()
}
}
2 changes: 2 additions & 0 deletions rpc/src/v1/helpers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

mod poll_manager;
mod poll_filter;
pub mod external_miner;

pub use self::poll_manager::PollManager;
pub use self::poll_filter::PollFilter;
pub use self::external_miner::{ExternalMinerService, ExternalMiner};
63 changes: 48 additions & 15 deletions rpc/src/v1/impls/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.

//! Eth rpc implementation.
use std::collections::{HashMap, HashSet};
use std::sync::{Arc, Weak, Mutex, RwLock};
use std::collections::HashSet;
use std::sync::{Arc, Weak, Mutex};
use std::ops::Deref;
use ethsync::{SyncProvider, SyncState};
use ethminer::{MinerService};
Expand All @@ -25,42 +25,59 @@ use util::numbers::*;
use util::sha3::*;
use util::rlp::encode;
use ethcore::client::*;
use ethcore::block::{IsBlock};
use ethcore::block::IsBlock;
use ethcore::views::*;
use ethcore::ethereum::Ethash;
use ethcore::ethereum::denominations::shannon;
use ethcore::transaction::Transaction as EthTransaction;
use v1::traits::{Eth, EthFilter};
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;

/// Eth rpc implementation.
pub struct EthClient<C, S, A, M>
pub struct EthClient<C, S, A, M, EM = ExternalMiner>
where C: BlockChainClient,
S: SyncProvider,
A: AccountProvider,
M: MinerService {
M: MinerService,
EM: ExternalMinerService {
client: Weak<C>,
sync: Weak<S>,
accounts: Weak<A>,
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,
S: SyncProvider,
A: AccountProvider,
M: MinerService {

/// Creates new EthClient.
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 {
client: Arc::downgrade(client),
sync: Arc::downgrade(sync),
miner: Arc::downgrade(miner),
accounts: Arc::downgrade(accounts),
hashrates: RwLock::new(HashMap::new()),
external_miner: em,
}
}

Expand Down Expand Up @@ -108,13 +125,19 @@ impl<C, S, A, M> EthClient<C, S, A, M>
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,
S: SyncProvider + 'static,
A: AccountProvider + 'static,
M: MinerService + 'static {
M: MinerService + 'static,
EM: ExternalMinerService + 'static {

fn protocol_version(&self, params: Params) -> Result<Value, Error> {
match params {
Expand Down Expand Up @@ -152,15 +175,15 @@ impl<C, S, A, M> Eth for EthClient<C, S, A, M>
// TODO: return real value of mining once it's implemented.
fn is_mining(&self, params: Params) -> Result<Value, Error> {
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())
}
}

// TODO: return real hashrate once we have mining
fn hashrate(&self, params: Params) -> Result<Value, Error> {
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())
}
}
Expand Down Expand Up @@ -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())))
}

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> {
match params {
Params::None => to_value(&vec![] as &Vec<String>),
Expand Down Expand Up @@ -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> {
// TODO: Index should be U256.
from_params::<(Index, H256)>(params).and_then(|(rate, id)| {
self.hashrates.write().unwrap().insert(id, rate.value() as u64);
from_params::<(U256, H256)>(params).and_then(|(rate, id)| {
self.external_miner.submit_hashrate(rate, id);
to_value(&true)
})
}
Expand Down
Loading

0 comments on commit 7628df6

Please sign in to comment.