2016-12-11 19:31:31 +01:00
// Copyright 2015, 2016 Parity Technologies (UK) Ltd.
2016-05-26 16:59:59 +02:00
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std ::str ::FromStr ;
use std ::collections ::HashMap ;
2016-07-13 19:59:59 +02:00
use std ::sync ::Arc ;
2016-08-02 18:53:32 +02:00
use std ::time ::{ Instant , Duration } ;
2016-12-10 20:01:04 +01:00
use rustc_serialize ::hex ::{ FromHex , ToHex } ;
2016-11-18 11:03:29 +01:00
use time ::get_time ;
2016-11-09 13:13:35 +01:00
use rlp ;
2016-11-18 11:03:29 +01:00
2016-12-10 20:01:04 +01:00
use util ::{ Uint , U256 , Address , H256 , FixedHash , Mutex , Hashable } ;
2016-06-20 00:10:34 +02:00
use ethcore ::account_provider ::AccountProvider ;
2016-12-09 23:01:43 +01:00
use ethcore ::client ::{ TestBlockChainClient , EachBlockWith , Executed , TransactionId } ;
2016-05-26 16:59:59 +02:00
use ethcore ::log_entry ::{ LocalizedLogEntry , LogEntry } ;
use ethcore ::receipt ::LocalizedReceipt ;
use ethcore ::transaction ::{ Transaction , Action } ;
2016-05-31 21:31:42 +02:00
use ethcore ::miner ::{ ExternalMiner , MinerService } ;
2016-05-30 12:33:49 +02:00
use ethsync ::SyncState ;
2016-11-18 11:03:29 +01:00
2016-11-22 11:56:27 +01:00
use jsonrpc_core ::{ IoHandler , GenericIoHandler } ;
2016-11-06 12:51:53 +01:00
use v1 ::{ Eth , EthClient , EthClientOptions , EthFilter , EthFilterClient , EthSigning , SigningUnsafeClient } ;
2016-10-31 17:32:53 +01:00
use v1 ::tests ::helpers ::{ TestSyncProvider , Config , TestMinerService , TestSnapshotService } ;
2016-05-26 16:59:59 +02:00
fn blockchain_client ( ) -> Arc < TestBlockChainClient > {
let client = TestBlockChainClient ::new ( ) ;
Arc ::new ( client )
}
2016-06-20 00:10:34 +02:00
fn accounts_provider ( ) -> Arc < AccountProvider > {
Arc ::new ( AccountProvider ::transient_provider ( ) )
2016-05-26 16:59:59 +02:00
}
fn sync_provider ( ) -> Arc < TestSyncProvider > {
Arc ::new ( TestSyncProvider ::new ( Config {
2016-11-03 22:22:25 +01:00
network_id : 3 ,
2016-05-26 16:59:59 +02:00
num_peers : 120 ,
} ) )
}
fn miner_service ( ) -> Arc < TestMinerService > {
Arc ::new ( TestMinerService ::default ( ) )
}
2016-10-31 17:32:53 +01:00
fn snapshot_service ( ) -> Arc < TestSnapshotService > {
Arc ::new ( TestSnapshotService ::new ( ) )
}
2016-05-26 16:59:59 +02:00
struct EthTester {
pub client : Arc < TestBlockChainClient > ,
pub sync : Arc < TestSyncProvider > ,
2016-06-20 00:10:34 +02:00
pub accounts_provider : Arc < AccountProvider > ,
2016-07-14 12:16:53 +02:00
pub miner : Arc < TestMinerService > ,
2016-10-31 17:32:53 +01:00
pub snapshot : Arc < TestSnapshotService > ,
2016-08-02 18:53:32 +02:00
hashrates : Arc < Mutex < HashMap < H256 , ( Instant , U256 ) > > > ,
2016-05-26 16:59:59 +02:00
pub io : IoHandler ,
}
impl Default for EthTester {
fn default ( ) -> Self {
2016-08-03 15:31:00 +02:00
Self ::new_with_options ( Default ::default ( ) )
}
}
impl EthTester {
pub fn new_with_options ( options : EthClientOptions ) -> Self {
2016-05-26 16:59:59 +02:00
let client = blockchain_client ( ) ;
let sync = sync_provider ( ) ;
let ap = accounts_provider ( ) ;
let miner = miner_service ( ) ;
2016-10-31 17:32:53 +01:00
let snapshot = snapshot_service ( ) ;
2016-08-02 18:53:32 +02:00
let hashrates = Arc ::new ( Mutex ::new ( HashMap ::new ( ) ) ) ;
2016-05-26 16:59:59 +02:00
let external_miner = Arc ::new ( ExternalMiner ::new ( hashrates . clone ( ) ) ) ;
2016-10-31 17:32:53 +01:00
let eth = EthClient ::new ( & client , & snapshot , & sync , & ap , & miner , & external_miner , options ) . to_delegate ( ) ;
2016-09-21 12:51:10 +02:00
let filter = EthFilterClient ::new ( & client , & miner ) . to_delegate ( ) ;
2016-11-06 12:51:53 +01:00
let sign = SigningUnsafeClient ::new ( & client , & ap , & miner ) . to_delegate ( ) ;
2016-05-26 16:59:59 +02:00
let io = IoHandler ::new ( ) ;
io . add_delegate ( eth ) ;
2016-06-01 19:37:34 +02:00
io . add_delegate ( sign ) ;
2016-09-21 12:51:10 +02:00
io . add_delegate ( filter ) ;
2016-06-01 19:37:34 +02:00
2016-05-26 16:59:59 +02:00
EthTester {
client : client ,
sync : sync ,
accounts_provider : ap ,
miner : miner ,
2016-10-31 17:32:53 +01:00
snapshot : snapshot ,
2016-05-26 16:59:59 +02:00
io : io ,
hashrates : hashrates ,
}
}
2016-10-19 18:35:39 +02:00
pub fn add_blocks ( & self , count : usize , with : EachBlockWith ) {
self . client . add_blocks ( count , with ) ;
self . sync . increase_imported_block_number ( count as u64 ) ;
}
2016-05-26 16:59:59 +02:00
}
#[ test ]
fn rpc_eth_protocol_version ( ) {
let request = r # "{"jsonrpc": "2.0", "method": "eth_protocolVersion", "params": [], "id": 1}"# ;
let response = r # "{"jsonrpc":"2.0","result":"63","id":1}"# ;
2016-09-01 12:00:00 +02:00
assert_eq! ( EthTester ::default ( ) . io . handle_request_sync ( request ) , Some ( response . to_owned ( ) ) ) ;
2016-05-26 16:59:59 +02:00
}
#[ test ]
fn rpc_eth_syncing ( ) {
2016-10-31 17:32:53 +01:00
use ethcore ::snapshot ::RestorationStatus ;
2016-05-30 12:33:49 +02:00
let request = r # "{"jsonrpc": "2.0", "method": "eth_syncing", "params": [], "id": 1}"# ;
let tester = EthTester ::default ( ) ;
let false_res = r # "{"jsonrpc":"2.0","result":false,"id":1}"# ;
2016-09-01 12:00:00 +02:00
assert_eq! ( tester . io . handle_request_sync ( request ) , Some ( false_res . to_owned ( ) ) ) ;
2016-05-30 12:33:49 +02:00
{
2016-07-13 19:59:59 +02:00
let mut status = tester . sync . status . write ( ) ;
2016-05-30 12:33:49 +02:00
status . state = SyncState ::Blocks ;
status . highest_block_number = Some ( 2500 ) ;
}
2016-10-19 18:35:39 +02:00
// "sync" to 1000 blocks.
// causes TestBlockChainClient to return 1000 for its best block number.
tester . add_blocks ( 1000 , EachBlockWith ::Nothing ) ;
2016-12-19 15:27:17 +01:00
let true_res = r # "{"jsonrpc":"2.0","result":{"currentBlock":"0x3e8","highestBlock":"0x9c4","startingBlock":"0x0","warpChunksAmount":null,"warpChunksProcessed":null},"id":1}"# ;
2016-09-01 12:00:00 +02:00
assert_eq! ( tester . io . handle_request_sync ( request ) , Some ( true_res . to_owned ( ) ) ) ;
2016-05-31 10:31:36 +02:00
2016-10-31 17:32:53 +01:00
* tester . client . ancient_block . write ( ) = None ;
* tester . client . first_block . write ( ) = None ;
2016-12-19 15:27:17 +01:00
let snap_res = r # "{"jsonrpc":"2.0","result":{"currentBlock":"0x3e8","highestBlock":"0x9c4","startingBlock":"0x0","warpChunksAmount":"0x32","warpChunksProcessed":"0x18"},"id":1}"# ;
2016-10-31 17:32:53 +01:00
tester . snapshot . set_status ( RestorationStatus ::Ongoing {
state_chunks : 40 ,
block_chunks : 10 ,
state_chunks_done : 18 ,
block_chunks_done : 6 ,
} ) ;
assert_eq! ( tester . io . handle_request_sync ( request ) , Some ( snap_res . to_owned ( ) ) ) ;
tester . snapshot . set_status ( RestorationStatus ::Inactive ) ;
2016-10-19 18:35:39 +02:00
// finish "syncing"
tester . add_blocks ( 1500 , EachBlockWith ::Nothing ) ;
2016-05-31 10:31:36 +02:00
{
2016-10-19 18:35:39 +02:00
let mut status = tester . sync . status . write ( ) ;
status . state = SyncState ::Idle ;
2016-05-31 10:31:36 +02:00
}
2016-09-01 12:00:00 +02:00
assert_eq! ( tester . io . handle_request_sync ( request ) , Some ( false_res . to_owned ( ) ) ) ;
2016-05-26 16:59:59 +02:00
}
#[ test ]
fn rpc_eth_hashrate ( ) {
let tester = EthTester ::default ( ) ;
2016-08-02 18:53:32 +02:00
tester . hashrates . lock ( ) . insert ( H256 ::from ( 0 ) , ( Instant ::now ( ) + Duration ::from_secs ( 2 ) , U256 ::from ( 0xfffa ) ) ) ;
tester . hashrates . lock ( ) . insert ( H256 ::from ( 0 ) , ( Instant ::now ( ) + Duration ::from_secs ( 2 ) , U256 ::from ( 0xfffb ) ) ) ;
tester . hashrates . lock ( ) . insert ( H256 ::from ( 1 ) , ( Instant ::now ( ) + Duration ::from_secs ( 2 ) , U256 ::from ( 0x1 ) ) ) ;
2016-05-26 16:59:59 +02:00
let request = r # "{"jsonrpc": "2.0", "method": "eth_hashrate", "params": [], "id": 1}"# ;
let response = r # "{"jsonrpc":"2.0","result":"0xfffc","id":1}"# ;
2016-09-01 12:00:00 +02:00
assert_eq! ( tester . io . handle_request_sync ( request ) , Some ( response . to_owned ( ) ) ) ;
2016-05-26 16:59:59 +02:00
}
2016-09-14 12:02:30 +02:00
#[ test ]
fn rpc_eth_logs ( ) {
let tester = EthTester ::default ( ) ;
2016-09-21 12:51:10 +02:00
tester . client . set_logs ( vec! [ LocalizedLogEntry {
block_number : 1 ,
block_hash : H256 ::default ( ) ,
entry : LogEntry {
address : Address ::default ( ) ,
topics : vec ! [ ] ,
data : vec ! [ 1 , 2 , 3 ] ,
} ,
transaction_index : 0 ,
2016-12-29 19:48:28 +01:00
transaction_log_index : 0 ,
2016-09-21 12:51:10 +02:00
transaction_hash : H256 ::default ( ) ,
log_index : 0 ,
} , LocalizedLogEntry {
block_number : 1 ,
block_hash : H256 ::default ( ) ,
entry : LogEntry {
address : Address ::default ( ) ,
topics : vec ! [ ] ,
data : vec ! [ 1 , 2 , 3 ] ,
} ,
transaction_index : 0 ,
2016-12-29 19:48:28 +01:00
transaction_log_index : 1 ,
2016-09-21 12:51:10 +02:00
transaction_hash : H256 ::default ( ) ,
2016-12-29 19:48:28 +01:00
log_index : 1 ,
2016-09-21 12:51:10 +02:00
} ] ) ;
let request1 = r # "{"jsonrpc": "2.0", "method": "eth_getLogs", "params": [{}], "id": 1}"# ;
let request2 = r # "{"jsonrpc": "2.0", "method": "eth_getLogs", "params": [{"limit":1}], "id": 1}"# ;
let request3 = r # "{"jsonrpc": "2.0", "method": "eth_getLogs", "params": [{"limit":0}], "id": 1}"# ;
2016-12-29 19:48:28 +01:00
let response1 = r # "{"jsonrpc":"2.0","result":[{"address":"0x0000000000000000000000000000000000000000","blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000","blockNumber":"0x1","data":"0x010203","logIndex":"0x0","topics":[],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","transactionLogIndex":"0x0","type":"mined"},{"address":"0x0000000000000000000000000000000000000000","blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000","blockNumber":"0x1","data":"0x010203","logIndex":"0x1","topics":[],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","transactionLogIndex":"0x1","type":"mined"}],"id":1}"# ;
let response2 = r # "{"jsonrpc":"2.0","result":[{"address":"0x0000000000000000000000000000000000000000","blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000","blockNumber":"0x1","data":"0x010203","logIndex":"0x1","topics":[],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","transactionLogIndex":"0x1","type":"mined"}],"id":1}"# ;
2016-09-21 12:51:10 +02:00
let response3 = r # "{"jsonrpc":"2.0","result":[],"id":1}"# ;
assert_eq! ( tester . io . handle_request_sync ( request1 ) , Some ( response1 . to_owned ( ) ) ) ;
assert_eq! ( tester . io . handle_request_sync ( request2 ) , Some ( response2 . to_owned ( ) ) ) ;
assert_eq! ( tester . io . handle_request_sync ( request3 ) , Some ( response3 . to_owned ( ) ) ) ;
2016-09-14 12:02:30 +02:00
}
#[ test ]
2016-09-21 12:51:10 +02:00
fn rpc_logs_filter ( ) {
2016-09-14 12:02:30 +02:00
let tester = EthTester ::default ( ) ;
2016-09-21 12:51:10 +02:00
// Set some logs
tester . client . set_logs ( vec! [ LocalizedLogEntry {
block_number : 1 ,
block_hash : H256 ::default ( ) ,
entry : LogEntry {
address : Address ::default ( ) ,
topics : vec ! [ ] ,
data : vec ! [ 1 , 2 , 3 ] ,
} ,
transaction_index : 0 ,
2016-12-29 19:48:28 +01:00
transaction_log_index : 0 ,
2016-09-21 12:51:10 +02:00
transaction_hash : H256 ::default ( ) ,
log_index : 0 ,
} , LocalizedLogEntry {
block_number : 1 ,
block_hash : H256 ::default ( ) ,
entry : LogEntry {
address : Address ::default ( ) ,
topics : vec ! [ ] ,
data : vec ! [ 1 , 2 , 3 ] ,
} ,
transaction_index : 0 ,
2016-12-29 19:48:28 +01:00
transaction_log_index : 1 ,
2016-09-21 12:51:10 +02:00
transaction_hash : H256 ::default ( ) ,
2016-12-29 19:48:28 +01:00
log_index : 1 ,
2016-09-21 12:51:10 +02:00
} ] ) ;
// Register filters first
let request_default = r # "{"jsonrpc": "2.0", "method": "eth_newFilter", "params": [{}], "id": 1}"# ;
let request_limit = r # "{"jsonrpc": "2.0", "method": "eth_newFilter", "params": [{"limit":1}], "id": 1}"# ;
let response1 = r # "{"jsonrpc":"2.0","result":"0x0","id":1}"# ;
let response2 = r # "{"jsonrpc":"2.0","result":"0x1","id":1}"# ;
assert_eq! ( tester . io . handle_request_sync ( request_default ) , Some ( response1 . to_owned ( ) ) ) ;
assert_eq! ( tester . io . handle_request_sync ( request_limit ) , Some ( response2 . to_owned ( ) ) ) ;
let request_changes1 = r # "{"jsonrpc": "2.0", "method": "eth_getFilterChanges", "params": ["0x0"], "id": 1}"# ;
let request_changes2 = r # "{"jsonrpc": "2.0", "method": "eth_getFilterChanges", "params": ["0x1"], "id": 1}"# ;
2016-12-29 19:48:28 +01:00
let response1 = r # "{"jsonrpc":"2.0","result":[{"address":"0x0000000000000000000000000000000000000000","blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000","blockNumber":"0x1","data":"0x010203","logIndex":"0x0","topics":[],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","transactionLogIndex":"0x0","type":"mined"},{"address":"0x0000000000000000000000000000000000000000","blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000","blockNumber":"0x1","data":"0x010203","logIndex":"0x1","topics":[],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","transactionLogIndex":"0x1","type":"mined"}],"id":1}"# ;
let response2 = r # "{"jsonrpc":"2.0","result":[{"address":"0x0000000000000000000000000000000000000000","blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000","blockNumber":"0x1","data":"0x010203","logIndex":"0x1","topics":[],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","transactionLogIndex":"0x1","type":"mined"}],"id":1}"# ;
2016-09-21 12:51:10 +02:00
assert_eq! ( tester . io . handle_request_sync ( request_changes1 ) , Some ( response1 . to_owned ( ) ) ) ;
assert_eq! ( tester . io . handle_request_sync ( request_changes2 ) , Some ( response2 . to_owned ( ) ) ) ;
2016-09-14 12:02:30 +02:00
}
2016-05-26 16:59:59 +02:00
#[ test ]
fn rpc_eth_submit_hashrate ( ) {
let tester = EthTester ::default ( ) ;
let request = r #" {
" jsonrpc " : " 2.0 " ,
" method " : " eth_submitHashrate " ,
" params " : [
" 0x0000000000000000000000000000000000000000000000000000000000500000 " ,
" 0x59daa26581d0acd1fce254fb7e85952f4c09d0915afd33d3886cd914bc7d283c " ] ,
" id " : 1
} " #;
let response = r # "{"jsonrpc":"2.0","result":true,"id":1}"# ;
2016-09-01 12:00:00 +02:00
assert_eq! ( tester . io . handle_request_sync ( request ) , Some ( response . to_owned ( ) ) ) ;
2016-08-02 18:53:32 +02:00
assert_eq! ( tester . hashrates . lock ( ) . get ( & H256 ::from ( " 0x59daa26581d0acd1fce254fb7e85952f4c09d0915afd33d3886cd914bc7d283c " ) ) . cloned ( ) . unwrap ( ) . 1 ,
U256 ::from ( 0x500_000 ) ) ;
2016-05-26 16:59:59 +02:00
}
#[ test ]
2016-05-29 15:46:57 +02:00
fn rpc_eth_sign ( ) {
let tester = EthTester ::default ( ) ;
let account = tester . accounts_provider . new_account ( " abcd " ) . unwrap ( ) ;
2016-06-20 00:10:34 +02:00
tester . accounts_provider . unlock_account_permanently ( account , " abcd " . into ( ) ) . unwrap ( ) ;
2016-12-10 20:01:04 +01:00
let message = " 0cc175b9c0f1b6a831c399e26977266192eb5ffee6ae2fec3ad71c777531578f " . from_hex ( ) . unwrap ( ) ;
let signed = tester . accounts_provider . sign ( account , None , message . sha3 ( ) ) . unwrap ( ) ;
2016-05-29 15:46:57 +02:00
let req = r #" {
" jsonrpc " : " 2.0 " ,
" method " : " eth_sign " ,
" params " : [
" " #. to_owned ( ) + & format! ( " 0x {:?} " , account ) + r #" " ,
" 0x0cc175b9c0f1b6a831c399e26977266192eb5ffee6ae2fec3ad71c777531578f "
] ,
" id " : 1
} " #;
2016-08-15 15:09:00 +02:00
let res = r # "{"jsonrpc":"2.0","result":""# . to_owned ( ) + & format! ( " 0x {} " , signed ) + r # "","id":1}"# ;
2016-05-29 15:46:57 +02:00
2016-09-01 12:00:00 +02:00
assert_eq! ( tester . io . handle_request_sync ( & req ) , Some ( res ) ) ;
2016-05-29 15:46:57 +02:00
}
2016-05-26 16:59:59 +02:00
#[ test ]
fn rpc_eth_author ( ) {
2016-05-29 17:18:37 +02:00
let make_res = | addr | r # "{"jsonrpc":"2.0","result":""# . to_owned ( ) + & format! ( " 0x {:?} " , addr ) + r # "","id":1}"# ;
let tester = EthTester ::default ( ) ;
let req = r #" {
" jsonrpc " : " 2.0 " ,
" method " : " eth_coinbase " ,
" params " : [ ] ,
" id " : 1
} " #;
2016-09-01 12:00:00 +02:00
assert_eq! ( tester . io . handle_request_sync ( req ) , Some ( make_res ( Address ::zero ( ) ) ) ) ;
2016-05-29 17:18:37 +02:00
for i in 0 .. 20 {
let addr = tester . accounts_provider . new_account ( & format! ( " {} " , i ) ) . unwrap ( ) ;
tester . miner . set_author ( addr . clone ( ) ) ;
2016-09-01 12:00:00 +02:00
assert_eq! ( tester . io . handle_request_sync ( req ) , Some ( make_res ( addr ) ) ) ;
2016-05-29 17:18:37 +02:00
}
2016-05-26 16:59:59 +02:00
}
#[ test ]
fn rpc_eth_mining ( ) {
let tester = EthTester ::default ( ) ;
2016-08-02 18:53:32 +02:00
tester . miner . set_author ( Address ::from_str ( " d46e8dd67c5d32be8058bb8eb970870f07244567 " ) . unwrap ( ) ) ;
2016-05-26 16:59:59 +02:00
let request = r # "{"jsonrpc": "2.0", "method": "eth_mining", "params": [], "id": 1}"# ;
let response = r # "{"jsonrpc":"2.0","result":false,"id":1}"# ;
2016-09-01 12:00:00 +02:00
assert_eq! ( tester . io . handle_request_sync ( request ) , Some ( response . to_owned ( ) ) ) ;
2016-05-26 16:59:59 +02:00
}
#[ test ]
fn rpc_eth_gas_price ( ) {
let request = r # "{"jsonrpc": "2.0", "method": "eth_gasPrice", "params": [], "id": 1}"# ;
2016-09-02 11:38:16 +02:00
let response = r # "{"jsonrpc":"2.0","result":"0x4a817c800","id":1}"# ;
2016-05-26 16:59:59 +02:00
2016-09-01 12:00:00 +02:00
assert_eq! ( EthTester ::default ( ) . io . handle_request_sync ( request ) , Some ( response . to_owned ( ) ) ) ;
2016-05-26 16:59:59 +02:00
}
#[ test ]
fn rpc_eth_accounts ( ) {
2016-06-20 00:10:34 +02:00
let tester = EthTester ::default ( ) ;
2016-12-10 12:34:20 +01:00
let address = tester . accounts_provider . new_account ( " " ) . unwrap ( ) ;
2016-12-11 17:51:34 +01:00
tester . accounts_provider . set_new_dapps_whitelist ( None ) . unwrap ( ) ;
2016-06-20 00:10:34 +02:00
2016-12-11 17:51:34 +01:00
// with current policy it should return the account
2016-12-10 12:34:20 +01:00
let request = r # "{"jsonrpc": "2.0", "method": "eth_accounts", "params": [], "id": 1}"# ;
let response = r # "{"jsonrpc":"2.0","result":[""# . to_owned ( ) + & format! ( " 0x {:?} " , address ) + r # ""],"id":1}"# ;
assert_eq! ( tester . io . handle_request_sync ( request ) , Some ( response . to_owned ( ) ) ) ;
tester . accounts_provider . set_new_dapps_whitelist ( Some ( vec! [ 1. into ( ) ] ) ) . unwrap ( ) ;
2016-11-22 11:56:27 +01:00
// even with some account it should return empty list (no dapp detected)
2016-05-26 16:59:59 +02:00
let request = r # "{"jsonrpc": "2.0", "method": "eth_accounts", "params": [], "id": 1}"# ;
2016-12-10 12:34:20 +01:00
let response = r # "{"jsonrpc":"2.0","result":["0x0000000000000000000000000000000000000001"],"id":1}"# ;
2016-11-22 11:56:27 +01:00
assert_eq! ( tester . io . handle_request_sync ( request ) , Some ( response . to_owned ( ) ) ) ;
2016-05-26 16:59:59 +02:00
2016-11-22 11:56:27 +01:00
// when we add visible address it should return that.
tester . accounts_provider . set_dapps_addresses ( " app1 " . into ( ) , vec! [ 10. into ( ) ] ) . unwrap ( ) ;
let request = r # "{"jsonrpc": "2.0", "method": "eth_accounts", "params": ["app1"], "id": 1}"# ;
let response = r # "{"jsonrpc":"2.0","result":["0x000000000000000000000000000000000000000a"],"id":1}"# ;
2016-09-01 12:00:00 +02:00
assert_eq! ( tester . io . handle_request_sync ( request ) , Some ( response . to_owned ( ) ) ) ;
2016-05-26 16:59:59 +02:00
}
#[ test ]
fn rpc_eth_block_number ( ) {
let tester = EthTester ::default ( ) ;
tester . client . add_blocks ( 10 , EachBlockWith ::Nothing ) ;
let request = r # "{"jsonrpc": "2.0", "method": "eth_blockNumber", "params": [], "id": 1}"# ;
2016-09-02 11:38:16 +02:00
let response = r # "{"jsonrpc":"2.0","result":"0xa","id":1}"# ;
2016-05-26 16:59:59 +02:00
2016-09-01 12:00:00 +02:00
assert_eq! ( tester . io . handle_request_sync ( request ) , Some ( response . to_owned ( ) ) ) ;
2016-05-26 16:59:59 +02:00
}
#[ test ]
fn rpc_eth_balance ( ) {
let tester = EthTester ::default ( ) ;
tester . client . set_balance ( Address ::from ( 1 ) , U256 ::from ( 5 ) ) ;
let request = r #" {
" jsonrpc " : " 2.0 " ,
" method " : " eth_getBalance " ,
" params " : [ " 0x0000000000000000000000000000000000000001 " , " latest " ] ,
" id " : 1
} " #;
2016-09-02 11:38:16 +02:00
let response = r # "{"jsonrpc":"2.0","result":"0x5","id":1}"# ;
2016-05-26 16:59:59 +02:00
2016-09-01 12:00:00 +02:00
assert_eq! ( tester . io . handle_request_sync ( request ) , Some ( response . to_owned ( ) ) ) ;
2016-05-26 16:59:59 +02:00
}
#[ test ]
fn rpc_eth_balance_pending ( ) {
let tester = EthTester ::default ( ) ;
2016-05-29 17:07:39 +02:00
tester . client . set_balance ( Address ::from ( 1 ) , U256 ::from ( 5 ) ) ;
2016-05-26 16:59:59 +02:00
let request = r #" {
" jsonrpc " : " 2.0 " ,
" method " : " eth_getBalance " ,
2016-05-29 17:07:39 +02:00
" params " : [ " 0x0000000000000000000000000000000000000001 " , " pending " ] ,
2016-05-26 16:59:59 +02:00
" id " : 1
} " #;
2016-05-29 17:07:39 +02:00
// 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.
2016-09-02 11:38:16 +02:00
let response = r # "{"jsonrpc":"2.0","result":"0x0","id":1}"# ;
2016-05-26 16:59:59 +02:00
2016-09-01 12:00:00 +02:00
assert_eq! ( tester . io . handle_request_sync ( request ) , Some ( response . to_owned ( ) ) ) ;
2016-05-26 16:59:59 +02:00
}
#[ test ]
fn rpc_eth_storage_at ( ) {
let tester = EthTester ::default ( ) ;
tester . client . set_storage ( Address ::from ( 1 ) , H256 ::from ( 4 ) , H256 ::from ( 7 ) ) ;
let request = r #" {
" jsonrpc " : " 2.0 " ,
" method " : " eth_getStorageAt " ,
" params " : [ " 0x0000000000000000000000000000000000000001 " , " 0x4 " , " latest " ] ,
" id " : 1
} " #;
2016-07-30 23:42:52 +02:00
let response = r # "{"jsonrpc":"2.0","result":"0x0000000000000000000000000000000000000000000000000000000000000007","id":1}"# ;
2016-05-26 16:59:59 +02:00
2016-09-01 12:00:00 +02:00
assert_eq! ( tester . io . handle_request_sync ( request ) , Some ( response . to_owned ( ) ) ) ;
2016-05-26 16:59:59 +02:00
}
#[ test ]
fn rpc_eth_transaction_count ( ) {
let request = r #" {
" jsonrpc " : " 2.0 " ,
" method " : " eth_getTransactionCount " ,
" params " : [ " 0x0000000000000000000000000000000000000001 " , " latest " ] ,
" id " : 1
} " #;
2016-09-02 11:38:16 +02:00
let response = r # "{"jsonrpc":"2.0","result":"0x0","id":1}"# ;
2016-05-26 16:59:59 +02:00
2016-09-01 12:00:00 +02:00
assert_eq! ( EthTester ::default ( ) . io . handle_request_sync ( request ) , Some ( response . to_owned ( ) ) ) ;
2016-05-26 16:59:59 +02:00
}
#[ test ]
fn rpc_eth_block_transaction_count_by_hash ( ) {
let request = r #" {
" jsonrpc " : " 2.0 " ,
" method " : " eth_getBlockTransactionCountByHash " ,
" params " : [ " 0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238 " ] ,
" id " : 1
} " #;
let response = r # "{"jsonrpc":"2.0","result":null,"id":1}"# ;
2016-09-01 12:00:00 +02:00
assert_eq! ( EthTester ::default ( ) . io . handle_request_sync ( request ) , Some ( response . to_owned ( ) ) ) ;
2016-05-26 16:59:59 +02:00
}
#[ test ]
fn rpc_eth_transaction_count_by_number ( ) {
let request = r #" {
" jsonrpc " : " 2.0 " ,
" method " : " eth_getBlockTransactionCountByNumber " ,
" params " : [ " latest " ] ,
" id " : 1
} " #;
2016-09-02 11:38:16 +02:00
let response = r # "{"jsonrpc":"2.0","result":"0x0","id":1}"# ;
2016-05-26 16:59:59 +02:00
2016-09-01 12:00:00 +02:00
assert_eq! ( EthTester ::default ( ) . io . handle_request_sync ( request ) , Some ( response . to_owned ( ) ) ) ;
2016-05-26 16:59:59 +02:00
}
#[ test ]
fn rpc_eth_transaction_count_by_number_pending ( ) {
let request = r #" {
" jsonrpc " : " 2.0 " ,
" method " : " eth_getBlockTransactionCountByNumber " ,
" params " : [ " pending " ] ,
" id " : 1
} " #;
2016-09-02 11:38:16 +02:00
let response = r # "{"jsonrpc":"2.0","result":"0x1","id":1}"# ;
2016-05-26 16:59:59 +02:00
2016-09-01 12:00:00 +02:00
assert_eq! ( EthTester ::default ( ) . io . handle_request_sync ( request ) , Some ( response . to_owned ( ) ) ) ;
2016-05-26 16:59:59 +02:00
}
#[ test ]
fn rpc_eth_pending_transaction_by_hash ( ) {
use util ::* ;
use ethcore ::transaction ::* ;
let tester = EthTester ::default ( ) ;
{
2016-09-01 14:49:12 +02:00
let tx : SignedTransaction = ::rlp ::decode ( & FromHex ::from_hex ( " f85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804 " ) . unwrap ( ) ) ;
2016-07-13 19:59:59 +02:00
tester . miner . pending_transactions . lock ( ) . insert ( H256 ::zero ( ) , tx ) ;
2016-05-26 16:59:59 +02:00
}
2016-12-15 18:19:19 +01:00
let response = r # "{"jsonrpc":"2.0","result":{"blockHash":null,"blockNumber":null,"creates":null,"from":"0x0f65fe9276bc9a24ae7083ae28e2660ef72df99e","gas":"0x5208","gasPrice":"0x1","hash":"0x41df922fd0d4766fcc02e161f8295ec28522f329ae487f14d811e4b64c8d6e31","input":"0x","minBlock":null,"networkId":null,"nonce":"0x0","publicKey":"0x7ae46da747962c2ee46825839c1ef9298e3bd2e70ca2938495c3693a485ec3eaa8f196327881090ff64cf4fbb0a48485d4f83098e189ed3b7a87d5941b59f789","r":"0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353","raw":"0xf85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804","s":"0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804","standardV":"0x0","to":"0x095e7baea6a6c7c4c2dfeb977efac326af552d87","transactionIndex":null,"v":"0x1b","value":"0xa"},"id":1}"# ;
2016-05-26 16:59:59 +02:00
let request = r #" {
" jsonrpc " : " 2.0 " ,
" method " : " eth_getTransactionByHash " ,
" params " : [ " 0x0000000000000000000000000000000000000000000000000000000000000000 " ] ,
" id " : 1
} " #;
2016-09-01 12:00:00 +02:00
assert_eq! ( tester . io . handle_request_sync ( request ) , Some ( response . to_owned ( ) ) ) ;
2016-05-26 16:59:59 +02:00
}
#[ test ]
fn rpc_eth_uncle_count_by_block_hash ( ) {
let request = r #" {
" jsonrpc " : " 2.0 " ,
" method " : " eth_getUncleCountByBlockHash " ,
" params " : [ " 0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238 " ] ,
" id " : 1
} " #;
let response = r # "{"jsonrpc":"2.0","result":null,"id":1}"# ;
2016-09-01 12:00:00 +02:00
assert_eq! ( EthTester ::default ( ) . io . handle_request_sync ( request ) , Some ( response . to_owned ( ) ) ) ;
2016-05-26 16:59:59 +02:00
}
#[ test ]
fn rpc_eth_uncle_count_by_block_number ( ) {
let request = r #" {
" jsonrpc " : " 2.0 " ,
" method " : " eth_getUncleCountByBlockNumber " ,
" params " : [ " latest " ] ,
" id " : 1
} " #;
2016-09-02 11:38:16 +02:00
let response = r # "{"jsonrpc":"2.0","result":"0x0","id":1}"# ;
2016-05-26 16:59:59 +02:00
2016-09-01 12:00:00 +02:00
assert_eq! ( EthTester ::default ( ) . io . handle_request_sync ( request ) , Some ( response . to_owned ( ) ) ) ;
2016-05-26 16:59:59 +02:00
}
#[ test ]
fn rpc_eth_code ( ) {
let tester = EthTester ::default ( ) ;
tester . client . set_code ( Address ::from ( 1 ) , vec! [ 0xff , 0x21 ] ) ;
let request = r #" {
" jsonrpc " : " 2.0 " ,
" method " : " eth_getCode " ,
" params " : [ " 0x0000000000000000000000000000000000000001 " , " latest " ] ,
" id " : 1
} " #;
let response = r # "{"jsonrpc":"2.0","result":"0xff21","id":1}"# ;
2016-09-01 12:00:00 +02:00
assert_eq! ( tester . io . handle_request_sync ( request ) , Some ( response . to_owned ( ) ) ) ;
2016-05-26 16:59:59 +02:00
}
#[ test ]
2016-08-04 18:17:21 +02:00
fn rpc_eth_call_latest ( ) {
2016-05-26 16:59:59 +02:00
let tester = EthTester ::default ( ) ;
2016-08-04 18:17:21 +02:00
tester . client . set_execution_result ( Ok ( Executed {
2017-01-12 17:06:15 +01:00
exception : None ,
2016-05-26 16:59:59 +02:00
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 ] ,
2016-07-28 20:31:29 +02:00
trace : vec ! [ ] ,
2016-05-30 11:53:20 +02:00
vm_trace : None ,
2016-06-02 12:39:25 +02:00
state_diff : None ,
2016-08-04 18:17:21 +02:00
} ) ) ;
2016-05-26 16:59:59 +02:00
let request = r #" {
" jsonrpc " : " 2.0 " ,
" method " : " eth_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}"# ;
2016-09-01 12:00:00 +02:00
assert_eq! ( tester . io . handle_request_sync ( request ) , Some ( response . to_owned ( ) ) ) ;
2016-05-26 16:59:59 +02:00
}
2016-08-04 18:17:21 +02:00
#[ test ]
fn rpc_eth_call ( ) {
let tester = EthTester ::default ( ) ;
tester . client . set_execution_result ( Ok ( Executed {
2017-01-12 17:06:15 +01:00
exception : None ,
2016-08-04 18:17:21 +02:00
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 request = r #" {
" jsonrpc " : " 2.0 " ,
" method " : " eth_call " ,
" params " : [ {
" from " : " 0xb60e8dd61c5d32be8058bb8eb970870f07233155 " ,
" to " : " 0xd46e8dd67c5d32be8058bb8eb970870f07244567 " ,
" gas " : " 0x76c0 " ,
" gasPrice " : " 0x9184e72a000 " ,
" value " : " 0x9184e72a " ,
" data " : " 0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675 "
} ,
" 0x0 " ] ,
" id " : 1
} " #;
let response = r # "{"jsonrpc":"2.0","result":"0x1234ff","id":1}"# ;
2016-09-01 12:00:00 +02:00
assert_eq! ( tester . io . handle_request_sync ( request ) , Some ( response . to_owned ( ) ) ) ;
2016-08-04 18:17:21 +02:00
}
2016-05-26 16:59:59 +02:00
#[ test ]
fn rpc_eth_call_default_block ( ) {
let tester = EthTester ::default ( ) ;
2016-08-04 18:17:21 +02:00
tester . client . set_execution_result ( Ok ( Executed {
2017-01-12 17:06:15 +01:00
exception : None ,
2016-05-26 16:59:59 +02:00
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 ] ,
2016-07-28 20:31:29 +02:00
trace : vec ! [ ] ,
2016-05-30 11:53:20 +02:00
vm_trace : None ,
2016-06-02 12:39:25 +02:00
state_diff : None ,
2016-08-04 18:17:21 +02:00
} ) ) ;
2016-05-26 16:59:59 +02:00
let request = r #" {
" jsonrpc " : " 2.0 " ,
" method " : " eth_call " ,
" params " : [ {
" from " : " 0xb60e8dd61c5d32be8058bb8eb970870f07233155 " ,
" to " : " 0xd46e8dd67c5d32be8058bb8eb970870f07244567 " ,
" gas " : " 0x76c0 " ,
" gasPrice " : " 0x9184e72a000 " ,
" value " : " 0x9184e72a " ,
" data " : " 0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675 "
} ] ,
" id " : 1
} " #;
let response = r # "{"jsonrpc":"2.0","result":"0x1234ff","id":1}"# ;
2016-09-01 12:00:00 +02:00
assert_eq! ( tester . io . handle_request_sync ( request ) , Some ( response . to_owned ( ) ) ) ;
2016-05-26 16:59:59 +02:00
}
#[ test ]
fn rpc_eth_estimate_gas ( ) {
let tester = EthTester ::default ( ) ;
2016-08-04 18:17:21 +02:00
tester . client . set_execution_result ( Ok ( Executed {
2017-01-12 17:06:15 +01:00
exception : None ,
2016-05-26 16:59:59 +02:00
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 ] ,
2016-07-28 20:31:29 +02:00
trace : vec ! [ ] ,
2016-05-30 11:53:20 +02:00
vm_trace : None ,
2016-06-02 12:39:25 +02:00
state_diff : None ,
2016-08-04 18:17:21 +02:00
} ) ) ;
2016-05-26 16:59:59 +02:00
let request = r #" {
" jsonrpc " : " 2.0 " ,
" method " : " eth_estimateGas " ,
" params " : [ {
" from " : " 0xb60e8dd61c5d32be8058bb8eb970870f07233155 " ,
" to " : " 0xd46e8dd67c5d32be8058bb8eb970870f07244567 " ,
" gas " : " 0x76c0 " ,
" gasPrice " : " 0x9184e72a000 " ,
" value " : " 0x9184e72a " ,
" data " : " 0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675 "
} ,
" latest " ] ,
" id " : 1
} " #;
2017-01-11 20:03:08 +01:00
let response = r # "{"jsonrpc":"2.0","result":"0x5208","id":1}"# ;
2016-05-26 16:59:59 +02:00
2016-09-01 12:00:00 +02:00
assert_eq! ( tester . io . handle_request_sync ( request ) , Some ( response . to_owned ( ) ) ) ;
2016-05-26 16:59:59 +02:00
}
#[ test ]
fn rpc_eth_estimate_gas_default_block ( ) {
let tester = EthTester ::default ( ) ;
2016-08-04 18:17:21 +02:00
tester . client . set_execution_result ( Ok ( Executed {
2017-01-12 17:06:15 +01:00
exception : None ,
2016-05-26 16:59:59 +02:00
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 ] ,
2016-07-28 20:31:29 +02:00
trace : vec ! [ ] ,
2016-05-30 11:53:20 +02:00
vm_trace : None ,
2016-06-02 12:39:25 +02:00
state_diff : None ,
2016-08-04 18:17:21 +02:00
} ) ) ;
2016-05-26 16:59:59 +02:00
let request = r #" {
" jsonrpc " : " 2.0 " ,
" method " : " eth_estimateGas " ,
" params " : [ {
" from " : " 0xb60e8dd61c5d32be8058bb8eb970870f07233155 " ,
" to " : " 0xd46e8dd67c5d32be8058bb8eb970870f07244567 " ,
" gas " : " 0x76c0 " ,
" gasPrice " : " 0x9184e72a000 " ,
" value " : " 0x9184e72a " ,
" data " : " 0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675 "
} ] ,
" id " : 1
} " #;
2017-01-11 20:03:08 +01:00
let response = r # "{"jsonrpc":"2.0","result":"0x5208","id":1}"# ;
2016-05-26 16:59:59 +02:00
2016-09-01 12:00:00 +02:00
assert_eq! ( tester . io . handle_request_sync ( request ) , Some ( response . to_owned ( ) ) ) ;
2016-05-26 16:59:59 +02:00
}
#[ test ]
fn rpc_eth_send_transaction ( ) {
let tester = EthTester ::default ( ) ;
2016-06-20 00:10:34 +02:00
let address = tester . accounts_provider . new_account ( " " ) . unwrap ( ) ;
tester . accounts_provider . unlock_account_permanently ( address , " " . into ( ) ) . unwrap ( ) ;
2016-05-26 16:59:59 +02:00
let request = r #" {
" jsonrpc " : " 2.0 " ,
" method " : " eth_sendTransaction " ,
" params " : [ {
" from " : " " #. to_owned ( ) + format! ( " 0x {:?} " , address ) . as_ref ( ) + r #" " ,
" to " : " 0xd46e8dd67c5d32be8058bb8eb970870f07244567 " ,
" gas " : " 0x76c0 " ,
" gasPrice " : " 0x9184e72a000 " ,
" value " : " 0x9184e72a "
} ] ,
" id " : 1
} " #;
let t = Transaction {
nonce : U256 ::zero ( ) ,
gas_price : U256 ::from ( 0x9184e72a000 u64 ) ,
gas : U256 ::from ( 0x76c0 ) ,
action : Action ::Call ( Address ::from_str ( " d46e8dd67c5d32be8058bb8eb970870f07244567 " ) . unwrap ( ) ) ,
value : U256 ::from ( 0x9184e72a u64 ) ,
data : vec ! [ ]
2016-06-20 00:10:34 +02:00
} ;
2016-11-03 22:22:25 +01:00
let signature = tester . accounts_provider . sign ( address , None , t . hash ( None ) ) . unwrap ( ) ;
let t = t . with_signature ( signature , None ) ;
2016-05-26 16:59:59 +02:00
let response = r # "{"jsonrpc":"2.0","result":""# . to_owned ( ) + format! ( " 0x {:?} " , t . hash ( ) ) . as_ref ( ) + r # "","id":1}"# ;
2016-09-01 12:00:00 +02:00
assert_eq! ( tester . io . handle_request_sync ( & request ) , Some ( response ) ) ;
2016-05-26 16:59:59 +02:00
2016-07-13 19:59:59 +02:00
tester . miner . last_nonces . write ( ) . insert ( address . clone ( ) , U256 ::zero ( ) ) ;
2016-05-26 16:59:59 +02:00
let t = Transaction {
nonce : U256 ::one ( ) ,
gas_price : U256 ::from ( 0x9184e72a000 u64 ) ,
gas : U256 ::from ( 0x76c0 ) ,
action : Action ::Call ( Address ::from_str ( " d46e8dd67c5d32be8058bb8eb970870f07244567 " ) . unwrap ( ) ) ,
value : U256 ::from ( 0x9184e72a u64 ) ,
data : vec ! [ ]
2016-06-20 00:10:34 +02:00
} ;
2016-11-03 22:22:25 +01:00
let signature = tester . accounts_provider . sign ( address , None , t . hash ( None ) ) . unwrap ( ) ;
let t = t . with_signature ( signature , None ) ;
2016-05-26 16:59:59 +02:00
let response = r # "{"jsonrpc":"2.0","result":""# . to_owned ( ) + format! ( " 0x {:?} " , t . hash ( ) ) . as_ref ( ) + r # "","id":1}"# ;
2016-09-01 12:00:00 +02:00
assert_eq! ( tester . io . handle_request_sync ( & request ) , Some ( response ) ) ;
2016-05-26 16:59:59 +02:00
}
2016-11-09 13:13:35 +01:00
#[ test ]
fn rpc_eth_sign_transaction ( ) {
let tester = EthTester ::default ( ) ;
let address = tester . accounts_provider . new_account ( " " ) . unwrap ( ) ;
tester . accounts_provider . unlock_account_permanently ( address , " " . into ( ) ) . unwrap ( ) ;
let request = r #" {
" jsonrpc " : " 2.0 " ,
" method " : " eth_signTransaction " ,
" params " : [ {
" from " : " " #. to_owned ( ) + format! ( " 0x {:?} " , address ) . as_ref ( ) + r #" " ,
" to " : " 0xd46e8dd67c5d32be8058bb8eb970870f07244567 " ,
" gas " : " 0x76c0 " ,
" gasPrice " : " 0x9184e72a000 " ,
" value " : " 0x9184e72a "
} ] ,
" id " : 1
} " #;
let t = Transaction {
nonce : U256 ::one ( ) ,
gas_price : U256 ::from ( 0x9184e72a000 u64 ) ,
gas : U256 ::from ( 0x76c0 ) ,
action : Action ::Call ( Address ::from_str ( " d46e8dd67c5d32be8058bb8eb970870f07244567 " ) . unwrap ( ) ) ,
value : U256 ::from ( 0x9184e72a u64 ) ,
data : vec ! [ ]
} ;
let signature = tester . accounts_provider . sign ( address , None , t . hash ( None ) ) . unwrap ( ) ;
let t = t . with_signature ( signature , None ) ;
2016-11-18 11:03:29 +01:00
let signature = t . signature ( ) ;
2016-11-09 13:13:35 +01:00
let rlp = rlp ::encode ( & t ) ;
2016-11-18 11:03:29 +01:00
let response = r # "{"jsonrpc":"2.0","result":{"# . to_owned ( ) +
r # ""raw":"0x"# + & rlp . to_hex ( ) + r # "","# +
r # ""tx":{"# +
r # ""blockHash":null,"blockNumber":null,"creates":null,"# +
& format! ( " \" from \" : \" 0x {:?} \" , " , & address ) +
r # ""gas":"0x76c0","gasPrice":"0x9184e72a000","# +
& format! ( " \" hash \" : \" 0x {:?} \" , " , t . hash ( ) ) +
2016-11-27 14:49:30 +01:00
r # ""input":"0x","# +
2016-12-15 18:19:19 +01:00
r # ""minBlock":null,"# +
2016-11-27 14:49:30 +01:00
& format! ( " \" networkId \" : {} , " , t . network_id ( ) . map_or ( " null " . to_owned ( ) , | n | format! ( " {} " , n ) ) ) +
r # ""nonce":"0x1","# +
2016-11-18 11:03:29 +01:00
& format! ( " \" publicKey \" : \" 0x {:?} \" , " , t . public_key ( ) . unwrap ( ) ) +
2016-11-29 13:46:06 +01:00
& format! ( " \" r \" : \" 0x {} \" , " , U256 ::from ( signature . r ( ) ) . to_hex ( ) ) +
2016-11-18 11:03:29 +01:00
& format! ( " \" raw \" : \" 0x {} \" , " , rlp . to_hex ( ) ) +
2016-11-29 13:46:06 +01:00
& format! ( " \" s \" : \" 0x {} \" , " , U256 ::from ( signature . s ( ) ) . to_hex ( ) ) +
& format! ( " \" standardV \" : \" 0x {} \" , " , U256 ::from ( t . standard_v ( ) ) . to_hex ( ) ) +
2016-11-18 11:03:29 +01:00
r # ""to":"0xd46e8dd67c5d32be8058bb8eb970870f07244567","transactionIndex":null,"# +
2016-11-29 13:46:06 +01:00
& format! ( " \" v \" : \" 0x {} \" , " , U256 ::from ( t . original_v ( ) ) . to_hex ( ) ) +
2016-11-18 11:03:29 +01:00
r # ""value":"0x9184e72a""# +
r # "}},"id":1}"# ;
2016-11-09 13:13:35 +01:00
tester . miner . last_nonces . write ( ) . insert ( address . clone ( ) , U256 ::zero ( ) ) ;
assert_eq! ( tester . io . handle_request_sync ( & request ) , Some ( response ) ) ;
}
2016-07-20 12:42:12 +02:00
#[ test ]
fn rpc_eth_send_transaction_with_bad_to ( ) {
let tester = EthTester ::default ( ) ;
let address = tester . accounts_provider . new_account ( " " ) . unwrap ( ) ;
let request = r #" {
" jsonrpc " : " 2.0 " ,
" method " : " eth_sendTransaction " ,
" params " : [ {
" from " : " " #. to_owned ( ) + format! ( " 0x {:?} " , address ) . as_ref ( ) + r #" " ,
" to " : " " ,
" gas " : " 0x76c0 " ,
" gasPrice " : " 0x9184e72a000 " ,
" value " : " 0x9184e72a "
} ] ,
" id " : 1
} " #;
let response = r # "{"jsonrpc":"2.0","error":{"code":-32602,"message":"Invalid params","data":null},"id":1}"# ;
2016-09-01 12:00:00 +02:00
assert_eq! ( tester . io . handle_request_sync ( & request ) , Some ( response . into ( ) ) ) ;
2016-07-20 12:42:12 +02:00
}
2016-05-26 16:59:59 +02:00
2016-07-20 12:37:49 +02:00
#[ test ]
fn rpc_eth_send_transaction_error ( ) {
let tester = EthTester ::default ( ) ;
let address = tester . accounts_provider . new_account ( " " ) . unwrap ( ) ;
let request = r #" {
" jsonrpc " : " 2.0 " ,
" method " : " eth_sendTransaction " ,
" params " : [ {
" from " : " " #. to_owned ( ) + format! ( " 0x {:?} " , address ) . as_ref ( ) + r #" " ,
" to " : " 0xd46e8dd67c5d32be8058bb8eb970870f07244567 " ,
" gas " : " 0x76c0 " ,
" gasPrice " : " 0x9184e72a000 " ,
" value " : " 0x9184e72a "
} ] ,
" id " : 1
} " #;
let response = r # "{"jsonrpc":"2.0","error":{"code":-32020,"message":"Your account is locked. Unlock the account via CLI, personal_unlockAccount or use Trusted Signer.","data":"NotUnlocked"},"id":1}"# ;
2016-09-01 12:00:00 +02:00
assert_eq! ( tester . io . handle_request_sync ( & request ) , Some ( response . into ( ) ) ) ;
2016-07-20 12:37:49 +02:00
}
2016-11-04 18:33:10 +01:00
#[ test ]
fn rpc_eth_send_raw_transaction_error ( ) {
let tester = EthTester ::default ( ) ;
let req = r #" {
" jsonrpc " : " 2.0 " ,
" method " : " eth_sendRawTransaction " ,
" params " : [
" 0x0123 "
] ,
" id " : 1
} " #;
let res = r # "{"jsonrpc":"2.0","error":{"code":-32602,"message":"Invalid RLP.","data":"RlpIncorrectListLen"},"id":1}"# . into ( ) ;
assert_eq! ( tester . io . handle_request_sync ( & req ) , Some ( res ) ) ;
}
2016-05-26 16:59:59 +02:00
#[ test ]
fn rpc_eth_send_raw_transaction ( ) {
2016-05-29 17:07:39 +02:00
let tester = EthTester ::default ( ) ;
let address = tester . accounts_provider . new_account ( " abcd " ) . unwrap ( ) ;
2016-06-20 00:10:34 +02:00
tester . accounts_provider . unlock_account_permanently ( address , " abcd " . into ( ) ) . unwrap ( ) ;
2016-05-26 16:59:59 +02:00
2016-05-29 17:07:39 +02:00
let t = Transaction {
nonce : U256 ::zero ( ) ,
gas_price : U256 ::from ( 0x9184e72a000 u64 ) ,
gas : U256 ::from ( 0x76c0 ) ,
action : Action ::Call ( Address ::from_str ( " d46e8dd67c5d32be8058bb8eb970870f07244567 " ) . unwrap ( ) ) ,
value : U256 ::from ( 0x9184e72a u64 ) ,
data : vec ! [ ]
2016-06-20 00:10:34 +02:00
} ;
2016-11-03 22:22:25 +01:00
let signature = tester . accounts_provider . sign ( address , None , t . hash ( None ) ) . unwrap ( ) ;
let t = t . with_signature ( signature , None ) ;
2016-05-29 17:07:39 +02:00
2016-11-09 13:13:35 +01:00
let rlp = rlp ::encode ( & t ) . to_vec ( ) . to_hex ( ) ;
2016-05-29 17:07:39 +02:00
let req = r #" {
" jsonrpc " : " 2.0 " ,
" method " : " eth_sendRawTransaction " ,
" params " : [
" 0x " #. to_owned ( ) + & rlp + r #" "
] ,
" id " : 1
} " #;
let res = r # "{"jsonrpc":"2.0","result":""# . to_owned ( ) + & format! ( " 0x {:?} " , t . hash ( ) ) + r # "","id":1}"# ;
2016-09-01 12:00:00 +02:00
assert_eq! ( tester . io . handle_request_sync ( & req ) , Some ( res ) ) ;
2016-05-26 16:59:59 +02:00
}
#[ test ]
fn rpc_eth_transaction_receipt ( ) {
let receipt = LocalizedReceipt {
transaction_hash : H256 ::zero ( ) ,
transaction_index : 0 ,
block_hash : H256 ::from_str ( " ed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5 " ) . unwrap ( ) ,
block_number : 0x4510c ,
cumulative_gas_used : U256 ::from ( 0x20 ) ,
gas_used : U256 ::from ( 0x10 ) ,
contract_address : None ,
logs : vec ! [ LocalizedLogEntry {
entry : LogEntry {
address : Address ::from_str ( " 33990122638b9132ca29c723bdf037f1a891a70c " ) . unwrap ( ) ,
topics : vec ! [
H256 ::from_str ( " a6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc " ) . unwrap ( ) ,
H256 ::from_str ( " 4861736852656700000000000000000000000000000000000000000000000000 " ) . unwrap ( )
] ,
data : vec ! [ ] ,
} ,
block_hash : H256 ::from_str ( " ed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5 " ) . unwrap ( ) ,
block_number : 0x4510c ,
transaction_hash : H256 ::new ( ) ,
transaction_index : 0 ,
2016-12-29 19:48:28 +01:00
transaction_log_index : 0 ,
2016-05-26 16:59:59 +02:00
log_index : 1 ,
2016-11-04 12:33:13 +01:00
} ] ,
log_bloom : 0. into ( ) ,
state_root : 0. into ( ) ,
2016-05-26 16:59:59 +02:00
} ;
let hash = H256 ::from_str ( " b903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238 " ) . unwrap ( ) ;
let tester = EthTester ::default ( ) ;
2016-12-09 23:01:43 +01:00
tester . client . set_transaction_receipt ( TransactionId ::Hash ( hash ) , receipt ) ;
2016-05-26 16:59:59 +02:00
let request = r #" {
" jsonrpc " : " 2.0 " ,
" method " : " eth_getTransactionReceipt " ,
" params " : [ " 0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238 " ] ,
" id " : 1
} " #;
2016-12-29 19:48:28 +01:00
let response = r # "{"jsonrpc":"2.0","result":{"blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","contractAddress":null,"cumulativeGasUsed":"0x20","gasUsed":"0x10","logs":[{"address":"0x33990122638b9132ca29c723bdf037f1a891a70c","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x4510c","data":"0x","logIndex":"0x1","topics":["0xa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc","0x4861736852656700000000000000000000000000000000000000000000000000"],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0","transactionLogIndex":"0x0","type":"mined"}],"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","root":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x0"},"id":1}"# ;
2016-05-26 16:59:59 +02:00
2016-09-01 12:00:00 +02:00
assert_eq! ( tester . io . handle_request_sync ( request ) , Some ( response . to_owned ( ) ) ) ;
2016-05-26 16:59:59 +02:00
}
#[ test ]
fn rpc_eth_transaction_receipt_null ( ) {
let tester = EthTester ::default ( ) ;
let request = r #" {
" jsonrpc " : " 2.0 " ,
" method " : " eth_getTransactionReceipt " ,
" params " : [ " 0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238 " ] ,
" id " : 1
} " #;
let response = r # "{"jsonrpc":"2.0","result":null,"id":1}"# ;
2016-09-01 12:00:00 +02:00
assert_eq! ( tester . io . handle_request_sync ( request ) , Some ( response . to_owned ( ) ) ) ;
2016-05-26 16:59:59 +02:00
}
2016-07-19 20:40:18 +02:00
// These tests are incorrect: their output is undefined as long as eth_getCompilers is [].
// Will ignore for now, but should probably be replaced by more substantial tests which check
// the output of eth_getCompilers to determine whether to test. CI systems can then be preinstalled
// with solc/serpent/lllc and they'll be proper again.
#[ ignore ]
2016-05-26 16:59:59 +02:00
#[ test ]
fn rpc_eth_compilers ( ) {
let request = r # "{"jsonrpc": "2.0", "method": "eth_getCompilers", "params": [], "id": 1}"# ;
let response = r # "{"jsonrpc":"2.0","result":[],"id":1}"# ;
2016-09-01 12:00:00 +02:00
assert_eq! ( EthTester ::default ( ) . io . handle_request_sync ( request ) , Some ( response . to_owned ( ) ) ) ;
2016-05-26 16:59:59 +02:00
}
2016-07-14 14:25:44 +02:00
#[ ignore ]
2016-05-26 16:59:59 +02:00
#[ test ]
fn rpc_eth_compile_lll ( ) {
let request = r # "{"jsonrpc": "2.0", "method": "eth_compileLLL", "params": [], "id": 1}"# ;
let response = r # "{"jsonrpc":"2.0","error":{"code":-32603,"message":"Internal error","data":null},"id":1}"# ;
2016-09-01 12:00:00 +02:00
assert_eq! ( EthTester ::default ( ) . io . handle_request_sync ( request ) , Some ( response . to_owned ( ) ) ) ;
2016-05-26 16:59:59 +02:00
}
2016-07-14 14:25:44 +02:00
#[ ignore ]
2016-05-26 16:59:59 +02:00
#[ test ]
fn rpc_eth_compile_solidity ( ) {
let request = r # "{"jsonrpc": "2.0", "method": "eth_compileSolidity", "params": [], "id": 1}"# ;
let response = r # "{"jsonrpc":"2.0","error":{"code":-32603,"message":"Internal error","data":null},"id":1}"# ;
2016-09-01 12:00:00 +02:00
assert_eq! ( EthTester ::default ( ) . io . handle_request_sync ( request ) , Some ( response . to_owned ( ) ) ) ;
2016-05-26 16:59:59 +02:00
}
2016-07-14 14:25:44 +02:00
#[ ignore ]
2016-05-26 16:59:59 +02:00
#[ test ]
fn rpc_eth_compile_serpent ( ) {
let request = r # "{"jsonrpc": "2.0", "method": "eth_compileSerpent", "params": [], "id": 1}"# ;
let response = r # "{"jsonrpc":"2.0","error":{"code":-32603,"message":"Internal error","data":null},"id":1}"# ;
2016-09-01 12:00:00 +02:00
assert_eq! ( EthTester ::default ( ) . io . handle_request_sync ( request ) , Some ( response . to_owned ( ) ) ) ;
2016-05-26 16:59:59 +02:00
}
#[ test ]
2016-08-23 17:07:00 +02:00
fn rpc_get_work_returns_no_work_if_cant_mine ( ) {
2016-05-26 16:59:59 +02:00
let eth_tester = EthTester ::default ( ) ;
eth_tester . client . set_queue_size ( 10 ) ;
let request = r # "{"jsonrpc": "2.0", "method": "eth_getWork", "params": [], "id": 1}"# ;
2016-06-15 01:26:58 +02:00
let response = r # "{"jsonrpc":"2.0","error":{"code":-32001,"message":"Still syncing.","data":null},"id":1}"# ;
2016-05-26 16:59:59 +02:00
2016-09-01 12:00:00 +02:00
assert_eq! ( eth_tester . io . handle_request_sync ( request ) , Some ( response . to_owned ( ) ) ) ;
2016-05-26 16:59:59 +02:00
}
#[ test ]
2016-08-23 17:07:00 +02:00
fn rpc_get_work_returns_correct_work_package ( ) {
2016-05-26 16:59:59 +02:00
let eth_tester = EthTester ::default ( ) ;
2016-07-14 12:16:53 +02:00
eth_tester . miner . set_author ( Address ::from_str ( " d46e8dd67c5d32be8058bb8eb970870f07244567 " ) . unwrap ( ) ) ;
2016-05-26 16:59:59 +02:00
let request = r # "{"jsonrpc": "2.0", "method": "eth_getWork", "params": [], "id": 1}"# ;
2016-09-02 11:38:16 +02:00
let response = r # "{"jsonrpc":"2.0","result":["0x3bbe93f74e7b97ae00784aeff8819c5cb600dd87e8b282a5d3446f3f871f0347","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000800000000000000000000000000000000000000000000000000000000000","0x1"],"id":1}"# ;
2016-08-03 15:31:00 +02:00
2016-09-01 12:00:00 +02:00
assert_eq! ( eth_tester . io . handle_request_sync ( request ) , Some ( response . to_owned ( ) ) ) ;
2016-08-03 15:31:00 +02:00
}
#[ test ]
2016-08-23 17:07:00 +02:00
fn rpc_get_work_should_not_return_block_number ( ) {
2016-08-03 15:31:00 +02:00
let eth_tester = EthTester ::new_with_options ( EthClientOptions {
allow_pending_receipt_query : true ,
send_block_number_in_get_work : false ,
} ) ;
eth_tester . miner . set_author ( Address ::from_str ( " d46e8dd67c5d32be8058bb8eb970870f07244567 " ) . unwrap ( ) ) ;
let request = r # "{"jsonrpc": "2.0", "method": "eth_getWork", "params": [], "id": 1}"# ;
let response = r # "{"jsonrpc":"2.0","result":["0x3bbe93f74e7b97ae00784aeff8819c5cb600dd87e8b282a5d3446f3f871f0347","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000800000000000000000000000000000000000000000000000000000000000"],"id":1}"# ;
2016-05-26 16:59:59 +02:00
2016-09-01 12:00:00 +02:00
assert_eq! ( eth_tester . io . handle_request_sync ( request ) , Some ( response . to_owned ( ) ) ) ;
2016-05-26 16:59:59 +02:00
}
2016-08-23 17:07:00 +02:00
#[ test ]
fn rpc_get_work_should_timeout ( ) {
let eth_tester = EthTester ::default ( ) ;
eth_tester . miner . set_author ( Address ::from_str ( " d46e8dd67c5d32be8058bb8eb970870f07244567 " ) . unwrap ( ) ) ;
eth_tester . client . set_latest_block_timestamp ( get_time ( ) . sec as u64 - 1000 ) ; // Set latest block to 1000 seconds ago
let hash = eth_tester . miner . map_sealing_work ( & * eth_tester . client , | b | b . hash ( ) ) . unwrap ( ) ;
2016-08-24 13:20:15 +02:00
// Request without providing timeout. This should work since we're disabling timeout.
2016-08-23 17:07:00 +02:00
let request = r # "{"jsonrpc": "2.0", "method": "eth_getWork", "params": [], "id": 1}"# ;
let work_response = format! (
2016-09-02 11:38:16 +02:00
r # "{{"jsonrpc":"2.0","result":["0x{:?}","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000800000000000000000000000000000000000000000000000000000000000","0x1"],"id":1}}"# ,
2016-08-23 17:07:00 +02:00
hash ,
) ;
2016-09-01 12:00:00 +02:00
assert_eq! ( eth_tester . io . handle_request_sync ( request ) , Some ( work_response . to_owned ( ) ) ) ;
2016-08-23 17:07:00 +02:00
2016-08-24 13:20:15 +02:00
// Request with timeout of 0 seconds. This should work since we're disabling timeout.
let request = r # "{"jsonrpc": "2.0", "method": "eth_getWork", "params": ["0"], "id": 1}"# ;
let work_response = format! (
2016-09-02 11:38:16 +02:00
r # "{{"jsonrpc":"2.0","result":["0x{:?}","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000800000000000000000000000000000000000000000000000000000000000","0x1"],"id":1}}"# ,
2016-08-24 13:20:15 +02:00
hash ,
) ;
2016-09-01 12:00:00 +02:00
assert_eq! ( eth_tester . io . handle_request_sync ( request ) , Some ( work_response . to_owned ( ) ) ) ;
2016-08-24 13:20:15 +02:00
2016-08-23 17:07:00 +02:00
// Request with timeout of 10K seconds. This should work.
let request = r # "{"jsonrpc": "2.0", "method": "eth_getWork", "params": ["10000"], "id": 1}"# ;
2016-09-01 12:00:00 +02:00
assert_eq! ( eth_tester . io . handle_request_sync ( request ) , Some ( work_response . to_owned ( ) ) ) ;
2016-08-23 17:07:00 +02:00
// Request with timeout of 10 seconds. This should fail.
let request = r # "{"jsonrpc": "2.0", "method": "eth_getWork", "params": ["10"], "id": 1}"# ;
let err_response = r # "{"jsonrpc":"2.0","error":{"code":-32003,"message":"Work has not changed.","data":null},"id":1}"# ;
2016-09-01 12:00:00 +02:00
assert_eq! ( eth_tester . io . handle_request_sync ( request ) , Some ( err_response . to_owned ( ) ) ) ;
2016-08-23 17:07:00 +02:00
}