2016-03-14 00:48:43 +01:00
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std ::sync ::Arc ;
2016-05-26 20:10:15 +02:00
use std ::str ::FromStr ;
2016-03-14 00:48:43 +01:00
use jsonrpc_core ::IoHandler ;
2016-08-03 18:05:17 +02:00
use util ::{ U256 , Uint , Address } ;
2016-06-20 00:10:34 +02:00
use ethcore ::account_provider ::AccountProvider ;
2016-10-27 19:26:34 +02:00
use v1 ::{ PersonalClient , PersonalAccountsClient , PersonalAccounts , Personal } ;
2016-05-26 20:10:15 +02:00
use v1 ::tests ::helpers ::TestMinerService ;
use ethcore ::client ::TestBlockChainClient ;
use ethcore ::transaction ::{ Action , Transaction } ;
struct PersonalTester {
2016-06-20 00:10:34 +02:00
accounts : Arc < AccountProvider > ,
2016-05-26 20:10:15 +02:00
io : IoHandler ,
miner : Arc < TestMinerService > ,
// these unused fields are necessary to keep the data alive
// as the handler has only weak pointers.
_client : Arc < TestBlockChainClient > ,
}
fn blockchain_client ( ) -> Arc < TestBlockChainClient > {
let client = TestBlockChainClient ::new ( ) ;
Arc ::new ( client )
}
2016-03-14 00:48:43 +01:00
2016-06-20 00:10:34 +02:00
fn accounts_provider ( ) -> Arc < AccountProvider > {
Arc ::new ( AccountProvider ::transient_provider ( ) )
2016-03-14 00:48:43 +01:00
}
2016-05-26 20:10:15 +02:00
fn miner_service ( ) -> Arc < TestMinerService > {
Arc ::new ( TestMinerService ::default ( ) )
}
2016-10-24 12:21:15 +02:00
fn setup ( ) -> PersonalTester {
2016-05-26 20:10:15 +02:00
let accounts = accounts_provider ( ) ;
let client = blockchain_client ( ) ;
let miner = miner_service ( ) ;
2016-10-27 19:26:34 +02:00
let personal = PersonalClient ::new ( & accounts , & client ) ;
let personal_accounts = PersonalAccountsClient ::new ( & accounts , & client , & miner , false ) ;
2016-05-26 20:10:15 +02:00
2016-03-14 00:48:43 +01:00
let io = IoHandler ::new ( ) ;
io . add_delegate ( personal . to_delegate ( ) ) ;
2016-10-27 19:26:34 +02:00
io . add_delegate ( personal_accounts . to_delegate ( ) ) ;
2016-05-26 20:10:15 +02:00
let tester = PersonalTester {
accounts : accounts ,
io : io ,
miner : miner ,
_client : client ,
} ;
tester
2016-03-14 00:48:43 +01:00
}
#[ test ]
fn accounts ( ) {
2016-10-24 12:21:15 +02:00
let tester = setup ( ) ;
2016-06-20 00:10:34 +02:00
let address = tester . accounts . new_account ( " " ) . unwrap ( ) ;
2016-03-14 00:48:43 +01:00
let request = r # "{"jsonrpc": "2.0", "method": "personal_listAccounts", "params": [], "id": 1}"# ;
2016-06-20 00:10:34 +02:00
let response = r # "{"jsonrpc":"2.0","result":[""# . to_owned ( ) + & format! ( " 0x {:?} " , address ) + r # ""],"id":1}"# ;
2016-03-14 00:48:43 +01:00
2016-09-01 12:00:00 +02:00
assert_eq! ( tester . io . handle_request_sync ( request ) , Some ( response . to_owned ( ) ) ) ;
2016-03-14 00:48:43 +01:00
}
2016-03-14 01:06:42 +01:00
#[ test ]
fn new_account ( ) {
2016-10-24 12:21:15 +02:00
let tester = setup ( ) ;
2016-03-14 01:06:42 +01:00
let request = r # "{"jsonrpc": "2.0", "method": "personal_newAccount", "params": ["pass"], "id": 1}"# ;
2016-09-01 12:00:00 +02:00
let res = tester . io . handle_request_sync ( request ) ;
2016-04-06 12:15:20 +02:00
2016-07-31 10:44:17 +02:00
let accounts = tester . accounts . accounts ( ) . unwrap ( ) ;
2016-04-06 12:15:20 +02:00
assert_eq! ( accounts . len ( ) , 1 ) ;
2016-06-20 00:10:34 +02:00
let address = accounts [ 0 ] ;
2016-04-06 12:15:20 +02:00
let response = r # "{"jsonrpc":"2.0","result":""# . to_owned ( ) + format! ( " 0x {:?} " , address ) . as_ref ( ) + r # "","id":1}"# ;
assert_eq! ( res , Some ( response ) ) ;
2016-03-14 01:06:42 +01:00
}
2016-07-24 17:38:21 +02:00
#[ test ]
fn should_be_able_to_get_account_info ( ) {
2016-10-24 12:21:15 +02:00
let tester = setup ( ) ;
2016-07-24 17:38:21 +02:00
tester . accounts . new_account ( " " ) . unwrap ( ) ;
2016-07-31 10:44:17 +02:00
let accounts = tester . accounts . accounts ( ) . unwrap ( ) ;
2016-07-24 17:38:21 +02:00
assert_eq! ( accounts . len ( ) , 1 ) ;
let address = accounts [ 0 ] ;
let uuid = tester . accounts . accounts_info ( ) . unwrap ( ) . get ( & address ) . unwrap ( ) . uuid . as_ref ( ) . unwrap ( ) . clone ( ) ;
tester . accounts . set_account_name ( address . clone ( ) , " Test " . to_owned ( ) ) . unwrap ( ) ;
tester . accounts . set_account_meta ( address . clone ( ) , " {foo: 69} " . to_owned ( ) ) . unwrap ( ) ;
let request = r # "{"jsonrpc": "2.0", "method": "personal_accountsInfo", "params": [], "id": 1}"# ;
2016-09-01 12:00:00 +02:00
let res = tester . io . handle_request_sync ( request ) ;
2016-07-24 17:38:21 +02:00
let response = format! ( " {{ \" jsonrpc \" : \" 2.0 \" , \" result \" : {{ \" 0x {} \" : {{ \" meta \" : \" {{ foo: 69 }} \" , \" name \" : \" Test \" , \" uuid \" : \" {} \" }} }} , \" id \" :1 }} " , address . hex ( ) , uuid ) ;
assert_eq! ( res , Some ( response ) ) ;
}
#[ test ]
fn should_be_able_to_set_name ( ) {
2016-10-24 12:21:15 +02:00
let tester = setup ( ) ;
2016-07-24 17:38:21 +02:00
tester . accounts . new_account ( " " ) . unwrap ( ) ;
2016-07-31 10:44:17 +02:00
let accounts = tester . accounts . accounts ( ) . unwrap ( ) ;
2016-07-24 17:38:21 +02:00
assert_eq! ( accounts . len ( ) , 1 ) ;
let address = accounts [ 0 ] ;
let request = format! ( r # "{{"jsonrpc": "2.0", "method": "personal_setAccountName", "params": ["0x{}", "Test"], "id": 1}}"# , address . hex ( ) ) ;
let response = r # "{"jsonrpc":"2.0","result":null,"id":1}"# ;
2016-09-01 12:00:00 +02:00
let res = tester . io . handle_request_sync ( & request ) ;
2016-07-24 17:38:21 +02:00
assert_eq! ( res , Some ( response . into ( ) ) ) ;
let uuid = tester . accounts . accounts_info ( ) . unwrap ( ) . get ( & address ) . unwrap ( ) . uuid . as_ref ( ) . unwrap ( ) . clone ( ) ;
let request = r # "{"jsonrpc": "2.0", "method": "personal_accountsInfo", "params": [], "id": 1}"# ;
2016-09-01 12:00:00 +02:00
let res = tester . io . handle_request_sync ( request ) ;
2016-07-24 17:38:21 +02:00
let response = format! ( " {{ \" jsonrpc \" : \" 2.0 \" , \" result \" : {{ \" 0x {} \" : {{ \" meta \" : \" {{ }} \" , \" name \" : \" Test \" , \" uuid \" : \" {} \" }} }} , \" id \" :1 }} " , address . hex ( ) , uuid ) ;
assert_eq! ( res , Some ( response ) ) ;
}
#[ test ]
fn should_be_able_to_set_meta ( ) {
2016-10-24 12:21:15 +02:00
let tester = setup ( ) ;
2016-07-24 17:38:21 +02:00
tester . accounts . new_account ( " " ) . unwrap ( ) ;
2016-07-31 10:44:17 +02:00
let accounts = tester . accounts . accounts ( ) . unwrap ( ) ;
2016-07-24 17:38:21 +02:00
assert_eq! ( accounts . len ( ) , 1 ) ;
let address = accounts [ 0 ] ;
let request = format! ( r # "{{"jsonrpc": "2.0", "method": "personal_setAccountMeta", "params": ["0x{}", "{{foo: 69}}"], "id": 1}}"# , address . hex ( ) ) ;
let response = r # "{"jsonrpc":"2.0","result":null,"id":1}"# ;
2016-09-01 12:00:00 +02:00
let res = tester . io . handle_request_sync ( & request ) ;
2016-07-24 17:38:21 +02:00
assert_eq! ( res , Some ( response . into ( ) ) ) ;
let uuid = tester . accounts . accounts_info ( ) . unwrap ( ) . get ( & address ) . unwrap ( ) . uuid . as_ref ( ) . unwrap ( ) . clone ( ) ;
let request = r # "{"jsonrpc": "2.0", "method": "personal_accountsInfo", "params": [], "id": 1}"# ;
2016-09-01 12:00:00 +02:00
let res = tester . io . handle_request_sync ( request ) ;
2016-07-24 17:38:21 +02:00
let response = format! ( " {{ \" jsonrpc \" : \" 2.0 \" , \" result \" : {{ \" 0x {} \" : {{ \" meta \" : \" {{ foo: 69 }} \" , \" name \" : \" {} \" , \" uuid \" : \" {} \" }} }} , \" id \" :1 }} " , address . hex ( ) , uuid , uuid ) ;
assert_eq! ( res , Some ( response ) ) ;
}
2016-05-26 20:10:15 +02:00
#[ test ]
fn sign_and_send_transaction_with_invalid_password ( ) {
2016-10-24 12:21:15 +02:00
let tester = setup ( ) ;
2016-06-20 00:10:34 +02:00
let address = tester . accounts . new_account ( " password123 " ) . unwrap ( ) ;
2016-05-26 20:10:15 +02:00
let request = r #" {
" jsonrpc " : " 2.0 " ,
" method " : " personal_signAndSendTransaction " ,
" params " : [ {
" from " : " " #. to_owned ( ) + format! ( " 0x {:?} " , address ) . as_ref ( ) + r #" " ,
" to " : " 0xd46e8dd67c5d32be8058bb8eb970870f07244567 " ,
" gas " : " 0x76c0 " ,
" gasPrice " : " 0x9184e72a000 " ,
" value " : " 0x9184e72a "
} , " password321 " ] ,
" id " : 1
} " #;
2016-07-20 12:37:49 +02:00
let response = r # "{"jsonrpc":"2.0","error":{"code":-32021,"message":"Account password is invalid or account does not exist.","data":"SStore(InvalidPassword)"},"id":1}"# ;
2016-05-26 20:10:15 +02:00
2016-09-01 12:00:00 +02:00
assert_eq! ( tester . io . handle_request_sync ( request . as_ref ( ) ) , Some ( response . into ( ) ) ) ;
2016-05-26 20:10:15 +02:00
}
#[ test ]
fn sign_and_send_transaction ( ) {
2016-10-24 12:21:15 +02:00
let tester = setup ( ) ;
2016-06-20 00:10:34 +02:00
let address = tester . accounts . new_account ( " password123 " ) . unwrap ( ) ;
2016-05-26 20:10:15 +02:00
let request = r #" {
" jsonrpc " : " 2.0 " ,
" method " : " personal_signAndSendTransaction " ,
" params " : [ {
" from " : " " #. to_owned ( ) + format! ( " 0x {:?} " , address ) . as_ref ( ) + r #" " ,
" to " : " 0xd46e8dd67c5d32be8058bb8eb970870f07244567 " ,
" gas " : " 0x76c0 " ,
" gasPrice " : " 0x9184e72a000 " ,
" value " : " 0x9184e72a "
} , " password123 " ] ,
" 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
} ;
tester . accounts . unlock_account_temporarily ( address , " password123 " . into ( ) ) . unwrap ( ) ;
2016-10-15 14:44:08 +02:00
let signature = tester . accounts . sign ( address , None , t . hash ( ) ) . unwrap ( ) ;
2016-06-20 00:10:34 +02:00
let t = t . with_signature ( signature ) ;
2016-05-26 20:10:15 +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 . as_ref ( ) ) , Some ( response ) ) ;
2016-05-26 20:10:15 +02:00
2016-07-13 19:59:59 +02:00
tester . miner . last_nonces . write ( ) . insert ( address . clone ( ) , U256 ::zero ( ) ) ;
2016-05-26 20:10:15 +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
} ;
tester . accounts . unlock_account_temporarily ( address , " password123 " . into ( ) ) . unwrap ( ) ;
2016-10-15 14:44:08 +02:00
let signature = tester . accounts . sign ( address , None , t . hash ( ) ) . unwrap ( ) ;
2016-06-20 00:10:34 +02:00
let t = t . with_signature ( signature ) ;
2016-05-26 20:10:15 +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 . as_ref ( ) ) , Some ( response ) ) ;
2016-06-01 19:37:34 +02:00
}