2019-01-07 11:33:07 +01:00
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity Ethereum.
2016-06-01 19:37:34 +02:00
2019-01-07 11:33:07 +01:00
// Parity Ethereum is free software: you can redistribute it and/or modify
2016-06-01 19:37:34 +02:00
// 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.
2019-01-07 11:33:07 +01:00
// Parity Ethereum is distributed in the hope that it will be useful,
2016-06-01 19:37:34 +02:00
// 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
2019-01-07 11:33:07 +01:00
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
2016-06-01 19:37:34 +02:00
2017-09-06 20:47:45 +02:00
use bytes ::ToPretty ;
2020-08-05 06:08:03 +02:00
use ethereum_types ::{ Address , H520 , U256 } ;
use std ::{ str ::FromStr , sync ::Arc } ;
2016-11-10 11:27:05 +01:00
2019-02-07 14:34:24 +01:00
use accounts ::AccountProvider ;
2016-06-01 19:37:34 +02:00
use ethcore ::client ::TestBlockChainClient ;
2018-10-22 09:40:50 +02:00
use parity_runtime ::Runtime ;
2017-11-01 11:23:18 +01:00
use parking_lot ::Mutex ;
2016-11-10 11:27:05 +01:00
use rlp ::encode ;
2020-08-05 06:08:03 +02:00
use types ::transaction ::{ Action , SignedTransaction , Transaction } ;
2016-11-10 11:27:05 +01:00
2017-01-11 20:02:27 +01:00
use jsonrpc_core ::IoHandler ;
2020-08-05 06:08:03 +02:00
use serde_json ;
use v1 ::{
helpers ::{
dispatch ::{ self , eth_data_hash , FullDispatcher } ,
external_signer ::{ SignerService , SigningQueue } ,
nonce , ConfirmationPayload , FilledTransactionRequest ,
} ,
metadata ::Metadata ,
tests ::helpers ::TestMinerService ,
types ::Bytes as RpcBytes ,
Origin , Signer , SignerClient ,
} ;
2016-06-01 19:37:34 +02:00
2016-11-06 12:51:53 +01:00
struct SignerTester {
2020-08-05 06:08:03 +02:00
_runtime : Runtime ,
signer : Arc < SignerService > ,
accounts : Arc < AccountProvider > ,
io : IoHandler < Metadata > ,
miner : Arc < TestMinerService > ,
2016-06-01 19:37:34 +02:00
}
fn blockchain_client ( ) -> Arc < TestBlockChainClient > {
2020-08-05 06:08:03 +02:00
let client = TestBlockChainClient ::new ( ) ;
Arc ::new ( client )
2016-06-01 19:37:34 +02:00
}
2016-06-20 00:10:34 +02:00
fn accounts_provider ( ) -> Arc < AccountProvider > {
2020-08-05 06:08:03 +02:00
Arc ::new ( AccountProvider ::transient_provider ( ) )
2016-06-01 19:37:34 +02:00
}
fn miner_service ( ) -> Arc < TestMinerService > {
2020-08-05 06:08:03 +02:00
Arc ::new ( TestMinerService ::default ( ) )
2016-06-01 19:37:34 +02:00
}
2016-11-06 12:51:53 +01:00
fn signer_tester ( ) -> SignerTester {
2020-08-05 06:08:03 +02:00
let runtime = Runtime ::with_thread_count ( 1 ) ;
let signer = Arc ::new ( SignerService ::new_test ( false ) ) ;
let accounts = accounts_provider ( ) ;
let account_signer = Arc ::new ( dispatch ::Signer ::new ( accounts . clone ( ) ) ) ;
let client = blockchain_client ( ) ;
let miner = miner_service ( ) ;
let reservations = Arc ::new ( Mutex ::new ( nonce ::Reservations ::new ( runtime . executor ( ) ) ) ) ;
let dispatcher = FullDispatcher ::new ( client , miner . clone ( ) , reservations , 50 ) ;
let mut io = IoHandler ::default ( ) ;
io . extend_with (
SignerClient ::new ( account_signer , dispatcher , & signer , runtime . executor ( ) ) . to_delegate ( ) ,
) ;
SignerTester {
_runtime : runtime ,
signer : signer ,
accounts : accounts ,
io : io ,
miner : miner ,
}
2016-06-01 19:37:34 +02:00
}
#[ test ]
2016-08-03 10:36:54 +02:00
fn should_return_list_of_items_to_confirm ( ) {
2020-08-05 06:08:03 +02:00
// given
let tester = signer_tester ( ) ;
let _send_future = tester
. signer
. add_request (
ConfirmationPayload ::SendTransaction ( FilledTransactionRequest {
from : Address ::from ( 1 ) ,
used_default_from : false ,
to : Some ( Address ::from_str ( " d46e8dd67c5d32be8058bb8eb970870f07244567 " ) . unwrap ( ) ) ,
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 ( ) ;
let _sign_future = tester
. signer
. add_request (
ConfirmationPayload ::EthSignMessage ( 1. into ( ) , vec! [ 5 ] . into ( ) ) ,
Origin ::Unknown ,
)
. unwrap ( ) ;
// when
let request = r # "{"jsonrpc":"2.0","method":"signer_requestsToConfirm","params":[],"id":1}"# ;
let response = concat! (
r # "{"jsonrpc":"2.0","result":["# ,
r # "{"id":"0x1","origin":"unknown","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"}}}"# ,
r # "],"id":1}"#
) ;
// then
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 ( ) {
2020-08-05 06:08:03 +02:00
// given
let tester = signer_tester ( ) ;
let _confirmation_future = tester
. signer
. add_request (
ConfirmationPayload ::SendTransaction ( FilledTransactionRequest {
from : Address ::from ( 1 ) ,
used_default_from : false ,
to : Some ( Address ::from_str ( " d46e8dd67c5d32be8058bb8eb970870f07244567 " ) . unwrap ( ) ) ,
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 ) ;
// when
let request = r # "{"jsonrpc":"2.0","method":"signer_rejectRequest","params":["0x1"],"id":1}"# ;
let response = r # "{"jsonrpc":"2.0","result":true,"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-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 ( ) {
2020-08-05 06:08:03 +02:00
// given
let tester = signer_tester ( ) ;
let _confirmation_future = tester
. signer
. add_request (
ConfirmationPayload ::SendTransaction ( FilledTransactionRequest {
from : Address ::from ( 1 ) ,
used_default_from : false ,
to : Some ( Address ::from_str ( " d46e8dd67c5d32be8058bb8eb970870f07244567 " ) . unwrap ( ) ) ,
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 ) ;
// when
let request =
r # "{"jsonrpc":"2.0","method":"signer_confirmRequest","params":["0x1",{},"xxx"],"id":1}"# ;
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
assert_eq! (
tester . io . handle_request_sync ( & request ) ,
Some ( response . to_owned ( ) )
) ;
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 ( ) {
2020-08-05 06:08:03 +02:00
// given
let tester = signer_tester ( ) ;
let _confirmation_future = tester
. signer
. add_request (
ConfirmationPayload ::EthSignMessage ( 0. into ( ) , vec! [ 5 ] . into ( ) ) ,
Origin ::Unknown ,
)
. unwrap ( ) ;
assert_eq! ( tester . signer . requests ( ) . len ( ) , 1 ) ;
// when
let request =
r # "{"jsonrpc":"2.0","method":"signer_confirmRequest","params":["0x1",{},"xxx"],"id":1}"# ;
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
assert_eq! (
tester . io . handle_request_sync ( & request ) ,
Some ( response . to_owned ( ) )
) ;
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 ( ) {
2020-08-05 06:08:03 +02:00
//// given
let tester = signer_tester ( ) ;
let address = tester . accounts . new_account ( & " test " . into ( ) ) . unwrap ( ) ;
let recipient = Address ::from_str ( " d46e8dd67c5d32be8058bb8eb970870f07244567 " ) . unwrap ( ) ;
let _confirmation_future = tester
. signer
. add_request (
ConfirmationPayload ::SendTransaction ( 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 ( ) ;
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 ! [ ] ,
} ;
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 ) ;
assert_eq! ( tester . signer . requests ( ) . len ( ) , 1 ) ;
// when
let request = r #" {
2016-06-01 19:37:34 +02:00
" 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
} " #;
2020-08-05 06:08:03 +02:00
let response = r # "{"jsonrpc":"2.0","result":""# . to_owned ( )
+ format! ( " 0x {:x} " , 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 ) ;
2016-06-01 19:37:34 +02:00
}
2017-01-30 11:10:58 +01:00
#[ test ]
fn should_alter_the_sender_and_nonce ( ) {
2020-08-05 06:08:03 +02:00
//// given
let tester = signer_tester ( ) ;
let recipient = Address ::from_str ( " d46e8dd67c5d32be8058bb8eb970870f07244567 " ) . unwrap ( ) ;
let _confirmation_future = tester
. signer
. add_request (
ConfirmationPayload ::SendTransaction ( FilledTransactionRequest {
from : 0. into ( ) ,
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 : Some ( 10. into ( ) ) ,
condition : None ,
} ) ,
Origin ::Unknown ,
)
. unwrap ( ) ;
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 " . into ( ) ) . 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 #" {
2017-01-30 11:10:58 +01:00
" jsonrpc " :" 2.0 " ,
" method " :" signer_confirmRequest " ,
2020-08-05 06:08:03 +02:00
" params " :[ " 0x1 " , { " sender " :" " #
. to_owned ( )
+ & format! ( " 0x {:x} " , address )
+ r #" " , " gasPrice " :" 0x1000 " , " gas " :" 0x50505 " } , " test " ] ,
2017-01-30 11:10:58 +01:00
" id " :1
} " #;
2020-08-05 06:08:03 +02:00
let response =
r # "{"jsonrpc":"2.0","result":""# . to_owned ( ) + & format! ( " 0x {:x} " , 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 ) ;
2017-01-30 11:10:58 +01:00
}
2016-11-30 16:11:41 +01:00
#[ test ]
fn should_confirm_transaction_with_token ( ) {
2020-08-05 06:08:03 +02:00
// given
let tester = signer_tester ( ) ;
let address = tester . accounts . new_account ( & " test " . into ( ) ) . unwrap ( ) ;
let recipient = Address ::from_str ( " d46e8dd67c5d32be8058bb8eb970870f07244567 " ) . unwrap ( ) ;
let _confirmation_future = tester
. signer
. add_request (
ConfirmationPayload ::SendTransaction ( 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 ( ) ;
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 #" {
2016-11-30 16:11:41 +01:00
" jsonrpc " :" 2.0 " ,
" method " :" signer_confirmRequestWithToken " ,
2020-08-05 06:08:03 +02:00
" params " :[ " 0x1 " , { " gasPrice " :" 0x1000 " } , " " #
. to_owned ( )
+ token . as_str ( )
+ r #" " ] ,
2016-11-30 16:11:41 +01:00
" id " :1
} " #;
2020-08-05 06:08:03 +02:00
let response = r # "{"jsonrpc":"2.0","result":{"result":""# . to_owned ( )
+ format! ( " 0x {:x} " , t . hash ( ) ) . as_ref ( )
+ r # "","token":""# ;
// then
let result = tester . io . handle_request_sync ( & request ) . unwrap ( ) ;
assert! (
result . starts_with ( & response ) ,
" Should return correct result. Expected: {:?}, Got: {:?} " ,
response ,
result
) ;
assert_eq! ( tester . signer . requests ( ) . len ( ) , 0 ) ;
assert_eq! ( tester . miner . imported_transactions . lock ( ) . len ( ) , 1 ) ;
2016-11-30 16:11:41 +01:00
}
2016-11-10 11:27:05 +01:00
#[ test ]
fn should_confirm_transaction_with_rlp ( ) {
2020-08-05 06:08:03 +02:00
// given
let tester = signer_tester ( ) ;
let address = tester . accounts . new_account ( & " test " . into ( ) ) . unwrap ( ) ;
let recipient = Address ::from_str ( " d46e8dd67c5d32be8058bb8eb970870f07244567 " ) . unwrap ( ) ;
let _confirmation_future = tester
. signer
. add_request (
ConfirmationPayload ::SendTransaction ( 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 ( ) ;
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 = t . with_signature ( signature , None ) ;
let rlp = encode ( & t ) ;
assert_eq! ( tester . signer . requests ( ) . len ( ) , 1 ) ;
// when
let request = r #" {
2016-11-10 11:27:05 +01:00
" jsonrpc " :" 2.0 " ,
" method " :" signer_confirmRequestRaw " ,
2020-08-05 06:08:03 +02:00
" params " :[ " 0x1 " , " 0x " #
. to_owned ( )
+ & rlp . to_hex ( )
+ r #" " ] ,
2016-11-10 11:27:05 +01:00
" id " :1
} " #;
2020-08-05 06:08:03 +02:00
let response = r # "{"jsonrpc":"2.0","result":""# . to_owned ( )
+ format! ( " 0x {:x} " , 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 ) ;
2016-11-10 11:27:05 +01:00
}
#[ test ]
fn should_return_error_when_sender_does_not_match ( ) {
2020-08-05 06:08:03 +02:00
// given
let tester = signer_tester ( ) ;
let address = tester . accounts . new_account ( & " test " . into ( ) ) . unwrap ( ) ;
let recipient = Address ::from_str ( " d46e8dd67c5d32be8058bb8eb970870f07244567 " ) . unwrap ( ) ;
let _confirmation_future = tester
. signer
. add_request (
ConfirmationPayload ::SendTransaction ( FilledTransactionRequest {
from : Address ::default ( ) ,
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 ( ) ;
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 #" {
2016-11-10 11:27:05 +01:00
" jsonrpc " :" 2.0 " ,
" method " :" signer_confirmRequestRaw " ,
2020-08-05 06:08:03 +02:00
" params " :[ " 0x1 " , " 0x " #
. to_owned ( )
+ & rlp . to_hex ( )
+ r #" " ] ,
2016-11-10 11:27:05 +01:00
" id " :1
} " #;
2020-08-05 06:08:03 +02:00
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 ) ;
2016-11-10 11:27:05 +01:00
}
2017-04-27 18:23:22 +02:00
#[ test ]
fn should_confirm_sign_transaction_with_rlp ( ) {
2020-08-05 06:08:03 +02:00
// given
let tester = signer_tester ( ) ;
let address = tester . accounts . new_account ( & " test " . into ( ) ) . unwrap ( ) ;
let recipient = Address ::from_str ( " d46e8dd67c5d32be8058bb8eb970870f07244567 " ) . unwrap ( ) ;
let _confirmation_future = 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 #" {
2017-04-27 18:23:22 +02:00
" jsonrpc " :" 2.0 " ,
" method " :" signer_confirmRequestRaw " ,
2020-08-05 06:08:03 +02:00
" params " :[ " 0x1 " , " 0x " #
. to_owned ( )
+ & rlp . to_hex ( )
+ r #" " ] ,
2017-04-27 18:23:22 +02:00
" id " :1
} " #;
2020-08-05 06:08:03 +02:00
let response = r # "{"jsonrpc":"2.0","result":{"# . to_owned ( )
+ r # ""raw":"0x"#
+ & rlp . to_hex ( )
+ r # "","#
+ r # ""tx":{"#
+ r # ""blockHash":null,"blockNumber":null,"#
+ & format! (
" \" chainId \" :{}, " ,
t . chain_id ( ) . map_or ( " null " . to_owned ( ) , | n | format! ( " {} " , n ) )
)
+ r # ""condition":null,"creates":null,"#
+ & format! ( " \" from \" : \" 0x {:x} \" , " , & address )
+ r # ""gas":"0x989680","gasPrice":"0x1000","#
+ & format! ( " \" hash \" : \" 0x {:x} \" , " , t . hash ( ) )
+ r # ""input":"0x","#
+ r # ""nonce":"0x0","#
+ & format! ( " \" publicKey \" : \" 0x {:x} \" , " , t . public_key ( ) . unwrap ( ) )
+ & format! ( " \" r \" : \" 0x {:x} \" , " , U256 ::from ( signature . r ( ) ) )
+ & format! ( " \" raw \" : \" 0x {} \" , " , rlp . to_hex ( ) )
+ & format! ( " \" s \" : \" 0x {:x} \" , " , U256 ::from ( signature . s ( ) ) )
+ & format! ( " \" standardV \" : \" 0x {:x} \" , " , U256 ::from ( t . standard_v ( ) ) )
+ r # ""to":"0xd46e8dd67c5d32be8058bb8eb970870f07244567","transactionIndex":null,"#
+ & format! ( " \" v \" : \" 0x {:x} \" , " , U256 ::from ( t . original_v ( ) ) )
+ 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 ) ;
2017-04-27 18:23:22 +02:00
}
#[ test ]
fn should_confirm_data_sign_with_signature ( ) {
2020-08-05 06:08:03 +02:00
// given
let tester = signer_tester ( ) ;
let address = tester . accounts . new_account ( & " test " . into ( ) ) . unwrap ( ) ;
let _confirmation_future = 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 ( ) ) ;
let signature = H520 (
tester
. accounts
. sign ( address , Some ( " test " . into ( ) ) , data_hash )
. unwrap ( )
. into_electrum ( ) ,
) ;
let signature = format! ( " {:?} " , signature ) ;
// when
let request = r #" {
2017-04-27 18:23:22 +02:00
" jsonrpc " :" 2.0 " ,
" method " :" signer_confirmRequestRaw " ,
2020-08-05 06:08:03 +02:00
" params " :[ " 0x1 " , " " #
. to_owned ( )
+ & signature
+ r #" " ] ,
2017-04-27 18:23:22 +02:00
" id " :1
} " #;
2020-08-05 06:08:03 +02:00
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-04-27 18:23:22 +02:00
}
2017-05-15 18:59:41 +02:00
#[ test ]
fn should_confirm_decrypt_with_phrase ( ) {
2020-08-05 06:08:03 +02:00
// given
let tester = signer_tester ( ) ;
let address = tester . accounts . new_account ( & " test " . into ( ) ) . unwrap ( ) ;
let _confirmation_future = 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 #" {
2017-05-15 18:59:41 +02:00
" jsonrpc " :" 2.0 " ,
" method " :" signer_confirmRequestRaw " ,
2020-08-05 06:08:03 +02:00
" params " :[ " 0x1 " , " #
. to_owned ( )
+ & decrypted
+ r #" ],
2017-05-15 18:59:41 +02:00
" id " :1
} " #;
2020-08-05 06:08:03 +02:00
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 ) ;
2017-05-15 18:59:41 +02:00
}
2016-09-21 12:44:49 +02:00
#[ test ]
fn should_generate_new_token ( ) {
2020-08-05 06:08:03 +02:00
// given
let tester = signer_tester ( ) ;
2016-09-21 12:44:49 +02:00
2020-08-05 06:08:03 +02:00
// when
let request = r #" {
2016-09-21 12:44:49 +02:00
" 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
} " #;
2020-08-05 06:08:03 +02:00
let response = r # "{"jsonrpc":"2.0","result":"new_token","id":1}"# ;
2016-09-21 12:44:49 +02:00
2020-08-05 06:08:03 +02:00
// then
assert_eq! (
tester . io . handle_request_sync ( & request ) ,
Some ( response . to_owned ( ) )
) ;
2016-09-21 12:44:49 +02:00
}