* WIP move errors, pod_account and state account to own crates * Sort out dependencies, fix broken code and tests Remove botched ethcore-error crate * remove template line * fix review feedback * Remove test-only AccountDBMut::new * Extract AccountDB to account-db * Move Substate to state-account – wip * Add lib.rs * cleanup * test failure * test failure 2 * third time's the charm * Add factories crate * Use new factories crate * Use factories crate * Extract trace * Fix tests * Sort out parity-util-mem and parking_lot * cleanup * WIP port over the rest of state from ethcore * Collect all impls for Machine * some notes * Rename pod-account to pod * Move PodState to pod crate * Use PodState from pod crate * Fix use clause for json tests * Sort out evmbin * Add missing code and use PodState * Move code that depends on Machine and Executive to own module * Sort out cloning errors, fix ethcore to use new state crate * Do without funky From impls * Fix ethcore tests * Fixes around the project to use new state crate * Add back the more specific impls of StateOrBlock From conversions * Move execute to freestanding function and remove it from trait Sort out the error handling in executive_state by moving the result types from state to ethcore Undo the verbose code added to work around the StateOrBlock From conversions * cleanup * Fix "error: enum variants on type aliases are experimental" * Bring back the state tests Fix whitespace * remove ethcore/state/mod.rs * cleanup * cleanup * Cleanup state-account errors * Fix more todos Add module docs * Add error.rs * Fixup Cargo.lock * Smaller ethcore API is fine * Add `to-pod-full` feature to state-account Fix evmbin * Fix a few more test failures * Fix RPC test build * Baptize the new trait * Remove resolved TODOs * Rename state-account to account-state * Do not re-export the trace crate * Don't export state_db from ethcore * Let private-tx use StateDB. :( * Remove ethcore/src/pod_state.rs * Inner type does not need to be pub/pub(crate) * optimise imports * Revert "Inner type does not need to be pub/pub(crate)" This reverts commit 2f839f8a0f72f71334da64620f57e6dd6039f06b. * Move DatabaseExtras to ethcore-blockchain * Add database_extra module to ethcore-blockchain * Remove to-pod-full feature * Sort out the merge * sort imports * address grumbles * rename crate * address more grumbles
246 lines
11 KiB
Rust
246 lines
11 KiB
Rust
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
|
|
// This file is part of Parity Ethereum.
|
|
|
|
// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
use std::sync::Arc;
|
|
|
|
use ethcore::executed::{Executed, CallError};
|
|
use trace::trace::{Action, Res, Call};
|
|
use trace::LocalizedTrace;
|
|
use ethcore::client::TestBlockChainClient;
|
|
use ethereum_types::{Address, H256};
|
|
|
|
use vm::CallType;
|
|
|
|
use jsonrpc_core::IoHandler;
|
|
use v1::tests::helpers::{TestMinerService};
|
|
use v1::{Metadata, Traces, TracesClient};
|
|
|
|
struct Tester {
|
|
client: Arc<TestBlockChainClient>,
|
|
_miner: Arc<TestMinerService>,
|
|
io: IoHandler<Metadata>,
|
|
}
|
|
|
|
fn io() -> Tester {
|
|
let client = Arc::new(TestBlockChainClient::new());
|
|
*client.traces.write() = Some(vec![LocalizedTrace {
|
|
action: Action::Call(Call {
|
|
from: Address::from_low_u64_be(0xf),
|
|
to: Address::from_low_u64_be(0x10),
|
|
value: 0x1.into(),
|
|
gas: 0x100.into(),
|
|
input: vec![1, 2, 3],
|
|
call_type: CallType::Call,
|
|
}),
|
|
result: Res::None,
|
|
subtraces: 0,
|
|
trace_address: vec![0],
|
|
transaction_number: Some(0),
|
|
transaction_hash: Some(H256::from_low_u64_be(5)),
|
|
block_number: 10,
|
|
block_hash: H256::from_low_u64_be(10),
|
|
}]);
|
|
*client.execution_result.write() = Some(Ok(Executed {
|
|
exception: None,
|
|
gas: 20_000.into(),
|
|
gas_used: 10_000.into(),
|
|
refunded: 0.into(),
|
|
cumulative_gas_used: 10_000.into(),
|
|
logs: vec![],
|
|
contracts_created: vec![],
|
|
output: vec![1, 2, 3],
|
|
trace: vec![],
|
|
vm_trace: None,
|
|
state_diff: None,
|
|
}));
|
|
let miner = Arc::new(TestMinerService::default());
|
|
let traces = TracesClient::new(&client);
|
|
let mut io = IoHandler::default();
|
|
io.extend_with(traces.to_delegate());
|
|
|
|
Tester {
|
|
client: client,
|
|
_miner: miner,
|
|
io: io,
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn rpc_trace_filter() {
|
|
let tester = io();
|
|
|
|
let request = r#"{"jsonrpc":"2.0","method":"trace_filter","params": [{}],"id":1}"#;
|
|
let response = r#"{"jsonrpc":"2.0","result":[{"action":{"callType":"call","from":"0x000000000000000000000000000000000000000f","gas":"0x100","input":"0x010203","to":"0x0000000000000000000000000000000000000010","value":"0x1"},"blockHash":"0x000000000000000000000000000000000000000000000000000000000000000a","blockNumber":10,"result":null,"subtraces":0,"traceAddress":[0],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000005","transactionPosition":0,"type":"call"}],"id":1}"#;
|
|
|
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
|
}
|
|
|
|
#[test]
|
|
fn rpc_trace_filter_missing_trace() {
|
|
let tester = io();
|
|
*tester.client.traces.write() = None;
|
|
|
|
let request = r#"{"jsonrpc":"2.0","method":"trace_filter","params": [{}],"id":1}"#;
|
|
let response = r#"{"jsonrpc":"2.0","result":null,"id":1}"#;
|
|
|
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
|
}
|
|
|
|
#[test]
|
|
fn rpc_trace_block() {
|
|
let tester = io();
|
|
|
|
let request = r#"{"jsonrpc":"2.0","method":"trace_block","params": ["0x10"],"id":1}"#;
|
|
let response = r#"{"jsonrpc":"2.0","result":[{"action":{"callType":"call","from":"0x000000000000000000000000000000000000000f","gas":"0x100","input":"0x010203","to":"0x0000000000000000000000000000000000000010","value":"0x1"},"blockHash":"0x000000000000000000000000000000000000000000000000000000000000000a","blockNumber":10,"result":null,"subtraces":0,"traceAddress":[0],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000005","transactionPosition":0,"type":"call"}],"id":1}"#;
|
|
|
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
|
}
|
|
|
|
#[test]
|
|
fn rpc_trace_block_missing_traces() {
|
|
let tester = io();
|
|
*tester.client.traces.write() = None;
|
|
|
|
let request = r#"{"jsonrpc":"2.0","method":"trace_block","params": ["0x10"],"id":1}"#;
|
|
let response = r#"{"jsonrpc":"2.0","result":null,"id":1}"#;
|
|
|
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
|
}
|
|
|
|
#[test]
|
|
fn rpc_trace_transaction() {
|
|
let tester = io();
|
|
|
|
let request = r#"{"jsonrpc":"2.0","method":"trace_transaction","params":["0x0000000000000000000000000000000000000000000000000000000000000005"],"id":1}"#;
|
|
let response = r#"{"jsonrpc":"2.0","result":[{"action":{"callType":"call","from":"0x000000000000000000000000000000000000000f","gas":"0x100","input":"0x010203","to":"0x0000000000000000000000000000000000000010","value":"0x1"},"blockHash":"0x000000000000000000000000000000000000000000000000000000000000000a","blockNumber":10,"result":null,"subtraces":0,"traceAddress":[0],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000005","transactionPosition":0,"type":"call"}],"id":1}"#;
|
|
|
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
|
}
|
|
|
|
#[test]
|
|
fn rpc_trace_transaction_missing_trace() {
|
|
let tester = io();
|
|
*tester.client.traces.write() = None;
|
|
|
|
let request = r#"{"jsonrpc":"2.0","method":"trace_transaction","params":["0x0000000000000000000000000000000000000000000000000000000000000005"],"id":1}"#;
|
|
let response = r#"{"jsonrpc":"2.0","result":null,"id":1}"#;
|
|
|
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
|
}
|
|
|
|
#[test]
|
|
fn rpc_trace_get() {
|
|
let tester = io();
|
|
|
|
let request = r#"{"jsonrpc":"2.0","method":"trace_get","params":["0x0000000000000000000000000000000000000000000000000000000000000005", ["0","0","0"]],"id":1}"#;
|
|
let response = r#"{"jsonrpc":"2.0","result":{"action":{"callType":"call","from":"0x000000000000000000000000000000000000000f","gas":"0x100","input":"0x010203","to":"0x0000000000000000000000000000000000000010","value":"0x1"},"blockHash":"0x000000000000000000000000000000000000000000000000000000000000000a","blockNumber":10,"result":null,"subtraces":0,"traceAddress":[0],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000005","transactionPosition":0,"type":"call"},"id":1}"#;
|
|
|
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
|
}
|
|
|
|
#[test]
|
|
fn rpc_trace_get_missing_trace() {
|
|
let tester = io();
|
|
*tester.client.traces.write() = None;
|
|
|
|
let request = r#"{"jsonrpc":"2.0","method":"trace_get","params":["0x0000000000000000000000000000000000000000000000000000000000000005", ["0","0","0"]],"id":1}"#;
|
|
let response = r#"{"jsonrpc":"2.0","result":null,"id":1}"#;
|
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
|
}
|
|
|
|
#[test]
|
|
fn rpc_trace_call() {
|
|
let tester = io();
|
|
|
|
let request = r#"{"jsonrpc":"2.0","method":"trace_call","params":[{}, ["stateDiff", "vmTrace", "trace"]],"id":1}"#;
|
|
let response = r#"{"jsonrpc":"2.0","result":{"output":"0x010203","stateDiff":null,"trace":[],"vmTrace":null},"id":1}"#;
|
|
|
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
|
}
|
|
|
|
#[test]
|
|
fn rpc_trace_multi_call() {
|
|
let tester = io();
|
|
|
|
let request = r#"{"jsonrpc":"2.0","method":"trace_callMany","params":[[[{}, ["stateDiff", "vmTrace", "trace"]]]],"id":1}"#;
|
|
let response = r#"{"jsonrpc":"2.0","result":[{"output":"0x010203","stateDiff":null,"trace":[],"vmTrace":null}],"id":1}"#;
|
|
|
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
|
}
|
|
|
|
#[test]
|
|
fn rpc_trace_call_state_pruned() {
|
|
let tester = io();
|
|
*tester.client.execution_result.write() = Some(Err(CallError::StatePruned));
|
|
|
|
let request = r#"{"jsonrpc":"2.0","method":"trace_call","params":[{}, ["stateDiff", "vmTrace", "trace"]],"id":1}"#;
|
|
let response = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"This request is not supported because your node is running with state pruning. Run with --pruning=archive."},"id":1}"#;
|
|
|
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
|
}
|
|
|
|
#[test]
|
|
fn rpc_trace_raw_transaction() {
|
|
let tester = io();
|
|
|
|
let request = r#"{"jsonrpc":"2.0","method":"trace_rawTransaction","params":["0xf869018609184e72a0008276c094d46e8dd67c5d32be8058bb8eb970870f07244567849184e72a801ba0617f39c1a107b63302449c476d96a6cb17a5842fc98ff0c5bcf4d5c4d8166b95a009fdb6097c6196b9bbafc3a59f02f38d91baeef23d0c60a8e4f23c7714cea3a9", ["stateDiff", "vmTrace", "trace"]],"id":1}"#;
|
|
let response = r#"{"jsonrpc":"2.0","result":{"output":"0x010203","stateDiff":null,"trace":[],"vmTrace":null},"id":1}"#;
|
|
|
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
|
}
|
|
|
|
#[test]
|
|
fn rpc_trace_raw_transaction_state_pruned() {
|
|
let tester = io();
|
|
*tester.client.execution_result.write() = Some(Err(CallError::StatePruned));
|
|
|
|
let request = r#"{"jsonrpc":"2.0","method":"trace_rawTransaction","params":["0xf869018609184e72a0008276c094d46e8dd67c5d32be8058bb8eb970870f07244567849184e72a801ba0617f39c1a107b63302449c476d96a6cb17a5842fc98ff0c5bcf4d5c4d8166b95a009fdb6097c6196b9bbafc3a59f02f38d91baeef23d0c60a8e4f23c7714cea3a9", ["stateDiff", "vmTrace", "trace"]],"id":1}"#;
|
|
let response = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"This request is not supported because your node is running with state pruning. Run with --pruning=archive."},"id":1}"#;
|
|
|
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
|
}
|
|
|
|
#[test]
|
|
fn rpc_trace_replay_transaction() {
|
|
let tester = io();
|
|
|
|
let request = r#"{"jsonrpc":"2.0","method":"trace_replayTransaction","params":["0x0000000000000000000000000000000000000000000000000000000000000005", ["trace", "stateDiff", "vmTrace"]],"id":1}"#;
|
|
let response = r#"{"jsonrpc":"2.0","result":{"output":"0x010203","stateDiff":null,"trace":[],"vmTrace":null},"id":1}"#;
|
|
|
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
|
}
|
|
|
|
#[test]
|
|
fn rpc_trace_replay_transaction_state_pruned() {
|
|
let tester = io();
|
|
*tester.client.execution_result.write() = Some(Err(CallError::StatePruned));
|
|
|
|
let request = r#"{"jsonrpc":"2.0","method":"trace_replayTransaction","params":["0x0000000000000000000000000000000000000000000000000000000000000005", ["trace", "stateDiff", "vmTrace"]],"id":1}"#;
|
|
let response = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"This request is not supported because your node is running with state pruning. Run with --pruning=archive."},"id":1}"#;
|
|
|
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
|
}
|
|
|
|
#[test]
|
|
fn rpc_trace_replay_block_transactions() {
|
|
let tester = io();
|
|
|
|
let request = r#"{"jsonrpc":"2.0","method":"trace_replayBlockTransactions","params":["0x10", ["trace", "stateDiff", "vmTrace"]],"id":1}"#;
|
|
let response = r#"{"jsonrpc":"2.0","result":[{"output":"0x010203","stateDiff":null,"trace":[],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000005","vmTrace":null}],"id":1}"#;
|
|
|
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
|
}
|