Merge branch 'master' into miner-no-default
Conflicts: sync/src/lib.rs
This commit is contained in:
@@ -23,7 +23,7 @@ ethcore-devtools = { path = "../devtools" }
|
||||
rustc-serialize = "0.3"
|
||||
transient-hashmap = "0.1"
|
||||
serde_macros = { version = "0.7.0", optional = true }
|
||||
clippy = { version = "0.0.76", optional = true}
|
||||
clippy = { version = "0.0.77", optional = true}
|
||||
json-ipc-server = { git = "https://github.com/ethcore/json-ipc-server.git" }
|
||||
|
||||
[build-dependencies]
|
||||
|
||||
@@ -69,6 +69,12 @@ pub trait SigningQueue: Send + Sync {
|
||||
|
||||
/// Return copy of all the requests in the queue.
|
||||
fn requests(&self) -> Vec<TransactionConfirmation>;
|
||||
|
||||
/// Returns number of transactions awaiting confirmation.
|
||||
fn len(&self) -> usize;
|
||||
|
||||
/// Returns true if there are no transactions awaiting confirmation.
|
||||
fn is_empty(&self) -> bool;
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
@@ -277,6 +283,16 @@ impl SigningQueue for ConfirmationsQueue {
|
||||
let queue = self.queue.read().unwrap();
|
||||
queue.values().map(|token| token.request.clone()).collect()
|
||||
}
|
||||
|
||||
fn len(&self) -> usize {
|
||||
let queue = self.queue.read().unwrap();
|
||||
queue.len()
|
||||
}
|
||||
|
||||
fn is_empty(&self) -> bool {
|
||||
let queue = self.queue.read().unwrap();
|
||||
queue.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ use ethcore::filter::Filter as EthcoreFilter;
|
||||
use self::ethash::SeedHashCompute;
|
||||
use v1::traits::Eth;
|
||||
use v1::types::{Block, BlockTransactions, BlockNumber, Bytes, SyncStatus, SyncInfo, Transaction, CallRequest, OptionalValue, Index, Filter, Log, Receipt};
|
||||
use v1::impls::{dispatch_transaction, error_codes};
|
||||
use v1::impls::{default_gas_price, dispatch_transaction, error_codes};
|
||||
use serde;
|
||||
|
||||
/// Eth rpc implementation.
|
||||
@@ -153,23 +153,14 @@ impl<C, S, M, EM> EthClient<C, S, 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 (client, miner) = (take_weak!(self.client), 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(|| self.default_gas_price().expect("call only fails if client or miner are unavailable; client and miner are both available to be here; qed")),
|
||||
gas_price: request.gas_price.unwrap_or_else(|| default_gas_price(&*client, &*miner)),
|
||||
value: request.value.unwrap_or_else(U256::zero),
|
||||
data: request.data.map_or_else(Vec::new, |d| d.to_vec())
|
||||
}.fake_sign(from))
|
||||
@@ -296,7 +287,10 @@ impl<C, S, M, EM> Eth for EthClient<C, S, M, EM> where
|
||||
|
||||
fn gas_price(&self, params: Params) -> Result<Value, Error> {
|
||||
match params {
|
||||
Params::None => to_value(&try!(self.default_gas_price())),
|
||||
Params::None => {
|
||||
let (client, miner) = (take_weak!(self.client), take_weak!(self.miner));
|
||||
to_value(&default_gas_price(&*client, &*miner))
|
||||
}
|
||||
_ => Err(Error::invalid_params())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,38 +25,44 @@ use ethcore::account_provider::AccountProvider;
|
||||
use v1::helpers::{SigningQueue, ConfirmationsQueue};
|
||||
use v1::traits::EthSigning;
|
||||
use v1::types::{TransactionRequest, Bytes};
|
||||
use v1::impls::sign_and_dispatch;
|
||||
use v1::impls::{default_gas_price, sign_and_dispatch};
|
||||
|
||||
fn fill_optional_fields<C, M>(request: &mut TransactionRequest, client: &C, miner: &M)
|
||||
where C: MiningBlockChainClient, M: MinerService {
|
||||
if request.gas.is_none() {
|
||||
request.gas = Some(miner.sensible_gas_limit());
|
||||
}
|
||||
if request.gas_price.is_none() {
|
||||
request.gas_price = Some(default_gas_price(client, miner));
|
||||
}
|
||||
if request.data.is_none() {
|
||||
request.data = Some(Bytes::new(Vec::new()));
|
||||
}
|
||||
}
|
||||
|
||||
/// Implementation of functions that require signing when no trusted signer is used.
|
||||
pub struct EthSigningQueueClient<M: MinerService> {
|
||||
pub struct EthSigningQueueClient<C, M> where C: MiningBlockChainClient, M: MinerService {
|
||||
queue: Weak<ConfirmationsQueue>,
|
||||
accounts: Weak<AccountProvider>,
|
||||
client: Weak<C>,
|
||||
miner: Weak<M>,
|
||||
}
|
||||
|
||||
impl<M: MinerService> EthSigningQueueClient<M> {
|
||||
impl<C, M> EthSigningQueueClient<C, M> where C: MiningBlockChainClient, M: MinerService {
|
||||
/// Creates a new signing queue client given shared signing queue.
|
||||
pub fn new(queue: &Arc<ConfirmationsQueue>, miner: &Arc<M>) -> Self {
|
||||
pub fn new(queue: &Arc<ConfirmationsQueue>, client: &Arc<C>, miner: &Arc<M>, accounts: &Arc<AccountProvider>) -> Self {
|
||||
EthSigningQueueClient {
|
||||
queue: Arc::downgrade(queue),
|
||||
accounts: Arc::downgrade(accounts),
|
||||
client: Arc::downgrade(client),
|
||||
miner: Arc::downgrade(miner),
|
||||
}
|
||||
}
|
||||
|
||||
fn fill_optional_fields(&self, miner: Arc<M>, mut request: TransactionRequest) -> TransactionRequest {
|
||||
if let None = request.gas {
|
||||
request.gas = Some(miner.sensible_gas_limit());
|
||||
}
|
||||
if let None = request.gas_price {
|
||||
request.gas_price = Some(miner.sensible_gas_price());
|
||||
}
|
||||
if let None = request.data {
|
||||
request.data = Some(Bytes::new(Vec::new()));
|
||||
}
|
||||
request
|
||||
}
|
||||
}
|
||||
|
||||
impl<M: MinerService + 'static> EthSigning for EthSigningQueueClient<M> {
|
||||
impl<C, M> EthSigning for EthSigningQueueClient<C, M>
|
||||
where C: MiningBlockChainClient + 'static, M: MinerService + 'static
|
||||
{
|
||||
|
||||
fn sign(&self, _params: Params) -> Result<Value, Error> {
|
||||
warn!("Invoking eth_sign is not yet supported with signer enabled.");
|
||||
@@ -66,10 +72,20 @@ impl<M: MinerService + 'static> EthSigning for EthSigningQueueClient<M> {
|
||||
|
||||
fn send_transaction(&self, params: Params) -> Result<Value, Error> {
|
||||
from_params::<(TransactionRequest, )>(params)
|
||||
.and_then(|(request, )| {
|
||||
.and_then(|(mut request, )| {
|
||||
let accounts = take_weak!(self.accounts);
|
||||
let (client, miner) = (take_weak!(self.client), take_weak!(self.miner));
|
||||
|
||||
if accounts.is_unlocked(request.from) {
|
||||
let sender = request.from;
|
||||
return match sign_and_dispatch(&*client, &*miner, request, &*accounts, sender) {
|
||||
Ok(hash) => to_value(&hash),
|
||||
_ => to_value(&H256::zero()),
|
||||
}
|
||||
}
|
||||
|
||||
let queue = take_weak!(self.queue);
|
||||
let miner = take_weak!(self.miner);
|
||||
let request = self.fill_optional_fields(miner, request);
|
||||
fill_optional_fields(&mut request, &*client, &*miner);
|
||||
let id = queue.add_request(request);
|
||||
let result = id.wait_with_timeout();
|
||||
result.unwrap_or_else(|| to_value(&H256::new()))
|
||||
|
||||
@@ -26,6 +26,8 @@ use jsonrpc_core::*;
|
||||
use ethcore::miner::MinerService;
|
||||
use v1::traits::Ethcore;
|
||||
use v1::types::{Bytes};
|
||||
use v1::helpers::{SigningQueue, ConfirmationsQueue};
|
||||
use v1::impls::error_codes;
|
||||
|
||||
/// Ethcore implementation.
|
||||
pub struct EthcoreClient<C, M> where
|
||||
@@ -36,16 +38,18 @@ pub struct EthcoreClient<C, M> where
|
||||
miner: Weak<M>,
|
||||
logger: Arc<RotatingLogger>,
|
||||
settings: Arc<NetworkSettings>,
|
||||
confirmations_queue: Option<Arc<ConfirmationsQueue>>,
|
||||
}
|
||||
|
||||
impl<C, M> EthcoreClient<C, M> where C: MiningBlockChainClient, M: MinerService {
|
||||
/// Creates new `EthcoreClient`.
|
||||
pub fn new(client: &Arc<C>, 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>, queue: Option<Arc<ConfirmationsQueue>>) -> Self {
|
||||
EthcoreClient {
|
||||
client: Arc::downgrade(client),
|
||||
miner: Arc::downgrade(miner),
|
||||
logger: logger,
|
||||
settings: settings,
|
||||
confirmations_queue: queue,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -120,4 +124,15 @@ impl<C, M> Ethcore for EthcoreClient<C, M> where M: MinerService + 'static, C: M
|
||||
_ => Err(Error::invalid_params()),
|
||||
}
|
||||
}
|
||||
|
||||
fn unsigned_transactions_count(&self, _params: Params) -> Result<Value, Error> {
|
||||
match self.confirmations_queue {
|
||||
None => Err(Error {
|
||||
code: ErrorCode::ServerError(error_codes::SIGNER_DISABLED),
|
||||
message: "Trusted Signer is disabled. This API is not available.".into(),
|
||||
data: None
|
||||
}),
|
||||
Some(ref queue) => to_value(&queue.len()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,9 +16,11 @@
|
||||
|
||||
/// Ethcore-specific rpc interface for operations altering the settings.
|
||||
use util::{U256, Address};
|
||||
use util::network::{NetworkService, NonReservedPeerMode};
|
||||
use std::sync::{Arc, Weak};
|
||||
use jsonrpc_core::*;
|
||||
use ethcore::miner::MinerService;
|
||||
use ethcore::service::SyncMessage;
|
||||
use v1::traits::EthcoreSet;
|
||||
use v1::types::{Bytes};
|
||||
|
||||
@@ -27,13 +29,15 @@ pub struct EthcoreSetClient<M> where
|
||||
M: MinerService {
|
||||
|
||||
miner: Weak<M>,
|
||||
net: Weak<NetworkService<SyncMessage>>,
|
||||
}
|
||||
|
||||
impl<M> EthcoreSetClient<M> where M: MinerService {
|
||||
/// Creates new `EthcoreSetClient`.
|
||||
pub fn new(miner: &Arc<M>) -> Self {
|
||||
pub fn new(miner: &Arc<M>, net: &Arc<NetworkService<SyncMessage>>) -> Self {
|
||||
EthcoreSetClient {
|
||||
miner: Arc::downgrade(miner),
|
||||
net: Arc::downgrade(net),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -75,4 +79,31 @@ impl<M> EthcoreSet for EthcoreSetClient<M> where M: MinerService + 'static {
|
||||
})
|
||||
}
|
||||
|
||||
fn add_reserved_peer(&self, params: Params) -> Result<Value, Error> {
|
||||
from_params::<(String,)>(params).and_then(|(peer,)| {
|
||||
match take_weak!(self.net).add_reserved_peer(&peer) {
|
||||
Ok(()) => to_value(&true),
|
||||
Err(_) => Err(Error::invalid_params()),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn remove_reserved_peer(&self, params: Params) -> Result<Value, Error> {
|
||||
from_params::<(String,)>(params).and_then(|(peer,)| {
|
||||
match take_weak!(self.net).remove_reserved_peer(&peer) {
|
||||
Ok(()) => to_value(&true),
|
||||
Err(_) => Err(Error::invalid_params()),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn drop_non_reserved_peers(&self, _: Params) -> Result<Value, Error> {
|
||||
take_weak!(self.net).set_non_reserved_mode(NonReservedPeerMode::Deny);
|
||||
to_value(&true)
|
||||
}
|
||||
|
||||
fn accept_non_reserved_peers(&self, _: Params) -> Result<Value, Error> {
|
||||
take_weak!(self.net).set_non_reserved_mode(NonReservedPeerMode::Accept);
|
||||
to_value(&true)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,6 +71,7 @@ mod error_codes {
|
||||
pub const UNKNOWN_ERROR: i64 = -32002;
|
||||
pub const TRANSACTION_ERROR: i64 = -32010;
|
||||
pub const ACCOUNT_LOCKED: i64 = -32020;
|
||||
pub const SIGNER_DISABLED: i64 = -32030;
|
||||
}
|
||||
|
||||
fn dispatch_transaction<C, M>(client: &C, miner: &M, signed_transaction: SignedTransaction) -> Result<Value, Error>
|
||||
@@ -99,7 +100,7 @@ fn prepare_transaction<C, M>(client: &C, miner: &M, request: TransactionRequest)
|
||||
|
||||
action: request.to.map_or(Action::Create, Action::Call),
|
||||
gas: request.gas.unwrap_or_else(|| miner.sensible_gas_limit()),
|
||||
gas_price: request.gas_price.unwrap_or_else(|| miner.sensible_gas_price()),
|
||||
gas_price: request.gas_price.unwrap_or_else(|| default_gas_price(client, miner)),
|
||||
value: request.value.unwrap_or_else(U256::zero),
|
||||
data: request.data.map_or_else(Vec::new, |b| b.to_vec()),
|
||||
}
|
||||
@@ -133,6 +134,14 @@ fn sign_and_dispatch<C, M>(client: &C, miner: &M, request: TransactionRequest, a
|
||||
dispatch_transaction(&*client, &*miner, signed_transaction)
|
||||
}
|
||||
|
||||
fn default_gas_price<C, M>(client: &C, miner: &M) -> U256 where C: MiningBlockChainClient, M: MinerService {
|
||||
client
|
||||
.gas_price_statistics(100, 8)
|
||||
.map(|x| x[4])
|
||||
.unwrap_or_else(|_| miner.sensible_gas_price())
|
||||
}
|
||||
|
||||
|
||||
fn signing_error(error: AccountError) -> Error {
|
||||
Error {
|
||||
code: ErrorCode::ServerError(error_codes::ACCOUNT_LOCKED),
|
||||
|
||||
@@ -49,7 +49,7 @@ fn sync_provider() -> Arc<TestSyncProvider> {
|
||||
}
|
||||
|
||||
fn miner_service(spec: Spec, accounts: Arc<AccountProvider>) -> Arc<Miner> {
|
||||
Miner::with_accounts(true, spec, accounts)
|
||||
Miner::new(true, spec, Some(accounts))
|
||||
}
|
||||
|
||||
fn make_spec(chain: &BlockChain) -> Spec {
|
||||
@@ -183,7 +183,8 @@ const TRANSACTION_COUNT_SPEC: &'static [u8] = br#"{
|
||||
"durationLimit": "0x0d",
|
||||
"blockReward": "0x4563918244F40000",
|
||||
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
||||
"frontierCompatibilityModeLimit": "0xffffffffffffffff"
|
||||
"frontierCompatibilityModeLimit": "0xffffffffffffffff",
|
||||
"daoRescueSoftFork": false
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -115,7 +115,7 @@ impl MinerService for TestMinerService {
|
||||
}
|
||||
|
||||
/// Imports transactions to transaction queue.
|
||||
fn import_transactions<T>(&self, transactions: Vec<SignedTransaction>, fetch_account: T) ->
|
||||
fn import_transactions<T>(&self, _chain: &MiningBlockChainClient, transactions: Vec<SignedTransaction>, fetch_account: T) ->
|
||||
Vec<Result<TransactionImportResult, Error>>
|
||||
where T: Fn(&Address) -> AccountDetails {
|
||||
// lets assume that all txs are valid
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
// 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::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
use jsonrpc_core::IoHandler;
|
||||
use v1::impls::EthSigningQueueClient;
|
||||
@@ -21,23 +22,33 @@ use v1::traits::EthSigning;
|
||||
use v1::helpers::{ConfirmationsQueue, SigningQueue};
|
||||
use v1::tests::helpers::TestMinerService;
|
||||
use util::{Address, FixedHash};
|
||||
use util::numbers::{Uint, U256};
|
||||
use ethcore::account_provider::AccountProvider;
|
||||
use ethcore::client::TestBlockChainClient;
|
||||
use ethcore::transaction::{Transaction, Action};
|
||||
|
||||
struct EthSigningTester {
|
||||
pub queue: Arc<ConfirmationsQueue>,
|
||||
pub client: Arc<TestBlockChainClient>,
|
||||
pub miner: Arc<TestMinerService>,
|
||||
pub accounts: Arc<AccountProvider>,
|
||||
pub io: IoHandler,
|
||||
}
|
||||
|
||||
impl Default for EthSigningTester {
|
||||
fn default() -> Self {
|
||||
let queue = Arc::new(ConfirmationsQueue::default());
|
||||
let client = Arc::new(TestBlockChainClient::default());
|
||||
let miner = Arc::new(TestMinerService::default());
|
||||
let accounts = Arc::new(AccountProvider::transient_provider());
|
||||
let io = IoHandler::new();
|
||||
io.add_delegate(EthSigningQueueClient::new(&queue, &miner).to_delegate());
|
||||
io.add_delegate(EthSigningQueueClient::new(&queue, &client, &miner, &accounts).to_delegate());
|
||||
|
||||
EthSigningTester {
|
||||
queue: queue,
|
||||
client: client,
|
||||
miner: miner,
|
||||
accounts: accounts,
|
||||
io: io,
|
||||
}
|
||||
}
|
||||
@@ -74,5 +85,41 @@ fn should_add_transaction_to_queue() {
|
||||
// then
|
||||
assert_eq!(tester.io.handle_request(&request), Some(response.to_owned()));
|
||||
assert_eq!(tester.queue.requests().len(), 1);
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_dispatch_transaction_if_account_is_unlocked() {
|
||||
// given
|
||||
let tester = eth_signing();
|
||||
let acc = tester.accounts.new_account("test").unwrap();
|
||||
tester.accounts.unlock_account_permanently(acc, "test".into()).unwrap();
|
||||
|
||||
let t = Transaction {
|
||||
nonce: U256::zero(),
|
||||
gas_price: U256::from(0x9184e72a000u64),
|
||||
gas: U256::from(0x76c0),
|
||||
action: Action::Call(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()),
|
||||
value: U256::from(0x9184e72au64),
|
||||
data: vec![]
|
||||
};
|
||||
let signature = tester.accounts.sign(acc, t.hash()).unwrap();
|
||||
let t = t.with_signature(signature);
|
||||
|
||||
// when
|
||||
let request = r#"{
|
||||
"jsonrpc": "2.0",
|
||||
"method": "eth_sendTransaction",
|
||||
"params": [{
|
||||
"from": ""#.to_owned() + format!("0x{:?}", acc).as_ref() + r#"",
|
||||
"to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
|
||||
"gas": "0x76c0",
|
||||
"gasPrice": "0x9184e72a000",
|
||||
"value": "0x9184e72a"
|
||||
}],
|
||||
"id": 1
|
||||
}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":""#.to_owned() + format!("0x{:?}", t.hash()).as_ref() + r#"","id":1}"#;
|
||||
|
||||
// then
|
||||
assert_eq!(tester.io.handle_request(&request), Some(response.to_owned()));
|
||||
}
|
||||
|
||||
@@ -15,14 +15,11 @@
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::str::FromStr;
|
||||
use jsonrpc_core::IoHandler;
|
||||
use v1::{Ethcore, EthcoreClient, EthcoreSet, EthcoreSetClient};
|
||||
use ethcore::miner::MinerService;
|
||||
use v1::{Ethcore, EthcoreClient};
|
||||
use v1::tests::helpers::TestMinerService;
|
||||
use v1::helpers::ConfirmationsQueue;
|
||||
use ethcore::client::{TestBlockChainClient};
|
||||
use util::numbers::*;
|
||||
use rustc_serialize::hex::FromHex;
|
||||
use util::log::RotatingLogger;
|
||||
use util::network_settings::NetworkSettings;
|
||||
|
||||
@@ -51,11 +48,7 @@ fn settings() -> Arc<NetworkSettings> {
|
||||
}
|
||||
|
||||
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)
|
||||
EthcoreClient::new(client, miner, logger(), settings(), None)
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -64,7 +57,6 @@ fn rpc_ethcore_extra_data() {
|
||||
let client = client_service();
|
||||
let io = IoHandler::new();
|
||||
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}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":"0x01020304","id":1}"#;
|
||||
@@ -81,7 +73,6 @@ fn rpc_ethcore_default_extra_data() {
|
||||
let client = client_service();
|
||||
let io = IoHandler::new();
|
||||
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}"#;
|
||||
let response = format!(r#"{{"jsonrpc":"2.0","result":"0x{}","id":1}}"#, misc::version_data().to_hex());
|
||||
@@ -95,7 +86,6 @@ fn rpc_ethcore_gas_floor_target() {
|
||||
let client = client_service();
|
||||
let io = IoHandler::new();
|
||||
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}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":"0x3039","id":1}"#;
|
||||
@@ -109,7 +99,6 @@ fn rpc_ethcore_min_gas_price() {
|
||||
let client = client_service();
|
||||
let io = IoHandler::new();
|
||||
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}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":"0x01312d00","id":1}"#;
|
||||
@@ -117,66 +106,6 @@ fn rpc_ethcore_min_gas_price() {
|
||||
assert_eq!(io.handle_request(request), Some(response.to_owned()));
|
||||
}
|
||||
|
||||
#[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(&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}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||
|
||||
assert_eq!(io.handle_request(request), Some(response.to_owned()));
|
||||
assert_eq!(miner.minimal_gas_price(), U256::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap());
|
||||
}
|
||||
|
||||
#[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(&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}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||
|
||||
assert_eq!(io.handle_request(request), Some(response.to_owned()));
|
||||
assert_eq!(miner.gas_floor_target(), U256::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_ethcore_set_extra_data() {
|
||||
let miner = miner_service();
|
||||
let client = client_service();
|
||||
let io = IoHandler::new();
|
||||
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}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||
|
||||
assert_eq!(io.handle_request(request), Some(response.to_owned()));
|
||||
assert_eq!(miner.extra_data(), "cd1722f3947def4cf144679da39c4c32bdc35681".from_hex().unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_ethcore_set_author() {
|
||||
let miner = miner_service();
|
||||
let client = client_service();
|
||||
let io = IoHandler::new();
|
||||
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}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||
|
||||
assert_eq!(io.handle_request(request), Some(response.to_owned()));
|
||||
assert_eq!(miner.author(), Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_ethcore_dev_logs() {
|
||||
let miner = miner_service();
|
||||
@@ -184,10 +113,9 @@ fn rpc_ethcore_dev_logs() {
|
||||
let logger = logger();
|
||||
logger.append("a".to_owned());
|
||||
logger.append("b".to_owned());
|
||||
let ethcore = EthcoreClient::new(&client, &miner, logger.clone(), settings()).to_delegate();
|
||||
let ethcore = EthcoreClient::new(&client, &miner, logger.clone(), settings(), None).to_delegate();
|
||||
let io = IoHandler::new();
|
||||
io.add_delegate(ethcore);
|
||||
io.add_delegate(ethcore_set_client(&miner).to_delegate());
|
||||
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_devLogs", "params":[], "id": 1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":["b","a"],"id":1}"#;
|
||||
@@ -201,26 +129,11 @@ fn rpc_ethcore_dev_logs_levels() {
|
||||
let client = client_service();
|
||||
let io = IoHandler::new();
|
||||
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}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":"rpc=trace","id":1}"#;
|
||||
assert_eq!(io.handle_request(request), Some(response.to_owned()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_ethcore_set_transactions_limit() {
|
||||
let miner = miner_service();
|
||||
let client = client_service();
|
||||
let io = IoHandler::new();
|
||||
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}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||
|
||||
assert_eq!(io.handle_request(request), Some(response.to_owned()));
|
||||
assert_eq!(miner.transactions_limit(), 10_240_240);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -229,7 +142,6 @@ fn rpc_ethcore_transactions_limit() {
|
||||
let client = client_service();
|
||||
let io = IoHandler::new();
|
||||
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}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":1024,"id":1}"#;
|
||||
@@ -243,7 +155,6 @@ fn rpc_ethcore_net_chain() {
|
||||
let client = client_service();
|
||||
let io = IoHandler::new();
|
||||
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}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":"testchain","id":1}"#;
|
||||
@@ -257,7 +168,6 @@ fn rpc_ethcore_net_max_peers() {
|
||||
let client = client_service();
|
||||
let io = IoHandler::new();
|
||||
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}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":25,"id":1}"#;
|
||||
@@ -271,7 +181,6 @@ fn rpc_ethcore_net_port() {
|
||||
let client = client_service();
|
||||
let io = IoHandler::new();
|
||||
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}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":30303,"id":1}"#;
|
||||
@@ -285,7 +194,6 @@ fn rpc_ethcore_rpc_settings() {
|
||||
let client = client_service();
|
||||
let io = IoHandler::new();
|
||||
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}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":{"enabled":true,"interface":"all","port":8545},"id":1}"#;
|
||||
@@ -299,10 +207,37 @@ fn rpc_ethcore_node_name() {
|
||||
let client = client_service();
|
||||
let io = IoHandler::new();
|
||||
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}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":"mynode","id":1}"#;
|
||||
|
||||
assert_eq!(io.handle_request(request), Some(response.to_owned()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_ethcore_unsigned_transactions_count() {
|
||||
let miner = miner_service();
|
||||
let client = client_service();
|
||||
let io = IoHandler::new();
|
||||
let queue = Arc::new(ConfirmationsQueue::default());
|
||||
let ethcore = EthcoreClient::new(&client, &miner, logger(), settings(), Some(queue)).to_delegate();
|
||||
io.add_delegate(ethcore);
|
||||
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_unsignedTransactionsCount", "params":[], "id": 1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":0,"id":1}"#;
|
||||
|
||||
assert_eq!(io.handle_request(request), Some(response.to_owned()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_ethcore_unsigned_transactions_count_when_signer_disabled() {
|
||||
let miner = miner_service();
|
||||
let client = client_service();
|
||||
let io = IoHandler::new();
|
||||
io.add_delegate(ethcore_client(&client, &miner).to_delegate());
|
||||
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_unsignedTransactionsCount", "params":[], "id": 1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","error":{"code":-32030,"message":"Trusted Signer is disabled. This API is not available.","data":null},"id":1}"#;
|
||||
|
||||
assert_eq!(io.handle_request(request), Some(response.to_owned()));
|
||||
}
|
||||
|
||||
107
rpc/src/v1/tests/mocked/ethcore_set.rs
Normal file
107
rpc/src/v1/tests/mocked/ethcore_set.rs
Normal file
@@ -0,0 +1,107 @@
|
||||
// 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::sync::Arc;
|
||||
use std::str::FromStr;
|
||||
use jsonrpc_core::IoHandler;
|
||||
use v1::{EthcoreSet, EthcoreSetClient};
|
||||
use ethcore::miner::MinerService;
|
||||
use ethcore::service::SyncMessage;
|
||||
use v1::tests::helpers::TestMinerService;
|
||||
use util::numbers::*;
|
||||
use util::network::{NetworkConfiguration, NetworkService};
|
||||
use rustc_serialize::hex::FromHex;
|
||||
|
||||
fn miner_service() -> Arc<TestMinerService> {
|
||||
Arc::new(TestMinerService::default())
|
||||
}
|
||||
|
||||
fn network_service() -> Arc<NetworkService<SyncMessage>> {
|
||||
Arc::new(NetworkService::new(NetworkConfiguration::new()).unwrap())
|
||||
}
|
||||
|
||||
fn ethcore_set_client(miner: &Arc<TestMinerService>, net: &Arc<NetworkService<SyncMessage>>) -> EthcoreSetClient<TestMinerService> {
|
||||
EthcoreSetClient::new(miner, net)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_ethcore_set_min_gas_price() {
|
||||
let miner = miner_service();
|
||||
let network = network_service();
|
||||
let io = IoHandler::new();
|
||||
io.add_delegate(ethcore_set_client(&miner, &network).to_delegate());
|
||||
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setMinGasPrice", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||
|
||||
assert_eq!(io.handle_request(request), Some(response.to_owned()));
|
||||
assert_eq!(miner.minimal_gas_price(), U256::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap());
|
||||
}
|
||||
#[test]
|
||||
fn rpc_ethcore_set_gas_floor_target() {
|
||||
let miner = miner_service();
|
||||
let network = network_service();
|
||||
let io = IoHandler::new();
|
||||
io.add_delegate(ethcore_set_client(&miner, &network).to_delegate());
|
||||
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setGasFloorTarget", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||
|
||||
assert_eq!(io.handle_request(request), Some(response.to_owned()));
|
||||
assert_eq!(miner.gas_floor_target(), U256::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_ethcore_set_extra_data() {
|
||||
let miner = miner_service();
|
||||
let network = network_service();
|
||||
let io = IoHandler::new();
|
||||
io.add_delegate(ethcore_set_client(&miner, &network).to_delegate());
|
||||
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setExtraData", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||
|
||||
assert_eq!(io.handle_request(request), Some(response.to_owned()));
|
||||
assert_eq!(miner.extra_data(), "cd1722f3947def4cf144679da39c4c32bdc35681".from_hex().unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_ethcore_set_author() {
|
||||
let miner = miner_service();
|
||||
let network = network_service();
|
||||
let io = IoHandler::new();
|
||||
io.add_delegate(ethcore_set_client(&miner, &network).to_delegate());
|
||||
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setAuthor", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||
|
||||
assert_eq!(io.handle_request(request), Some(response.to_owned()));
|
||||
assert_eq!(miner.author(), Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_ethcore_set_transactions_limit() {
|
||||
let miner = miner_service();
|
||||
let network = network_service();
|
||||
let io = IoHandler::new();
|
||||
io.add_delegate(ethcore_set_client(&miner, &network).to_delegate());
|
||||
|
||||
let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setTransactionsLimit", "params":[10240240], "id": 1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
|
||||
|
||||
assert_eq!(io.handle_request(request), Some(response.to_owned()));
|
||||
assert_eq!(miner.transactions_limit(), 10_240_240);
|
||||
}
|
||||
@@ -24,4 +24,5 @@ mod web3;
|
||||
mod personal;
|
||||
mod personal_signer;
|
||||
mod ethcore;
|
||||
mod ethcore_set;
|
||||
mod rpc;
|
||||
|
||||
@@ -60,6 +60,10 @@ pub trait Ethcore: Sized + Send + Sync + 'static {
|
||||
/// Returns distribution of gas price in latest blocks.
|
||||
fn gas_price_statistics(&self, _: Params) -> Result<Value, Error>;
|
||||
|
||||
/// Returns number of unsigned transactions waiting in the signer queue (if signer enabled)
|
||||
/// Returns error when signer is disabled
|
||||
fn unsigned_transactions_count(&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));
|
||||
@@ -77,6 +81,7 @@ pub trait Ethcore: Sized + Send + Sync + 'static {
|
||||
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.add_method("ethcore_unsignedTransactionsCount", Ethcore::unsigned_transactions_count);
|
||||
|
||||
delegate
|
||||
}
|
||||
|
||||
@@ -37,6 +37,18 @@ pub trait EthcoreSet: Sized + Send + Sync + 'static {
|
||||
/// Sets the limits for transaction queue.
|
||||
fn set_transactions_limit(&self, _: Params) -> Result<Value, Error>;
|
||||
|
||||
/// Add a reserved peer.
|
||||
fn add_reserved_peer(&self, _: Params) -> Result<Value, Error>;
|
||||
|
||||
/// Remove a reserved peer.
|
||||
fn remove_reserved_peer(&self, _: Params) -> Result<Value, Error>;
|
||||
|
||||
/// Drop all non-reserved peers.
|
||||
fn drop_non_reserved_peers(&self, _: Params) -> Result<Value, Error>;
|
||||
|
||||
/// Accept non-reserved peers (default behavior)
|
||||
fn accept_non_reserved_peers(&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));
|
||||
@@ -45,6 +57,10 @@ pub trait EthcoreSet: Sized + Send + Sync + 'static {
|
||||
delegate.add_method("ethcore_setExtraData", EthcoreSet::set_extra_data);
|
||||
delegate.add_method("ethcore_setAuthor", EthcoreSet::set_author);
|
||||
delegate.add_method("ethcore_setTransactionsLimit", EthcoreSet::set_transactions_limit);
|
||||
delegate.add_method("ethcore_addReservedPeer", EthcoreSet::add_reserved_peer);
|
||||
delegate.add_method("ethcore_removeReservedPeer", EthcoreSet::remove_reserved_peer);
|
||||
delegate.add_method("ethcore_dropNonReservedPeers", EthcoreSet::drop_non_reserved_peers);
|
||||
delegate.add_method("ethcore_acceptNonReservedPeers", EthcoreSet::accept_non_reserved_peers);
|
||||
|
||||
delegate
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user