Merge branch 'master' into ui-2
This commit is contained in:
commit
fce0167991
83
docker/hub/Dockerfile
Normal file
83
docker/hub/Dockerfile
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
FROM ubuntu:14.04
|
||||||
|
MAINTAINER Parity Technologies <devops@parity.io>
|
||||||
|
WORKDIR /build
|
||||||
|
#ENV for build TAG
|
||||||
|
ARG BUILD_TAG
|
||||||
|
ENV BUILD_TAG ${BUILD_TAG:-master}
|
||||||
|
RUN echo $BUILD_TAG
|
||||||
|
# install tools and dependencies
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y --force-yes --no-install-recommends \
|
||||||
|
# make
|
||||||
|
build-essential \
|
||||||
|
# add-apt-repository
|
||||||
|
software-properties-common \
|
||||||
|
make \
|
||||||
|
curl \
|
||||||
|
wget \
|
||||||
|
git \
|
||||||
|
g++ \
|
||||||
|
gcc \
|
||||||
|
libc6 \
|
||||||
|
libc6-dev \
|
||||||
|
binutils \
|
||||||
|
file \
|
||||||
|
openssl \
|
||||||
|
libssl-dev \
|
||||||
|
libudev-dev \
|
||||||
|
pkg-config \
|
||||||
|
dpkg-dev \
|
||||||
|
# evmjit dependencies
|
||||||
|
zlib1g-dev \
|
||||||
|
libedit-dev \
|
||||||
|
libudev-dev &&\
|
||||||
|
# cmake and llvm ppa's. then update ppa's
|
||||||
|
add-apt-repository -y "ppa:george-edison55/cmake-3.x" && \
|
||||||
|
add-apt-repository "deb http://llvm.org/apt/trusty/ llvm-toolchain-trusty-3.7 main" && \
|
||||||
|
apt-get update && \
|
||||||
|
apt-get install -y --force-yes cmake llvm-3.7-dev && \
|
||||||
|
# install evmjit
|
||||||
|
git clone https://github.com/debris/evmjit && \
|
||||||
|
cd evmjit && \
|
||||||
|
mkdir build && cd build && \
|
||||||
|
cmake .. && make && make install && cd && \
|
||||||
|
# install rustup
|
||||||
|
curl https://sh.rustup.rs -sSf | sh -s -- -y && \
|
||||||
|
# rustup directory
|
||||||
|
PATH=/root/.cargo/bin:$PATH && \
|
||||||
|
# show backtraces
|
||||||
|
RUST_BACKTRACE=1 && \
|
||||||
|
# build parity
|
||||||
|
cd /build&&git clone https://github.com/paritytech/parity && \
|
||||||
|
cd parity && \
|
||||||
|
git pull&& \
|
||||||
|
git checkout $BUILD_TAG && \
|
||||||
|
cargo build --verbose --release --features final && \
|
||||||
|
#ls /build/parity/target/release/parity && \
|
||||||
|
strip /build/parity/target/release/parity && \
|
||||||
|
file /build/parity/target/release/parity&&mkdir -p /parity&& cp /build/parity/target/release/parity /parity&&\
|
||||||
|
#cleanup Docker image
|
||||||
|
rm -rf /root/.cargo&&rm -rf /root/.multirust&&rm -rf /root/.rustup&&rm -rf /build&&\
|
||||||
|
apt-get purge -y \
|
||||||
|
# make
|
||||||
|
build-essential \
|
||||||
|
# add-apt-repository
|
||||||
|
software-properties-common \
|
||||||
|
make \
|
||||||
|
curl \
|
||||||
|
wget \
|
||||||
|
git \
|
||||||
|
g++ \
|
||||||
|
gcc \
|
||||||
|
binutils \
|
||||||
|
file \
|
||||||
|
pkg-config \
|
||||||
|
dpkg-dev \
|
||||||
|
# evmjit dependencies
|
||||||
|
zlib1g-dev \
|
||||||
|
libedit-dev \
|
||||||
|
cmake llvm-3.7-dev&&\
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
# setup ENTRYPOINT
|
||||||
|
EXPOSE 8080 8545 8180
|
||||||
|
ENTRYPOINT ["/parity/parity"]
|
117
ethcore/src/client/evm_test_client.rs
Normal file
117
ethcore/src/client/evm_test_client.rs
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (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/>.
|
||||||
|
|
||||||
|
//! Simple Client used for EVM tests.
|
||||||
|
|
||||||
|
use std::fmt;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use util::{self, U256, journaldb, trie};
|
||||||
|
use util::kvdb::{self, KeyValueDB};
|
||||||
|
use {state, state_db, client, executive, trace, db, spec};
|
||||||
|
use factory::Factories;
|
||||||
|
use evm::{self, VMType};
|
||||||
|
use action_params::ActionParams;
|
||||||
|
|
||||||
|
/// EVM test Error.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum EvmTestError {
|
||||||
|
/// Trie integrity error.
|
||||||
|
Trie(util::TrieError),
|
||||||
|
/// EVM error.
|
||||||
|
Evm(evm::Error),
|
||||||
|
/// Initialization error.
|
||||||
|
Initialization(::error::Error),
|
||||||
|
/// Low-level database error.
|
||||||
|
Database(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for EvmTestError {
|
||||||
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
use self::EvmTestError::*;
|
||||||
|
|
||||||
|
match *self {
|
||||||
|
Trie(ref err) => write!(fmt, "Trie: {}", err),
|
||||||
|
Evm(ref err) => write!(fmt, "EVM: {}", err),
|
||||||
|
Initialization(ref err) => write!(fmt, "Initialization: {}", err),
|
||||||
|
Database(ref err) => write!(fmt, "DB: {}", err),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Simplified, single-block EVM test client.
|
||||||
|
pub struct EvmTestClient {
|
||||||
|
state_db: state_db::StateDB,
|
||||||
|
factories: Factories,
|
||||||
|
spec: spec::Spec,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EvmTestClient {
|
||||||
|
/// Creates new EVM test client with in-memory DB initialized with genesis of given Spec.
|
||||||
|
pub fn new(spec: spec::Spec) -> Result<Self, EvmTestError> {
|
||||||
|
let factories = Factories {
|
||||||
|
vm: evm::Factory::new(VMType::Interpreter, 5 * 1024),
|
||||||
|
trie: trie::TrieFactory::new(trie::TrieSpec::Secure),
|
||||||
|
accountdb: Default::default(),
|
||||||
|
};
|
||||||
|
let db = Arc::new(kvdb::in_memory(db::NUM_COLUMNS.expect("We use column-based DB; qed")));
|
||||||
|
let journal_db = journaldb::new(db.clone(), journaldb::Algorithm::EarlyMerge, db::COL_STATE);
|
||||||
|
let mut state_db = state_db::StateDB::new(journal_db, 5 * 1024 * 1024);
|
||||||
|
state_db = spec.ensure_db_good(state_db, &factories).map_err(EvmTestError::Initialization)?;
|
||||||
|
// Write DB
|
||||||
|
{
|
||||||
|
let mut batch = kvdb::DBTransaction::new();
|
||||||
|
state_db.journal_under(&mut batch, 0, &spec.genesis_header().hash()).map_err(|e| EvmTestError::Initialization(e.into()))?;
|
||||||
|
db.write(batch).map_err(EvmTestError::Database)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(EvmTestClient {
|
||||||
|
state_db,
|
||||||
|
factories,
|
||||||
|
spec,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Call given contract.
|
||||||
|
pub fn call<T: trace::VMTracer>(&mut self, params: ActionParams, vm_tracer: &mut T)
|
||||||
|
-> Result<(U256, Vec<u8>), EvmTestError>
|
||||||
|
{
|
||||||
|
let genesis = self.spec.genesis_header();
|
||||||
|
let mut state = state::State::from_existing(self.state_db.boxed_clone(), *genesis.state_root(), self.spec.engine.account_start_nonce(), self.factories.clone())
|
||||||
|
.map_err(EvmTestError::Trie)?;
|
||||||
|
let info = client::EnvInfo {
|
||||||
|
number: genesis.number(),
|
||||||
|
author: *genesis.author(),
|
||||||
|
timestamp: genesis.timestamp(),
|
||||||
|
difficulty: *genesis.difficulty(),
|
||||||
|
last_hashes: Arc::new([util::H256::default(); 256].to_vec()),
|
||||||
|
gas_used: 0.into(),
|
||||||
|
gas_limit: *genesis.gas_limit(),
|
||||||
|
};
|
||||||
|
let mut substate = state::Substate::new();
|
||||||
|
let mut tracer = trace::NoopTracer;
|
||||||
|
let mut output = vec![];
|
||||||
|
let mut executive = executive::Executive::new(&mut state, &info, &*self.spec.engine, &self.factories.vm);
|
||||||
|
let gas_left = executive.call(
|
||||||
|
params,
|
||||||
|
&mut substate,
|
||||||
|
util::BytesRef::Flexible(&mut output),
|
||||||
|
&mut tracer,
|
||||||
|
vm_tracer,
|
||||||
|
).map_err(EvmTestError::Evm)?;
|
||||||
|
|
||||||
|
Ok((gas_left, output))
|
||||||
|
}
|
||||||
|
}
|
@ -19,6 +19,7 @@
|
|||||||
mod ancient_import;
|
mod ancient_import;
|
||||||
mod config;
|
mod config;
|
||||||
mod error;
|
mod error;
|
||||||
|
mod evm_test_client;
|
||||||
mod test_client;
|
mod test_client;
|
||||||
mod trace;
|
mod trace;
|
||||||
mod client;
|
mod client;
|
||||||
@ -26,6 +27,7 @@ mod client;
|
|||||||
pub use self::client::*;
|
pub use self::client::*;
|
||||||
pub use self::config::{Mode, ClientConfig, DatabaseCompactionProfile, BlockChainConfig, VMType};
|
pub use self::config::{Mode, ClientConfig, DatabaseCompactionProfile, BlockChainConfig, VMType};
|
||||||
pub use self::error::Error;
|
pub use self::error::Error;
|
||||||
|
pub use self::evm_test_client::{EvmTestClient, EvmTestError};
|
||||||
pub use self::test_client::{TestBlockChainClient, EachBlockWith};
|
pub use self::test_client::{TestBlockChainClient, EachBlockWith};
|
||||||
pub use self::chain_notify::ChainNotify;
|
pub use self::chain_notify::ChainNotify;
|
||||||
pub use self::traits::{BlockChainClient, MiningBlockChainClient, EngineClient};
|
pub use self::traits::{BlockChainClient, MiningBlockChainClient, EngineClient};
|
||||||
|
@ -131,7 +131,7 @@ pub trait Ext {
|
|||||||
fn inc_sstore_clears(&mut self);
|
fn inc_sstore_clears(&mut self);
|
||||||
|
|
||||||
/// Prepare to trace an operation. Passthrough for the VM trace.
|
/// Prepare to trace an operation. Passthrough for the VM trace.
|
||||||
fn trace_prepare_execute(&mut self, _pc: usize, _instruction: u8, _gas_cost: &U256) -> bool { false }
|
fn trace_prepare_execute(&mut self, _pc: usize, _instruction: u8, _stack_pop: usize, _gas_cost: &U256) -> bool { false }
|
||||||
|
|
||||||
/// Trace the finalised execution of a single instruction.
|
/// Trace the finalised execution of a single instruction.
|
||||||
fn trace_executed(&mut self, _gas_used: U256, _stack_push: &[U256], _mem_diff: Option<(usize, &[u8])>, _store_diff: Option<(U256, U256)>) {}
|
fn trace_executed(&mut self, _gas_used: U256, _stack_push: &[U256], _mem_diff: Option<(usize, &[u8])>, _store_diff: Option<(U256, U256)>) {}
|
||||||
|
@ -129,7 +129,7 @@ impl<Cost: CostType> evm::Evm for Interpreter<Cost> {
|
|||||||
// Calculate gas cost
|
// Calculate gas cost
|
||||||
let requirements = gasometer.requirements(ext, instruction, info, &stack, self.mem.size())?;
|
let requirements = gasometer.requirements(ext, instruction, info, &stack, self.mem.size())?;
|
||||||
// TODO: make compile-time removable if too much of a performance hit.
|
// TODO: make compile-time removable if too much of a performance hit.
|
||||||
let trace_executed = ext.trace_prepare_execute(reader.position - 1, instruction, &requirements.gas_cost.as_u256());
|
let trace_executed = ext.trace_prepare_execute(reader.position - 1, instruction, info.args, &requirements.gas_cost.as_u256());
|
||||||
|
|
||||||
gasometer.verify_gas(&requirements.gas_cost)?;
|
gasometer.verify_gas(&requirements.gas_cost)?;
|
||||||
self.mem.expand(requirements.memory_required_size);
|
self.mem.expand(requirements.memory_required_size);
|
||||||
|
@ -333,8 +333,8 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B>
|
|||||||
self.substate.sstore_clears_count = self.substate.sstore_clears_count + U256::one();
|
self.substate.sstore_clears_count = self.substate.sstore_clears_count + U256::one();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trace_prepare_execute(&mut self, pc: usize, instruction: u8, gas_cost: &U256) -> bool {
|
fn trace_prepare_execute(&mut self, pc: usize, instruction: u8, stack_pop: usize, gas_cost: &U256) -> bool {
|
||||||
self.vm_tracer.trace_prepare_execute(pc, instruction, gas_cost)
|
self.vm_tracer.trace_prepare_execute(pc, instruction, stack_pop, gas_cost)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trace_executed(&mut self, gas_used: U256, stack_push: &[U256], mem_diff: Option<(usize, &[u8])>, store_diff: Option<(U256, U256)>) {
|
fn trace_executed(&mut self, gas_used: U256, stack_push: &[U256], mem_diff: Option<(usize, &[u8])>, store_diff: Option<(U256, U256)>) {
|
||||||
|
@ -192,7 +192,7 @@ impl ExecutiveVMTracer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl VMTracer for ExecutiveVMTracer {
|
impl VMTracer for ExecutiveVMTracer {
|
||||||
fn trace_prepare_execute(&mut self, pc: usize, instruction: u8, gas_cost: &U256) -> bool {
|
fn trace_prepare_execute(&mut self, pc: usize, instruction: u8, _stack_pop: usize, gas_cost: &U256) -> bool {
|
||||||
self.data.operations.push(VMOperation {
|
self.data.operations.push(VMOperation {
|
||||||
pc: pc,
|
pc: pc,
|
||||||
instruction: instruction,
|
instruction: instruction,
|
||||||
|
@ -89,7 +89,7 @@ pub trait Tracer: Send {
|
|||||||
pub trait VMTracer: Send {
|
pub trait VMTracer: Send {
|
||||||
/// Trace the preparation to execute a single instruction.
|
/// Trace the preparation to execute a single instruction.
|
||||||
/// @returns true if `trace_executed` should be called.
|
/// @returns true if `trace_executed` should be called.
|
||||||
fn trace_prepare_execute(&mut self, _pc: usize, _instruction: u8, _gas_cost: &U256) -> bool { false }
|
fn trace_prepare_execute(&mut self, _pc: usize, _instruction: u8, _stack_pop: usize, _gas_cost: &U256) -> bool { false }
|
||||||
|
|
||||||
/// Trace the finalised execution of a single instruction.
|
/// Trace the finalised execution of a single instruction.
|
||||||
fn trace_executed(&mut self, _gas_used: U256, _stack_push: &[U256], _mem_diff: Option<(usize, &[u8])>, _store_diff: Option<(U256, U256)>) {}
|
fn trace_executed(&mut self, _gas_used: U256, _stack_push: &[U256], _mem_diff: Option<(usize, &[u8])>, _store_diff: Option<(U256, U256)>) {}
|
||||||
@ -97,7 +97,7 @@ pub trait VMTracer: Send {
|
|||||||
/// Spawn subtracer which will be used to trace deeper levels of execution.
|
/// Spawn subtracer which will be used to trace deeper levels of execution.
|
||||||
fn prepare_subtrace(&self, code: &[u8]) -> Self where Self: Sized;
|
fn prepare_subtrace(&self, code: &[u8]) -> Self where Self: Sized;
|
||||||
|
|
||||||
/// Spawn subtracer which will be used to trace deeper levels of execution.
|
/// Finalize subtracer.
|
||||||
fn done_subtrace(&mut self, sub: Self) where Self: Sized;
|
fn done_subtrace(&mut self, sub: Self) where Self: Sized;
|
||||||
|
|
||||||
/// Consumes self and returns the VM trace.
|
/// Consumes self and returns the VM trace.
|
||||||
|
@ -72,7 +72,7 @@ pub struct NoopVMTracer;
|
|||||||
|
|
||||||
impl VMTracer for NoopVMTracer {
|
impl VMTracer for NoopVMTracer {
|
||||||
/// Trace the preparation to execute a single instruction.
|
/// Trace the preparation to execute a single instruction.
|
||||||
fn trace_prepare_execute(&mut self, _pc: usize, _instruction: u8, _gas_cost: &U256) -> bool { false }
|
fn trace_prepare_execute(&mut self, _pc: usize, _instruction: u8, _stack_pop: usize, _gas_cost: &U256) -> bool { false }
|
||||||
|
|
||||||
/// Trace the finalised execution of a single instruction.
|
/// Trace the finalised execution of a single instruction.
|
||||||
fn trace_executed(&mut self, _gas_used: U256, _stack_push: &[U256], _mem_diff: Option<(usize, &[u8])>, _store_diff: Option<(U256, U256)>) {}
|
fn trace_executed(&mut self, _gas_used: U256, _stack_push: &[U256], _mem_diff: Option<(usize, &[u8])>, _store_diff: Option<(U256, U256)>) {}
|
||||||
|
116
evmbin/src/display/json.rs
Normal file
116
evmbin/src/display/json.rs
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (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/>.
|
||||||
|
|
||||||
|
//! JSON VM output.
|
||||||
|
|
||||||
|
use ethcore::trace;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use util::{U256, H256, ToPretty};
|
||||||
|
|
||||||
|
use display;
|
||||||
|
use vm;
|
||||||
|
|
||||||
|
/// JSON formatting informant.
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct Informant {
|
||||||
|
depth: usize,
|
||||||
|
pc: usize,
|
||||||
|
instruction: u8,
|
||||||
|
gas_cost: U256,
|
||||||
|
stack: Vec<U256>,
|
||||||
|
memory: Vec<u8>,
|
||||||
|
storage: HashMap<H256, H256>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Informant {
|
||||||
|
fn memory(&self) -> String {
|
||||||
|
format!("\"0x{}\"", self.memory.to_hex())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn stack(&self) -> String {
|
||||||
|
let items = self.stack.iter().map(display::u256_as_str).collect::<Vec<_>>();
|
||||||
|
format!("[{}]", items.join(","))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn storage(&self) -> String {
|
||||||
|
let vals = self.storage.iter()
|
||||||
|
.map(|(k, v)| format!("\"0x{:?}\": \"0x{:?}\"", k, v))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
format!("{{{}}}", vals.join(","))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl vm::Informant for Informant {
|
||||||
|
fn finish(&mut self, result: Result<vm::Success, vm::Failure>) {
|
||||||
|
match result {
|
||||||
|
Ok(success) => println!(
|
||||||
|
"{{\"output\":\"0x{output}\",\"gasUsed\":\"{gas:x}\",\"time\":\"{time}\"}}",
|
||||||
|
output = success.output.to_hex(),
|
||||||
|
gas = success.gas_used,
|
||||||
|
time = display::format_time(&success.time),
|
||||||
|
),
|
||||||
|
Err(failure) => println!(
|
||||||
|
"{{\"error\":\"{error}\",\"time\":\"{time}\"}}",
|
||||||
|
error = failure.error,
|
||||||
|
time = display::format_time(&failure.time),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl trace::VMTracer for Informant {
|
||||||
|
fn trace_prepare_execute(&mut self, pc: usize, instruction: u8, stack_pop: usize, gas_cost: &U256) -> bool {
|
||||||
|
self.pc = pc;
|
||||||
|
self.instruction = instruction;
|
||||||
|
self.gas_cost = *gas_cost;
|
||||||
|
let len = self.stack.len();
|
||||||
|
self.stack.truncate(len - stack_pop);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn trace_executed(&mut self, gas_used: U256, stack_push: &[U256], mem_diff: Option<(usize, &[u8])>, store_diff: Option<(U256, U256)>) {
|
||||||
|
self.stack.extend_from_slice(stack_push);
|
||||||
|
|
||||||
|
if let Some((pos, data)) = mem_diff {
|
||||||
|
self.memory[pos..pos + data.len()].copy_from_slice(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some((pos, val)) = store_diff {
|
||||||
|
self.storage.insert(pos.into(), val.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"{{\"pc\":{pc},\"op\":{op},\"gas\":{gas},\"gasCost\":{gas_cost},\"memory\":{memory},\"stack\":{stack},\"storage\":{storage},\"depth\":{depth}}}",
|
||||||
|
pc = self.pc,
|
||||||
|
op = self.instruction,
|
||||||
|
gas = display::u256_as_str(&gas_used),
|
||||||
|
gas_cost = display::u256_as_str(&self.gas_cost),
|
||||||
|
memory = self.memory(),
|
||||||
|
stack = self.stack(),
|
||||||
|
storage = self.storage(),
|
||||||
|
depth = self.depth,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn prepare_subtrace(&self, _code: &[u8]) -> Self where Self: Sized {
|
||||||
|
let mut vm = Informant::default();
|
||||||
|
vm.depth = self.depth + 1;
|
||||||
|
vm
|
||||||
|
}
|
||||||
|
|
||||||
|
fn done_subtrace(&mut self, _sub: Self) where Self: Sized {}
|
||||||
|
fn drain(self) -> Option<trace::VMTrace> { None }
|
||||||
|
}
|
38
evmbin/src/display/mod.rs
Normal file
38
evmbin/src/display/mod.rs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (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/>.
|
||||||
|
|
||||||
|
//! VM Output display utils.
|
||||||
|
|
||||||
|
use std::time::Duration;
|
||||||
|
use util::U256;
|
||||||
|
|
||||||
|
pub mod json;
|
||||||
|
pub mod simple;
|
||||||
|
|
||||||
|
/// Formats duration into human readable format.
|
||||||
|
pub fn format_time(time: &Duration) -> String {
|
||||||
|
format!("{}.{:.9}s", time.as_secs(), time.subsec_nanos())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Converts U256 into string.
|
||||||
|
/// TODO Overcomes: https://github.com/paritytech/bigint/issues/13
|
||||||
|
pub fn u256_as_str(v: &U256) -> String {
|
||||||
|
if v.is_zero() {
|
||||||
|
"\"0x0\"".into()
|
||||||
|
} else {
|
||||||
|
format!("\"{:x}\"", v)
|
||||||
|
}
|
||||||
|
}
|
49
evmbin/src/display/simple.rs
Normal file
49
evmbin/src/display/simple.rs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (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/>.
|
||||||
|
|
||||||
|
//! Simple VM output.
|
||||||
|
|
||||||
|
use ethcore::trace;
|
||||||
|
use util::ToPretty;
|
||||||
|
|
||||||
|
use display;
|
||||||
|
use vm;
|
||||||
|
|
||||||
|
/// Simple formatting informant.
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct Informant;
|
||||||
|
|
||||||
|
impl vm::Informant for Informant {
|
||||||
|
fn finish(&mut self, result: Result<vm::Success, vm::Failure>) {
|
||||||
|
match result {
|
||||||
|
Ok(success) => {
|
||||||
|
println!("Output: 0x{}", success.output.to_hex());
|
||||||
|
println!("Gas used: {:x}", success.gas_used);
|
||||||
|
println!("Time: {}", display::format_time(&success.time));
|
||||||
|
},
|
||||||
|
Err(failure) => {
|
||||||
|
println!("Error: {}", failure.error);
|
||||||
|
println!("Time: {}", display::format_time(&failure.time));
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl trace::VMTracer for Informant {
|
||||||
|
fn prepare_subtrace(&self, _code: &[u8]) -> Self where Self: Sized { Default::default() }
|
||||||
|
fn done_subtrace(&mut self, _sub: Self) where Self: Sized {}
|
||||||
|
fn drain(self) -> Option<trace::VMTrace> { None }
|
||||||
|
}
|
@ -1,123 +0,0 @@
|
|||||||
// Copyright 2015-2017 Parity Technologies (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/>.
|
|
||||||
|
|
||||||
//! Externalities implementation.
|
|
||||||
|
|
||||||
use std::sync::Arc;
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use util::{U256, H256, Address, Bytes, trie};
|
|
||||||
use ethcore::client::EnvInfo;
|
|
||||||
use ethcore::evm::{self, Ext, ContractCreateResult, MessageCallResult, Schedule, CallType, CreateContractAddress};
|
|
||||||
|
|
||||||
pub struct FakeExt {
|
|
||||||
schedule: Schedule,
|
|
||||||
store: HashMap<H256, H256>,
|
|
||||||
depth: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for FakeExt {
|
|
||||||
fn default() -> Self {
|
|
||||||
FakeExt {
|
|
||||||
schedule: Schedule::new_post_eip150(usize::max_value(), true, true, true, true),
|
|
||||||
store: HashMap::new(),
|
|
||||||
depth: 1,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Ext for FakeExt {
|
|
||||||
fn storage_at(&self, key: &H256) -> trie::Result<H256> {
|
|
||||||
Ok(self.store.get(key).unwrap_or(&H256::new()).clone())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_storage(&mut self, key: H256, value: H256) -> trie::Result<()> {
|
|
||||||
self.store.insert(key, value);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn exists(&self, _address: &Address) -> trie::Result<bool> {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn exists_and_not_null(&self, _address: &Address) -> trie::Result<bool> {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn origin_balance(&self) -> trie::Result<U256> {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn balance(&self, _address: &Address) -> trie::Result<U256> {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn blockhash(&self, _number: &U256) -> H256 {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create(&mut self, _gas: &U256, _value: &U256, _code: &[u8], _address: CreateContractAddress) -> ContractCreateResult {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn call(&mut self,
|
|
||||||
_gas: &U256,
|
|
||||||
_sender_address: &Address,
|
|
||||||
_receive_address: &Address,
|
|
||||||
_value: Option<U256>,
|
|
||||||
_data: &[u8],
|
|
||||||
_code_address: &Address,
|
|
||||||
_output: &mut [u8],
|
|
||||||
_call_type: CallType) -> MessageCallResult {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn extcode(&self, _address: &Address) -> trie::Result<Arc<Bytes>> {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn extcodesize(&self, _address: &Address) -> trie::Result<usize> {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn log(&mut self, _topics: Vec<H256>, _data: &[u8]) {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn ret(self, gas: &U256, _data: &[u8]) -> evm::Result<U256> {
|
|
||||||
Ok(*gas)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn suicide(&mut self, _refund_address: &Address) -> trie::Result<()> {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn schedule(&self) -> &Schedule {
|
|
||||||
&self.schedule
|
|
||||||
}
|
|
||||||
|
|
||||||
fn env_info(&self) -> &EnvInfo {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn depth(&self) -> usize {
|
|
||||||
self.depth
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inc_sstore_clears(&mut self) {
|
|
||||||
unimplemented!();
|
|
||||||
// self.sstore_clears += 1;
|
|
||||||
}
|
|
||||||
}
|
|
@ -23,31 +23,36 @@ extern crate rustc_serialize;
|
|||||||
extern crate docopt;
|
extern crate docopt;
|
||||||
extern crate ethcore_util as util;
|
extern crate ethcore_util as util;
|
||||||
|
|
||||||
mod ext;
|
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::{Instant, Duration};
|
use std::{fmt, fs};
|
||||||
use std::fmt;
|
|
||||||
use std::str::FromStr;
|
|
||||||
use docopt::Docopt;
|
use docopt::Docopt;
|
||||||
use util::{U256, FromHex, Bytes};
|
use util::{U256, FromHex, Bytes, Address};
|
||||||
use ethcore::evm::{self, Factory, VMType, Finalize};
|
use ethcore::spec;
|
||||||
use ethcore::action_params::ActionParams;
|
use ethcore::action_params::ActionParams;
|
||||||
|
|
||||||
|
mod vm;
|
||||||
|
mod display;
|
||||||
|
|
||||||
|
use vm::Informant;
|
||||||
|
|
||||||
const USAGE: &'static str = r#"
|
const USAGE: &'static str = r#"
|
||||||
EVM implementation for Parity.
|
EVM implementation for Parity.
|
||||||
Copyright 2016, 2017 Parity Technologies (UK) Ltd
|
Copyright 2016, 2017 Parity Technologies (UK) Ltd
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
evmbin stats [options]
|
evmbin stats [options]
|
||||||
|
evmbin [options]
|
||||||
evmbin [-h | --help]
|
evmbin [-h | --help]
|
||||||
|
|
||||||
Transaction options:
|
Transaction options:
|
||||||
--code CODE Contract code as hex (without 0x)
|
--code CODE Contract code as hex (without 0x).
|
||||||
--input DATA Input data as hex (without 0x)
|
--from ADDRESS Sender address (without 0x).
|
||||||
--gas GAS Supplied gas as hex (without 0x)
|
--input DATA Input data as hex (without 0x).
|
||||||
|
--gas GAS Supplied gas as hex (without 0x).
|
||||||
|
|
||||||
General options:
|
General options:
|
||||||
|
--json Display verbose results in JSON.
|
||||||
|
--chain CHAIN Chain spec file path.
|
||||||
-h, --help Display this message and exit.
|
-h, --help Display this message and exit.
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
@ -55,107 +60,93 @@ General options:
|
|||||||
fn main() {
|
fn main() {
|
||||||
let args: Args = Docopt::new(USAGE).and_then(|d| d.decode()).unwrap_or_else(|e| e.exit());
|
let args: Args = Docopt::new(USAGE).and_then(|d| d.decode()).unwrap_or_else(|e| e.exit());
|
||||||
|
|
||||||
|
if args.flag_json {
|
||||||
|
run(args, display::json::Informant::default())
|
||||||
|
} else {
|
||||||
|
run(args, display::simple::Informant::default())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run<T: Informant>(args: Args, mut informant: T) {
|
||||||
|
let from = arg(args.from(), "--from");
|
||||||
|
let code = arg(args.code(), "--code");
|
||||||
|
let spec = arg(args.spec(), "--chain");
|
||||||
|
let gas = arg(args.gas(), "--gas");
|
||||||
|
let data = arg(args.data(), "--input");
|
||||||
|
|
||||||
let mut params = ActionParams::default();
|
let mut params = ActionParams::default();
|
||||||
params.gas = args.gas();
|
params.sender = from;
|
||||||
params.code = Some(Arc::new(args.code()));
|
params.origin = from;
|
||||||
params.data = args.data();
|
params.gas = gas;
|
||||||
|
params.code = Some(Arc::new(code));
|
||||||
|
params.data = data;
|
||||||
|
|
||||||
let result = run_vm(params);
|
let result = vm::run(&mut informant, spec, params);
|
||||||
match result {
|
informant.finish(result);
|
||||||
Ok(success) => println!("{}", success),
|
|
||||||
Err(failure) => println!("{}", failure),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Execute VM with given `ActionParams`
|
|
||||||
pub fn run_vm(params: ActionParams) -> Result<Success, Failure> {
|
|
||||||
let initial_gas = params.gas;
|
|
||||||
let factory = Factory::new(VMType::Interpreter, 1024);
|
|
||||||
let mut vm = factory.create(params.gas);
|
|
||||||
let mut ext = ext::FakeExt::default();
|
|
||||||
|
|
||||||
let start = Instant::now();
|
|
||||||
let res = vm.exec(params, &mut ext).finalize(ext);
|
|
||||||
let duration = start.elapsed();
|
|
||||||
|
|
||||||
match res {
|
|
||||||
Ok(res) => Ok(Success {
|
|
||||||
gas_used: initial_gas - res.gas_left,
|
|
||||||
// TODO [ToDr] get output from ext
|
|
||||||
output: Vec::new(),
|
|
||||||
time: duration,
|
|
||||||
}),
|
|
||||||
Err(e) => Err(Failure {
|
|
||||||
error: e,
|
|
||||||
time: duration,
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Execution finished correctly
|
|
||||||
pub struct Success {
|
|
||||||
/// Used gas
|
|
||||||
gas_used: U256,
|
|
||||||
/// Output as bytes
|
|
||||||
output: Vec<u8>,
|
|
||||||
/// Time Taken
|
|
||||||
time: Duration,
|
|
||||||
}
|
|
||||||
impl fmt::Display for Success {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
|
||||||
writeln!(f, "Gas used: {:?}", self.gas_used)?;
|
|
||||||
writeln!(f, "Output: {:?}", self.output)?;
|
|
||||||
writeln!(f, "Time: {}.{:.9}s", self.time.as_secs(), self.time.subsec_nanos())?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Execution failed
|
|
||||||
pub struct Failure {
|
|
||||||
/// Internal error
|
|
||||||
error: evm::Error,
|
|
||||||
/// Duration
|
|
||||||
time: Duration,
|
|
||||||
}
|
|
||||||
impl fmt::Display for Failure {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
|
||||||
writeln!(f, "Error: {:?}", self.error)?;
|
|
||||||
writeln!(f, "Time: {}.{:.9}s", self.time.as_secs(), self.time.subsec_nanos())?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, RustcDecodable)]
|
#[derive(Debug, RustcDecodable)]
|
||||||
struct Args {
|
struct Args {
|
||||||
cmd_stats: bool,
|
cmd_stats: bool,
|
||||||
|
flag_from: Option<String>,
|
||||||
flag_code: Option<String>,
|
flag_code: Option<String>,
|
||||||
flag_gas: Option<String>,
|
flag_gas: Option<String>,
|
||||||
flag_input: Option<String>,
|
flag_input: Option<String>,
|
||||||
|
flag_spec: Option<String>,
|
||||||
|
flag_json: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Args {
|
impl Args {
|
||||||
pub fn gas(&self) -> U256 {
|
pub fn gas(&self) -> Result<U256, String> {
|
||||||
self.flag_gas
|
match self.flag_gas {
|
||||||
.clone()
|
Some(ref gas) => gas.parse().map_err(to_string),
|
||||||
.and_then(|g| U256::from_str(&g).ok())
|
None => Ok(!U256::zero()),
|
||||||
.unwrap_or_else(|| !U256::zero())
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn code(&self) -> Bytes {
|
pub fn from(&self) -> Result<Address, String> {
|
||||||
self.flag_code
|
match self.flag_from {
|
||||||
.clone()
|
Some(ref from) => from.parse().map_err(to_string),
|
||||||
.and_then(|c| c.from_hex().ok())
|
None => Ok(Address::default()),
|
||||||
.unwrap_or_else(|| die("Code is required."))
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn data(&self) -> Option<Bytes> {
|
pub fn code(&self) -> Result<Bytes, String> {
|
||||||
self.flag_input
|
match self.flag_code {
|
||||||
.clone()
|
Some(ref code) => code.from_hex().map_err(to_string),
|
||||||
.and_then(|d| d.from_hex().ok())
|
None => Err("Code is required!".into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn data(&self) -> Result<Option<Bytes>, String> {
|
||||||
|
match self.flag_input {
|
||||||
|
Some(ref input) => input.from_hex().map_err(to_string).map(Some),
|
||||||
|
None => Ok(None),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spec(&self) -> Result<spec::Spec, String> {
|
||||||
|
Ok(match self.flag_spec {
|
||||||
|
Some(ref filename) => {
|
||||||
|
let file = fs::File::open(filename).map_err(|e| format!("{}", e))?;
|
||||||
|
spec::Spec::load(file)?
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
spec::Spec::new_instant()
|
||||||
|
},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn die(msg: &'static str) -> ! {
|
fn arg<T>(v: Result<T, String>, param: &str) -> T {
|
||||||
|
v.unwrap_or_else(|e| die(format!("Invalid {}: {}", param, e)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_string<T: fmt::Display>(msg: T) -> String {
|
||||||
|
format!("{}", msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn die<T: fmt::Display>(msg: T) -> ! {
|
||||||
println!("{}", msg);
|
println!("{}", msg);
|
||||||
::std::process::exit(-1)
|
::std::process::exit(-1)
|
||||||
}
|
}
|
||||||
|
72
evmbin/src/vm.rs
Normal file
72
evmbin/src/vm.rs
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (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/>.
|
||||||
|
|
||||||
|
//! VM runner.
|
||||||
|
|
||||||
|
use std::time::{Instant, Duration};
|
||||||
|
use util::U256;
|
||||||
|
use ethcore::{trace, spec};
|
||||||
|
use ethcore::client::{EvmTestClient, EvmTestError};
|
||||||
|
use ethcore::action_params::ActionParams;
|
||||||
|
|
||||||
|
/// VM execution informant
|
||||||
|
pub trait Informant: trace::VMTracer {
|
||||||
|
/// Display final result.
|
||||||
|
fn finish(&mut self, result: Result<Success, Failure>);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Execution finished correctly
|
||||||
|
pub struct Success {
|
||||||
|
/// Used gas
|
||||||
|
pub gas_used: U256,
|
||||||
|
/// Output as bytes
|
||||||
|
pub output: Vec<u8>,
|
||||||
|
/// Time Taken
|
||||||
|
pub time: Duration,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Execution failed
|
||||||
|
pub struct Failure {
|
||||||
|
/// Internal error
|
||||||
|
pub error: EvmTestError,
|
||||||
|
/// Duration
|
||||||
|
pub time: Duration,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Execute VM with given `ActionParams`
|
||||||
|
pub fn run<T: trace::VMTracer>(vm_tracer: &mut T, spec: spec::Spec, params: ActionParams) -> Result<Success, Failure> {
|
||||||
|
let mut test_client = EvmTestClient::new(spec).map_err(|error| Failure {
|
||||||
|
error,
|
||||||
|
time: Duration::from_secs(0)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let initial_gas = params.gas;
|
||||||
|
let start = Instant::now();
|
||||||
|
let result = test_client.call(params, vm_tracer);
|
||||||
|
let duration = start.elapsed();
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Ok((gas_left, output)) => Ok(Success {
|
||||||
|
gas_used: initial_gas - gas_left,
|
||||||
|
output: output,
|
||||||
|
time: duration,
|
||||||
|
}),
|
||||||
|
Err(e) => Err(Failure {
|
||||||
|
error: e,
|
||||||
|
time: duration,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
@ -226,7 +226,7 @@ impl FullDependencies {
|
|||||||
($namespace:ident, $handler:expr, $deps:expr) => {
|
($namespace:ident, $handler:expr, $deps:expr) => {
|
||||||
{
|
{
|
||||||
let deps = &$deps;
|
let deps = &$deps;
|
||||||
let dispatcher = FullDispatcher::new(Arc::downgrade(&deps.client), Arc::downgrade(&deps.miner));
|
let dispatcher = FullDispatcher::new(deps.client.clone(), deps.miner.clone());
|
||||||
if deps.signer_service.is_enabled() {
|
if deps.signer_service.is_enabled() {
|
||||||
$handler.extend_with($namespace::to_delegate(SigningQueueClient::new(&deps.signer_service, dispatcher, &deps.secret_store)))
|
$handler.extend_with($namespace::to_delegate(SigningQueueClient::new(&deps.signer_service, dispatcher, &deps.secret_store)))
|
||||||
} else {
|
} else {
|
||||||
@ -236,7 +236,7 @@ impl FullDependencies {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let dispatcher = FullDispatcher::new(Arc::downgrade(&self.client), Arc::downgrade(&self.miner));
|
let dispatcher = FullDispatcher::new(self.client.clone(), self.miner.clone());
|
||||||
for api in apis {
|
for api in apis {
|
||||||
match *api {
|
match *api {
|
||||||
Api::Web3 => {
|
Api::Web3 => {
|
||||||
|
@ -14,14 +14,14 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::Arc;
|
||||||
use ethcore::account_provider::AccountProvider;
|
use ethcore::account_provider::AccountProvider;
|
||||||
use jsonrpc_core::Error;
|
use jsonrpc_core::Error;
|
||||||
use v1::helpers::errors;
|
use v1::helpers::errors;
|
||||||
|
|
||||||
pub fn unwrap_provider(provider: &Option<Weak<AccountProvider>>) -> Result<Arc<AccountProvider>, Error> {
|
pub fn unwrap_provider(provider: &Option<Arc<AccountProvider>>) -> Result<Arc<AccountProvider>, Error> {
|
||||||
match *provider {
|
match *provider {
|
||||||
Some(ref weak) => weak.upgrade().ok_or_else(Error::internal_error),
|
Some(ref arc) => Ok(arc.clone()),
|
||||||
None => Err(errors::public_unsupported(None)),
|
None => Err(errors::public_unsupported(None)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::Arc;
|
||||||
|
|
||||||
use futures::{future, Future, BoxFuture};
|
use futures::{future, Future, BoxFuture};
|
||||||
use light::cache::Cache as LightDataCache;
|
use light::cache::Cache as LightDataCache;
|
||||||
@ -74,16 +74,16 @@ pub trait Dispatcher: Send + Sync + Clone {
|
|||||||
/// requests locally.
|
/// requests locally.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct FullDispatcher<C, M> {
|
pub struct FullDispatcher<C, M> {
|
||||||
client: Weak<C>,
|
client: Arc<C>,
|
||||||
miner: Weak<M>,
|
miner: Arc<M>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, M> FullDispatcher<C, M> {
|
impl<C, M> FullDispatcher<C, M> {
|
||||||
/// Create a `FullDispatcher` from weak references to a client and miner.
|
/// Create a `FullDispatcher` from Arc references to a client and miner.
|
||||||
pub fn new(client: Weak<C>, miner: Weak<M>) -> Self {
|
pub fn new(client: Arc<C>, miner: Arc<M>) -> Self {
|
||||||
FullDispatcher {
|
FullDispatcher {
|
||||||
client: client,
|
client,
|
||||||
miner: miner,
|
miner,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -109,7 +109,7 @@ impl<C: MiningBlockChainClient, M: MinerService> Dispatcher for FullDispatcher<C
|
|||||||
fn fill_optional_fields(&self, request: TransactionRequest, default_sender: Address, force_nonce: bool)
|
fn fill_optional_fields(&self, request: TransactionRequest, default_sender: Address, force_nonce: bool)
|
||||||
-> BoxFuture<FilledTransactionRequest, Error>
|
-> BoxFuture<FilledTransactionRequest, Error>
|
||||||
{
|
{
|
||||||
let (client, miner) = (take_weakf!(self.client), take_weakf!(self.miner));
|
let (client, miner) = (self.client.clone(), self.miner.clone());
|
||||||
let request = request;
|
let request = request;
|
||||||
let from = request.from.unwrap_or(default_sender);
|
let from = request.from.unwrap_or(default_sender);
|
||||||
let nonce = match force_nonce {
|
let nonce = match force_nonce {
|
||||||
@ -132,7 +132,7 @@ impl<C: MiningBlockChainClient, M: MinerService> Dispatcher for FullDispatcher<C
|
|||||||
fn sign(&self, accounts: Arc<AccountProvider>, filled: FilledTransactionRequest, password: SignWith)
|
fn sign(&self, accounts: Arc<AccountProvider>, filled: FilledTransactionRequest, password: SignWith)
|
||||||
-> BoxFuture<WithToken<SignedTransaction>, Error>
|
-> BoxFuture<WithToken<SignedTransaction>, Error>
|
||||||
{
|
{
|
||||||
let (client, miner) = (take_weakf!(self.client), take_weakf!(self.miner));
|
let (client, miner) = (self.client.clone(), self.miner.clone());
|
||||||
let network_id = client.signing_network_id();
|
let network_id = client.signing_network_id();
|
||||||
let address = filled.from;
|
let address = filled.from;
|
||||||
future::done({
|
future::done({
|
||||||
@ -161,7 +161,7 @@ impl<C: MiningBlockChainClient, M: MinerService> Dispatcher for FullDispatcher<C
|
|||||||
fn dispatch_transaction(&self, signed_transaction: PendingTransaction) -> Result<H256, Error> {
|
fn dispatch_transaction(&self, signed_transaction: PendingTransaction) -> Result<H256, Error> {
|
||||||
let hash = signed_transaction.transaction.hash();
|
let hash = signed_transaction.transaction.hash();
|
||||||
|
|
||||||
take_weak!(self.miner).import_own_transaction(&*take_weak!(self.client), signed_transaction)
|
self.miner.import_own_transaction(&*self.client, signed_transaction)
|
||||||
.map_err(errors::from_transaction_error)
|
.map_err(errors::from_transaction_error)
|
||||||
.map(|_| hash)
|
.map(|_| hash)
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use std::sync::Weak;
|
use std::sync::Arc;
|
||||||
use ethcore::client::MiningBlockChainClient;
|
use ethcore::client::MiningBlockChainClient;
|
||||||
use ethcore::miner::MinerService;
|
use ethcore::miner::MinerService;
|
||||||
use ethcore::transaction::{Transaction, SignedTransaction, Action};
|
use ethcore::transaction::{Transaction, SignedTransaction, Action};
|
||||||
@ -24,19 +24,17 @@ use v1::helpers::CallRequest;
|
|||||||
use v1::helpers::dispatch::default_gas_price;
|
use v1::helpers::dispatch::default_gas_price;
|
||||||
|
|
||||||
pub fn sign_call<B: MiningBlockChainClient, M: MinerService>(
|
pub fn sign_call<B: MiningBlockChainClient, M: MinerService>(
|
||||||
client: &Weak<B>,
|
client: &Arc<B>,
|
||||||
miner: &Weak<M>,
|
miner: &Arc<M>,
|
||||||
request: CallRequest,
|
request: CallRequest,
|
||||||
) -> Result<SignedTransaction, Error> {
|
) -> Result<SignedTransaction, Error> {
|
||||||
let client = take_weak!(client);
|
|
||||||
let miner = take_weak!(miner);
|
|
||||||
let from = request.from.unwrap_or(0.into());
|
let from = request.from.unwrap_or(0.into());
|
||||||
|
|
||||||
Ok(Transaction {
|
Ok(Transaction {
|
||||||
nonce: request.nonce.unwrap_or_else(|| client.latest_nonce(&from)),
|
nonce: request.nonce.unwrap_or_else(|| client.latest_nonce(&from)),
|
||||||
action: request.to.map_or(Action::Create, Action::Call),
|
action: request.to.map_or(Action::Create, Action::Call),
|
||||||
gas: request.gas.unwrap_or(50_000_000.into()),
|
gas: request.gas.unwrap_or(50_000_000.into()),
|
||||||
gas_price: request.gas_price.unwrap_or_else(|| default_gas_price(&*client, &*miner)),
|
gas_price: request.gas_price.unwrap_or_else(|| default_gas_price(&**client, &**miner)),
|
||||||
value: request.value.unwrap_or(0.into()),
|
value: request.value.unwrap_or(0.into()),
|
||||||
data: request.data.map_or_else(Vec::new, |d| d.to_vec())
|
data: request.data.map_or_else(Vec::new, |d| d.to_vec())
|
||||||
}.fake_sign(from))
|
}.fake_sign(from))
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::{Instant, Duration};
|
use std::time::{Instant, Duration};
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::Arc;
|
||||||
|
|
||||||
use futures::{self, future, BoxFuture, Future};
|
use futures::{self, future, BoxFuture, Future};
|
||||||
use rlp::{self, UntrustedRlp};
|
use rlp::{self, UntrustedRlp};
|
||||||
@ -95,11 +95,11 @@ pub struct EthClient<C, SN: ?Sized, S: ?Sized, M, EM> where
|
|||||||
M: MinerService,
|
M: MinerService,
|
||||||
EM: ExternalMinerService {
|
EM: ExternalMinerService {
|
||||||
|
|
||||||
client: Weak<C>,
|
client: Arc<C>,
|
||||||
snapshot: Weak<SN>,
|
snapshot: Arc<SN>,
|
||||||
sync: Weak<S>,
|
sync: Arc<S>,
|
||||||
accounts: Option<Weak<AccountProvider>>,
|
accounts: Option<Arc<AccountProvider>>,
|
||||||
miner: Weak<M>,
|
miner: Arc<M>,
|
||||||
external_miner: Arc<EM>,
|
external_miner: Arc<EM>,
|
||||||
seed_compute: Mutex<SeedHashCompute>,
|
seed_compute: Mutex<SeedHashCompute>,
|
||||||
options: EthClientOptions,
|
options: EthClientOptions,
|
||||||
@ -124,11 +124,11 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> EthClient<C, SN, S, M, EM> where
|
|||||||
options: EthClientOptions
|
options: EthClientOptions
|
||||||
) -> Self {
|
) -> Self {
|
||||||
EthClient {
|
EthClient {
|
||||||
client: Arc::downgrade(client),
|
client: client.clone(),
|
||||||
snapshot: Arc::downgrade(snapshot),
|
snapshot: snapshot.clone(),
|
||||||
sync: Arc::downgrade(sync),
|
sync: sync.clone(),
|
||||||
miner: Arc::downgrade(miner),
|
miner: miner.clone(),
|
||||||
accounts: accounts.as_ref().map(Arc::downgrade),
|
accounts: accounts.clone(),
|
||||||
external_miner: em.clone(),
|
external_miner: em.clone(),
|
||||||
seed_compute: Mutex::new(SeedHashCompute::new()),
|
seed_compute: Mutex::new(SeedHashCompute::new()),
|
||||||
options: options,
|
options: options,
|
||||||
@ -137,13 +137,13 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> EthClient<C, SN, S, M, EM> where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Attempt to get the `Arc<AccountProvider>`, errors if provider was not
|
/// Attempt to get the `Arc<AccountProvider>`, errors if provider was not
|
||||||
/// set, or if upgrading the weak reference failed.
|
/// set.
|
||||||
fn account_provider(&self) -> Result<Arc<AccountProvider>, Error> {
|
fn account_provider(&self) -> Result<Arc<AccountProvider>, Error> {
|
||||||
unwrap_provider(&self.accounts)
|
unwrap_provider(&self.accounts)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn block(&self, id: BlockId, include_txs: bool) -> Result<Option<RichBlock>, Error> {
|
fn block(&self, id: BlockId, include_txs: bool) -> Result<Option<RichBlock>, Error> {
|
||||||
let client = take_weak!(self.client);
|
let client = &self.client;
|
||||||
match (client.block(id.clone()), client.block_total_difficulty(id)) {
|
match (client.block(id.clone()), client.block_total_difficulty(id)) {
|
||||||
(Some(block), Some(total_difficulty)) => {
|
(Some(block), Some(total_difficulty)) => {
|
||||||
let view = block.header_view();
|
let view = block.header_view();
|
||||||
@ -181,14 +181,14 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> EthClient<C, SN, S, M, EM> where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn transaction(&self, id: TransactionId) -> Result<Option<Transaction>, Error> {
|
fn transaction(&self, id: TransactionId) -> Result<Option<Transaction>, Error> {
|
||||||
match take_weak!(self.client).transaction(id) {
|
match self.client.transaction(id) {
|
||||||
Some(t) => Ok(Some(Transaction::from_localized(t, self.eip86_transition))),
|
Some(t) => Ok(Some(Transaction::from_localized(t, self.eip86_transition))),
|
||||||
None => Ok(None),
|
None => Ok(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn uncle(&self, id: UncleId) -> Result<Option<RichBlock>, Error> {
|
fn uncle(&self, id: UncleId) -> Result<Option<RichBlock>, Error> {
|
||||||
let client = take_weak!(self.client);
|
let client = &self.client;
|
||||||
let uncle: BlockHeader = match client.uncle(id) {
|
let uncle: BlockHeader = match client.uncle(id) {
|
||||||
Some(hdr) => hdr.decode(),
|
Some(hdr) => hdr.decode(),
|
||||||
None => { return Ok(None); }
|
None => { return Ok(None); }
|
||||||
@ -280,16 +280,16 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
|||||||
type Metadata = Metadata;
|
type Metadata = Metadata;
|
||||||
|
|
||||||
fn protocol_version(&self) -> Result<String, Error> {
|
fn protocol_version(&self) -> Result<String, Error> {
|
||||||
let version = take_weak!(self.sync).status().protocol_version.to_owned();
|
let version = self.sync.status().protocol_version.to_owned();
|
||||||
Ok(format!("{}", version))
|
Ok(format!("{}", version))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn syncing(&self) -> Result<SyncStatus, Error> {
|
fn syncing(&self) -> Result<SyncStatus, Error> {
|
||||||
use ethcore::snapshot::RestorationStatus;
|
use ethcore::snapshot::RestorationStatus;
|
||||||
|
|
||||||
let status = take_weak!(self.sync).status();
|
let status = self.sync.status();
|
||||||
let client = take_weak!(self.client);
|
let client = &self.client;
|
||||||
let snapshot_status = take_weak!(self.snapshot).status();
|
let snapshot_status = self.snapshot.status();
|
||||||
|
|
||||||
let (warping, warp_chunks_amount, warp_chunks_processed) = match snapshot_status {
|
let (warping, warp_chunks_amount, warp_chunks_processed) = match snapshot_status {
|
||||||
RestorationStatus::Ongoing { state_chunks, block_chunks, state_chunks_done, block_chunks_done } =>
|
RestorationStatus::Ongoing { state_chunks, block_chunks, state_chunks_done, block_chunks_done } =>
|
||||||
@ -320,7 +320,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
|||||||
let dapp = meta.dapp_id();
|
let dapp = meta.dapp_id();
|
||||||
|
|
||||||
let author = move || {
|
let author = move || {
|
||||||
let mut miner = take_weak!(self.miner).author();
|
let mut miner = self.miner.author();
|
||||||
if miner == 0.into() {
|
if miner == 0.into() {
|
||||||
miner = self.dapp_accounts(dapp.into())?.get(0).cloned().unwrap_or_default();
|
miner = self.dapp_accounts(dapp.into())?.get(0).cloned().unwrap_or_default();
|
||||||
}
|
}
|
||||||
@ -332,7 +332,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn is_mining(&self) -> Result<bool, Error> {
|
fn is_mining(&self) -> Result<bool, Error> {
|
||||||
Ok(take_weak!(self.miner).is_sealing())
|
Ok(self.miner.is_sealing())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hashrate(&self) -> Result<RpcU256, Error> {
|
fn hashrate(&self) -> Result<RpcU256, Error> {
|
||||||
@ -340,8 +340,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn gas_price(&self) -> Result<RpcU256, Error> {
|
fn gas_price(&self) -> Result<RpcU256, Error> {
|
||||||
let (client, miner) = (take_weak!(self.client), take_weak!(self.miner));
|
Ok(RpcU256::from(default_gas_price(&*self.client, &*self.miner)))
|
||||||
Ok(RpcU256::from(default_gas_price(&*client, &*miner)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn accounts(&self, meta: Metadata) -> BoxFuture<Vec<RpcH160>, Error> {
|
fn accounts(&self, meta: Metadata) -> BoxFuture<Vec<RpcH160>, Error> {
|
||||||
@ -356,23 +355,22 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn block_number(&self) -> Result<RpcU256, Error> {
|
fn block_number(&self) -> Result<RpcU256, Error> {
|
||||||
Ok(RpcU256::from(take_weak!(self.client).chain_info().best_block_number))
|
Ok(RpcU256::from(self.client.chain_info().best_block_number))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn balance(&self, address: RpcH160, num: Trailing<BlockNumber>) -> BoxFuture<RpcU256, Error> {
|
fn balance(&self, address: RpcH160, num: Trailing<BlockNumber>) -> BoxFuture<RpcU256, Error> {
|
||||||
let address = address.into();
|
let address = address.into();
|
||||||
let client = take_weakf!(self.client);
|
|
||||||
|
|
||||||
let res = match num.0.clone() {
|
let res = match num.0.clone() {
|
||||||
BlockNumber::Pending => {
|
BlockNumber::Pending => {
|
||||||
match take_weakf!(self.miner).balance(&*client, &address) {
|
match self.miner.balance(&*self.client, &address) {
|
||||||
Some(balance) => Ok(balance.into()),
|
Some(balance) => Ok(balance.into()),
|
||||||
None => Err(errors::database_error("latest balance missing"))
|
None => Err(errors::database_error("latest balance missing"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
id => {
|
id => {
|
||||||
try_bf!(check_known(&*client, id.clone()));
|
try_bf!(check_known(&*self.client, id.clone()));
|
||||||
match client.balance(&address, id.into()) {
|
match self.client.balance(&address, id.into()) {
|
||||||
Some(balance) => Ok(balance.into()),
|
Some(balance) => Ok(balance.into()),
|
||||||
None => Err(errors::state_pruned()),
|
None => Err(errors::state_pruned()),
|
||||||
}
|
}
|
||||||
@ -388,17 +386,14 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
|||||||
|
|
||||||
let res = match num.0.clone() {
|
let res = match num.0.clone() {
|
||||||
BlockNumber::Pending => {
|
BlockNumber::Pending => {
|
||||||
let client = take_weakf!(self.client);
|
match self.miner.storage_at(&*self.client, &address, &H256::from(position)) {
|
||||||
match take_weakf!(self.miner).storage_at(&*client, &address, &H256::from(position)) {
|
|
||||||
Some(s) => Ok(s.into()),
|
Some(s) => Ok(s.into()),
|
||||||
None => Err(errors::database_error("latest storage missing"))
|
None => Err(errors::database_error("latest storage missing"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
id => {
|
id => {
|
||||||
let client = take_weakf!(self.client);
|
try_bf!(check_known(&*self.client, id.clone()));
|
||||||
|
match self.client.storage_at(&address, &H256::from(position), id.into()) {
|
||||||
try_bf!(check_known(&*client, id.clone()));
|
|
||||||
match client.storage_at(&address, &H256::from(position), id.into()) {
|
|
||||||
Some(s) => Ok(s.into()),
|
Some(s) => Ok(s.into()),
|
||||||
None => Err(errors::state_pruned()),
|
None => Err(errors::state_pruned()),
|
||||||
}
|
}
|
||||||
@ -410,28 +405,26 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
|||||||
|
|
||||||
fn transaction_count(&self, address: RpcH160, num: Trailing<BlockNumber>) -> BoxFuture<RpcU256, Error> {
|
fn transaction_count(&self, address: RpcH160, num: Trailing<BlockNumber>) -> BoxFuture<RpcU256, Error> {
|
||||||
let address: Address = RpcH160::into(address);
|
let address: Address = RpcH160::into(address);
|
||||||
let client = take_weakf!(self.client);
|
|
||||||
let miner = take_weakf!(self.miner);
|
|
||||||
|
|
||||||
let res = match num.0.clone() {
|
let res = match num.0.clone() {
|
||||||
BlockNumber::Pending if self.options.pending_nonce_from_queue => {
|
BlockNumber::Pending if self.options.pending_nonce_from_queue => {
|
||||||
let nonce = miner.last_nonce(&address)
|
let nonce = self.miner.last_nonce(&address)
|
||||||
.map(|n| n + 1.into())
|
.map(|n| n + 1.into())
|
||||||
.or_else(|| miner.nonce(&*client, &address));
|
.or_else(|| self.miner.nonce(&*self.client, &address));
|
||||||
match nonce {
|
match nonce {
|
||||||
Some(nonce) => Ok(nonce.into()),
|
Some(nonce) => Ok(nonce.into()),
|
||||||
None => Err(errors::database_error("latest nonce missing"))
|
None => Err(errors::database_error("latest nonce missing"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BlockNumber::Pending => {
|
BlockNumber::Pending => {
|
||||||
match miner.nonce(&*client, &address) {
|
match self.miner.nonce(&*self.client, &address) {
|
||||||
Some(nonce) => Ok(nonce.into()),
|
Some(nonce) => Ok(nonce.into()),
|
||||||
None => Err(errors::database_error("latest nonce missing"))
|
None => Err(errors::database_error("latest nonce missing"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
id => {
|
id => {
|
||||||
try_bf!(check_known(&*client, id.clone()));
|
try_bf!(check_known(&*self.client, id.clone()));
|
||||||
match client.nonce(&address, id.into()) {
|
match self.client.nonce(&address, id.into()) {
|
||||||
Some(nonce) => Ok(nonce.into()),
|
Some(nonce) => Ok(nonce.into()),
|
||||||
None => Err(errors::state_pruned()),
|
None => Err(errors::state_pruned()),
|
||||||
}
|
}
|
||||||
@ -442,23 +435,23 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn block_transaction_count_by_hash(&self, hash: RpcH256) -> BoxFuture<Option<RpcU256>, Error> {
|
fn block_transaction_count_by_hash(&self, hash: RpcH256) -> BoxFuture<Option<RpcU256>, Error> {
|
||||||
future::ok(take_weakf!(self.client).block(BlockId::Hash(hash.into()))
|
future::ok(self.client.block(BlockId::Hash(hash.into()))
|
||||||
.map(|block| block.transactions_count().into())).boxed()
|
.map(|block| block.transactions_count().into())).boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn block_transaction_count_by_number(&self, num: BlockNumber) -> BoxFuture<Option<RpcU256>, Error> {
|
fn block_transaction_count_by_number(&self, num: BlockNumber) -> BoxFuture<Option<RpcU256>, Error> {
|
||||||
future::ok(match num {
|
future::ok(match num {
|
||||||
BlockNumber::Pending => Some(
|
BlockNumber::Pending => Some(
|
||||||
take_weakf!(self.miner).status().transactions_in_pending_block.into()
|
self.miner.status().transactions_in_pending_block.into()
|
||||||
),
|
),
|
||||||
_ =>
|
_ =>
|
||||||
take_weakf!(self.client).block(num.into())
|
self.client.block(num.into())
|
||||||
.map(|block| block.transactions_count().into())
|
.map(|block| block.transactions_count().into())
|
||||||
}).boxed()
|
}).boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn block_uncles_count_by_hash(&self, hash: RpcH256) -> BoxFuture<Option<RpcU256>, Error> {
|
fn block_uncles_count_by_hash(&self, hash: RpcH256) -> BoxFuture<Option<RpcU256>, Error> {
|
||||||
future::ok(take_weakf!(self.client).block(BlockId::Hash(hash.into()))
|
future::ok(self.client.block(BlockId::Hash(hash.into()))
|
||||||
.map(|block| block.uncles_count().into()))
|
.map(|block| block.uncles_count().into()))
|
||||||
.boxed()
|
.boxed()
|
||||||
}
|
}
|
||||||
@ -466,7 +459,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
|||||||
fn block_uncles_count_by_number(&self, num: BlockNumber) -> BoxFuture<Option<RpcU256>, Error> {
|
fn block_uncles_count_by_number(&self, num: BlockNumber) -> BoxFuture<Option<RpcU256>, Error> {
|
||||||
future::ok(match num {
|
future::ok(match num {
|
||||||
BlockNumber::Pending => Some(0.into()),
|
BlockNumber::Pending => Some(0.into()),
|
||||||
_ => take_weakf!(self.client).block(num.into())
|
_ => self.client.block(num.into())
|
||||||
.map(|block| block.uncles_count().into()
|
.map(|block| block.uncles_count().into()
|
||||||
),
|
),
|
||||||
}).boxed()
|
}).boxed()
|
||||||
@ -477,17 +470,14 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
|||||||
|
|
||||||
let res = match num.0.clone() {
|
let res = match num.0.clone() {
|
||||||
BlockNumber::Pending => {
|
BlockNumber::Pending => {
|
||||||
let client = take_weakf!(self.client);
|
match self.miner.code(&*self.client, &address) {
|
||||||
match take_weakf!(self.miner).code(&*client, &address) {
|
|
||||||
Some(code) => Ok(code.map_or_else(Bytes::default, Bytes::new)),
|
Some(code) => Ok(code.map_or_else(Bytes::default, Bytes::new)),
|
||||||
None => Err(errors::database_error("latest code missing"))
|
None => Err(errors::database_error("latest code missing"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
id => {
|
id => {
|
||||||
let client = take_weakf!(self.client);
|
try_bf!(check_known(&*self.client, id.clone()));
|
||||||
|
match self.client.code(&address, id.into()) {
|
||||||
try_bf!(check_known(&*client, id.clone()));
|
|
||||||
match client.code(&address, id.into()) {
|
|
||||||
Some(code) => Ok(code.map_or_else(Bytes::default, Bytes::new)),
|
Some(code) => Ok(code.map_or_else(Bytes::default, Bytes::new)),
|
||||||
None => Err(errors::state_pruned()),
|
None => Err(errors::state_pruned()),
|
||||||
}
|
}
|
||||||
@ -507,10 +497,8 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
|||||||
|
|
||||||
fn transaction_by_hash(&self, hash: RpcH256) -> Result<Option<Transaction>, Error> {
|
fn transaction_by_hash(&self, hash: RpcH256) -> Result<Option<Transaction>, Error> {
|
||||||
let hash: H256 = hash.into();
|
let hash: H256 = hash.into();
|
||||||
let miner = take_weak!(self.miner);
|
let block_number = self.client.chain_info().best_block_number;
|
||||||
let client = take_weak!(self.client);
|
Ok(self.transaction(TransactionId::Hash(hash))?.or_else(|| self.miner.transaction(block_number, &hash).map(|t| Transaction::from_pending(t, block_number, self.eip86_transition))))
|
||||||
let block_number = client.chain_info().best_block_number;
|
|
||||||
Ok(self.transaction(TransactionId::Hash(hash))?.or_else(|| miner.transaction(block_number, &hash).map(|t| Transaction::from_pending(t, block_number, self.eip86_transition))))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transaction_by_block_hash_and_index(&self, hash: RpcH256, index: Index) -> Result<Option<Transaction>, Error> {
|
fn transaction_by_block_hash_and_index(&self, hash: RpcH256, index: Index) -> Result<Option<Transaction>, Error> {
|
||||||
@ -522,14 +510,12 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn transaction_receipt(&self, hash: RpcH256) -> Result<Option<Receipt>, Error> {
|
fn transaction_receipt(&self, hash: RpcH256) -> Result<Option<Receipt>, Error> {
|
||||||
let miner = take_weak!(self.miner);
|
let best_block = self.client.chain_info().best_block_number;
|
||||||
let best_block = take_weak!(self.client).chain_info().best_block_number;
|
|
||||||
let hash: H256 = hash.into();
|
let hash: H256 = hash.into();
|
||||||
match (miner.pending_receipt(best_block, &hash), self.options.allow_pending_receipt_query) {
|
match (self.miner.pending_receipt(best_block, &hash), self.options.allow_pending_receipt_query) {
|
||||||
(Some(receipt), true) => Ok(Some(receipt.into())),
|
(Some(receipt), true) => Ok(Some(receipt.into())),
|
||||||
_ => {
|
_ => {
|
||||||
let client = take_weak!(self.client);
|
let receipt = self.client.transaction_receipt(TransactionId::Hash(hash));
|
||||||
let receipt = client.transaction_receipt(TransactionId::Hash(hash));
|
|
||||||
Ok(receipt.map(Into::into))
|
Ok(receipt.map(Into::into))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -550,14 +536,14 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
|||||||
fn logs(&self, filter: Filter) -> BoxFuture<Vec<Log>, Error> {
|
fn logs(&self, filter: Filter) -> BoxFuture<Vec<Log>, Error> {
|
||||||
let include_pending = filter.to_block == Some(BlockNumber::Pending);
|
let include_pending = filter.to_block == Some(BlockNumber::Pending);
|
||||||
let filter: EthcoreFilter = filter.into();
|
let filter: EthcoreFilter = filter.into();
|
||||||
let mut logs = take_weakf!(self.client).logs(filter.clone())
|
let mut logs = self.client.logs(filter.clone())
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(From::from)
|
.map(From::from)
|
||||||
.collect::<Vec<Log>>();
|
.collect::<Vec<Log>>();
|
||||||
|
|
||||||
if include_pending {
|
if include_pending {
|
||||||
let best_block = take_weakf!(self.client).chain_info().best_block_number;
|
let best_block = self.client.chain_info().best_block_number;
|
||||||
let pending = pending_logs(&*take_weakf!(self.miner), best_block, &filter);
|
let pending = pending_logs(&*self.miner, best_block, &filter);
|
||||||
logs.extend(pending);
|
logs.extend(pending);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -569,29 +555,27 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
|||||||
fn work(&self, no_new_work_timeout: Trailing<u64>) -> Result<Work, Error> {
|
fn work(&self, no_new_work_timeout: Trailing<u64>) -> Result<Work, Error> {
|
||||||
let no_new_work_timeout = no_new_work_timeout.0;
|
let no_new_work_timeout = no_new_work_timeout.0;
|
||||||
|
|
||||||
let client = take_weak!(self.client);
|
|
||||||
// check if we're still syncing and return empty strings in that case
|
// check if we're still syncing and return empty strings in that case
|
||||||
{
|
{
|
||||||
//TODO: check if initial sync is complete here
|
//TODO: check if initial sync is complete here
|
||||||
//let sync = take_weak!(self.sync);
|
//let sync = self.sync;
|
||||||
if /*sync.status().state != SyncState::Idle ||*/ client.queue_info().total_queue_size() > MAX_QUEUE_SIZE_TO_MINE_ON {
|
if /*sync.status().state != SyncState::Idle ||*/ self.client.queue_info().total_queue_size() > MAX_QUEUE_SIZE_TO_MINE_ON {
|
||||||
trace!(target: "miner", "Syncing. Cannot give any work.");
|
trace!(target: "miner", "Syncing. Cannot give any work.");
|
||||||
return Err(errors::no_work());
|
return Err(errors::no_work());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise spin until our submitted block has been included.
|
// Otherwise spin until our submitted block has been included.
|
||||||
let timeout = Instant::now() + Duration::from_millis(1000);
|
let timeout = Instant::now() + Duration::from_millis(1000);
|
||||||
while Instant::now() < timeout && client.queue_info().total_queue_size() > 0 {
|
while Instant::now() < timeout && self.client.queue_info().total_queue_size() > 0 {
|
||||||
thread::sleep(Duration::from_millis(1));
|
thread::sleep(Duration::from_millis(1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let miner = take_weak!(self.miner);
|
if self.miner.author().is_zero() {
|
||||||
if miner.author().is_zero() {
|
|
||||||
warn!(target: "miner", "Cannot give work package - no author is configured. Use --author to configure!");
|
warn!(target: "miner", "Cannot give work package - no author is configured. Use --author to configure!");
|
||||||
return Err(errors::no_author())
|
return Err(errors::no_author())
|
||||||
}
|
}
|
||||||
miner.map_sealing_work(&*client, |b| {
|
self.miner.map_sealing_work(&*self.client, |b| {
|
||||||
let pow_hash = b.hash();
|
let pow_hash = b.hash();
|
||||||
let target = Ethash::difficulty_to_boundary(b.block().header().difficulty());
|
let target = Ethash::difficulty_to_boundary(b.block().header().difficulty());
|
||||||
let seed_hash = self.seed_compute.lock().get_seedhash(b.block().header().number());
|
let seed_hash = self.seed_compute.lock().get_seedhash(b.block().header().number());
|
||||||
@ -623,10 +607,8 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
|||||||
let mix_hash: H256 = mix_hash.into();
|
let mix_hash: H256 = mix_hash.into();
|
||||||
trace!(target: "miner", "submit_work: Decoded: nonce={}, pow_hash={}, mix_hash={}", nonce, pow_hash, mix_hash);
|
trace!(target: "miner", "submit_work: Decoded: nonce={}, pow_hash={}, mix_hash={}", nonce, pow_hash, mix_hash);
|
||||||
|
|
||||||
let miner = take_weak!(self.miner);
|
|
||||||
let client = take_weak!(self.client);
|
|
||||||
let seal = vec![rlp::encode(&mix_hash).to_vec(), rlp::encode(&nonce).to_vec()];
|
let seal = vec![rlp::encode(&mix_hash).to_vec(), rlp::encode(&nonce).to_vec()];
|
||||||
Ok(miner.submit_seal(&*client, pow_hash, seal).is_ok())
|
Ok(self.miner.submit_seal(&*self.client, pow_hash, seal).is_ok())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn submit_hashrate(&self, rate: RpcU256, id: RpcH256) -> Result<bool, Error> {
|
fn submit_hashrate(&self, rate: RpcU256, id: RpcH256) -> Result<bool, Error> {
|
||||||
@ -657,8 +639,8 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
|||||||
};
|
};
|
||||||
|
|
||||||
let result = match num.0 {
|
let result = match num.0 {
|
||||||
BlockNumber::Pending => take_weakf!(self.miner).call(&*take_weakf!(self.client), &signed, Default::default()),
|
BlockNumber::Pending => self.miner.call(&*self.client, &signed, Default::default()),
|
||||||
num => take_weakf!(self.client).call(&signed, num.into(), Default::default()),
|
num => self.client.call(&signed, num.into(), Default::default()),
|
||||||
};
|
};
|
||||||
|
|
||||||
future::done(result
|
future::done(result
|
||||||
@ -673,7 +655,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
|||||||
Ok(signed) => signed,
|
Ok(signed) => signed,
|
||||||
Err(e) => return future::err(e).boxed(),
|
Err(e) => return future::err(e).boxed(),
|
||||||
};
|
};
|
||||||
future::done(take_weakf!(self.client).estimate_gas(&signed, num.0.into())
|
future::done(self.client.estimate_gas(&signed, num.0.into())
|
||||||
.map(Into::into)
|
.map(Into::into)
|
||||||
.map_err(errors::from_call_error)
|
.map_err(errors::from_call_error)
|
||||||
).boxed()
|
).boxed()
|
||||||
|
@ -15,32 +15,32 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
//! Net rpc implementation.
|
//! Net rpc implementation.
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::Arc;
|
||||||
use jsonrpc_core::Error;
|
use jsonrpc_core::Error;
|
||||||
use ethsync::SyncProvider;
|
use ethsync::SyncProvider;
|
||||||
use v1::traits::Net;
|
use v1::traits::Net;
|
||||||
|
|
||||||
/// Net rpc implementation.
|
/// Net rpc implementation.
|
||||||
pub struct NetClient<S: ?Sized> {
|
pub struct NetClient<S: ?Sized> {
|
||||||
sync: Weak<S>
|
sync: Arc<S>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: ?Sized> NetClient<S> where S: SyncProvider {
|
impl<S: ?Sized> NetClient<S> where S: SyncProvider {
|
||||||
/// Creates new NetClient.
|
/// Creates new NetClient.
|
||||||
pub fn new(sync: &Arc<S>) -> Self {
|
pub fn new(sync: &Arc<S>) -> Self {
|
||||||
NetClient {
|
NetClient {
|
||||||
sync: Arc::downgrade(sync)
|
sync: sync.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: ?Sized> Net for NetClient<S> where S: SyncProvider + 'static {
|
impl<S: ?Sized> Net for NetClient<S> where S: SyncProvider + 'static {
|
||||||
fn version(&self) -> Result<String, Error> {
|
fn version(&self) -> Result<String, Error> {
|
||||||
Ok(format!("{}", take_weak!(self.sync).status().network_id).to_owned())
|
Ok(format!("{}", self.sync.status().network_id).to_owned())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn peer_count(&self) -> Result<String, Error> {
|
fn peer_count(&self) -> Result<String, Error> {
|
||||||
Ok(format!("0x{:x}", take_weak!(self.sync).status().num_peers as u64).to_owned())
|
Ok(format!("0x{:x}", self.sync.status().num_peers as u64).to_owned())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_listening(&self) -> Result<bool, Error> {
|
fn is_listening(&self) -> Result<bool, Error> {
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
//! Parity-specific rpc implementation.
|
//! Parity-specific rpc implementation.
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::Arc;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::collections::{BTreeMap, HashSet};
|
use std::collections::{BTreeMap, HashSet};
|
||||||
use futures::{future, Future, BoxFuture};
|
use futures::{future, Future, BoxFuture};
|
||||||
@ -58,12 +58,12 @@ pub struct ParityClient<C, M, S: ?Sized, U> where
|
|||||||
S: SyncProvider,
|
S: SyncProvider,
|
||||||
U: UpdateService,
|
U: UpdateService,
|
||||||
{
|
{
|
||||||
client: Weak<C>,
|
client: Arc<C>,
|
||||||
miner: Weak<M>,
|
miner: Arc<M>,
|
||||||
sync: Weak<S>,
|
sync: Arc<S>,
|
||||||
updater: Weak<U>,
|
updater: Arc<U>,
|
||||||
net: Weak<ManageNetwork>,
|
net: Arc<ManageNetwork>,
|
||||||
accounts: Option<Weak<AccountProvider>>,
|
accounts: Option<Arc<AccountProvider>>,
|
||||||
logger: Arc<RotatingLogger>,
|
logger: Arc<RotatingLogger>,
|
||||||
settings: Arc<NetworkSettings>,
|
settings: Arc<NetworkSettings>,
|
||||||
signer: Option<Arc<SignerService>>,
|
signer: Option<Arc<SignerService>>,
|
||||||
@ -93,12 +93,12 @@ impl<C, M, S: ?Sized, U> ParityClient<C, M, S, U> where
|
|||||||
ws_address: Option<(String, u16)>,
|
ws_address: Option<(String, u16)>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
ParityClient {
|
ParityClient {
|
||||||
client: Arc::downgrade(client),
|
client: client.clone(),
|
||||||
miner: Arc::downgrade(miner),
|
miner: miner.clone(),
|
||||||
sync: Arc::downgrade(sync),
|
sync: sync.clone(),
|
||||||
updater: Arc::downgrade(updater),
|
updater: updater.clone(),
|
||||||
net: Arc::downgrade(net),
|
net: net.clone(),
|
||||||
accounts: store.as_ref().map(Arc::downgrade),
|
accounts: store.clone(),
|
||||||
logger: logger,
|
logger: logger,
|
||||||
settings: settings,
|
settings: settings,
|
||||||
signer: signer,
|
signer: signer,
|
||||||
@ -109,7 +109,7 @@ impl<C, M, S: ?Sized, U> ParityClient<C, M, S, U> where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Attempt to get the `Arc<AccountProvider>`, errors if provider was not
|
/// Attempt to get the `Arc<AccountProvider>`, errors if provider was not
|
||||||
/// set, or if upgrading the weak reference failed.
|
/// set.
|
||||||
fn account_provider(&self) -> Result<Arc<AccountProvider>, Error> {
|
fn account_provider(&self) -> Result<Arc<AccountProvider>, Error> {
|
||||||
unwrap_provider(&self.accounts)
|
unwrap_provider(&self.accounts)
|
||||||
}
|
}
|
||||||
@ -167,23 +167,23 @@ impl<C, M, S: ?Sized, U> Parity for ParityClient<C, M, S, U> where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn transactions_limit(&self) -> Result<usize, Error> {
|
fn transactions_limit(&self) -> Result<usize, Error> {
|
||||||
Ok(take_weak!(self.miner).transactions_limit())
|
Ok(self.miner.transactions_limit())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn min_gas_price(&self) -> Result<U256, Error> {
|
fn min_gas_price(&self) -> Result<U256, Error> {
|
||||||
Ok(U256::from(take_weak!(self.miner).minimal_gas_price()))
|
Ok(U256::from(self.miner.minimal_gas_price()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extra_data(&self) -> Result<Bytes, Error> {
|
fn extra_data(&self) -> Result<Bytes, Error> {
|
||||||
Ok(Bytes::new(take_weak!(self.miner).extra_data()))
|
Ok(Bytes::new(self.miner.extra_data()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gas_floor_target(&self) -> Result<U256, Error> {
|
fn gas_floor_target(&self) -> Result<U256, Error> {
|
||||||
Ok(U256::from(take_weak!(self.miner).gas_floor_target()))
|
Ok(U256::from(self.miner.gas_floor_target()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gas_ceil_target(&self) -> Result<U256, Error> {
|
fn gas_ceil_target(&self) -> Result<U256, Error> {
|
||||||
Ok(U256::from(take_weak!(self.miner).gas_ceil_target()))
|
Ok(U256::from(self.miner.gas_ceil_target()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dev_logs(&self) -> Result<Vec<String>, Error> {
|
fn dev_logs(&self) -> Result<Vec<String>, Error> {
|
||||||
@ -200,14 +200,13 @@ impl<C, M, S: ?Sized, U> Parity for ParityClient<C, M, S, U> where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn chain(&self) -> Result<String, Error> {
|
fn chain(&self) -> Result<String, Error> {
|
||||||
Ok(take_weak!(self.client).spec_name())
|
Ok(self.client.spec_name())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn net_peers(&self) -> Result<Peers, Error> {
|
fn net_peers(&self) -> Result<Peers, Error> {
|
||||||
let sync = take_weak!(self.sync);
|
let sync_status = self.sync.status();
|
||||||
let sync_status = sync.status();
|
let net_config = self.net.network_config();
|
||||||
let net_config = take_weak!(self.net).network_config();
|
let peers = self.sync.peers().into_iter().map(Into::into).collect();
|
||||||
let peers = sync.peers().into_iter().map(Into::into).collect();
|
|
||||||
|
|
||||||
Ok(Peers {
|
Ok(Peers {
|
||||||
active: sync_status.num_active_peers,
|
active: sync_status.num_active_peers,
|
||||||
@ -227,7 +226,7 @@ impl<C, M, S: ?Sized, U> Parity for ParityClient<C, M, S, U> where
|
|||||||
|
|
||||||
fn registry_address(&self) -> Result<Option<H160>, Error> {
|
fn registry_address(&self) -> Result<Option<H160>, Error> {
|
||||||
Ok(
|
Ok(
|
||||||
take_weak!(self.client)
|
self.client
|
||||||
.additional_params()
|
.additional_params()
|
||||||
.get("registrar")
|
.get("registrar")
|
||||||
.and_then(|s| Address::from_str(s).ok())
|
.and_then(|s| Address::from_str(s).ok())
|
||||||
@ -248,7 +247,7 @@ impl<C, M, S: ?Sized, U> Parity for ParityClient<C, M, S, U> where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn gas_price_histogram(&self) -> BoxFuture<Histogram, Error> {
|
fn gas_price_histogram(&self) -> BoxFuture<Histogram, Error> {
|
||||||
future::done(take_weakf!(self.client)
|
future::done(self.client
|
||||||
.gas_price_corpus(100)
|
.gas_price_corpus(100)
|
||||||
.histogram(10)
|
.histogram(10)
|
||||||
.ok_or_else(errors::not_enough_data)
|
.ok_or_else(errors::not_enough_data)
|
||||||
@ -272,13 +271,13 @@ impl<C, M, S: ?Sized, U> Parity for ParityClient<C, M, S, U> where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn list_accounts(&self, count: u64, after: Option<H160>, block_number: Trailing<BlockNumber>) -> Result<Option<Vec<H160>>, Error> {
|
fn list_accounts(&self, count: u64, after: Option<H160>, block_number: Trailing<BlockNumber>) -> Result<Option<Vec<H160>>, Error> {
|
||||||
Ok(take_weak!(self.client)
|
Ok(self.client
|
||||||
.list_accounts(block_number.0.into(), after.map(Into::into).as_ref(), count)
|
.list_accounts(block_number.0.into(), after.map(Into::into).as_ref(), count)
|
||||||
.map(|a| a.into_iter().map(Into::into).collect()))
|
.map(|a| a.into_iter().map(Into::into).collect()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn list_storage_keys(&self, address: H160, count: u64, after: Option<H256>, block_number: Trailing<BlockNumber>) -> Result<Option<Vec<H256>>, Error> {
|
fn list_storage_keys(&self, address: H160, count: u64, after: Option<H256>, block_number: Trailing<BlockNumber>) -> Result<Option<Vec<H256>>, Error> {
|
||||||
Ok(take_weak!(self.client)
|
Ok(self.client
|
||||||
.list_storage(block_number.0.into(), &address.into(), after.map(Into::into).as_ref(), count)
|
.list_storage(block_number.0.into(), &address.into(), after.map(Into::into).as_ref(), count)
|
||||||
.map(|a| a.into_iter().map(Into::into).collect()))
|
.map(|a| a.into_iter().map(Into::into).collect()))
|
||||||
}
|
}
|
||||||
@ -290,17 +289,17 @@ impl<C, M, S: ?Sized, U> Parity for ParityClient<C, M, S, U> where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn pending_transactions(&self) -> Result<Vec<Transaction>, Error> {
|
fn pending_transactions(&self) -> Result<Vec<Transaction>, Error> {
|
||||||
let block_number = take_weak!(self.client).chain_info().best_block_number;
|
let block_number = self.client.chain_info().best_block_number;
|
||||||
Ok(take_weak!(self.miner).pending_transactions().into_iter().map(|t| Transaction::from_pending(t, block_number, self.eip86_transition)).collect::<Vec<_>>())
|
Ok(self.miner.pending_transactions().into_iter().map(|t| Transaction::from_pending(t, block_number, self.eip86_transition)).collect::<Vec<_>>())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn future_transactions(&self) -> Result<Vec<Transaction>, Error> {
|
fn future_transactions(&self) -> Result<Vec<Transaction>, Error> {
|
||||||
let block_number = take_weak!(self.client).chain_info().best_block_number;
|
let block_number = self.client.chain_info().best_block_number;
|
||||||
Ok(take_weak!(self.miner).future_transactions().into_iter().map(|t| Transaction::from_pending(t, block_number, self.eip86_transition)).collect::<Vec<_>>())
|
Ok(self.miner.future_transactions().into_iter().map(|t| Transaction::from_pending(t, block_number, self.eip86_transition)).collect::<Vec<_>>())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pending_transactions_stats(&self) -> Result<BTreeMap<H256, TransactionStats>, Error> {
|
fn pending_transactions_stats(&self) -> Result<BTreeMap<H256, TransactionStats>, Error> {
|
||||||
let stats = take_weak!(self.sync).transactions_stats();
|
let stats = self.sync.transactions_stats();
|
||||||
Ok(stats.into_iter()
|
Ok(stats.into_iter()
|
||||||
.map(|(hash, stats)| (hash.into(), stats.into()))
|
.map(|(hash, stats)| (hash.into(), stats.into()))
|
||||||
.collect()
|
.collect()
|
||||||
@ -308,8 +307,8 @@ impl<C, M, S: ?Sized, U> Parity for ParityClient<C, M, S, U> where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn local_transactions(&self) -> Result<BTreeMap<H256, LocalTransactionStatus>, Error> {
|
fn local_transactions(&self) -> Result<BTreeMap<H256, LocalTransactionStatus>, Error> {
|
||||||
let transactions = take_weak!(self.miner).local_transactions();
|
let transactions = self.miner.local_transactions();
|
||||||
let block_number = take_weak!(self.client).chain_info().best_block_number;
|
let block_number = self.client.chain_info().best_block_number;
|
||||||
Ok(transactions
|
Ok(transactions
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(hash, status)| (hash.into(), LocalTransactionStatus::from(status, block_number, self.eip86_transition)))
|
.map(|(hash, status)| (hash.into(), LocalTransactionStatus::from(status, block_number, self.eip86_transition)))
|
||||||
@ -329,18 +328,16 @@ impl<C, M, S: ?Sized, U> Parity for ParityClient<C, M, S, U> where
|
|||||||
|
|
||||||
fn next_nonce(&self, address: H160) -> BoxFuture<U256, Error> {
|
fn next_nonce(&self, address: H160) -> BoxFuture<U256, Error> {
|
||||||
let address: Address = address.into();
|
let address: Address = address.into();
|
||||||
let miner = take_weakf!(self.miner);
|
|
||||||
let client = take_weakf!(self.client);
|
|
||||||
|
|
||||||
future::ok(miner.last_nonce(&address)
|
future::ok(self.miner.last_nonce(&address)
|
||||||
.map(|n| n + 1.into())
|
.map(|n| n + 1.into())
|
||||||
.unwrap_or_else(|| client.latest_nonce(&address))
|
.unwrap_or_else(|| self.client.latest_nonce(&address))
|
||||||
.into()
|
.into()
|
||||||
).boxed()
|
).boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mode(&self) -> Result<String, Error> {
|
fn mode(&self) -> Result<String, Error> {
|
||||||
Ok(match take_weak!(self.client).mode() {
|
Ok(match self.client.mode() {
|
||||||
Mode::Off => "offline",
|
Mode::Off => "offline",
|
||||||
Mode::Dark(..) => "dark",
|
Mode::Dark(..) => "dark",
|
||||||
Mode::Passive(..) => "passive",
|
Mode::Passive(..) => "passive",
|
||||||
@ -349,26 +346,23 @@ impl<C, M, S: ?Sized, U> Parity for ParityClient<C, M, S, U> where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn enode(&self) -> Result<String, Error> {
|
fn enode(&self) -> Result<String, Error> {
|
||||||
take_weak!(self.sync).enode().ok_or_else(errors::network_disabled)
|
self.sync.enode().ok_or_else(errors::network_disabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn consensus_capability(&self) -> Result<ConsensusCapability, Error> {
|
fn consensus_capability(&self) -> Result<ConsensusCapability, Error> {
|
||||||
let updater = take_weak!(self.updater);
|
Ok(self.updater.capability().into())
|
||||||
Ok(updater.capability().into())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn version_info(&self) -> Result<VersionInfo, Error> {
|
fn version_info(&self) -> Result<VersionInfo, Error> {
|
||||||
let updater = take_weak!(self.updater);
|
Ok(self.updater.version_info().into())
|
||||||
Ok(updater.version_info().into())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn releases_info(&self) -> Result<Option<OperationsInfo>, Error> {
|
fn releases_info(&self) -> Result<Option<OperationsInfo>, Error> {
|
||||||
let updater = take_weak!(self.updater);
|
Ok(self.updater.info().map(Into::into))
|
||||||
Ok(updater.info().map(Into::into))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn chain_status(&self) -> Result<ChainStatus, Error> {
|
fn chain_status(&self) -> Result<ChainStatus, Error> {
|
||||||
let chain_info = take_weak!(self.client).chain_info();
|
let chain_info = self.client.chain_info();
|
||||||
|
|
||||||
let gap = chain_info.ancient_block_number.map(|x| U256::from(x + 1))
|
let gap = chain_info.ancient_block_number.map(|x| U256::from(x + 1))
|
||||||
.and_then(|first| chain_info.first_block_number.map(|last| (first, U256::from(last))));
|
.and_then(|first| chain_info.first_block_number.map(|last| (first, U256::from(last))));
|
||||||
@ -395,16 +389,15 @@ impl<C, M, S: ?Sized, U> Parity for ParityClient<C, M, S, U> where
|
|||||||
fn block_header(&self, number: Trailing<BlockNumber>) -> BoxFuture<RichHeader, Error> {
|
fn block_header(&self, number: Trailing<BlockNumber>) -> BoxFuture<RichHeader, Error> {
|
||||||
const EXTRA_INFO_PROOF: &'static str = "Object exists in in blockchain (fetched earlier), extra_info is always available if object exists; qed";
|
const EXTRA_INFO_PROOF: &'static str = "Object exists in in blockchain (fetched earlier), extra_info is always available if object exists; qed";
|
||||||
|
|
||||||
let client = take_weakf!(self.client);
|
|
||||||
let id: BlockId = number.0.into();
|
let id: BlockId = number.0.into();
|
||||||
let encoded = match client.block_header(id.clone()) {
|
let encoded = match self.client.block_header(id.clone()) {
|
||||||
Some(encoded) => encoded,
|
Some(encoded) => encoded,
|
||||||
None => return future::err(errors::unknown_block()).boxed(),
|
None => return future::err(errors::unknown_block()).boxed(),
|
||||||
};
|
};
|
||||||
|
|
||||||
future::ok(RichHeader {
|
future::ok(RichHeader {
|
||||||
inner: encoded.into(),
|
inner: encoded.into(),
|
||||||
extra_info: client.block_extra_info(id).expect(EXTRA_INFO_PROOF),
|
extra_info: self.client.block_extra_info(id).expect(EXTRA_INFO_PROOF),
|
||||||
}).boxed()
|
}).boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
//! Account management (personal) rpc implementation
|
//! Account management (personal) rpc implementation
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::Arc;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use util::Address;
|
use util::Address;
|
||||||
|
|
||||||
@ -31,19 +31,19 @@ use v1::types::{H160 as RpcH160, H256 as RpcH256, H520 as RpcH520, DappId, Deriv
|
|||||||
|
|
||||||
/// Account management (personal) rpc implementation.
|
/// Account management (personal) rpc implementation.
|
||||||
pub struct ParityAccountsClient {
|
pub struct ParityAccountsClient {
|
||||||
accounts: Option<Weak<AccountProvider>>,
|
accounts: Option<Arc<AccountProvider>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ParityAccountsClient {
|
impl ParityAccountsClient {
|
||||||
/// Creates new PersonalClient
|
/// Creates new PersonalClient
|
||||||
pub fn new(store: &Option<Arc<AccountProvider>>) -> Self {
|
pub fn new(store: &Option<Arc<AccountProvider>>) -> Self {
|
||||||
ParityAccountsClient {
|
ParityAccountsClient {
|
||||||
accounts: store.as_ref().map(Arc::downgrade),
|
accounts: store.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempt to get the `Arc<AccountProvider>`, errors if provider was not
|
/// Attempt to get the `Arc<AccountProvider>`, errors if provider was not
|
||||||
/// set, or if upgrading the weak reference failed.
|
/// set.
|
||||||
fn account_provider(&self) -> Result<Arc<AccountProvider>, Error> {
|
fn account_provider(&self) -> Result<Arc<AccountProvider>, Error> {
|
||||||
unwrap_provider(&self.accounts)
|
unwrap_provider(&self.accounts)
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
/// Parity-specific rpc interface for operations altering the settings.
|
/// Parity-specific rpc interface for operations altering the settings.
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::Arc;
|
||||||
|
|
||||||
use ethcore::miner::MinerService;
|
use ethcore::miner::MinerService;
|
||||||
use ethcore::client::MiningBlockChainClient;
|
use ethcore::client::MiningBlockChainClient;
|
||||||
@ -35,10 +35,10 @@ use v1::types::{Bytes, H160, H256, U256, ReleaseInfo, Transaction, LocalDapp};
|
|||||||
|
|
||||||
/// Parity-specific rpc interface for operations altering the settings.
|
/// Parity-specific rpc interface for operations altering the settings.
|
||||||
pub struct ParitySetClient<C, M, U, F = fetch::Client> {
|
pub struct ParitySetClient<C, M, U, F = fetch::Client> {
|
||||||
client: Weak<C>,
|
client: Arc<C>,
|
||||||
miner: Weak<M>,
|
miner: Arc<M>,
|
||||||
updater: Weak<U>,
|
updater: Arc<U>,
|
||||||
net: Weak<ManageNetwork>,
|
net: Arc<ManageNetwork>,
|
||||||
dapps: Option<Arc<DappsService>>,
|
dapps: Option<Arc<DappsService>>,
|
||||||
fetch: F,
|
fetch: F,
|
||||||
eip86_transition: u64,
|
eip86_transition: u64,
|
||||||
@ -57,10 +57,10 @@ impl<C, M, U, F> ParitySetClient<C, M, U, F>
|
|||||||
fetch: F,
|
fetch: F,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
ParitySetClient {
|
ParitySetClient {
|
||||||
client: Arc::downgrade(client),
|
client: client.clone(),
|
||||||
miner: Arc::downgrade(miner),
|
miner: miner.clone(),
|
||||||
updater: Arc::downgrade(updater),
|
updater: updater.clone(),
|
||||||
net: Arc::downgrade(net),
|
net: net.clone(),
|
||||||
dapps: dapps,
|
dapps: dapps,
|
||||||
fetch: fetch,
|
fetch: fetch,
|
||||||
eip86_transition: client.eip86_transition(),
|
eip86_transition: client.eip86_transition(),
|
||||||
@ -76,81 +76,81 @@ impl<C, M, U, F> ParitySet for ParitySetClient<C, M, U, F> where
|
|||||||
{
|
{
|
||||||
|
|
||||||
fn set_min_gas_price(&self, gas_price: U256) -> Result<bool, Error> {
|
fn set_min_gas_price(&self, gas_price: U256) -> Result<bool, Error> {
|
||||||
take_weak!(self.miner).set_minimal_gas_price(gas_price.into());
|
self.miner.set_minimal_gas_price(gas_price.into());
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_gas_floor_target(&self, target: U256) -> Result<bool, Error> {
|
fn set_gas_floor_target(&self, target: U256) -> Result<bool, Error> {
|
||||||
take_weak!(self.miner).set_gas_floor_target(target.into());
|
self.miner.set_gas_floor_target(target.into());
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_gas_ceil_target(&self, target: U256) -> Result<bool, Error> {
|
fn set_gas_ceil_target(&self, target: U256) -> Result<bool, Error> {
|
||||||
take_weak!(self.miner).set_gas_ceil_target(target.into());
|
self.miner.set_gas_ceil_target(target.into());
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_extra_data(&self, extra_data: Bytes) -> Result<bool, Error> {
|
fn set_extra_data(&self, extra_data: Bytes) -> Result<bool, Error> {
|
||||||
take_weak!(self.miner).set_extra_data(extra_data.into_vec());
|
self.miner.set_extra_data(extra_data.into_vec());
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_author(&self, author: H160) -> Result<bool, Error> {
|
fn set_author(&self, author: H160) -> Result<bool, Error> {
|
||||||
take_weak!(self.miner).set_author(author.into());
|
self.miner.set_author(author.into());
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_engine_signer(&self, address: H160, password: String) -> Result<bool, Error> {
|
fn set_engine_signer(&self, address: H160, password: String) -> Result<bool, Error> {
|
||||||
take_weak!(self.miner).set_engine_signer(address.into(), password).map_err(Into::into).map_err(errors::from_password_error)?;
|
self.miner.set_engine_signer(address.into(), password).map_err(Into::into).map_err(errors::from_password_error)?;
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_transactions_limit(&self, limit: usize) -> Result<bool, Error> {
|
fn set_transactions_limit(&self, limit: usize) -> Result<bool, Error> {
|
||||||
take_weak!(self.miner).set_transactions_limit(limit);
|
self.miner.set_transactions_limit(limit);
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_tx_gas_limit(&self, limit: U256) -> Result<bool, Error> {
|
fn set_tx_gas_limit(&self, limit: U256) -> Result<bool, Error> {
|
||||||
take_weak!(self.miner).set_tx_gas_limit(limit.into());
|
self.miner.set_tx_gas_limit(limit.into());
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_reserved_peer(&self, peer: String) -> Result<bool, Error> {
|
fn add_reserved_peer(&self, peer: String) -> Result<bool, Error> {
|
||||||
match take_weak!(self.net).add_reserved_peer(peer) {
|
match self.net.add_reserved_peer(peer) {
|
||||||
Ok(()) => Ok(true),
|
Ok(()) => Ok(true),
|
||||||
Err(e) => Err(errors::invalid_params("Peer address", e)),
|
Err(e) => Err(errors::invalid_params("Peer address", e)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_reserved_peer(&self, peer: String) -> Result<bool, Error> {
|
fn remove_reserved_peer(&self, peer: String) -> Result<bool, Error> {
|
||||||
match take_weak!(self.net).remove_reserved_peer(peer) {
|
match self.net.remove_reserved_peer(peer) {
|
||||||
Ok(()) => Ok(true),
|
Ok(()) => Ok(true),
|
||||||
Err(e) => Err(errors::invalid_params("Peer address", e)),
|
Err(e) => Err(errors::invalid_params("Peer address", e)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn drop_non_reserved_peers(&self) -> Result<bool, Error> {
|
fn drop_non_reserved_peers(&self) -> Result<bool, Error> {
|
||||||
take_weak!(self.net).deny_unreserved_peers();
|
self.net.deny_unreserved_peers();
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn accept_non_reserved_peers(&self) -> Result<bool, Error> {
|
fn accept_non_reserved_peers(&self) -> Result<bool, Error> {
|
||||||
take_weak!(self.net).accept_unreserved_peers();
|
self.net.accept_unreserved_peers();
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_network(&self) -> Result<bool, Error> {
|
fn start_network(&self) -> Result<bool, Error> {
|
||||||
take_weak!(self.net).start_network();
|
self.net.start_network();
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stop_network(&self) -> Result<bool, Error> {
|
fn stop_network(&self) -> Result<bool, Error> {
|
||||||
take_weak!(self.net).stop_network();
|
self.net.stop_network();
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_mode(&self, mode: String) -> Result<bool, Error> {
|
fn set_mode(&self, mode: String) -> Result<bool, Error> {
|
||||||
take_weak!(self.client).set_mode(match mode.as_str() {
|
self.client.set_mode(match mode.as_str() {
|
||||||
"offline" => Mode::Off,
|
"offline" => Mode::Off,
|
||||||
"dark" => Mode::Dark(300),
|
"dark" => Mode::Dark(300),
|
||||||
"passive" => Mode::Passive(300, 3600),
|
"passive" => Mode::Passive(300, 3600),
|
||||||
@ -161,7 +161,7 @@ impl<C, M, U, F> ParitySet for ParitySetClient<C, M, U, F> where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn set_spec_name(&self, spec_name: String) -> Result<bool, Error> {
|
fn set_spec_name(&self, spec_name: String) -> Result<bool, Error> {
|
||||||
take_weak!(self.client).set_spec_name(spec_name);
|
self.client.set_spec_name(spec_name);
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,21 +181,17 @@ impl<C, M, U, F> ParitySet for ParitySetClient<C, M, U, F> where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn upgrade_ready(&self) -> Result<Option<ReleaseInfo>, Error> {
|
fn upgrade_ready(&self) -> Result<Option<ReleaseInfo>, Error> {
|
||||||
let updater = take_weak!(self.updater);
|
Ok(self.updater.upgrade_ready().map(Into::into))
|
||||||
Ok(updater.upgrade_ready().map(Into::into))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute_upgrade(&self) -> Result<bool, Error> {
|
fn execute_upgrade(&self) -> Result<bool, Error> {
|
||||||
let updater = take_weak!(self.updater);
|
Ok(self.updater.execute_upgrade())
|
||||||
Ok(updater.execute_upgrade())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_transaction(&self, hash: H256) -> Result<Option<Transaction>, Error> {
|
fn remove_transaction(&self, hash: H256) -> Result<Option<Transaction>, Error> {
|
||||||
let miner = take_weak!(self.miner);
|
let block_number = self.client.chain_info().best_block_number;
|
||||||
let client = take_weak!(self.client);
|
|
||||||
let block_number = take_weak!(self.client).chain_info().best_block_number;
|
|
||||||
let hash = hash.into();
|
let hash = hash.into();
|
||||||
|
|
||||||
Ok(miner.remove_pending_transaction(&*client, &hash).map(|t| Transaction::from_pending(t, block_number, self.eip86_transition)))
|
Ok(self.miner.remove_pending_transaction(&*self.client, &hash).map(|t| Transaction::from_pending(t, block_number, self.eip86_transition)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
//! Account management (personal) rpc implementation
|
//! Account management (personal) rpc implementation
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::Arc;
|
||||||
|
|
||||||
use ethcore::account_provider::AccountProvider;
|
use ethcore::account_provider::AccountProvider;
|
||||||
use ethcore::transaction::PendingTransaction;
|
use ethcore::transaction::PendingTransaction;
|
||||||
@ -33,7 +33,7 @@ use v1::metadata::Metadata;
|
|||||||
|
|
||||||
/// Account management (personal) rpc implementation.
|
/// Account management (personal) rpc implementation.
|
||||||
pub struct PersonalClient<D: Dispatcher> {
|
pub struct PersonalClient<D: Dispatcher> {
|
||||||
accounts: Option<Weak<AccountProvider>>,
|
accounts: Option<Arc<AccountProvider>>,
|
||||||
dispatcher: D,
|
dispatcher: D,
|
||||||
allow_perm_unlock: bool,
|
allow_perm_unlock: bool,
|
||||||
}
|
}
|
||||||
@ -42,7 +42,7 @@ impl<D: Dispatcher> PersonalClient<D> {
|
|||||||
/// Creates new PersonalClient
|
/// Creates new PersonalClient
|
||||||
pub fn new(store: &Option<Arc<AccountProvider>>, dispatcher: D, allow_perm_unlock: bool) -> Self {
|
pub fn new(store: &Option<Arc<AccountProvider>>, dispatcher: D, allow_perm_unlock: bool) -> Self {
|
||||||
PersonalClient {
|
PersonalClient {
|
||||||
accounts: store.as_ref().map(Arc::downgrade),
|
accounts: store.clone(),
|
||||||
dispatcher: dispatcher,
|
dispatcher: dispatcher,
|
||||||
allow_perm_unlock: allow_perm_unlock,
|
allow_perm_unlock: allow_perm_unlock,
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
//! SecretStore-specific rpc implementation.
|
//! SecretStore-specific rpc implementation.
|
||||||
|
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crypto::DEFAULT_MAC;
|
use crypto::DEFAULT_MAC;
|
||||||
use ethkey::Secret;
|
use ethkey::Secret;
|
||||||
@ -31,19 +31,19 @@ use v1::types::{H160, H512, Bytes};
|
|||||||
|
|
||||||
/// Parity implementation.
|
/// Parity implementation.
|
||||||
pub struct SecretStoreClient {
|
pub struct SecretStoreClient {
|
||||||
accounts: Option<Weak<AccountProvider>>,
|
accounts: Option<Arc<AccountProvider>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SecretStoreClient {
|
impl SecretStoreClient {
|
||||||
/// Creates new SecretStoreClient
|
/// Creates new SecretStoreClient
|
||||||
pub fn new(store: &Option<Arc<AccountProvider>>) -> Self {
|
pub fn new(store: &Option<Arc<AccountProvider>>) -> Self {
|
||||||
SecretStoreClient {
|
SecretStoreClient {
|
||||||
accounts: store.as_ref().map(Arc::downgrade),
|
accounts: store.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempt to get the `Arc<AccountProvider>`, errors if provider was not
|
/// Attempt to get the `Arc<AccountProvider>`, errors if provider was not
|
||||||
/// set, or if upgrading the weak reference failed.
|
/// set.
|
||||||
fn account_provider(&self) -> Result<Arc<AccountProvider>, Error> {
|
fn account_provider(&self) -> Result<Arc<AccountProvider>, Error> {
|
||||||
unwrap_provider(&self.accounts)
|
unwrap_provider(&self.accounts)
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
//! Transactions Confirmations rpc implementation
|
//! Transactions Confirmations rpc implementation
|
||||||
|
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::Arc;
|
||||||
|
|
||||||
use ethcore::account_provider::AccountProvider;
|
use ethcore::account_provider::AccountProvider;
|
||||||
use ethcore::transaction::{SignedTransaction, PendingTransaction};
|
use ethcore::transaction::{SignedTransaction, PendingTransaction};
|
||||||
@ -38,8 +38,8 @@ use v1::types::{TransactionModification, ConfirmationRequest, ConfirmationRespon
|
|||||||
|
|
||||||
/// Transactions confirmation (personal) rpc implementation.
|
/// Transactions confirmation (personal) rpc implementation.
|
||||||
pub struct SignerClient<D: Dispatcher> {
|
pub struct SignerClient<D: Dispatcher> {
|
||||||
signer: Weak<SignerService>,
|
signer: Arc<SignerService>,
|
||||||
accounts: Option<Weak<AccountProvider>>,
|
accounts: Option<Arc<AccountProvider>>,
|
||||||
dispatcher: D,
|
dispatcher: D,
|
||||||
subscribers: Arc<Mutex<Subscribers<Sink<Vec<ConfirmationRequest>>>>>,
|
subscribers: Arc<Mutex<Subscribers<Sink<Vec<ConfirmationRequest>>>>>,
|
||||||
}
|
}
|
||||||
@ -70,8 +70,8 @@ impl<D: Dispatcher + 'static> SignerClient<D> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
SignerClient {
|
SignerClient {
|
||||||
signer: Arc::downgrade(signer),
|
signer: signer.clone(),
|
||||||
accounts: store.as_ref().map(Arc::downgrade),
|
accounts: store.clone(),
|
||||||
dispatcher: dispatcher,
|
dispatcher: dispatcher,
|
||||||
subscribers: subscribers,
|
subscribers: subscribers,
|
||||||
}
|
}
|
||||||
@ -90,7 +90,7 @@ impl<D: Dispatcher + 'static> SignerClient<D> {
|
|||||||
let dispatcher = self.dispatcher.clone();
|
let dispatcher = self.dispatcher.clone();
|
||||||
|
|
||||||
let setup = || {
|
let setup = || {
|
||||||
Ok((self.account_provider()?, take_weak!(self.signer)))
|
Ok((self.account_provider()?, self.signer.clone()))
|
||||||
};
|
};
|
||||||
|
|
||||||
let (accounts, signer) = match setup() {
|
let (accounts, signer) = match setup() {
|
||||||
@ -166,8 +166,7 @@ impl<D: Dispatcher + 'static> Signer for SignerClient<D> {
|
|||||||
type Metadata = Metadata;
|
type Metadata = Metadata;
|
||||||
|
|
||||||
fn requests_to_confirm(&self) -> Result<Vec<ConfirmationRequest>, Error> {
|
fn requests_to_confirm(&self) -> Result<Vec<ConfirmationRequest>, Error> {
|
||||||
let signer = take_weak!(self.signer);
|
Ok(self.signer.requests()
|
||||||
Ok(signer.requests()
|
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(Into::into)
|
.map(Into::into)
|
||||||
.collect()
|
.collect()
|
||||||
@ -200,9 +199,8 @@ impl<D: Dispatcher + 'static> Signer for SignerClient<D> {
|
|||||||
|
|
||||||
fn confirm_request_raw(&self, id: U256, bytes: Bytes) -> Result<ConfirmationResponse, Error> {
|
fn confirm_request_raw(&self, id: U256, bytes: Bytes) -> Result<ConfirmationResponse, Error> {
|
||||||
let id = id.into();
|
let id = id.into();
|
||||||
let signer = take_weak!(self.signer);
|
|
||||||
|
|
||||||
signer.peek(&id).map(|confirmation| {
|
self.signer.peek(&id).map(|confirmation| {
|
||||||
let result = match confirmation.payload {
|
let result = match confirmation.payload {
|
||||||
ConfirmationPayload::SendTransaction(request) => {
|
ConfirmationPayload::SendTransaction(request) => {
|
||||||
Self::verify_transaction(bytes, request, |pending_transaction| {
|
Self::verify_transaction(bytes, request, |pending_transaction| {
|
||||||
@ -231,24 +229,24 @@ impl<D: Dispatcher + 'static> Signer for SignerClient<D> {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
if let Ok(ref response) = result {
|
if let Ok(ref response) = result {
|
||||||
signer.request_confirmed(id, Ok(response.clone()));
|
self.signer.request_confirmed(id, Ok(response.clone()));
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
}).unwrap_or_else(|| Err(errors::invalid_params("Unknown RequestID", id)))
|
}).unwrap_or_else(|| Err(errors::invalid_params("Unknown RequestID", id)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reject_request(&self, id: U256) -> Result<bool, Error> {
|
fn reject_request(&self, id: U256) -> Result<bool, Error> {
|
||||||
let res = take_weak!(self.signer).request_rejected(id.into());
|
let res = self.signer.request_rejected(id.into());
|
||||||
Ok(res.is_some())
|
Ok(res.is_some())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_token(&self) -> Result<String, Error> {
|
fn generate_token(&self) -> Result<String, Error> {
|
||||||
take_weak!(self.signer).generate_token()
|
self.signer.generate_token()
|
||||||
.map_err(|e| errors::token(e))
|
.map_err(|e| errors::token(e))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_web_proxy_token(&self) -> Result<String, Error> {
|
fn generate_web_proxy_token(&self) -> Result<String, Error> {
|
||||||
Ok(take_weak!(self.signer).generate_web_proxy_access_token())
|
Ok(self.signer.generate_web_proxy_access_token())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn subscribe_pending(&self, _meta: Self::Metadata, sub: Subscriber<Vec<ConfirmationRequest>>) {
|
fn subscribe_pending(&self, _meta: Self::Metadata, sub: Subscriber<Vec<ConfirmationRequest>>) {
|
||||||
@ -260,4 +258,3 @@ impl<D: Dispatcher + 'static> Signer for SignerClient<D> {
|
|||||||
futures::future::ok(res).boxed()
|
futures::future::ok(res).boxed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
//! Signing RPC implementation.
|
//! Signing RPC implementation.
|
||||||
|
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::Arc;
|
||||||
use transient_hashmap::TransientHashMap;
|
use transient_hashmap::TransientHashMap;
|
||||||
use util::{U256, Mutex};
|
use util::{U256, Mutex};
|
||||||
|
|
||||||
@ -55,8 +55,8 @@ enum DispatchResult {
|
|||||||
|
|
||||||
/// Implementation of functions that require signing when no trusted signer is used.
|
/// Implementation of functions that require signing when no trusted signer is used.
|
||||||
pub struct SigningQueueClient<D> {
|
pub struct SigningQueueClient<D> {
|
||||||
signer: Weak<SignerService>,
|
signer: Arc<SignerService>,
|
||||||
accounts: Option<Weak<AccountProvider>>,
|
accounts: Option<Arc<AccountProvider>>,
|
||||||
dispatcher: D,
|
dispatcher: D,
|
||||||
pending: Arc<Mutex<TransientHashMap<U256, ConfirmationPromise>>>,
|
pending: Arc<Mutex<TransientHashMap<U256, ConfirmationPromise>>>,
|
||||||
}
|
}
|
||||||
@ -94,8 +94,8 @@ impl<D: Dispatcher + 'static> SigningQueueClient<D> {
|
|||||||
/// Creates a new signing queue client given shared signing queue.
|
/// Creates a new signing queue client given shared signing queue.
|
||||||
pub fn new(signer: &Arc<SignerService>, dispatcher: D, accounts: &Option<Arc<AccountProvider>>) -> Self {
|
pub fn new(signer: &Arc<SignerService>, dispatcher: D, accounts: &Option<Arc<AccountProvider>>) -> Self {
|
||||||
SigningQueueClient {
|
SigningQueueClient {
|
||||||
signer: Arc::downgrade(signer),
|
signer: signer.clone(),
|
||||||
accounts: accounts.as_ref().map(Arc::downgrade),
|
accounts: accounts.clone(),
|
||||||
dispatcher: dispatcher,
|
dispatcher: dispatcher,
|
||||||
pending: Arc::new(Mutex::new(TransientHashMap::new(MAX_PENDING_DURATION_SEC))),
|
pending: Arc::new(Mutex::new(TransientHashMap::new(MAX_PENDING_DURATION_SEC))),
|
||||||
}
|
}
|
||||||
@ -113,7 +113,7 @@ impl<D: Dispatcher + 'static> SigningQueueClient<D> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let dispatcher = self.dispatcher.clone();
|
let dispatcher = self.dispatcher.clone();
|
||||||
let signer = take_weakf!(self.signer);
|
let signer = self.signer.clone();
|
||||||
dispatch::from_rpc(payload, default_account, &dispatcher)
|
dispatch::from_rpc(payload, default_account, &dispatcher)
|
||||||
.and_then(move |payload| {
|
.and_then(move |payload| {
|
||||||
let sender = payload.sender();
|
let sender = payload.sender();
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
//! Unsafe Signing RPC implementation.
|
//! Unsafe Signing RPC implementation.
|
||||||
|
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::Arc;
|
||||||
|
|
||||||
use ethcore::account_provider::AccountProvider;
|
use ethcore::account_provider::AccountProvider;
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ use v1::types::{
|
|||||||
|
|
||||||
/// Implementation of functions that require signing when no trusted signer is used.
|
/// Implementation of functions that require signing when no trusted signer is used.
|
||||||
pub struct SigningUnsafeClient<D> {
|
pub struct SigningUnsafeClient<D> {
|
||||||
accounts: Option<Weak<AccountProvider>>,
|
accounts: Option<Arc<AccountProvider>>,
|
||||||
dispatcher: D,
|
dispatcher: D,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ impl<D: Dispatcher + 'static> SigningUnsafeClient<D> {
|
|||||||
/// Creates new SigningUnsafeClient.
|
/// Creates new SigningUnsafeClient.
|
||||||
pub fn new(accounts: &Option<Arc<AccountProvider>>, dispatcher: D) -> Self {
|
pub fn new(accounts: &Option<Arc<AccountProvider>>, dispatcher: D) -> Self {
|
||||||
SigningUnsafeClient {
|
SigningUnsafeClient {
|
||||||
accounts: accounts.as_ref().map(Arc::downgrade),
|
accounts: accounts.clone(),
|
||||||
dispatcher: dispatcher,
|
dispatcher: dispatcher,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
//! Traces api implementation.
|
//! Traces api implementation.
|
||||||
|
|
||||||
use std::sync::{Weak, Arc};
|
use std::sync::Arc;
|
||||||
|
|
||||||
use rlp::UntrustedRlp;
|
use rlp::UntrustedRlp;
|
||||||
use ethcore::client::{MiningBlockChainClient, CallAnalytics, TransactionId, TraceId};
|
use ethcore::client::{MiningBlockChainClient, CallAnalytics, TransactionId, TraceId};
|
||||||
@ -39,33 +39,33 @@ fn to_call_analytics(flags: Vec<String>) -> CallAnalytics {
|
|||||||
|
|
||||||
/// Traces api implementation.
|
/// Traces api implementation.
|
||||||
pub struct TracesClient<C, M> {
|
pub struct TracesClient<C, M> {
|
||||||
client: Weak<C>,
|
client: Arc<C>,
|
||||||
miner: Weak<M>,
|
miner: Arc<M>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, M> TracesClient<C, M> {
|
impl<C, M> TracesClient<C, M> {
|
||||||
/// Creates new Traces client.
|
/// Creates new Traces client.
|
||||||
pub fn new(client: &Arc<C>, miner: &Arc<M>) -> Self {
|
pub fn new(client: &Arc<C>, miner: &Arc<M>) -> Self {
|
||||||
TracesClient {
|
TracesClient {
|
||||||
client: Arc::downgrade(client),
|
client: client.clone(),
|
||||||
miner: Arc::downgrade(miner),
|
miner: miner.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, M> Traces for TracesClient<C, M> where C: MiningBlockChainClient + 'static, M: MinerService + 'static {
|
impl<C, M> Traces for TracesClient<C, M> where C: MiningBlockChainClient + 'static, M: MinerService + 'static {
|
||||||
fn filter(&self, filter: TraceFilter) -> Result<Option<Vec<LocalizedTrace>>, Error> {
|
fn filter(&self, filter: TraceFilter) -> Result<Option<Vec<LocalizedTrace>>, Error> {
|
||||||
Ok(take_weak!(self.client).filter_traces(filter.into())
|
Ok(self.client.filter_traces(filter.into())
|
||||||
.map(|traces| traces.into_iter().map(LocalizedTrace::from).collect()))
|
.map(|traces| traces.into_iter().map(LocalizedTrace::from).collect()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn block_traces(&self, block_number: BlockNumber) -> Result<Option<Vec<LocalizedTrace>>, Error> {
|
fn block_traces(&self, block_number: BlockNumber) -> Result<Option<Vec<LocalizedTrace>>, Error> {
|
||||||
Ok(take_weak!(self.client).block_traces(block_number.into())
|
Ok(self.client.block_traces(block_number.into())
|
||||||
.map(|traces| traces.into_iter().map(LocalizedTrace::from).collect()))
|
.map(|traces| traces.into_iter().map(LocalizedTrace::from).collect()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transaction_traces(&self, transaction_hash: H256) -> Result<Option<Vec<LocalizedTrace>>, Error> {
|
fn transaction_traces(&self, transaction_hash: H256) -> Result<Option<Vec<LocalizedTrace>>, Error> {
|
||||||
Ok(take_weak!(self.client).transaction_traces(TransactionId::Hash(transaction_hash.into()))
|
Ok(self.client.transaction_traces(TransactionId::Hash(transaction_hash.into()))
|
||||||
.map(|traces| traces.into_iter().map(LocalizedTrace::from).collect()))
|
.map(|traces| traces.into_iter().map(LocalizedTrace::from).collect()))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ impl<C, M> Traces for TracesClient<C, M> where C: MiningBlockChainClient + 'stat
|
|||||||
address: address.into_iter().map(|i| i.value()).collect()
|
address: address.into_iter().map(|i| i.value()).collect()
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(take_weak!(self.client).trace(id)
|
Ok(self.client.trace(id)
|
||||||
.map(LocalizedTrace::from))
|
.map(LocalizedTrace::from))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ impl<C, M> Traces for TracesClient<C, M> where C: MiningBlockChainClient + 'stat
|
|||||||
let request = CallRequest::into(request);
|
let request = CallRequest::into(request);
|
||||||
let signed = fake_sign::sign_call(&self.client, &self.miner, request)?;
|
let signed = fake_sign::sign_call(&self.client, &self.miner, request)?;
|
||||||
|
|
||||||
take_weak!(self.client).call(&signed, block.into(), to_call_analytics(flags))
|
self.client.call(&signed, block.into(), to_call_analytics(flags))
|
||||||
.map(TraceResults::from)
|
.map(TraceResults::from)
|
||||||
.map_err(errors::from_call_error)
|
.map_err(errors::from_call_error)
|
||||||
}
|
}
|
||||||
@ -96,13 +96,13 @@ impl<C, M> Traces for TracesClient<C, M> where C: MiningBlockChainClient + 'stat
|
|||||||
let tx = UntrustedRlp::new(&raw_transaction.into_vec()).as_val().map_err(|e| errors::invalid_params("Transaction is not valid RLP", e))?;
|
let tx = UntrustedRlp::new(&raw_transaction.into_vec()).as_val().map_err(|e| errors::invalid_params("Transaction is not valid RLP", e))?;
|
||||||
let signed = SignedTransaction::new(tx).map_err(errors::from_transaction_error)?;
|
let signed = SignedTransaction::new(tx).map_err(errors::from_transaction_error)?;
|
||||||
|
|
||||||
take_weak!(self.client).call(&signed, block.into(), to_call_analytics(flags))
|
self.client.call(&signed, block.into(), to_call_analytics(flags))
|
||||||
.map(TraceResults::from)
|
.map(TraceResults::from)
|
||||||
.map_err(errors::from_call_error)
|
.map_err(errors::from_call_error)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn replay_transaction(&self, transaction_hash: H256, flags: Vec<String>) -> Result<TraceResults, Error> {
|
fn replay_transaction(&self, transaction_hash: H256, flags: Vec<String>) -> Result<TraceResults, Error> {
|
||||||
take_weak!(self.client).replay(TransactionId::Hash(transaction_hash.into()), to_call_analytics(flags))
|
self.client.replay(TransactionId::Hash(transaction_hash.into()), to_call_analytics(flags))
|
||||||
.map(TraceResults::from)
|
.map(TraceResults::from)
|
||||||
.map_err(errors::from_call_error)
|
.map_err(errors::from_call_error)
|
||||||
}
|
}
|
||||||
|
@ -18,26 +18,6 @@
|
|||||||
//!
|
//!
|
||||||
//! Compliant with ethereum rpc.
|
//! Compliant with ethereum rpc.
|
||||||
|
|
||||||
// Upgrade a weak pointer, returning an error on failure.
|
|
||||||
macro_rules! take_weak {
|
|
||||||
($weak: expr) => {
|
|
||||||
match $weak.upgrade() {
|
|
||||||
Some(arc) => arc,
|
|
||||||
None => return Err(Error::internal_error()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Upgrade a weak pointer, returning an error leaf-future on failure.
|
|
||||||
macro_rules! take_weakf {
|
|
||||||
($weak: expr) => {
|
|
||||||
match $weak.upgrade() {
|
|
||||||
Some(arc) => arc,
|
|
||||||
None => return ::futures::future::err(Error::internal_error()).boxed(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// short for "try_boxfuture"
|
// short for "try_boxfuture"
|
||||||
// unwrap a result, returning a BoxFuture<_, Err> on failure.
|
// unwrap a result, returning a BoxFuture<_, Err> on failure.
|
||||||
macro_rules! try_bf {
|
macro_rules! try_bf {
|
||||||
|
@ -141,7 +141,7 @@ impl EthTester {
|
|||||||
Default::default(),
|
Default::default(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let dispatcher = FullDispatcher::new(Arc::downgrade(&client), Arc::downgrade(&miner_service));
|
let dispatcher = FullDispatcher::new(client.clone(), miner_service.clone());
|
||||||
let eth_sign = SigningUnsafeClient::new(
|
let eth_sign = SigningUnsafeClient::new(
|
||||||
&opt_account_provider,
|
&opt_account_provider,
|
||||||
dispatcher,
|
dispatcher,
|
||||||
|
@ -92,7 +92,7 @@ impl EthTester {
|
|||||||
let eth = EthClient::new(&client, &snapshot, &sync, &opt_ap, &miner, &external_miner, options).to_delegate();
|
let eth = EthClient::new(&client, &snapshot, &sync, &opt_ap, &miner, &external_miner, options).to_delegate();
|
||||||
let filter = EthFilterClient::new(client.clone(), miner.clone()).to_delegate();
|
let filter = EthFilterClient::new(client.clone(), miner.clone()).to_delegate();
|
||||||
|
|
||||||
let dispatcher = FullDispatcher::new(Arc::downgrade(&client), Arc::downgrade(&miner));
|
let dispatcher = FullDispatcher::new(client.clone(), miner.clone());
|
||||||
let sign = SigningUnsafeClient::new(&opt_ap, dispatcher).to_delegate();
|
let sign = SigningUnsafeClient::new(&opt_ap, dispatcher).to_delegate();
|
||||||
let mut io: IoHandler<Metadata> = IoHandler::default();
|
let mut io: IoHandler<Metadata> = IoHandler::default();
|
||||||
io.extend_with(eth);
|
io.extend_with(eth);
|
||||||
|
@ -31,9 +31,6 @@ struct PersonalTester {
|
|||||||
accounts: Arc<AccountProvider>,
|
accounts: Arc<AccountProvider>,
|
||||||
io: IoHandler<Metadata>,
|
io: IoHandler<Metadata>,
|
||||||
miner: Arc<TestMinerService>,
|
miner: Arc<TestMinerService>,
|
||||||
// these unused fields are necessary to keep the data alive
|
|
||||||
// as the handler has only weak pointers.
|
|
||||||
_client: Arc<TestBlockChainClient>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn blockchain_client() -> Arc<TestBlockChainClient> {
|
fn blockchain_client() -> Arc<TestBlockChainClient> {
|
||||||
@ -55,7 +52,7 @@ fn setup() -> PersonalTester {
|
|||||||
let client = blockchain_client();
|
let client = blockchain_client();
|
||||||
let miner = miner_service();
|
let miner = miner_service();
|
||||||
|
|
||||||
let dispatcher = FullDispatcher::new(Arc::downgrade(&client), Arc::downgrade(&miner));
|
let dispatcher = FullDispatcher::new(client, miner.clone());
|
||||||
let personal = PersonalClient::new(&opt_accounts, dispatcher, false);
|
let personal = PersonalClient::new(&opt_accounts, dispatcher, false);
|
||||||
|
|
||||||
let mut io = IoHandler::default();
|
let mut io = IoHandler::default();
|
||||||
@ -65,7 +62,6 @@ fn setup() -> PersonalTester {
|
|||||||
accounts: accounts,
|
accounts: accounts,
|
||||||
io: io,
|
io: io,
|
||||||
miner: miner,
|
miner: miner,
|
||||||
_client: client,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
tester
|
tester
|
||||||
@ -220,4 +216,3 @@ fn should_unlock_account_permanently() {
|
|||||||
assert_eq!(tester.io.handle_request_sync(&request), Some(response.into()));
|
assert_eq!(tester.io.handle_request_sync(&request), Some(response.into()));
|
||||||
assert!(tester.accounts.sign(address, None, Default::default()).is_ok(), "Should unlock account.");
|
assert!(tester.accounts.sign(address, None, Default::default()).is_ok(), "Should unlock account.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,10 +38,6 @@ struct SignerTester {
|
|||||||
accounts: Arc<AccountProvider>,
|
accounts: Arc<AccountProvider>,
|
||||||
io: IoHandler<Metadata>,
|
io: IoHandler<Metadata>,
|
||||||
miner: Arc<TestMinerService>,
|
miner: Arc<TestMinerService>,
|
||||||
// these unused fields are necessary to keep the data alive
|
|
||||||
// as the handler has only weak pointers.
|
|
||||||
_client: Arc<TestBlockChainClient>,
|
|
||||||
_event_loop: EventLoop,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn blockchain_client() -> Arc<TestBlockChainClient> {
|
fn blockchain_client() -> Arc<TestBlockChainClient> {
|
||||||
@ -65,7 +61,7 @@ fn signer_tester() -> SignerTester {
|
|||||||
let miner = miner_service();
|
let miner = miner_service();
|
||||||
let event_loop = EventLoop::spawn();
|
let event_loop = EventLoop::spawn();
|
||||||
|
|
||||||
let dispatcher = FullDispatcher::new(Arc::downgrade(&client), Arc::downgrade(&miner));
|
let dispatcher = FullDispatcher::new(client, miner.clone());
|
||||||
let mut io = IoHandler::default();
|
let mut io = IoHandler::default();
|
||||||
io.extend_with(SignerClient::new(&opt_accounts, dispatcher, &signer, event_loop.remote()).to_delegate());
|
io.extend_with(SignerClient::new(&opt_accounts, dispatcher, &signer, event_loop.remote()).to_delegate());
|
||||||
|
|
||||||
@ -74,8 +70,6 @@ fn signer_tester() -> SignerTester {
|
|||||||
accounts: accounts,
|
accounts: accounts,
|
||||||
io: io,
|
io: io,
|
||||||
miner: miner,
|
miner: miner,
|
||||||
_client: client,
|
|
||||||
_event_loop: event_loop,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ impl Default for SigningTester {
|
|||||||
let opt_accounts = Some(accounts.clone());
|
let opt_accounts = Some(accounts.clone());
|
||||||
let mut io = IoHandler::default();
|
let mut io = IoHandler::default();
|
||||||
|
|
||||||
let dispatcher = FullDispatcher::new(Arc::downgrade(&client), Arc::downgrade(&miner));
|
let dispatcher = FullDispatcher::new(client.clone(), miner.clone());
|
||||||
|
|
||||||
let rpc = SigningQueueClient::new(&signer, dispatcher.clone(), &opt_accounts);
|
let rpc = SigningQueueClient::new(&signer, dispatcher.clone(), &opt_accounts);
|
||||||
io.extend_with(EthSigning::to_delegate(rpc));
|
io.extend_with(EthSigning::to_delegate(rpc));
|
||||||
|
@ -27,6 +27,8 @@ echo "Vcs-Browser: https://github.com/paritytech/parity" >> $control
|
|||||||
echo "Architecture: $1" >> $control
|
echo "Architecture: $1" >> $control
|
||||||
echo "Depends: libssl1.0.0 (>=1.0.0)" >> $control
|
echo "Depends: libssl1.0.0 (>=1.0.0)" >> $control
|
||||||
echo "Description: Ethereum network client by Parity Technologies" >> $control
|
echo "Description: Ethereum network client by Parity Technologies" >> $control
|
||||||
|
size=`du deb/|awk 'END {print $1}'`
|
||||||
|
echo "Installed-Size: $size" >> $control
|
||||||
#build .deb package
|
#build .deb package
|
||||||
|
|
||||||
exit
|
exit
|
||||||
|
@ -28,7 +28,7 @@ use std::collections::hash_map::Entry;
|
|||||||
/// Reference-counted memory-based `HashDB` implementation.
|
/// Reference-counted memory-based `HashDB` implementation.
|
||||||
///
|
///
|
||||||
/// Use `new()` to create a new database. Insert items with `insert()`, remove items
|
/// Use `new()` to create a new database. Insert items with `insert()`, remove items
|
||||||
/// with `remove()`, check for existence with `containce()` and lookup a hash to derive
|
/// with `remove()`, check for existence with `contains()` and lookup a hash to derive
|
||||||
/// the data with `get()`. Clear with `clear()` and purge the portions of the data
|
/// the data with `get()`. Clear with `clear()` and purge the portions of the data
|
||||||
/// that have no references with `purge()`.
|
/// that have no references with `purge()`.
|
||||||
///
|
///
|
||||||
|
Loading…
Reference in New Issue
Block a user