Gas price statistics. (#1291)
* Gas price statistics. Affects eth_gasPrice. Added ethcore_gasPriceStatistics. Closes #1265 * Fix a bug in eth_gasPrice * Fix tests. * Revert minor alteration. * Tests for gas_price_statistics. - Tests; - Additional infrastructure for generating test blocks with transactions.
This commit is contained in:
parent
1e9da1e0fa
commit
88b03580ff
33
ethcore/res/null.json
Normal file
33
ethcore/res/null.json
Normal file
@ -0,0 +1,33 @@
|
||||
{
|
||||
"name": "Morden",
|
||||
"engine": {
|
||||
"Null": null
|
||||
},
|
||||
"params": {
|
||||
"accountStartNonce": "0x0",
|
||||
"maximumExtraDataSize": "0x20",
|
||||
"minGasLimit": "0x1388",
|
||||
"networkID" : "0x2"
|
||||
},
|
||||
"genesis": {
|
||||
"seal": {
|
||||
"ethereum": {
|
||||
"nonce": "0x00006d6f7264656e",
|
||||
"mixHash": "0x00000000000000000000000000000000000000647572616c65787365646c6578"
|
||||
}
|
||||
},
|
||||
"difficulty": "0x20000",
|
||||
"author": "0x0000000000000000000000000000000000000000",
|
||||
"timestamp": "0x00",
|
||||
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"extraData": "0x",
|
||||
"gasLimit": "0x2fefd8"
|
||||
},
|
||||
"accounts": {
|
||||
"0000000000000000000000000000000000000001": { "balance": "1", "nonce": "0", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
|
||||
"0000000000000000000000000000000000000002": { "balance": "1", "nonce": "0", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
|
||||
"0000000000000000000000000000000000000003": { "balance": "1", "nonce": "0", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
|
||||
"0000000000000000000000000000000000000004": { "balance": "1", "nonce": "0", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
|
||||
"9cce34f7ab185c7aba1b7c8140d620b4bda941d6": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "0" }
|
||||
}
|
||||
}
|
@ -770,8 +770,7 @@ impl<V> MiningBlockChainClient for Client<V> where V: Verifier {
|
||||
author,
|
||||
gas_floor_target,
|
||||
extra_data,
|
||||
).expect("OpenBlock::new only fails if parent state root invalid. State root of best block's header is never invalid. \
|
||||
Therefore creating an OpenBlock with the best block's header will not fail.");
|
||||
).expect("OpenBlock::new only fails if parent state root invalid; state root of best block's header is never invalid; qed");
|
||||
|
||||
// Add uncles
|
||||
self.chain
|
||||
|
@ -34,6 +34,7 @@ pub use env_info::{LastHashes, EnvInfo};
|
||||
use util::bytes::Bytes;
|
||||
use util::hash::{Address, H256, H2048};
|
||||
use util::numbers::U256;
|
||||
use util::Itertools;
|
||||
use blockchain::TreeRoute;
|
||||
use block_queue::BlockQueueInfo;
|
||||
use block::OpenBlock;
|
||||
@ -41,6 +42,7 @@ use header::{BlockNumber, Header};
|
||||
use transaction::{LocalizedTransaction, SignedTransaction};
|
||||
use log_entry::LocalizedLogEntry;
|
||||
use filter::Filter;
|
||||
use views::BlockView;
|
||||
use error::{ImportResult, ExecutionError};
|
||||
use receipt::LocalizedReceipt;
|
||||
use trace::LocalizedTrace;
|
||||
@ -193,6 +195,32 @@ pub trait BlockChainClient : Sync + Send {
|
||||
|
||||
/// list all transactions
|
||||
fn all_transactions(&self) -> Vec<SignedTransaction>;
|
||||
|
||||
/// Get the gas price distribution.
|
||||
fn gas_price_statistics(&self, sample_size: usize, distribution_size: usize) -> Result<Vec<U256>, ()> {
|
||||
let mut h = self.chain_info().best_block_hash;
|
||||
let mut corpus = Vec::new();
|
||||
for _ in 0..sample_size {
|
||||
let block_bytes = self.block(BlockID::Hash(h)).expect("h is either the best_block_hash or an ancestor; qed");
|
||||
let block = BlockView::new(&block_bytes);
|
||||
let header = block.header_view();
|
||||
if header.number() == 0 {
|
||||
break;
|
||||
}
|
||||
block.transaction_views().iter().foreach(|t| corpus.push(t.gas_price()));
|
||||
h = header.parent_hash().clone();
|
||||
}
|
||||
corpus.sort();
|
||||
let n = corpus.len();
|
||||
if n > 0 {
|
||||
Ok((0..(distribution_size + 1))
|
||||
.map(|i| corpus[i * (n - 1) / distribution_size])
|
||||
.collect::<Vec<_>>()
|
||||
)
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Extended client interface used for mining
|
||||
|
@ -244,6 +244,11 @@ impl Spec {
|
||||
pub fn new_test() -> Spec {
|
||||
Spec::load(include_bytes!("../../res/null_morden.json"))
|
||||
}
|
||||
|
||||
/// Create a new Spec which is a NullEngine consensus with a premine of address whose secret is sha3('').
|
||||
pub fn new_null() -> Spec {
|
||||
Spec::load(include_bytes!("../../res/null.json"))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -112,6 +112,18 @@ fn can_collect_garbage() {
|
||||
assert!(client.blockchain_cache_info().blocks < 100 * 1024);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_generate_gas_price_statistics() {
|
||||
let client_result = generate_dummy_client_with_data(16, 1, &vec_into![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
|
||||
let client = client_result.reference();
|
||||
let s = client.gas_price_statistics(8, 8).unwrap();
|
||||
assert_eq!(s, vec_into![8, 8, 9, 10, 11, 12, 13, 14, 15]);
|
||||
let s = client.gas_price_statistics(16, 8).unwrap();
|
||||
assert_eq!(s, vec_into![0, 1, 3, 5, 7, 9, 11, 13, 15]);
|
||||
let s = client.gas_price_statistics(32, 8).unwrap();
|
||||
assert_eq!(s, vec_into![0, 1, 3, 5, 7, 9, 11, 13, 15]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_handle_long_fork() {
|
||||
let client_result = generate_dummy_client(1200);
|
||||
|
@ -17,6 +17,7 @@
|
||||
use client::{BlockChainClient, Client, ClientConfig};
|
||||
use common::*;
|
||||
use spec::*;
|
||||
use block::{OpenBlock};
|
||||
use blockchain::{BlockChain, Config as BlockChainConfig};
|
||||
use state::*;
|
||||
use evm::Schedule;
|
||||
@ -85,6 +86,7 @@ impl Engine for TestEngine {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: move everything over to get_null_spec.
|
||||
pub fn get_test_spec() -> Spec {
|
||||
Spec::new_test()
|
||||
}
|
||||
@ -126,7 +128,7 @@ fn create_unverifiable_block(order: u32, parent_hash: H256) -> Bytes {
|
||||
create_test_block(&create_unverifiable_block_header(order, parent_hash))
|
||||
}
|
||||
|
||||
pub fn create_test_block_with_data(header: &Header, transactions: &[&SignedTransaction], uncles: &[Header]) -> Bytes {
|
||||
pub fn create_test_block_with_data(header: &Header, transactions: &[SignedTransaction], uncles: &[Header]) -> Bytes {
|
||||
let mut rlp = RlpStream::new_list(3);
|
||||
rlp.append(header);
|
||||
rlp.begin_list(transactions.len());
|
||||
@ -138,33 +140,74 @@ pub fn create_test_block_with_data(header: &Header, transactions: &[&SignedTrans
|
||||
}
|
||||
|
||||
pub fn generate_dummy_client(block_number: u32) -> GuardedTempResult<Arc<Client>> {
|
||||
generate_dummy_client_with_spec_and_data(Spec::new_test, block_number, 0, &(vec![]))
|
||||
}
|
||||
|
||||
pub fn generate_dummy_client_with_data(block_number: u32, txs_per_block: usize, tx_gas_prices: &[U256]) -> GuardedTempResult<Arc<Client>> {
|
||||
generate_dummy_client_with_spec_and_data(Spec::new_null, block_number, txs_per_block, tx_gas_prices)
|
||||
}
|
||||
|
||||
pub fn generate_dummy_client_with_spec_and_data<F>(get_test_spec: F, block_number: u32, txs_per_block: usize, tx_gas_prices: &[U256]) -> GuardedTempResult<Arc<Client>> where F: Fn()->Spec {
|
||||
let dir = RandomTempPath::new();
|
||||
|
||||
let client = Client::new(ClientConfig::default(), get_test_spec(), dir.as_path(), Arc::new(Miner::default()), IoChannel::disconnected()).unwrap();
|
||||
let test_spec = get_test_spec();
|
||||
let client = Client::new(ClientConfig::default(), get_test_spec(), dir.as_path(), Arc::new(Miner::default()), IoChannel::disconnected()).unwrap();
|
||||
let test_engine = &test_spec.engine;
|
||||
let state_root = test_spec.genesis_header().state_root;
|
||||
let mut rolling_hash = test_spec.genesis_header().hash();
|
||||
let mut rolling_block_number = 1;
|
||||
|
||||
let mut db_result = get_temp_journal_db();
|
||||
let mut db = db_result.take();
|
||||
test_spec.ensure_db_good(db.as_hashdb_mut());
|
||||
let vm_factory = Default::default();
|
||||
let genesis_header = test_spec.genesis_header();
|
||||
|
||||
let mut rolling_timestamp = 40;
|
||||
let mut last_hashes = vec![];
|
||||
let mut last_header = genesis_header.clone();
|
||||
|
||||
let kp = KeyPair::from_secret("".sha3()).unwrap() ;
|
||||
let author = kp.address();
|
||||
|
||||
let mut n = 0;
|
||||
for _ in 0..block_number {
|
||||
let mut header = Header::new();
|
||||
last_hashes.push(last_header.hash());
|
||||
|
||||
header.gas_limit = test_engine.params().min_gas_limit;
|
||||
header.difficulty = U256::from(0x20000);
|
||||
header.timestamp = rolling_timestamp;
|
||||
header.number = rolling_block_number;
|
||||
header.parent_hash = rolling_hash;
|
||||
header.state_root = state_root.clone();
|
||||
// forge block.
|
||||
let mut b = OpenBlock::new(
|
||||
test_engine.deref(),
|
||||
&vm_factory,
|
||||
false,
|
||||
db,
|
||||
&last_header,
|
||||
last_hashes.clone(),
|
||||
author.clone(),
|
||||
3141562.into(),
|
||||
vec![]
|
||||
).unwrap();
|
||||
b.set_difficulty(U256::from(0x20000));
|
||||
rolling_timestamp += 10;
|
||||
b.set_timestamp(rolling_timestamp);
|
||||
|
||||
rolling_hash = header.hash();
|
||||
rolling_block_number = rolling_block_number + 1;
|
||||
rolling_timestamp = rolling_timestamp + 10;
|
||||
// first block we don't have any balance, so can't send any transactions.
|
||||
for _ in 0..txs_per_block {
|
||||
b.push_transaction(Transaction {
|
||||
nonce: n.into(),
|
||||
gas_price: tx_gas_prices[n % tx_gas_prices.len()],
|
||||
gas: 100000.into(),
|
||||
action: Action::Create,
|
||||
data: vec![],
|
||||
value: U256::zero(),
|
||||
}.sign(kp.secret()), None).unwrap();
|
||||
n += 1;
|
||||
}
|
||||
|
||||
if let Err(e) = client.import_block(create_test_block(&header)) {
|
||||
let b = b.close_and_lock().seal(test_engine.deref(), vec![]).unwrap();
|
||||
|
||||
if let Err(e) = client.import_block(b.rlp_bytes()) {
|
||||
panic!("error importing block which is valid by definition: {:?}", e);
|
||||
}
|
||||
|
||||
last_header = BlockView::new(&b.rlp_bytes()).header();
|
||||
db = b.drain();
|
||||
}
|
||||
client.flush_queue();
|
||||
client.import_verified_blocks(&IoChannel::disconnected());
|
||||
|
@ -361,7 +361,7 @@ mod tests {
|
||||
nonce: U256::from(2)
|
||||
}.sign(&keypair.secret());
|
||||
|
||||
let good_transactions = [ &tr1, &tr2 ];
|
||||
let good_transactions = [ tr1.clone(), tr2.clone() ];
|
||||
|
||||
let diff_inc = U256::from(0x40);
|
||||
|
||||
|
@ -159,7 +159,7 @@ pub fn setup_rpc<T: Extendable>(server: T, deps: Arc<Dependencies>, apis: ApiSet
|
||||
server.add_delegate(SignerClient::new(&deps.secret_store, &deps.client, &deps.miner, &deps.signer_queue).to_delegate());
|
||||
},
|
||||
Api::Ethcore => {
|
||||
server.add_delegate(EthcoreClient::new(&deps.miner, deps.logger.clone(), deps.settings.clone()).to_delegate())
|
||||
server.add_delegate(EthcoreClient::new(&deps.client, &deps.miner, deps.logger.clone(), deps.settings.clone()).to_delegate())
|
||||
},
|
||||
Api::EthcoreSet => {
|
||||
server.add_delegate(EthcoreSetClient::new(&deps.miner).to_delegate())
|
||||
|
@ -153,15 +153,23 @@ impl<C, S, A, M, EM> EthClient<C, S, A, M, EM> where
|
||||
}
|
||||
}
|
||||
|
||||
fn default_gas_price(&self) -> Result<U256, Error> {
|
||||
let miner = take_weak!(self.miner);
|
||||
Ok(take_weak!(self.client)
|
||||
.gas_price_statistics(100, 8)
|
||||
.map(|x| x[4])
|
||||
.unwrap_or_else(|_| miner.sensible_gas_price())
|
||||
)
|
||||
}
|
||||
|
||||
fn sign_call(&self, request: CallRequest) -> Result<SignedTransaction, Error> {
|
||||
let client = take_weak!(self.client);
|
||||
let miner = take_weak!(self.miner);
|
||||
let from = request.from.unwrap_or(Address::zero());
|
||||
Ok(EthTransaction {
|
||||
nonce: request.nonce.unwrap_or_else(|| client.latest_nonce(&from)),
|
||||
action: request.to.map_or(Action::Create, Action::Call),
|
||||
gas: request.gas.unwrap_or(U256::from(50_000_000)),
|
||||
gas_price: request.gas_price.unwrap_or_else(|| miner.sensible_gas_price()),
|
||||
gas_price: request.gas_price.unwrap_or_else(|| self.default_gas_price().expect("call only fails if client or miner are unavailable; client and miner are both available to be here; qed")),
|
||||
value: request.value.unwrap_or_else(U256::zero),
|
||||
data: request.data.map_or_else(Vec::new, |d| d.to_vec())
|
||||
}.fake_sign(from))
|
||||
@ -293,7 +301,7 @@ impl<C, S, A, M, EM> Eth for EthClient<C, S, A, M, EM> where
|
||||
|
||||
fn gas_price(&self, params: Params) -> Result<Value, Error> {
|
||||
match params {
|
||||
Params::None => to_value(&take_weak!(self.miner).sensible_gas_price()),
|
||||
Params::None => to_value(&try!(self.default_gas_price())),
|
||||
_ => Err(Error::invalid_params())
|
||||
}
|
||||
}
|
||||
|
@ -15,30 +15,34 @@
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Ethcore-specific rpc implementation.
|
||||
use util::RotatingLogger;
|
||||
use util::{RotatingLogger};
|
||||
use util::network_settings::NetworkSettings;
|
||||
use util::misc::version_data;
|
||||
use std::sync::{Arc, Weak};
|
||||
use std::ops::Deref;
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::{BTreeMap};
|
||||
use ethcore::client::{MiningBlockChainClient};
|
||||
use jsonrpc_core::*;
|
||||
use ethcore::miner::MinerService;
|
||||
use v1::traits::Ethcore;
|
||||
use v1::types::{Bytes};
|
||||
|
||||
/// Ethcore implementation.
|
||||
pub struct EthcoreClient<M> where
|
||||
pub struct EthcoreClient<C, M> where
|
||||
C: MiningBlockChainClient,
|
||||
M: MinerService {
|
||||
|
||||
client: Weak<C>,
|
||||
miner: Weak<M>,
|
||||
logger: Arc<RotatingLogger>,
|
||||
settings: Arc<NetworkSettings>,
|
||||
}
|
||||
|
||||
impl<M> EthcoreClient<M> where M: MinerService {
|
||||
impl<C, M> EthcoreClient<C, M> where C: MiningBlockChainClient, M: MinerService {
|
||||
/// Creates new `EthcoreClient`.
|
||||
pub fn new(miner: &Arc<M>, logger: Arc<RotatingLogger>, settings: Arc<NetworkSettings>) -> Self {
|
||||
pub fn new(client: &Arc<C>, miner: &Arc<M>, logger: Arc<RotatingLogger>, settings: Arc<NetworkSettings>) -> Self {
|
||||
EthcoreClient {
|
||||
client: Arc::downgrade(client),
|
||||
miner: Arc::downgrade(miner),
|
||||
logger: logger,
|
||||
settings: settings,
|
||||
@ -46,7 +50,7 @@ impl<M> EthcoreClient<M> where M: MinerService {
|
||||
}
|
||||
}
|
||||
|
||||
impl<M> Ethcore for EthcoreClient<M> where M: MinerService + 'static {
|
||||
impl<C, M> Ethcore for EthcoreClient<C, M> where M: MinerService + 'static, C: MiningBlockChainClient + 'static {
|
||||
|
||||
fn transactions_limit(&self, _: Params) -> Result<Value, Error> {
|
||||
to_value(&take_weak!(self.miner).transactions_limit())
|
||||
@ -97,8 +101,23 @@ impl<M> Ethcore for EthcoreClient<M> where M: MinerService + 'static {
|
||||
Ok(Value::Object(map))
|
||||
}
|
||||
|
||||
fn default_extra_data(&self, _params: Params) -> Result<Value, Error> {
|
||||
let version = version_data();
|
||||
to_value(&Bytes::new(version))
|
||||
fn default_extra_data(&self, params: Params) -> Result<Value, Error> {
|
||||
match params {
|
||||
Params::None => to_value(&Bytes::new(version_data())),
|
||||
_ => Err(Error::invalid_params()),
|
||||
}
|
||||
}
|
||||
|
||||
fn gas_price_statistics(&self, params: Params) -> Result<Value, Error> {
|
||||
match params {
|
||||
Params::None => match take_weak!(self.client).gas_price_statistics(100, 8) {
|
||||
Ok(stats) => to_value(&stats
|
||||
.iter()
|
||||
.map(|x| to_value(&x).expect("x must be U256; qed"))
|
||||
.collect::<Vec<_>>()),
|
||||
_ => Err(Error::internal_error()),
|
||||
},
|
||||
_ => Err(Error::invalid_params()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ use jsonrpc_core::IoHandler;
|
||||
use v1::{Ethcore, EthcoreClient, EthcoreSet, EthcoreSetClient};
|
||||
use ethcore::miner::MinerService;
|
||||
use v1::tests::helpers::TestMinerService;
|
||||
use ethcore::client::{TestBlockChainClient};
|
||||
use util::numbers::*;
|
||||
use rustc_serialize::hex::FromHex;
|
||||
use util::log::RotatingLogger;
|
||||
@ -29,6 +30,10 @@ fn miner_service() -> Arc<TestMinerService> {
|
||||
Arc::new(TestMinerService::default())
|
||||
}
|
||||
|
||||
fn client_service() -> Arc<TestBlockChainClient> {
|
||||
Arc::new(TestBlockChainClient::default())
|
||||
}
|
||||
|
||||
fn logger() -> Arc<RotatingLogger> {
|
||||
Arc::new(RotatingLogger::new("rpc=trace".to_owned()))
|
||||
}
|
||||
@ -45,19 +50,20 @@ fn settings() -> Arc<NetworkSettings> {
|
||||
})
|
||||
}
|
||||
|
||||
fn ethcore_client(miner: &Arc<TestMinerService>) -> EthcoreClient<TestMinerService> {
|
||||
EthcoreClient::new(&miner, logger(), settings())
|
||||
fn ethcore_client(client: &Arc<TestBlockChainClient>, miner: &Arc<TestMinerService>) -> EthcoreClient<TestBlockChainClient, TestMinerService> {
|
||||
EthcoreClient::new(client, miner, logger(), settings())
|
||||
}
|
||||
|
||||
fn ethcore_set_client(miner: &Arc<TestMinerService>) -> EthcoreSetClient<TestMinerService> {
|
||||
EthcoreSetClient::new(&miner)
|
||||
EthcoreSetClient::new(miner)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_ethcore_extra_data() {
|
||||
let miner = miner_service();
|
||||
let client = client_service();
|
||||
let io = IoHandler::new();
|
||||
io.add_delegate(ethcore_client(&miner).to_delegate());
|
||||
io.add_delegate(ethcore_client(&client, &miner).to_delegate());
|
||||
io.add_delegate(ethcore_set_client(&miner).to_delegate());
|
||||
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_extraData", "params": [], "id": 1}"#;
|
||||
@ -72,8 +78,9 @@ fn rpc_ethcore_default_extra_data() {
|
||||
use util::ToPretty;
|
||||
|
||||
let miner = miner_service();
|
||||
let client = client_service();
|
||||
let io = IoHandler::new();
|
||||
io.add_delegate(ethcore_client(&miner).to_delegate());
|
||||
io.add_delegate(ethcore_client(&client, &miner).to_delegate());
|
||||
io.add_delegate(ethcore_set_client(&miner).to_delegate());
|
||||
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_defaultExtraData", "params": [], "id": 1}"#;
|
||||
@ -85,8 +92,9 @@ fn rpc_ethcore_default_extra_data() {
|
||||
#[test]
|
||||
fn rpc_ethcore_gas_floor_target() {
|
||||
let miner = miner_service();
|
||||
let client = client_service();
|
||||
let io = IoHandler::new();
|
||||
io.add_delegate(ethcore_client(&miner).to_delegate());
|
||||
io.add_delegate(ethcore_client(&client, &miner).to_delegate());
|
||||
io.add_delegate(ethcore_set_client(&miner).to_delegate());
|
||||
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_gasFloorTarget", "params": [], "id": 1}"#;
|
||||
@ -98,8 +106,9 @@ fn rpc_ethcore_gas_floor_target() {
|
||||
#[test]
|
||||
fn rpc_ethcore_min_gas_price() {
|
||||
let miner = miner_service();
|
||||
let client = client_service();
|
||||
let io = IoHandler::new();
|
||||
io.add_delegate(ethcore_client(&miner).to_delegate());
|
||||
io.add_delegate(ethcore_client(&client, &miner).to_delegate());
|
||||
io.add_delegate(ethcore_set_client(&miner).to_delegate());
|
||||
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_minGasPrice", "params": [], "id": 1}"#;
|
||||
@ -111,8 +120,9 @@ fn rpc_ethcore_min_gas_price() {
|
||||
#[test]
|
||||
fn rpc_ethcore_set_min_gas_price() {
|
||||
let miner = miner_service();
|
||||
let client = client_service();
|
||||
let io = IoHandler::new();
|
||||
io.add_delegate(ethcore_client(&miner).to_delegate());
|
||||
io.add_delegate(ethcore_client(&client, &miner).to_delegate());
|
||||
io.add_delegate(ethcore_set_client(&miner).to_delegate());
|
||||
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setMinGasPrice", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
|
||||
@ -125,8 +135,9 @@ fn rpc_ethcore_set_min_gas_price() {
|
||||
#[test]
|
||||
fn rpc_ethcore_set_gas_floor_target() {
|
||||
let miner = miner_service();
|
||||
let client = client_service();
|
||||
let io = IoHandler::new();
|
||||
io.add_delegate(ethcore_client(&miner).to_delegate());
|
||||
io.add_delegate(ethcore_client(&client, &miner).to_delegate());
|
||||
io.add_delegate(ethcore_set_client(&miner).to_delegate());
|
||||
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setGasFloorTarget", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
|
||||
@ -139,8 +150,9 @@ fn rpc_ethcore_set_gas_floor_target() {
|
||||
#[test]
|
||||
fn rpc_ethcore_set_extra_data() {
|
||||
let miner = miner_service();
|
||||
let client = client_service();
|
||||
let io = IoHandler::new();
|
||||
io.add_delegate(ethcore_client(&miner).to_delegate());
|
||||
io.add_delegate(ethcore_client(&client, &miner).to_delegate());
|
||||
io.add_delegate(ethcore_set_client(&miner).to_delegate());
|
||||
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setExtraData", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
|
||||
@ -153,8 +165,9 @@ fn rpc_ethcore_set_extra_data() {
|
||||
#[test]
|
||||
fn rpc_ethcore_set_author() {
|
||||
let miner = miner_service();
|
||||
let client = client_service();
|
||||
let io = IoHandler::new();
|
||||
io.add_delegate(ethcore_client(&miner).to_delegate());
|
||||
io.add_delegate(ethcore_client(&client, &miner).to_delegate());
|
||||
io.add_delegate(ethcore_set_client(&miner).to_delegate());
|
||||
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setAuthor", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
|
||||
@ -167,10 +180,11 @@ fn rpc_ethcore_set_author() {
|
||||
#[test]
|
||||
fn rpc_ethcore_dev_logs() {
|
||||
let miner = miner_service();
|
||||
let client = client_service();
|
||||
let logger = logger();
|
||||
logger.append("a".to_owned());
|
||||
logger.append("b".to_owned());
|
||||
let ethcore = EthcoreClient::new(&miner, logger.clone(), settings()).to_delegate();
|
||||
let ethcore = EthcoreClient::new(&client, &miner, logger.clone(), settings()).to_delegate();
|
||||
let io = IoHandler::new();
|
||||
io.add_delegate(ethcore);
|
||||
io.add_delegate(ethcore_set_client(&miner).to_delegate());
|
||||
@ -184,8 +198,9 @@ fn rpc_ethcore_dev_logs() {
|
||||
#[test]
|
||||
fn rpc_ethcore_dev_logs_levels() {
|
||||
let miner = miner_service();
|
||||
let client = client_service();
|
||||
let io = IoHandler::new();
|
||||
io.add_delegate(ethcore_client(&miner).to_delegate());
|
||||
io.add_delegate(ethcore_client(&client, &miner).to_delegate());
|
||||
io.add_delegate(ethcore_set_client(&miner).to_delegate());
|
||||
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_devLogsLevels", "params":[], "id": 1}"#;
|
||||
@ -196,8 +211,9 @@ fn rpc_ethcore_dev_logs_levels() {
|
||||
#[test]
|
||||
fn rpc_ethcore_set_transactions_limit() {
|
||||
let miner = miner_service();
|
||||
let client = client_service();
|
||||
let io = IoHandler::new();
|
||||
io.add_delegate(ethcore_client(&miner).to_delegate());
|
||||
io.add_delegate(ethcore_client(&client, &miner).to_delegate());
|
||||
io.add_delegate(ethcore_set_client(&miner).to_delegate());
|
||||
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setTransactionsLimit", "params":[10240240], "id": 1}"#;
|
||||
@ -210,8 +226,9 @@ fn rpc_ethcore_set_transactions_limit() {
|
||||
#[test]
|
||||
fn rpc_ethcore_transactions_limit() {
|
||||
let miner = miner_service();
|
||||
let client = client_service();
|
||||
let io = IoHandler::new();
|
||||
io.add_delegate(ethcore_client(&miner).to_delegate());
|
||||
io.add_delegate(ethcore_client(&client, &miner).to_delegate());
|
||||
io.add_delegate(ethcore_set_client(&miner).to_delegate());
|
||||
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_transactionsLimit", "params":[], "id": 1}"#;
|
||||
@ -223,8 +240,9 @@ fn rpc_ethcore_transactions_limit() {
|
||||
#[test]
|
||||
fn rpc_ethcore_net_chain() {
|
||||
let miner = miner_service();
|
||||
let client = client_service();
|
||||
let io = IoHandler::new();
|
||||
io.add_delegate(ethcore_client(&miner).to_delegate());
|
||||
io.add_delegate(ethcore_client(&client, &miner).to_delegate());
|
||||
io.add_delegate(ethcore_set_client(&miner).to_delegate());
|
||||
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_netChain", "params":[], "id": 1}"#;
|
||||
@ -236,8 +254,9 @@ fn rpc_ethcore_net_chain() {
|
||||
#[test]
|
||||
fn rpc_ethcore_net_max_peers() {
|
||||
let miner = miner_service();
|
||||
let client = client_service();
|
||||
let io = IoHandler::new();
|
||||
io.add_delegate(ethcore_client(&miner).to_delegate());
|
||||
io.add_delegate(ethcore_client(&client, &miner).to_delegate());
|
||||
io.add_delegate(ethcore_set_client(&miner).to_delegate());
|
||||
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_netMaxPeers", "params":[], "id": 1}"#;
|
||||
@ -249,8 +268,9 @@ fn rpc_ethcore_net_max_peers() {
|
||||
#[test]
|
||||
fn rpc_ethcore_net_port() {
|
||||
let miner = miner_service();
|
||||
let client = client_service();
|
||||
let io = IoHandler::new();
|
||||
io.add_delegate(ethcore_client(&miner).to_delegate());
|
||||
io.add_delegate(ethcore_client(&client, &miner).to_delegate());
|
||||
io.add_delegate(ethcore_set_client(&miner).to_delegate());
|
||||
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_netPort", "params":[], "id": 1}"#;
|
||||
@ -262,8 +282,9 @@ fn rpc_ethcore_net_port() {
|
||||
#[test]
|
||||
fn rpc_ethcore_rpc_settings() {
|
||||
let miner = miner_service();
|
||||
let client = client_service();
|
||||
let io = IoHandler::new();
|
||||
io.add_delegate(ethcore_client(&miner).to_delegate());
|
||||
io.add_delegate(ethcore_client(&client, &miner).to_delegate());
|
||||
io.add_delegate(ethcore_set_client(&miner).to_delegate());
|
||||
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_rpcSettings", "params":[], "id": 1}"#;
|
||||
@ -275,8 +296,9 @@ fn rpc_ethcore_rpc_settings() {
|
||||
#[test]
|
||||
fn rpc_ethcore_node_name() {
|
||||
let miner = miner_service();
|
||||
let client = client_service();
|
||||
let io = IoHandler::new();
|
||||
io.add_delegate(ethcore_client(&miner).to_delegate());
|
||||
io.add_delegate(ethcore_client(&client, &miner).to_delegate());
|
||||
io.add_delegate(ethcore_set_client(&miner).to_delegate());
|
||||
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_nodeName", "params":[], "id": 1}"#;
|
||||
|
@ -57,6 +57,9 @@ pub trait Ethcore: Sized + Send + Sync + 'static {
|
||||
/// Returns default extra data
|
||||
fn default_extra_data(&self, _: Params) -> Result<Value, Error>;
|
||||
|
||||
/// Returns distribution of gas price in latest blocks.
|
||||
fn gas_price_statistics(&self, _: Params) -> Result<Value, Error>;
|
||||
|
||||
/// Should be used to convert object to io delegate.
|
||||
fn to_delegate(self) -> IoDelegate<Self> {
|
||||
let mut delegate = IoDelegate::new(Arc::new(self));
|
||||
@ -73,6 +76,7 @@ pub trait Ethcore: Sized + Send + Sync + 'static {
|
||||
delegate.add_method("ethcore_rpcSettings", Ethcore::rpc_settings);
|
||||
delegate.add_method("ethcore_nodeName", Ethcore::node_name);
|
||||
delegate.add_method("ethcore_defaultExtraData", Ethcore::default_extra_data);
|
||||
delegate.add_method("ethcore_gasPriceStatistics", Ethcore::gas_price_statistics);
|
||||
|
||||
delegate
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user