2017-01-25 18:51:41 +01:00
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
2016-06-01 19:37:34 +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 ::sync ::Arc ;
use std ::str ::FromStr ;
2017-09-04 16:36:49 +02:00
use bigint ::prelude ::U256 ;
use util ::{ Address , ToPretty } ;
2016-11-10 11:27:05 +01:00
2016-06-20 00:10:34 +02:00
use ethcore ::account_provider ::AccountProvider ;
2016-06-01 19:37:34 +02:00
use ethcore ::client ::TestBlockChainClient ;
2017-04-27 18:23:22 +02:00
use ethcore ::transaction ::{ Transaction , Action , SignedTransaction } ;
2017-05-17 16:20:41 +02:00
use parity_reactor ::EventLoop ;
2016-11-10 11:27:05 +01:00
use rlp ::encode ;
2016-12-27 11:15:02 +01:00
use serde_json ;
2017-01-11 20:02:27 +01:00
use jsonrpc_core ::IoHandler ;
2017-02-14 22:45:43 +01:00
use v1 ::{ SignerClient , Signer , Origin } ;
2017-01-30 21:08:36 +01:00
use v1 ::metadata ::Metadata ;
2016-06-01 19:37:34 +02:00
use v1 ::tests ::helpers ::TestMinerService ;
2017-05-15 18:59:41 +02:00
use v1 ::types ::{ Bytes as RpcBytes , H520 } ;
2016-09-21 12:44:49 +02:00
use v1 ::helpers ::{ SigningQueue , SignerService , FilledTransactionRequest , ConfirmationPayload } ;
2017-04-27 18:23:22 +02:00
use v1 ::helpers ::dispatch ::{ FullDispatcher , eth_data_hash } ;
2016-06-01 19:37:34 +02:00
2016-11-06 12:51:53 +01:00
struct SignerTester {
2016-09-21 12:44:49 +02:00
signer : Arc < SignerService > ,
2016-06-20 00:10:34 +02:00
accounts : Arc < AccountProvider > ,
2017-01-30 21:08:36 +01:00
io : IoHandler < Metadata > ,
2016-06-01 19:37:34 +02:00
miner : Arc < TestMinerService > ,
}
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-06-01 19:37:34 +02:00
}
fn miner_service ( ) -> Arc < TestMinerService > {
Arc ::new ( TestMinerService ::default ( ) )
}
2016-11-06 12:51:53 +01:00
fn signer_tester ( ) -> SignerTester {
2017-05-24 12:24:07 +02:00
let signer = Arc ::new ( SignerService ::new_test ( false ) ) ;
2016-06-01 19:37:34 +02:00
let accounts = accounts_provider ( ) ;
2017-03-29 17:07:58 +02:00
let opt_accounts = Some ( accounts . clone ( ) ) ;
2016-06-01 19:37:34 +02:00
let client = blockchain_client ( ) ;
let miner = miner_service ( ) ;
2017-05-17 16:20:41 +02:00
let event_loop = EventLoop ::spawn ( ) ;
2016-06-01 19:37:34 +02:00
2017-05-28 14:40:36 +02:00
let dispatcher = FullDispatcher ::new ( client , miner . clone ( ) ) ;
2017-01-11 20:02:27 +01:00
let mut io = IoHandler ::default ( ) ;
2017-05-17 16:20:41 +02:00
io . extend_with ( SignerClient ::new ( & opt_accounts , dispatcher , & signer , event_loop . remote ( ) ) . to_delegate ( ) ) ;
2016-06-01 19:37:34 +02:00
2016-11-06 12:51:53 +01:00
SignerTester {
2016-09-21 12:44:49 +02:00
signer : signer ,
2016-06-01 19:37:34 +02:00
accounts : accounts ,
io : io ,
miner : miner ,
}
}
#[ test ]
2016-08-03 10:36:54 +02:00
fn should_return_list_of_items_to_confirm ( ) {
2016-06-01 19:37:34 +02:00
// given
let tester = signer_tester ( ) ;
2016-11-09 13:13:35 +01:00
tester . signer . add_request ( ConfirmationPayload ::SendTransaction ( FilledTransactionRequest {
2016-06-01 19:37:34 +02:00
from : Address ::from ( 1 ) ,
2017-01-30 21:08:36 +01:00
used_default_from : false ,
2016-06-01 19:37:34 +02:00
to : Some ( Address ::from_str ( " d46e8dd67c5d32be8058bb8eb970870f07244567 " ) . unwrap ( ) ) ,
2016-08-03 10:36:54 +02:00
gas_price : U256 ::from ( 10_000 ) ,
gas : U256 ::from ( 10_000_000 ) ,
value : U256 ::from ( 1 ) ,
data : vec ! [ ] ,
2016-06-01 19:37:34 +02:00
nonce : None ,
2017-02-03 19:32:10 +01:00
condition : None ,
2017-02-14 22:45:43 +01:00
} ) , Origin ::Dapps ( " http://parity.io " . into ( ) ) ) . unwrap ( ) ;
2017-04-12 12:15:13 +02:00
tester . signer . add_request ( ConfirmationPayload ::EthSignMessage ( 1. into ( ) , vec! [ 5 ] . into ( ) ) , Origin ::Unknown ) . unwrap ( ) ;
2016-06-01 19:37:34 +02:00
// when
2016-11-06 12:51:53 +01:00
let request = r # "{"jsonrpc":"2.0","method":"signer_requestsToConfirm","params":[],"id":1}"# ;
2016-08-03 10:36:54 +02:00
let response = concat! (
r # "{"jsonrpc":"2.0","result":["# ,
2017-02-14 22:45:43 +01:00
r # "{"id":"0x1","origin":{"dapp":"http://parity.io"},"payload":{"sendTransaction":{"condition":null,"data":"0x","from":"0x0000000000000000000000000000000000000001","gas":"0x989680","gasPrice":"0x2710","nonce":null,"to":"0xd46e8dd67c5d32be8058bb8eb970870f07244567","value":"0x1"}}},"# ,
r # "{"id":"0x2","origin":"unknown","payload":{"sign":{"address":"0x0000000000000000000000000000000000000001","data":"0x05"}}}"# ,
2016-08-03 10:36:54 +02:00
r # "],"id":1}"#
) ;
2016-06-01 19:37:34 +02:00
// then
2016-09-01 12:00:00 +02:00
assert_eq! ( tester . io . handle_request_sync ( & request ) , Some ( response . to_owned ( ) ) ) ;
2016-06-01 19:37:34 +02:00
}
#[ test ]
fn should_reject_transaction_from_queue_without_dispatching ( ) {
// given
let tester = signer_tester ( ) ;
2016-11-09 13:13:35 +01:00
tester . signer . add_request ( ConfirmationPayload ::SendTransaction ( FilledTransactionRequest {
2016-06-01 19:37:34 +02:00
from : Address ::from ( 1 ) ,
2017-01-30 21:08:36 +01:00
used_default_from : false ,
2016-06-01 19:37:34 +02:00
to : Some ( Address ::from_str ( " d46e8dd67c5d32be8058bb8eb970870f07244567 " ) . unwrap ( ) ) ,
2016-08-03 10:36:54 +02:00
gas_price : U256 ::from ( 10_000 ) ,
gas : U256 ::from ( 10_000_000 ) ,
value : U256 ::from ( 1 ) ,
data : vec ! [ ] ,
2016-06-01 19:37:34 +02:00
nonce : None ,
2017-02-03 19:32:10 +01:00
condition : None ,
2017-02-14 22:45:43 +01:00
} ) , Origin ::Unknown ) . unwrap ( ) ;
2016-09-21 12:44:49 +02:00
assert_eq! ( tester . signer . requests ( ) . len ( ) , 1 ) ;
2016-06-01 19:37:34 +02:00
// when
2016-11-06 12:51:53 +01:00
let request = r # "{"jsonrpc":"2.0","method":"signer_rejectRequest","params":["0x1"],"id":1}"# ;
2016-06-01 19:37:34 +02:00
let response = r # "{"jsonrpc":"2.0","result":true,"id":1}"# ;
// then
2016-09-01 12:00:00 +02:00
assert_eq! ( tester . io . handle_request_sync ( & request ) , Some ( response . to_owned ( ) ) ) ;
2016-09-21 12:44:49 +02:00
assert_eq! ( tester . signer . requests ( ) . len ( ) , 0 ) ;
2016-07-13 19:59:59 +02:00
assert_eq! ( tester . miner . imported_transactions . lock ( ) . len ( ) , 0 ) ;
2016-06-01 19:37:34 +02:00
}
2016-06-07 17:25:01 +02:00
#[ test ]
fn should_not_remove_transaction_if_password_is_invalid ( ) {
// given
let tester = signer_tester ( ) ;
2016-11-09 13:13:35 +01:00
tester . signer . add_request ( ConfirmationPayload ::SendTransaction ( FilledTransactionRequest {
2016-06-07 17:25:01 +02:00
from : Address ::from ( 1 ) ,
2017-01-30 21:08:36 +01:00
used_default_from : false ,
2016-06-07 17:25:01 +02:00
to : Some ( Address ::from_str ( " d46e8dd67c5d32be8058bb8eb970870f07244567 " ) . unwrap ( ) ) ,
2016-08-03 10:36:54 +02:00
gas_price : U256 ::from ( 10_000 ) ,
gas : U256 ::from ( 10_000_000 ) ,
value : U256 ::from ( 1 ) ,
data : vec ! [ ] ,
2016-06-07 17:25:01 +02:00
nonce : None ,
2017-02-03 19:32:10 +01:00
condition : None ,
2017-02-14 22:45:43 +01:00
} ) , Origin ::Unknown ) . unwrap ( ) ;
2016-09-21 12:44:49 +02:00
assert_eq! ( tester . signer . requests ( ) . len ( ) , 1 ) ;
2016-06-07 17:25:01 +02:00
// when
2016-11-06 12:51:53 +01:00
let request = r # "{"jsonrpc":"2.0","method":"signer_confirmRequest","params":["0x1",{},"xxx"],"id":1}"# ;
2016-08-03 10:36:54 +02:00
let response = r # "{"jsonrpc":"2.0","error":{"code":-32021,"message":"Account password is invalid or account does not exist.","data":"SStore(InvalidAccount)"},"id":1}"# ;
// then
2016-09-01 12:00:00 +02:00
assert_eq! ( tester . io . handle_request_sync ( & request ) , Some ( response . to_owned ( ) ) ) ;
2016-09-21 12:44:49 +02:00
assert_eq! ( tester . signer . requests ( ) . len ( ) , 1 ) ;
2016-08-03 10:36:54 +02:00
}
#[ test ]
fn should_not_remove_sign_if_password_is_invalid ( ) {
// given
let tester = signer_tester ( ) ;
2017-04-12 12:15:13 +02:00
tester . signer . add_request ( ConfirmationPayload ::EthSignMessage ( 0. into ( ) , vec! [ 5 ] . into ( ) ) , Origin ::Unknown ) . unwrap ( ) ;
2016-09-21 12:44:49 +02:00
assert_eq! ( tester . signer . requests ( ) . len ( ) , 1 ) ;
2016-08-03 10:36:54 +02:00
// when
2016-11-06 12:51:53 +01:00
let request = r # "{"jsonrpc":"2.0","method":"signer_confirmRequest","params":["0x1",{},"xxx"],"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(InvalidAccount)"},"id":1}"# ;
2016-06-07 17:25:01 +02:00
// then
2016-09-01 12:00:00 +02:00
assert_eq! ( tester . io . handle_request_sync ( & request ) , Some ( response . to_owned ( ) ) ) ;
2016-09-21 12:44:49 +02:00
assert_eq! ( tester . signer . requests ( ) . len ( ) , 1 ) ;
2016-06-07 17:25:01 +02:00
}
2016-06-01 19:37:34 +02:00
#[ test ]
fn should_confirm_transaction_and_dispatch ( ) {
2016-06-20 00:10:34 +02:00
//// given
2016-06-01 19:37:34 +02:00
let tester = signer_tester ( ) ;
2016-06-20 00:10:34 +02:00
let address = tester . accounts . new_account ( " test " ) . unwrap ( ) ;
2016-06-01 19:37:34 +02:00
let recipient = Address ::from_str ( " d46e8dd67c5d32be8058bb8eb970870f07244567 " ) . unwrap ( ) ;
2016-11-09 13:13:35 +01:00
tester . signer . add_request ( ConfirmationPayload ::SendTransaction ( FilledTransactionRequest {
2016-06-01 19:37:34 +02:00
from : address ,
2017-01-30 21:08:36 +01:00
used_default_from : false ,
2016-06-01 19:37:34 +02:00
to : Some ( recipient ) ,
2016-08-03 10:36:54 +02:00
gas_price : U256 ::from ( 10_000 ) ,
gas : U256 ::from ( 10_000_000 ) ,
value : U256 ::from ( 1 ) ,
data : vec ! [ ] ,
2016-06-01 19:37:34 +02:00
nonce : None ,
2017-02-03 19:32:10 +01:00
condition : None ,
2017-02-14 22:45:43 +01:00
} ) , Origin ::Unknown ) . unwrap ( ) ;
2016-06-20 00:10:34 +02:00
2016-06-01 19:37:34 +02:00
let t = Transaction {
nonce : U256 ::zero ( ) ,
gas_price : U256 ::from ( 0x1000 ) ,
2016-12-10 20:18:42 +01:00
gas : U256 ::from ( 0x50505 ) ,
2016-06-01 19:37:34 +02:00
action : Action ::Call ( recipient ) ,
value : U256 ::from ( 0x1 ) ,
data : vec ! [ ]
2016-06-20 00:10:34 +02:00
} ;
tester . accounts . unlock_account_temporarily ( address , " test " . into ( ) ) . unwrap ( ) ;
2016-11-03 22:22:25 +01:00
let signature = tester . accounts . sign ( address , None , t . hash ( None ) ) . unwrap ( ) ;
let t = t . with_signature ( signature , None ) ;
2016-06-01 19:37:34 +02:00
2016-09-21 12:44:49 +02:00
assert_eq! ( tester . signer . requests ( ) . len ( ) , 1 ) ;
2016-06-01 19:37:34 +02:00
// when
let request = r #" {
" jsonrpc " :" 2.0 " ,
2016-11-06 12:51:53 +01:00
" method " :" signer_confirmRequest " ,
2016-12-10 20:18:42 +01:00
" params " :[ " 0x1 " , { " gasPrice " :" 0x1000 " , " gas " :" 0x50505 " } , " test " ] ,
2016-06-01 19:37:34 +02:00
" id " :1
} " #;
let response = r # "{"jsonrpc":"2.0","result":""# . to_owned ( ) + format! ( " 0x {:?} " , t . hash ( ) ) . as_ref ( ) + r # "","id":1}"# ;
// then
2016-09-01 12:00:00 +02:00
assert_eq! ( tester . io . handle_request_sync ( & request ) , Some ( response . to_owned ( ) ) ) ;
2016-09-21 12:44:49 +02:00
assert_eq! ( tester . signer . requests ( ) . len ( ) , 0 ) ;
2016-07-13 19:59:59 +02:00
assert_eq! ( tester . miner . imported_transactions . lock ( ) . len ( ) , 1 ) ;
2016-06-01 19:37:34 +02:00
}
2017-01-30 11:10:58 +01:00
#[ test ]
fn should_alter_the_sender_and_nonce ( ) {
//// given
let tester = signer_tester ( ) ;
let recipient = Address ::from_str ( " d46e8dd67c5d32be8058bb8eb970870f07244567 " ) . unwrap ( ) ;
tester . signer . add_request ( ConfirmationPayload ::SendTransaction ( FilledTransactionRequest {
from : 0. into ( ) ,
2017-01-30 21:08:36 +01:00
used_default_from : false ,
2017-01-30 11:10:58 +01:00
to : Some ( recipient ) ,
gas_price : U256 ::from ( 10_000 ) ,
gas : U256 ::from ( 10_000_000 ) ,
value : U256 ::from ( 1 ) ,
data : vec ! [ ] ,
nonce : Some ( 10. into ( ) ) ,
2017-02-03 19:32:10 +01:00
condition : None ,
2017-02-14 22:45:43 +01:00
} ) , Origin ::Unknown ) . unwrap ( ) ;
2017-01-30 11:10:58 +01:00
let t = Transaction {
nonce : U256 ::zero ( ) ,
gas_price : U256 ::from ( 0x1000 ) ,
gas : U256 ::from ( 0x50505 ) ,
action : Action ::Call ( recipient ) ,
value : U256 ::from ( 0x1 ) ,
data : vec ! [ ]
} ;
let address = tester . accounts . new_account ( " test " ) . unwrap ( ) ;
let signature = tester . accounts . sign ( address , Some ( " test " . into ( ) ) , t . hash ( None ) ) . unwrap ( ) ;
let t = t . with_signature ( signature , None ) ;
assert_eq! ( tester . signer . requests ( ) . len ( ) , 1 ) ;
// when
let request = r #" {
" jsonrpc " :" 2.0 " ,
" method " :" signer_confirmRequest " ,
" params " :[ " 0x1 " , { " sender " :" " #. to_owned ( )
+ & format! ( " 0x {:?} " , address )
+ r #" " , " gasPrice " :" 0x1000 " , " gas " :" 0x50505 " } , " test " ] ,
" id " :1
} " #;
let response = r # "{"jsonrpc":"2.0","result":""# . to_owned ( ) + & format! ( " 0x {:?} " , t . hash ( ) ) + r # "","id":1}"# ;
// then
assert_eq! ( tester . io . handle_request_sync ( & request ) , Some ( response . to_owned ( ) ) ) ;
assert_eq! ( tester . signer . requests ( ) . len ( ) , 0 ) ;
assert_eq! ( tester . miner . imported_transactions . lock ( ) . len ( ) , 1 ) ;
}
2016-11-30 16:11:41 +01:00
#[ test ]
fn should_confirm_transaction_with_token ( ) {
// given
let tester = signer_tester ( ) ;
let address = tester . accounts . new_account ( " test " ) . unwrap ( ) ;
let recipient = Address ::from_str ( " d46e8dd67c5d32be8058bb8eb970870f07244567 " ) . unwrap ( ) ;
tester . signer . add_request ( ConfirmationPayload ::SendTransaction ( FilledTransactionRequest {
from : address ,
2017-01-30 21:08:36 +01:00
used_default_from : false ,
2016-11-30 16:11:41 +01:00
to : Some ( recipient ) ,
gas_price : U256 ::from ( 10_000 ) ,
gas : U256 ::from ( 10_000_000 ) ,
value : U256 ::from ( 1 ) ,
data : vec ! [ ] ,
nonce : None ,
2017-02-03 19:32:10 +01:00
condition : None ,
2017-02-14 22:45:43 +01:00
} ) , Origin ::Unknown ) . unwrap ( ) ;
2016-11-30 16:11:41 +01:00
let t = Transaction {
nonce : U256 ::zero ( ) ,
gas_price : U256 ::from ( 0x1000 ) ,
gas : U256 ::from ( 10_000_000 ) ,
action : Action ::Call ( recipient ) ,
value : U256 ::from ( 0x1 ) ,
data : vec ! [ ]
} ;
let ( signature , token ) = tester . accounts . sign_with_token ( address , " test " . into ( ) , t . hash ( None ) ) . unwrap ( ) ;
let t = t . with_signature ( signature , None ) ;
assert_eq! ( tester . signer . requests ( ) . len ( ) , 1 ) ;
// when
let request = r #" {
" jsonrpc " :" 2.0 " ,
" method " :" signer_confirmRequestWithToken " ,
" params " :[ " 0x1 " , { " gasPrice " :" 0x1000 " } , " " #. to_owned ( ) + & token + r #" " ] ,
" id " :1
} " #;
let response = r # "{"jsonrpc":"2.0","result":{"result":""# . to_owned ( ) +
format! ( " 0x {:?} " , t . hash ( ) ) . as_ref ( ) +
2016-11-30 17:05:31 +01:00
r # "","token":""# ;
2016-11-30 16:11:41 +01:00
// then
2016-11-30 17:05:31 +01:00
let result = tester . io . handle_request_sync ( & request ) . unwrap ( ) ;
assert! ( result . starts_with ( & response ) , " Should return correct result. Expected: {:?}, Got: {:?} " , response , result ) ;
2016-11-30 16:11:41 +01:00
assert_eq! ( tester . signer . requests ( ) . len ( ) , 0 ) ;
assert_eq! ( tester . miner . imported_transactions . lock ( ) . len ( ) , 1 ) ;
}
2016-11-10 11:27:05 +01:00
#[ test ]
fn should_confirm_transaction_with_rlp ( ) {
// given
let tester = signer_tester ( ) ;
let address = tester . accounts . new_account ( " test " ) . unwrap ( ) ;
let recipient = Address ::from_str ( " d46e8dd67c5d32be8058bb8eb970870f07244567 " ) . unwrap ( ) ;
tester . signer . add_request ( ConfirmationPayload ::SendTransaction ( FilledTransactionRequest {
from : address ,
2017-01-30 21:08:36 +01:00
used_default_from : false ,
2016-11-10 11:27:05 +01:00
to : Some ( recipient ) ,
gas_price : U256 ::from ( 10_000 ) ,
gas : U256 ::from ( 10_000_000 ) ,
value : U256 ::from ( 1 ) ,
data : vec ! [ ] ,
nonce : None ,
2017-02-03 19:32:10 +01:00
condition : None ,
2017-02-14 22:45:43 +01:00
} ) , Origin ::Unknown ) . unwrap ( ) ;
2016-11-10 11:27:05 +01:00
let t = Transaction {
nonce : U256 ::zero ( ) ,
gas_price : U256 ::from ( 0x1000 ) ,
gas : U256 ::from ( 10_000_000 ) ,
action : Action ::Call ( recipient ) ,
value : U256 ::from ( 0x1 ) ,
data : vec ! [ ]
} ;
2017-01-30 11:10:58 +01:00
let signature = tester . accounts . sign ( address , Some ( " test " . into ( ) ) , t . hash ( None ) ) . unwrap ( ) ;
2016-11-10 11:27:05 +01:00
let t = t . with_signature ( signature , None ) ;
let rlp = encode ( & t ) ;
assert_eq! ( tester . signer . requests ( ) . len ( ) , 1 ) ;
// when
let request = r #" {
" jsonrpc " :" 2.0 " ,
" method " :" signer_confirmRequestRaw " ,
" params " :[ " 0x1 " , " 0x " #. to_owned ( ) + & rlp . to_hex ( ) + r #" " ] ,
" id " :1
} " #;
let response = r # "{"jsonrpc":"2.0","result":""# . to_owned ( ) + format! ( " 0x {:?} " , t . hash ( ) ) . as_ref ( ) + r # "","id":1}"# ;
// then
assert_eq! ( tester . io . handle_request_sync ( & request ) , Some ( response . to_owned ( ) ) ) ;
assert_eq! ( tester . signer . requests ( ) . len ( ) , 0 ) ;
assert_eq! ( tester . miner . imported_transactions . lock ( ) . len ( ) , 1 ) ;
}
#[ test ]
fn should_return_error_when_sender_does_not_match ( ) {
// given
let tester = signer_tester ( ) ;
let address = tester . accounts . new_account ( " test " ) . unwrap ( ) ;
let recipient = Address ::from_str ( " d46e8dd67c5d32be8058bb8eb970870f07244567 " ) . unwrap ( ) ;
tester . signer . add_request ( ConfirmationPayload ::SendTransaction ( FilledTransactionRequest {
from : Address ::default ( ) ,
2017-01-30 21:08:36 +01:00
used_default_from : false ,
2016-11-10 11:27:05 +01:00
to : Some ( recipient ) ,
gas_price : U256 ::from ( 10_000 ) ,
gas : U256 ::from ( 10_000_000 ) ,
value : U256 ::from ( 1 ) ,
data : vec ! [ ] ,
nonce : None ,
2017-02-03 19:32:10 +01:00
condition : None ,
2017-02-14 22:45:43 +01:00
} ) , Origin ::Unknown ) . unwrap ( ) ;
2016-11-10 11:27:05 +01:00
let t = Transaction {
nonce : U256 ::zero ( ) ,
gas_price : U256 ::from ( 0x1000 ) ,
gas : U256 ::from ( 10_000_000 ) ,
action : Action ::Call ( recipient ) ,
value : U256 ::from ( 0x1 ) ,
data : vec ! [ ]
} ;
tester . accounts . unlock_account_temporarily ( address , " test " . into ( ) ) . unwrap ( ) ;
let signature = tester . accounts . sign ( address , None , t . hash ( None ) ) . unwrap ( ) ;
let t = t . with_signature ( signature , None ) ;
let rlp = encode ( & t ) ;
assert_eq! ( tester . signer . requests ( ) . len ( ) , 1 ) ;
// when
let request = r #" {
" jsonrpc " :" 2.0 " ,
" method " :" signer_confirmRequestRaw " ,
" params " :[ " 0x1 " , " 0x " #. to_owned ( ) + & rlp . to_hex ( ) + r #" " ] ,
" id " :1
} " #;
let response = r # "{"jsonrpc":"2.0","error":{"code":-32602,"message":"Couldn't parse parameters: Sent transaction does not match the request.","data":"[\"from\"]"},"id":1}"# ;
// then
assert_eq! ( tester . io . handle_request_sync ( & request ) , Some ( response . to_owned ( ) ) ) ;
assert_eq! ( tester . signer . requests ( ) . len ( ) , 1 ) ;
}
2017-04-27 18:23:22 +02:00
#[ test ]
fn should_confirm_sign_transaction_with_rlp ( ) {
// given
let tester = signer_tester ( ) ;
let address = tester . accounts . new_account ( " test " ) . unwrap ( ) ;
let recipient = Address ::from_str ( " d46e8dd67c5d32be8058bb8eb970870f07244567 " ) . unwrap ( ) ;
tester . signer . add_request ( ConfirmationPayload ::SignTransaction ( FilledTransactionRequest {
from : address ,
used_default_from : false ,
to : Some ( recipient ) ,
gas_price : U256 ::from ( 10_000 ) ,
gas : U256 ::from ( 10_000_000 ) ,
value : U256 ::from ( 1 ) ,
data : vec ! [ ] ,
nonce : None ,
condition : None ,
} ) , Origin ::Unknown ) . unwrap ( ) ;
assert_eq! ( tester . signer . requests ( ) . len ( ) , 1 ) ;
let t = Transaction {
nonce : U256 ::zero ( ) ,
gas_price : U256 ::from ( 0x1000 ) ,
gas : U256 ::from ( 10_000_000 ) ,
action : Action ::Call ( recipient ) ,
value : U256 ::from ( 0x1 ) ,
data : vec ! [ ]
} ;
let signature = tester . accounts . sign ( address , Some ( " test " . into ( ) ) , t . hash ( None ) ) . unwrap ( ) ;
let t = SignedTransaction ::new ( t . with_signature ( signature . clone ( ) , None ) ) . unwrap ( ) ;
let rlp = encode ( & t ) ;
// when
let request = r #" {
" jsonrpc " :" 2.0 " ,
" method " :" signer_confirmRequestRaw " ,
" params " :[ " 0x1 " , " 0x " #. to_owned ( ) + & rlp . to_hex ( ) + r #" " ] ,
" id " :1
} " #;
let response = r # "{"jsonrpc":"2.0","result":{"# . to_owned ( ) +
r # ""raw":"0x"# + & rlp . to_hex ( ) + r # "","# +
r # ""tx":{"# +
2017-08-21 13:46:58 +02:00
r # ""blockHash":null,"blockNumber":null,"# +
& format! ( " \" chainId \" : {} , " , t . chain_id ( ) . map_or ( " null " . to_owned ( ) , | n | format! ( " {} " , n ) ) ) +
r # ""condition":null,"creates":null,"# +
2017-04-27 18:23:22 +02:00
& format! ( " \" from \" : \" 0x {:?} \" , " , & address ) +
r # ""gas":"0x989680","gasPrice":"0x1000","# +
& format! ( " \" hash \" : \" 0x {:?} \" , " , t . hash ( ) ) +
r # ""input":"0x","# +
r # ""nonce":"0x0","# +
& format! ( " \" publicKey \" : \" 0x {:?} \" , " , t . public_key ( ) . unwrap ( ) ) +
& format! ( " \" r \" : \" 0x {} \" , " , U256 ::from ( signature . r ( ) ) . to_hex ( ) ) +
& format! ( " \" raw \" : \" 0x {} \" , " , rlp . to_hex ( ) ) +
& format! ( " \" s \" : \" 0x {} \" , " , U256 ::from ( signature . s ( ) ) . to_hex ( ) ) +
& format! ( " \" standardV \" : \" 0x {} \" , " , U256 ::from ( t . standard_v ( ) ) . to_hex ( ) ) +
r # ""to":"0xd46e8dd67c5d32be8058bb8eb970870f07244567","transactionIndex":null,"# +
& format! ( " \" v \" : \" 0x {} \" , " , U256 ::from ( t . original_v ( ) ) . to_hex ( ) ) +
r # ""value":"0x1""# +
r # "}},"id":1}"# ;
// then
assert_eq! ( tester . io . handle_request_sync ( & request ) , Some ( response . to_owned ( ) ) ) ;
assert_eq! ( tester . signer . requests ( ) . len ( ) , 0 ) ;
assert_eq! ( tester . miner . imported_transactions . lock ( ) . len ( ) , 0 ) ;
}
#[ test ]
fn should_confirm_data_sign_with_signature ( ) {
// given
let tester = signer_tester ( ) ;
let address = tester . accounts . new_account ( " test " ) . unwrap ( ) ;
tester . signer . add_request ( ConfirmationPayload ::EthSignMessage (
address ,
vec! [ 1 , 2 , 3 , 4 ] . into ( ) ,
) , Origin ::Unknown ) . unwrap ( ) ;
assert_eq! ( tester . signer . requests ( ) . len ( ) , 1 ) ;
let data_hash = eth_data_hash ( vec! [ 1 , 2 , 3 , 4 ] . into ( ) ) ;
2017-05-11 12:18:20 +02:00
let signature = H520 ( tester . accounts . sign ( address , Some ( " test " . into ( ) ) , data_hash ) . unwrap ( ) . into_electrum ( ) ) ;
2017-04-27 18:23:22 +02:00
let signature = format! ( " 0x {:?} " , signature ) ;
// when
let request = r #" {
" jsonrpc " :" 2.0 " ,
" method " :" signer_confirmRequestRaw " ,
" params " :[ " 0x1 " , " " #. to_owned ( ) + & signature + r #" " ] ,
" id " :1
} " #;
let response = r # "{"jsonrpc":"2.0","result":""# . to_owned ( ) + & signature + r # "","id":1}"# ;
// then
assert_eq! ( tester . io . handle_request_sync ( & request ) , Some ( response . to_owned ( ) ) ) ;
assert_eq! ( tester . signer . requests ( ) . len ( ) , 0 ) ;
assert_eq! ( tester . miner . imported_transactions . lock ( ) . len ( ) , 0 ) ;
}
2017-05-15 18:59:41 +02:00
#[ test ]
fn should_confirm_decrypt_with_phrase ( ) {
// given
let tester = signer_tester ( ) ;
let address = tester . accounts . new_account ( " test " ) . unwrap ( ) ;
tester . signer . add_request ( ConfirmationPayload ::Decrypt (
address ,
vec! [ 1 , 2 , 3 , 4 ] . into ( ) ,
) , Origin ::Unknown ) . unwrap ( ) ;
assert_eq! ( tester . signer . requests ( ) . len ( ) , 1 ) ;
let decrypted = serde_json ::to_string ( & RpcBytes ::new ( b " phrase " . to_vec ( ) ) ) . unwrap ( ) ;
// when
let request = r #" {
" jsonrpc " :" 2.0 " ,
" method " :" signer_confirmRequestRaw " ,
" params " :[ " 0x1 " , " #.to_owned() + &decrypted + r# " ] ,
" id " :1
} " #;
let response = r # "{"jsonrpc":"2.0","result":"# . to_owned ( ) + & decrypted + r # ","id":1}"# ;
// then
assert_eq! ( tester . io . handle_request_sync ( & request ) , Some ( response . to_owned ( ) ) ) ;
assert_eq! ( tester . signer . requests ( ) . len ( ) , 0 ) ;
assert_eq! ( tester . miner . imported_transactions . lock ( ) . len ( ) , 0 ) ;
}
2016-09-21 12:44:49 +02:00
#[ test ]
fn should_generate_new_token ( ) {
// given
let tester = signer_tester ( ) ;
// when
let request = r #" {
" jsonrpc " :" 2.0 " ,
2016-11-06 12:51:53 +01:00
" method " :" signer_generateAuthorizationToken " ,
2016-09-21 12:44:49 +02:00
" params " :[ ] ,
" id " :1
} " #;
let response = r # "{"jsonrpc":"2.0","result":"new_token","id":1}"# ;
// then
assert_eq! ( tester . io . handle_request_sync ( & request ) , Some ( response . to_owned ( ) ) ) ;
}
2016-12-27 11:15:02 +01:00
#[ test ]
fn should_generate_new_web_proxy_token ( ) {
use jsonrpc_core ::{ Response , Output , Value } ;
// given
let tester = signer_tester ( ) ;
// when
let request = r #" {
" jsonrpc " :" 2.0 " ,
" method " :" signer_generateWebProxyAccessToken " ,
2017-06-23 16:17:04 +02:00
" params " :[ " https://parity.io " ] ,
2016-12-27 11:15:02 +01:00
" id " :1
} " #;
let response = tester . io . handle_request_sync ( & request ) . unwrap ( ) ;
let result = serde_json ::from_str ( & response ) . unwrap ( ) ;
if let Response ::Single ( Output ::Success ( ref success ) ) = result {
if let Value ::String ( ref token ) = success . result {
2017-06-23 16:17:04 +02:00
assert_eq! ( tester . signer . web_proxy_access_token_domain ( & token ) , Some ( " https://parity.io " . into ( ) ) ) ;
2016-12-27 11:15:02 +01:00
return ;
}
}
assert! ( false , " Expected successful response, got: {:?} " , result ) ;
}