Fix several RPCs (#1926)
* Fix up pending receipts details. * Add support for additional params and registry over RPC. * Fix tests. * Add test, additional fix. Fixes #1932. * Fix up tests. * Fix test. * Fix test.
This commit is contained in:
parent
bcf6b0b7d8
commit
ccdf80f4dc
@ -8,7 +8,7 @@
|
|||||||
"difficultyBoundDivisor": "0x0800",
|
"difficultyBoundDivisor": "0x0800",
|
||||||
"durationLimit": "0x0d",
|
"durationLimit": "0x0d",
|
||||||
"blockReward": "0x4563918244F40000",
|
"blockReward": "0x4563918244F40000",
|
||||||
"registrar": "",
|
"registrar": "0x8e4e9b13d4b45cb0befc93c3061b1408f67316b2",
|
||||||
"frontierCompatibilityModeLimit": "0x789b0"
|
"frontierCompatibilityModeLimit": "0x789b0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,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::collections::{HashSet, HashMap, VecDeque};
|
use std::collections::{HashSet, HashMap, BTreeMap, VecDeque};
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
use std::path::{Path};
|
use std::path::{Path};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@ -49,8 +49,11 @@ use types::filter::Filter;
|
|||||||
use log_entry::LocalizedLogEntry;
|
use log_entry::LocalizedLogEntry;
|
||||||
use block_queue::{BlockQueue, BlockQueueInfo};
|
use block_queue::{BlockQueue, BlockQueueInfo};
|
||||||
use blockchain::{BlockChain, BlockProvider, TreeRoute, ImportRoute};
|
use blockchain::{BlockChain, BlockProvider, TreeRoute, ImportRoute};
|
||||||
use client::{BlockID, TransactionID, UncleID, TraceId, ClientConfig, BlockChainClient, MiningBlockChainClient,
|
use client::{
|
||||||
TraceFilter, CallAnalytics, BlockImportError, Mode, ChainNotify};
|
BlockID, TransactionID, UncleID, TraceId, ClientConfig, BlockChainClient,
|
||||||
|
MiningBlockChainClient, TraceFilter, CallAnalytics, BlockImportError, Mode,
|
||||||
|
ChainNotify
|
||||||
|
};
|
||||||
use client::Error as ClientError;
|
use client::Error as ClientError;
|
||||||
use env_info::EnvInfo;
|
use env_info::EnvInfo;
|
||||||
use executive::{Executive, Executed, TransactOptions, contract_address};
|
use executive::{Executive, Executed, TransactOptions, contract_address};
|
||||||
@ -916,6 +919,10 @@ impl BlockChainClient for Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn additional_params(&self) -> BTreeMap<String, String> {
|
||||||
|
self.engine.additional_params().into_iter().collect()
|
||||||
|
}
|
||||||
|
|
||||||
fn blocks_with_bloom(&self, bloom: &H2048, from_block: BlockID, to_block: BlockID) -> Option<Vec<BlockNumber>> {
|
fn blocks_with_bloom(&self, bloom: &H2048, from_block: BlockID, to_block: BlockID) -> Option<Vec<BlockNumber>> {
|
||||||
match (self.block_number(from_block), self.block_number(to_block)) {
|
match (self.block_number(from_block), self.block_number(to_block)) {
|
||||||
(Some(from), Some(to)) => Some(self.chain.blocks_with_bloom(bloom, from, to)),
|
(Some(from), Some(to)) => Some(self.chain.blocks_with_bloom(bloom, from, to)),
|
||||||
|
@ -21,9 +21,10 @@ use util::*;
|
|||||||
use devtools::*;
|
use devtools::*;
|
||||||
use transaction::{Transaction, LocalizedTransaction, SignedTransaction, Action};
|
use transaction::{Transaction, LocalizedTransaction, SignedTransaction, Action};
|
||||||
use blockchain::TreeRoute;
|
use blockchain::TreeRoute;
|
||||||
use client::{BlockChainClient, MiningBlockChainClient, BlockChainInfo, BlockStatus, BlockID,
|
use client::{
|
||||||
TransactionID, UncleID, TraceId, TraceFilter, LastHashes, CallAnalytics,
|
BlockChainClient, MiningBlockChainClient, BlockChainInfo, BlockStatus, BlockID,
|
||||||
BlockImportError};
|
TransactionID, UncleID, TraceId, TraceFilter, LastHashes, CallAnalytics, BlockImportError
|
||||||
|
};
|
||||||
use header::{Header as BlockHeader, BlockNumber};
|
use header::{Header as BlockHeader, BlockNumber};
|
||||||
use filter::Filter;
|
use filter::Filter;
|
||||||
use log_entry::LocalizedLogEntry;
|
use log_entry::LocalizedLogEntry;
|
||||||
@ -517,6 +518,10 @@ impl BlockChainClient for TestBlockChainClient {
|
|||||||
fn clear_queue(&self) {
|
fn clear_queue(&self) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn additional_params(&self) -> BTreeMap<String, String> {
|
||||||
|
Default::default()
|
||||||
|
}
|
||||||
|
|
||||||
fn chain_info(&self) -> BlockChainInfo {
|
fn chain_info(&self) -> BlockChainInfo {
|
||||||
BlockChainInfo {
|
BlockChainInfo {
|
||||||
total_difficulty: *self.difficulty.read(),
|
total_difficulty: *self.difficulty.read(),
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
// 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::mem;
|
||||||
|
use std::collections::{BTreeMap, VecDeque};
|
||||||
use util::{U256, Address, H256, H2048, Bytes, Itertools};
|
use util::{U256, Address, H256, H2048, Bytes, Itertools};
|
||||||
use blockchain::TreeRoute;
|
use blockchain::TreeRoute;
|
||||||
use block_queue::BlockQueueInfo;
|
use block_queue::BlockQueueInfo;
|
||||||
@ -145,6 +147,9 @@ pub trait BlockChainClient : Sync + Send {
|
|||||||
/// Get blockchain information.
|
/// Get blockchain information.
|
||||||
fn chain_info(&self) -> BlockChainInfo;
|
fn chain_info(&self) -> BlockChainInfo;
|
||||||
|
|
||||||
|
/// Get the registrar address, if it exists.
|
||||||
|
fn additional_params(&self) -> BTreeMap<String, String>;
|
||||||
|
|
||||||
/// Get the best block header.
|
/// Get the best block header.
|
||||||
fn best_block_header(&self) -> Bytes;
|
fn best_block_header(&self) -> Bytes;
|
||||||
|
|
||||||
|
@ -44,6 +44,9 @@ pub trait Engine : Sync + Send {
|
|||||||
/// Additional engine-specific information for the user/developer concerning `header`.
|
/// Additional engine-specific information for the user/developer concerning `header`.
|
||||||
fn extra_info(&self, _header: &Header) -> HashMap<String, String> { HashMap::new() }
|
fn extra_info(&self, _header: &Header) -> HashMap<String, String> { HashMap::new() }
|
||||||
|
|
||||||
|
/// Additional information.
|
||||||
|
fn additional_params(&self) -> HashMap<String, String> { HashMap::new() }
|
||||||
|
|
||||||
/// Get the general parameters of the chain.
|
/// Get the general parameters of the chain.
|
||||||
fn params(&self) -> &CommonParams;
|
fn params(&self) -> &CommonParams;
|
||||||
|
|
||||||
|
@ -92,6 +92,7 @@ impl Engine for Ethash {
|
|||||||
fn seal_fields(&self) -> usize { 2 }
|
fn seal_fields(&self) -> usize { 2 }
|
||||||
|
|
||||||
fn params(&self) -> &CommonParams { &self.params }
|
fn params(&self) -> &CommonParams { &self.params }
|
||||||
|
fn additional_params(&self) -> HashMap<String, String> { hash_map!["registrar".to_owned() => self.ethash_params.registrar.hex()] }
|
||||||
|
|
||||||
fn builtins(&self) -> &BTreeMap<Address, Builtin> {
|
fn builtins(&self) -> &BTreeMap<Address, Builtin> {
|
||||||
&self.builtins
|
&self.builtins
|
||||||
|
@ -23,10 +23,11 @@ use account_provider::AccountProvider;
|
|||||||
use views::{BlockView, HeaderView};
|
use views::{BlockView, HeaderView};
|
||||||
use state::State;
|
use state::State;
|
||||||
use client::{MiningBlockChainClient, Executive, Executed, EnvInfo, TransactOptions, BlockID, CallAnalytics};
|
use client::{MiningBlockChainClient, Executive, Executed, EnvInfo, TransactOptions, BlockID, CallAnalytics};
|
||||||
|
use executive::contract_address;
|
||||||
use block::{ClosedBlock, IsBlock, Block};
|
use block::{ClosedBlock, IsBlock, Block};
|
||||||
use error::*;
|
use error::*;
|
||||||
use transaction::SignedTransaction;
|
use transaction::{Action, SignedTransaction};
|
||||||
use receipt::Receipt;
|
use receipt::{Receipt, RichReceipt};
|
||||||
use spec::Spec;
|
use spec::Spec;
|
||||||
use engines::Engine;
|
use engines::Engine;
|
||||||
use miner::{MinerService, MinerStatus, TransactionQueue, AccountDetails, TransactionOrigin};
|
use miner::{MinerService, MinerStatus, TransactionQueue, AccountDetails, TransactionOrigin};
|
||||||
@ -712,6 +713,35 @@ impl MinerService for Miner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn pending_receipt(&self, hash: &H256) -> Option<RichReceipt> {
|
||||||
|
let sealing_work = self.sealing_work.lock();
|
||||||
|
match (sealing_work.enabled, sealing_work.queue.peek_last_ref()) {
|
||||||
|
(true, Some(pending)) => {
|
||||||
|
let txs = pending.transactions();
|
||||||
|
txs.iter()
|
||||||
|
.map(|t| t.hash())
|
||||||
|
.position(|t| t == *hash)
|
||||||
|
.map(|index| {
|
||||||
|
let prev_gas = if index == 0 { Default::default() } else { pending.receipts()[index - 1].gas_used };
|
||||||
|
let ref tx = txs[index];
|
||||||
|
let ref receipt = pending.receipts()[index];
|
||||||
|
RichReceipt {
|
||||||
|
transaction_hash: hash.clone(),
|
||||||
|
transaction_index: index,
|
||||||
|
cumulative_gas_used: receipt.gas_used,
|
||||||
|
gas_used: receipt.gas_used - prev_gas,
|
||||||
|
contract_address: match tx.action {
|
||||||
|
Action::Call(_) => None,
|
||||||
|
Action::Create => Some(contract_address(&tx.sender().unwrap(), &tx.nonce)),
|
||||||
|
},
|
||||||
|
logs: receipt.logs.clone(),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn pending_receipts(&self) -> BTreeMap<H256, Receipt> {
|
fn pending_receipts(&self) -> BTreeMap<H256, Receipt> {
|
||||||
let sealing_work = self.sealing_work.lock();
|
let sealing_work = self.sealing_work.lock();
|
||||||
match (sealing_work.enabled, sealing_work.queue.peek_last_ref()) {
|
match (sealing_work.enabled, sealing_work.queue.peek_last_ref()) {
|
||||||
|
@ -56,7 +56,7 @@ use std::collections::BTreeMap;
|
|||||||
use util::{H256, U256, Address, Bytes};
|
use util::{H256, U256, Address, Bytes};
|
||||||
use client::{MiningBlockChainClient, Executed, CallAnalytics};
|
use client::{MiningBlockChainClient, Executed, CallAnalytics};
|
||||||
use block::ClosedBlock;
|
use block::ClosedBlock;
|
||||||
use receipt::Receipt;
|
use receipt::{RichReceipt, Receipt};
|
||||||
use error::{Error, CallError};
|
use error::{Error, CallError};
|
||||||
use transaction::SignedTransaction;
|
use transaction::SignedTransaction;
|
||||||
|
|
||||||
@ -146,6 +146,9 @@ pub trait MinerService : Send + Sync {
|
|||||||
/// Get a list of all pending receipts.
|
/// Get a list of all pending receipts.
|
||||||
fn pending_receipts(&self) -> BTreeMap<H256, Receipt>;
|
fn pending_receipts(&self) -> BTreeMap<H256, Receipt>;
|
||||||
|
|
||||||
|
/// Get a particular reciept.
|
||||||
|
fn pending_receipt(&self, hash: &H256) -> Option<RichReceipt>;
|
||||||
|
|
||||||
/// Returns highest transaction nonce for given address.
|
/// Returns highest transaction nonce for given address.
|
||||||
fn last_nonce(&self, address: &Address) -> Option<U256>;
|
fn last_nonce(&self, address: &Address) -> Option<U256>;
|
||||||
|
|
||||||
|
@ -241,7 +241,7 @@ impl State {
|
|||||||
// trace!("Applied transaction. Diff:\n{}\n", state_diff::diff_pod(&old, &self.to_pod()));
|
// trace!("Applied transaction. Diff:\n{}\n", state_diff::diff_pod(&old, &self.to_pod()));
|
||||||
try!(self.commit());
|
try!(self.commit());
|
||||||
let receipt = Receipt::new(self.root().clone(), e.cumulative_gas_used, e.logs);
|
let receipt = Receipt::new(self.root().clone(), e.cumulative_gas_used, e.logs);
|
||||||
// trace!("Transaction receipt: {:?}", receipt);
|
trace!(target: "state", "Transaction receipt: {:?}", receipt);
|
||||||
Ok(ApplyOutcome{receipt: receipt, trace: e.trace})
|
Ok(ApplyOutcome{receipt: receipt, trace: e.trace})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
use io::IoChannel;
|
use io::IoChannel;
|
||||||
use client::{BlockChainClient, MiningBlockChainClient, Client, ClientConfig, BlockID};
|
use client::{BlockChainClient, MiningBlockChainClient, Client, ClientConfig, BlockID};
|
||||||
|
use ethereum;
|
||||||
use block::IsBlock;
|
use block::IsBlock;
|
||||||
use tests::helpers::*;
|
use tests::helpers::*;
|
||||||
use common::*;
|
use common::*;
|
||||||
@ -31,6 +32,14 @@ fn imports_from_empty() {
|
|||||||
client.flush_queue();
|
client.flush_queue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_return_registrar() {
|
||||||
|
let dir = RandomTempPath::new();
|
||||||
|
let spec = ethereum::new_morden();
|
||||||
|
let client = Client::new(ClientConfig::default(), &spec, dir.as_path(), Arc::new(Miner::with_spec(&spec)), IoChannel::disconnected()).unwrap();
|
||||||
|
assert_eq!(client.additional_params().get("registrar"), Some(&"8e4e9b13d4b45cb0befc93c3061b1408f67316b2".to_owned()));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn returns_state_root_basic() {
|
fn returns_state_root_basic() {
|
||||||
let client_result = generate_dummy_client(6);
|
let client_result = generate_dummy_client(6);
|
||||||
|
@ -77,6 +77,23 @@ impl HeapSizeOf for Receipt {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Receipt with additional info.
|
||||||
|
#[derive(Debug, Clone, PartialEq, Binary)]
|
||||||
|
pub struct RichReceipt {
|
||||||
|
/// Transaction hash.
|
||||||
|
pub transaction_hash: H256,
|
||||||
|
/// Transaction index.
|
||||||
|
pub transaction_index: usize,
|
||||||
|
/// The total gas used in the block following execution of the transaction.
|
||||||
|
pub cumulative_gas_used: U256,
|
||||||
|
/// The gas used in the execution of the transaction. Note the difference of meaning to `Receipt::gas_used`.
|
||||||
|
pub gas_used: U256,
|
||||||
|
/// Contract address.
|
||||||
|
pub contract_address: Option<Address>,
|
||||||
|
/// Logs
|
||||||
|
pub logs: Vec<LogEntry>,
|
||||||
|
}
|
||||||
|
|
||||||
/// Receipt with additional info.
|
/// Receipt with additional info.
|
||||||
#[derive(Debug, Clone, PartialEq, Binary)]
|
#[derive(Debug, Clone, PartialEq, Binary)]
|
||||||
pub struct LocalizedReceipt {
|
pub struct LocalizedReceipt {
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
use ipc::*;
|
|
||||||
use util::Bytes;
|
use util::Bytes;
|
||||||
|
|
||||||
#[derive(Binary)]
|
#[derive(Binary)]
|
||||||
|
@ -107,7 +107,7 @@ impl<C, S: ?Sized, M, EM> EthClient<C, S, M, EM> where
|
|||||||
let view = block_view.header_view();
|
let view = block_view.header_view();
|
||||||
let block = Block {
|
let block = Block {
|
||||||
hash: Some(view.sha3().into()),
|
hash: Some(view.sha3().into()),
|
||||||
size: Some(bytes.len()),
|
size: Some(bytes.len().into()),
|
||||||
parent_hash: view.parent_hash().into(),
|
parent_hash: view.parent_hash().into(),
|
||||||
uncles_hash: view.uncles_hash().into(),
|
uncles_hash: view.uncles_hash().into(),
|
||||||
author: view.author().into(),
|
author: view.author().into(),
|
||||||
@ -460,8 +460,8 @@ impl<C, S: ?Sized, M, EM> Eth for EthClient<C, S, M, EM> where
|
|||||||
.and_then(|(hash,)| {
|
.and_then(|(hash,)| {
|
||||||
let miner = take_weak!(self.miner);
|
let miner = take_weak!(self.miner);
|
||||||
let hash: H256 = hash.into();
|
let hash: H256 = hash.into();
|
||||||
match miner.pending_receipts().get(&hash) {
|
match (miner.pending_receipt(&hash), self.options.allow_pending_receipt_query) {
|
||||||
Some(receipt) if self.options.allow_pending_receipt_query => to_value(&Receipt::from(receipt.clone())),
|
(Some(receipt), true) => to_value(&Receipt::from(receipt)),
|
||||||
_ => {
|
_ => {
|
||||||
let client = take_weak!(self.client);
|
let client = take_weak!(self.client);
|
||||||
let receipt = client.transaction_receipt(TransactionID::Hash(hash));
|
let receipt = client.transaction_receipt(TransactionID::Hash(hash));
|
||||||
|
@ -15,10 +15,11 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
//! Ethcore-specific rpc implementation.
|
//! Ethcore-specific rpc implementation.
|
||||||
use util::{RotatingLogger, KeyPair};
|
|
||||||
use util::misc::version_data;
|
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
|
use std::str::FromStr;
|
||||||
use std::collections::{BTreeMap};
|
use std::collections::{BTreeMap};
|
||||||
|
use util::{RotatingLogger, KeyPair, Address};
|
||||||
|
use util::misc::version_data;
|
||||||
|
|
||||||
use ethstore::random_phrase;
|
use ethstore::random_phrase;
|
||||||
use ethsync::{SyncProvider, ManageNetwork};
|
use ethsync::{SyncProvider, ManageNetwork};
|
||||||
@ -56,7 +57,7 @@ impl<C, M, S: ?Sized> EthcoreClient<C, M, S> where C: MiningBlockChainClient, M:
|
|||||||
logger: Arc<RotatingLogger>,
|
logger: Arc<RotatingLogger>,
|
||||||
settings: Arc<NetworkSettings>,
|
settings: Arc<NetworkSettings>,
|
||||||
queue: Option<Arc<ConfirmationsQueue>>
|
queue: Option<Arc<ConfirmationsQueue>>
|
||||||
) -> Self {
|
) -> Self {
|
||||||
EthcoreClient {
|
EthcoreClient {
|
||||||
client: Arc::downgrade(client),
|
client: Arc::downgrade(client),
|
||||||
miner: Arc::downgrade(miner),
|
miner: Arc::downgrade(miner),
|
||||||
@ -152,6 +153,17 @@ impl<C, M, S: ?Sized> Ethcore for EthcoreClient<C, M, S> where M: MinerService +
|
|||||||
to_value(&self.settings.name)
|
to_value(&self.settings.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn registry_address(&self, params: Params) -> Result<Value, Error> {
|
||||||
|
try!(self.active());
|
||||||
|
try!(expect_no_params(params));
|
||||||
|
let r = take_weak!(self.client)
|
||||||
|
.additional_params()
|
||||||
|
.get("registrar")
|
||||||
|
.and_then(|s| Address::from_str(s).ok())
|
||||||
|
.map(|s| H160::from(s));
|
||||||
|
to_value(&r)
|
||||||
|
}
|
||||||
|
|
||||||
fn rpc_settings(&self, params: Params) -> Result<Value, Error> {
|
fn rpc_settings(&self, params: Params) -> Result<Value, Error> {
|
||||||
try!(self.active());
|
try!(self.active());
|
||||||
try!(expect_no_params(params));
|
try!(expect_no_params(params));
|
||||||
|
@ -22,7 +22,7 @@ use ethcore::error::{Error, CallError};
|
|||||||
use ethcore::client::{MiningBlockChainClient, Executed, CallAnalytics};
|
use ethcore::client::{MiningBlockChainClient, Executed, CallAnalytics};
|
||||||
use ethcore::block::{ClosedBlock, IsBlock};
|
use ethcore::block::{ClosedBlock, IsBlock};
|
||||||
use ethcore::transaction::SignedTransaction;
|
use ethcore::transaction::SignedTransaction;
|
||||||
use ethcore::receipt::Receipt;
|
use ethcore::receipt::{Receipt, RichReceipt};
|
||||||
use ethcore::miner::{MinerService, MinerStatus, TransactionImportResult};
|
use ethcore::miner::{MinerService, MinerStatus, TransactionImportResult};
|
||||||
|
|
||||||
/// Test miner service.
|
/// Test miner service.
|
||||||
@ -198,6 +198,20 @@ impl MinerService for TestMinerService {
|
|||||||
self.pending_transactions.lock().values().cloned().collect()
|
self.pending_transactions.lock().values().cloned().collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn pending_receipt(&self, hash: &H256) -> Option<RichReceipt> {
|
||||||
|
// Not much point implementing this since the logic is complex and the only thing it relies on is pending_receipts, which is already tested.
|
||||||
|
self.pending_receipts().get(hash).map(|r|
|
||||||
|
RichReceipt {
|
||||||
|
transaction_hash: Default::default(),
|
||||||
|
transaction_index: Default::default(),
|
||||||
|
cumulative_gas_used: r.gas_used.clone(),
|
||||||
|
gas_used: r.gas_used.clone(),
|
||||||
|
contract_address: None,
|
||||||
|
logs: r.logs.clone(),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn pending_receipts(&self) -> BTreeMap<H256, Receipt> {
|
fn pending_receipts(&self) -> BTreeMap<H256, Receipt> {
|
||||||
self.pending_receipts.lock().clone()
|
self.pending_receipts.lock().clone()
|
||||||
}
|
}
|
||||||
|
@ -73,6 +73,9 @@ pub trait Ethcore: Sized + Send + Sync + 'static {
|
|||||||
/// Returns whatever address would be derived from the given phrase if it were to seed a brainwallet.
|
/// Returns whatever address would be derived from the given phrase if it were to seed a brainwallet.
|
||||||
fn phrase_to_address(&self, _: Params) -> Result<Value, Error>;
|
fn phrase_to_address(&self, _: Params) -> Result<Value, Error>;
|
||||||
|
|
||||||
|
/// Returns the value of the registrar for this network.
|
||||||
|
fn registry_address(&self, _: Params) -> Result<Value, Error>;
|
||||||
|
|
||||||
/// Should be used to convert object to io delegate.
|
/// Should be used to convert object to io delegate.
|
||||||
fn to_delegate(self) -> IoDelegate<Self> {
|
fn to_delegate(self) -> IoDelegate<Self> {
|
||||||
let mut delegate = IoDelegate::new(Arc::new(self));
|
let mut delegate = IoDelegate::new(Arc::new(self));
|
||||||
@ -94,6 +97,7 @@ pub trait Ethcore: Sized + Send + Sync + 'static {
|
|||||||
delegate.add_method("ethcore_unsignedTransactionsCount", Ethcore::unsigned_transactions_count);
|
delegate.add_method("ethcore_unsignedTransactionsCount", Ethcore::unsigned_transactions_count);
|
||||||
delegate.add_method("ethcore_generateSecretPhrase", Ethcore::generate_secret_phrase);
|
delegate.add_method("ethcore_generateSecretPhrase", Ethcore::generate_secret_phrase);
|
||||||
delegate.add_method("ethcore_phraseToAddress", Ethcore::phrase_to_address);
|
delegate.add_method("ethcore_phraseToAddress", Ethcore::phrase_to_address);
|
||||||
|
delegate.add_method("ethcore_registryAddress", Ethcore::registry_address);
|
||||||
|
|
||||||
delegate
|
delegate
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ pub struct Block {
|
|||||||
/// Transactions
|
/// Transactions
|
||||||
pub transactions: BlockTransactions,
|
pub transactions: BlockTransactions,
|
||||||
/// Size in bytes
|
/// Size in bytes
|
||||||
pub size: Option<usize>,
|
pub size: Option<U256>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -132,10 +132,10 @@ mod tests {
|
|||||||
seal_fields: vec![Bytes::default(), Bytes::default()],
|
seal_fields: vec![Bytes::default(), Bytes::default()],
|
||||||
uncles: vec![],
|
uncles: vec![],
|
||||||
transactions: BlockTransactions::Hashes(vec![].into()),
|
transactions: BlockTransactions::Hashes(vec![].into()),
|
||||||
size: Some(69usize),
|
size: Some(69.into()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let serialized = serde_json::to_string(&block).unwrap();
|
let serialized = serde_json::to_string(&block).unwrap();
|
||||||
assert_eq!(serialized, r#"{"hash":"0x0000000000000000000000000000000000000000000000000000000000000000","parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000","sha3Uncles":"0x0000000000000000000000000000000000000000000000000000000000000000","author":"0x0000000000000000000000000000000000000000","miner":"0x0000000000000000000000000000000000000000","stateRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionsRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","receiptsRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","number":"0x00","gasUsed":"0x00","gasLimit":"0x00","extraData":"0x","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","timestamp":"0x00","difficulty":"0x00","totalDifficulty":"0x00","sealFields":["0x","0x"],"uncles":[],"transactions":[],"size":69}"#);
|
assert_eq!(serialized, r#"{"hash":"0x0000000000000000000000000000000000000000000000000000000000000000","parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000","sha3Uncles":"0x0000000000000000000000000000000000000000000000000000000000000000","author":"0x0000000000000000000000000000000000000000","miner":"0x0000000000000000000000000000000000000000","stateRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionsRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","receiptsRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","number":"0x00","gasUsed":"0x00","gasLimit":"0x00","extraData":"0x","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","timestamp":"0x00","difficulty":"0x00","totalDifficulty":"0x00","sealFields":["0x","0x"],"uncles":[],"transactions":[],"size":"0x45"}"#);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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/>.
|
||||||
|
|
||||||
use v1::types::{Log, H160, H256, U256};
|
use v1::types::{Log, H160, H256, U256};
|
||||||
use ethcore::receipt::{Receipt as EthReceipt, LocalizedReceipt};
|
use ethcore::receipt::{Receipt as EthReceipt, RichReceipt, LocalizedReceipt};
|
||||||
|
|
||||||
/// Receipt
|
/// Receipt
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
@ -37,7 +37,7 @@ pub struct Receipt {
|
|||||||
pub cumulative_gas_used: U256,
|
pub cumulative_gas_used: U256,
|
||||||
/// Gas used
|
/// Gas used
|
||||||
#[serde(rename="gasUsed")]
|
#[serde(rename="gasUsed")]
|
||||||
pub gas_used: U256,
|
pub gas_used: Option<U256>,
|
||||||
/// Contract address
|
/// Contract address
|
||||||
#[serde(rename="contractAddress")]
|
#[serde(rename="contractAddress")]
|
||||||
pub contract_address: Option<H160>,
|
pub contract_address: Option<H160>,
|
||||||
@ -53,7 +53,22 @@ impl From<LocalizedReceipt> for Receipt {
|
|||||||
block_hash: Some(r.block_hash.into()),
|
block_hash: Some(r.block_hash.into()),
|
||||||
block_number: Some(r.block_number.into()),
|
block_number: Some(r.block_number.into()),
|
||||||
cumulative_gas_used: r.cumulative_gas_used.into(),
|
cumulative_gas_used: r.cumulative_gas_used.into(),
|
||||||
gas_used: r.gas_used.into(),
|
gas_used: Some(r.gas_used.into()),
|
||||||
|
contract_address: r.contract_address.map(Into::into),
|
||||||
|
logs: r.logs.into_iter().map(Into::into).collect(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<RichReceipt> for Receipt {
|
||||||
|
fn from(r: RichReceipt) -> Self {
|
||||||
|
Receipt {
|
||||||
|
transaction_hash: Some(r.transaction_hash.into()),
|
||||||
|
transaction_index: Some(r.transaction_index.into()),
|
||||||
|
block_hash: None,
|
||||||
|
block_number: None,
|
||||||
|
cumulative_gas_used: r.cumulative_gas_used.into(),
|
||||||
|
gas_used: Some(r.gas_used.into()),
|
||||||
contract_address: r.contract_address.map(Into::into),
|
contract_address: r.contract_address.map(Into::into),
|
||||||
logs: r.logs.into_iter().map(Into::into).collect(),
|
logs: r.logs.into_iter().map(Into::into).collect(),
|
||||||
}
|
}
|
||||||
@ -68,7 +83,7 @@ impl From<EthReceipt> for Receipt {
|
|||||||
block_hash: None,
|
block_hash: None,
|
||||||
block_number: None,
|
block_number: None,
|
||||||
cumulative_gas_used: r.gas_used.into(),
|
cumulative_gas_used: r.gas_used.into(),
|
||||||
gas_used: r.gas_used.into(),
|
gas_used: None,
|
||||||
contract_address: None,
|
contract_address: None,
|
||||||
logs: r.logs.into_iter().map(Into::into).collect(),
|
logs: r.logs.into_iter().map(Into::into).collect(),
|
||||||
}
|
}
|
||||||
@ -91,7 +106,7 @@ mod tests {
|
|||||||
block_hash: Some(H256::from_str("ed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5").unwrap()),
|
block_hash: Some(H256::from_str("ed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5").unwrap()),
|
||||||
block_number: Some(U256::from(0x4510c)),
|
block_number: Some(U256::from(0x4510c)),
|
||||||
cumulative_gas_used: U256::from(0x20),
|
cumulative_gas_used: U256::from(0x20),
|
||||||
gas_used: U256::from(0x10),
|
gas_used: Some(U256::from(0x10)),
|
||||||
contract_address: None,
|
contract_address: None,
|
||||||
logs: vec![Log {
|
logs: vec![Log {
|
||||||
address: H160::from_str("33990122638b9132ca29c723bdf037f1a891a70c").unwrap(),
|
address: H160::from_str("33990122638b9132ca29c723bdf037f1a891a70c").unwrap(),
|
||||||
|
@ -32,14 +32,14 @@ pub struct MemoryDiff {
|
|||||||
/// Offset into memory the change begins.
|
/// Offset into memory the change begins.
|
||||||
pub off: usize,
|
pub off: usize,
|
||||||
/// The changed data.
|
/// The changed data.
|
||||||
pub data: Vec<u8>,
|
pub data: Bytes,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<et::MemoryDiff> for MemoryDiff {
|
impl From<et::MemoryDiff> for MemoryDiff {
|
||||||
fn from(c: et::MemoryDiff) -> Self {
|
fn from(c: et::MemoryDiff) -> Self {
|
||||||
MemoryDiff {
|
MemoryDiff {
|
||||||
off: c.offset,
|
off: c.offset,
|
||||||
data: c.data,
|
data: c.data.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -117,7 +117,7 @@ impl From<(et::VMOperation, Option<et::VMTrace>)> for VMOperation {
|
|||||||
/// A record of a full VM trace for a CALL/CREATE.
|
/// A record of a full VM trace for a CALL/CREATE.
|
||||||
pub struct VMTrace {
|
pub struct VMTrace {
|
||||||
/// The code to be executed.
|
/// The code to be executed.
|
||||||
pub code: Vec<u8>,
|
pub code: Bytes,
|
||||||
/// The operations executed.
|
/// The operations executed.
|
||||||
pub ops: Vec<VMOperation>,
|
pub ops: Vec<VMOperation>,
|
||||||
}
|
}
|
||||||
@ -127,7 +127,7 @@ impl From<et::VMTrace> for VMTrace {
|
|||||||
let mut subs = c.subs.into_iter();
|
let mut subs = c.subs.into_iter();
|
||||||
let mut next_sub = subs.next();
|
let mut next_sub = subs.next();
|
||||||
VMTrace {
|
VMTrace {
|
||||||
code: c.code,
|
code: c.code.into(),
|
||||||
ops: c.operations
|
ops: c.operations
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
@ -484,7 +484,7 @@ impl From<FlatTrace> for Trace {
|
|||||||
/// A diff of some chunk of memory.
|
/// A diff of some chunk of memory.
|
||||||
pub struct TraceResults {
|
pub struct TraceResults {
|
||||||
/// The output of the call/create
|
/// The output of the call/create
|
||||||
pub output: Vec<u8>,
|
pub output: Bytes,
|
||||||
/// The transaction trace.
|
/// The transaction trace.
|
||||||
pub trace: Vec<Trace>,
|
pub trace: Vec<Trace>,
|
||||||
/// The transaction trace.
|
/// The transaction trace.
|
||||||
@ -516,13 +516,13 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn should_serialize_trace_results() {
|
fn should_serialize_trace_results() {
|
||||||
let r = TraceResults {
|
let r = TraceResults {
|
||||||
output: vec![0x60],
|
output: vec![0x60].into(),
|
||||||
trace: vec![],
|
trace: vec![],
|
||||||
vm_trace: None,
|
vm_trace: None,
|
||||||
state_diff: None,
|
state_diff: None,
|
||||||
};
|
};
|
||||||
let serialized = serde_json::to_string(&r).unwrap();
|
let serialized = serde_json::to_string(&r).unwrap();
|
||||||
assert_eq!(serialized, r#"{"output":[96],"trace":[],"vmTrace":null,"stateDiff":null}"#);
|
assert_eq!(serialized, r#"{"output":"0x60","trace":[],"vmTrace":null,"stateDiff":null}"#);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -554,7 +554,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_vmtrace_serialize() {
|
fn test_vmtrace_serialize() {
|
||||||
let t = VMTrace {
|
let t = VMTrace {
|
||||||
code: vec![0, 1, 2, 3],
|
code: vec![0, 1, 2, 3].into(),
|
||||||
ops: vec![
|
ops: vec![
|
||||||
VMOperation {
|
VMOperation {
|
||||||
pc: 0,
|
pc: 0,
|
||||||
@ -572,15 +572,15 @@ mod tests {
|
|||||||
store: None,
|
store: None,
|
||||||
}),
|
}),
|
||||||
sub: Some(VMTrace {
|
sub: Some(VMTrace {
|
||||||
code: vec![0],
|
code: vec![0].into(),
|
||||||
ops: vec![
|
ops: vec![
|
||||||
VMOperation {
|
VMOperation {
|
||||||
pc: 0,
|
pc: 0,
|
||||||
cost: 0,
|
cost: 0,
|
||||||
ex: Some(VMExecutedOperation {
|
ex: Some(VMExecutedOperation {
|
||||||
used: 10,
|
used: 10,
|
||||||
push: vec![42.into()],
|
push: vec![42.into()].into(),
|
||||||
mem: Some(MemoryDiff {off: 42, data: vec![1, 2, 3]}),
|
mem: Some(MemoryDiff {off: 42, data: vec![1, 2, 3].into()}),
|
||||||
store: Some(StorageDiff {key: 69.into(), val: 42.into()}),
|
store: Some(StorageDiff {key: 69.into(), val: 42.into()}),
|
||||||
}),
|
}),
|
||||||
sub: None,
|
sub: None,
|
||||||
@ -591,7 +591,7 @@ mod tests {
|
|||||||
]
|
]
|
||||||
};
|
};
|
||||||
let serialized = serde_json::to_string(&t).unwrap();
|
let serialized = serde_json::to_string(&t).unwrap();
|
||||||
assert_eq!(serialized, r#"{"code":[0,1,2,3],"ops":[{"pc":0,"cost":10,"ex":null,"sub":null},{"pc":1,"cost":11,"ex":{"used":10,"push":["0x45"],"mem":null,"store":null},"sub":{"code":[0],"ops":[{"pc":0,"cost":0,"ex":{"used":10,"push":["0x2a"],"mem":{"off":42,"data":[1,2,3]},"store":{"key":"0x45","val":"0x2a"}},"sub":null}]}}]}"#);
|
assert_eq!(serialized, r#"{"code":"0x00010203","ops":[{"pc":0,"cost":10,"ex":null,"sub":null},{"pc":1,"cost":11,"ex":{"used":10,"push":["0x45"],"mem":null,"store":null},"sub":{"code":"0x00","ops":[{"pc":0,"cost":0,"ex":{"used":10,"push":["0x2a"],"mem":{"off":42,"data":"0x010203"},"store":{"key":"0x45","val":"0x2a"}},"sub":null}]}}]}"#);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
Loading…
Reference in New Issue
Block a user