Multi-call RPC (#6195)
* Removing duplicated pending state accessors in miner. * Merge miner+client call. * Multicall & multicall RPC. * Sensible defaults. * Fix tests.
This commit is contained in:
committed by
Marek Kotewicz
parent
62153b1ff0
commit
f157461ee1
@@ -19,9 +19,9 @@
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::collections::hash_map::Entry;
|
||||
use util::{Address, H256, Bytes, U256, RwLock, Mutex};
|
||||
use ethcore::error::{Error, CallError};
|
||||
use ethcore::client::{MiningBlockChainClient, Executed, CallAnalytics};
|
||||
use ethcore::block::{ClosedBlock, IsBlock};
|
||||
use ethcore::error::Error;
|
||||
use ethcore::client::MiningBlockChainClient;
|
||||
use ethcore::block::ClosedBlock;
|
||||
use ethcore::header::BlockNumber;
|
||||
use ethcore::transaction::{UnverifiedTransaction, SignedTransaction, PendingTransaction};
|
||||
use ethcore::receipt::{Receipt, RichReceipt};
|
||||
@@ -280,41 +280,6 @@ impl MinerService for TestMinerService {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn balance(&self, _chain: &MiningBlockChainClient, address: &Address) -> Option<U256> {
|
||||
self.latest_closed_block.lock()
|
||||
.as_ref()
|
||||
.map(|b| b.block().fields().state.balance(address))
|
||||
.map(|b| b.ok())
|
||||
.unwrap_or(Some(U256::default()))
|
||||
}
|
||||
|
||||
fn call(&self, _chain: &MiningBlockChainClient, _t: &SignedTransaction, _analytics: CallAnalytics) -> Result<Executed, CallError> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn storage_at(&self, _chain: &MiningBlockChainClient, address: &Address, position: &H256) -> Option<H256> {
|
||||
self.latest_closed_block.lock()
|
||||
.as_ref()
|
||||
.map(|b| b.block().fields().state.storage_at(address, position))
|
||||
.map(|s| s.ok())
|
||||
.unwrap_or(Some(H256::default()))
|
||||
}
|
||||
|
||||
fn nonce(&self, _chain: &MiningBlockChainClient, address: &Address) -> Option<U256> {
|
||||
// we assume all transactions are in a pending block, ignoring the
|
||||
// reality of gas limits.
|
||||
Some(self.last_nonce(address).unwrap_or(U256::zero()))
|
||||
}
|
||||
|
||||
fn code(&self, _chain: &MiningBlockChainClient, address: &Address) -> Option<Option<Bytes>> {
|
||||
self.latest_closed_block.lock()
|
||||
.as_ref()
|
||||
.map(|b| b.block().fields().state.code(address))
|
||||
.map(|c| c.ok())
|
||||
.unwrap_or(None)
|
||||
.map(|c| c.map(|c| (&*c).clone()))
|
||||
}
|
||||
|
||||
fn sensible_gas_price(&self) -> U256 {
|
||||
20000000000u64.into()
|
||||
}
|
||||
|
||||
@@ -432,10 +432,7 @@ fn rpc_eth_balance_pending() {
|
||||
"id": 1
|
||||
}"#;
|
||||
|
||||
// the TestMinerService doesn't communicate with the the TestBlockChainClient in any way.
|
||||
// if this returns zero, we know that the "pending" call is being properly forwarded to the
|
||||
// miner.
|
||||
let response = r#"{"jsonrpc":"2.0","result":"0x0","id":1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":"0x5","id":1}"#;
|
||||
|
||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||
}
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
|
||||
use std::sync::Arc;
|
||||
use ethcore_logger::RotatingLogger;
|
||||
use util::Address;
|
||||
use util::{Address, U256};
|
||||
use ethsync::ManageNetwork;
|
||||
use ethcore::account_provider::AccountProvider;
|
||||
use ethcore::client::{TestBlockChainClient};
|
||||
use ethcore::client::{TestBlockChainClient, Executed};
|
||||
use ethcore::miner::LocalTransactionStatus;
|
||||
use ethstore::ethkey::{Generator, Random};
|
||||
|
||||
@@ -504,3 +504,40 @@ fn rpc_parity_cid() {
|
||||
|
||||
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_parity_call() {
|
||||
let deps = Dependencies::new();
|
||||
deps.client.set_execution_result(Ok(Executed {
|
||||
exception: None,
|
||||
gas: U256::zero(),
|
||||
gas_used: U256::from(0xff30),
|
||||
refunded: U256::from(0x5),
|
||||
cumulative_gas_used: U256::zero(),
|
||||
logs: vec![],
|
||||
contracts_created: vec![],
|
||||
output: vec![0x12, 0x34, 0xff],
|
||||
trace: vec![],
|
||||
vm_trace: None,
|
||||
state_diff: None,
|
||||
}));
|
||||
let io = deps.default_client();
|
||||
|
||||
let request = r#"{
|
||||
"jsonrpc": "2.0",
|
||||
"method": "parity_call",
|
||||
"params": [[{
|
||||
"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155",
|
||||
"to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
|
||||
"gas": "0x76c0",
|
||||
"gasPrice": "0x9184e72a000",
|
||||
"value": "0x9184e72a",
|
||||
"data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"
|
||||
}],
|
||||
"latest"],
|
||||
"id": 1
|
||||
}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":["0x1234ff"],"id":1}"#;
|
||||
|
||||
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||
}
|
||||
|
||||
@@ -170,6 +170,16 @@ fn rpc_trace_call() {
|
||||
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();
|
||||
|
||||
Reference in New Issue
Block a user