387 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			387 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 
								 | 
							
								// Copyright 2018 The go-ethereum Authors
							 | 
						||
| 
								 | 
							
								// This file is part of go-ethereum.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// go-ethereum 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.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// go-ethereum 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 go-ethereum. If not, see <http://www.gnu.org/licenses/>.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								package core
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import (
							 | 
						||
| 
								 | 
							
									"bytes"
							 | 
						||
| 
								 | 
							
									"context"
							 | 
						||
| 
								 | 
							
									"fmt"
							 | 
						||
| 
								 | 
							
									"io/ioutil"
							 | 
						||
| 
								 | 
							
									"math/big"
							 | 
						||
| 
								 | 
							
									"os"
							 | 
						||
| 
								 | 
							
									"path/filepath"
							 | 
						||
| 
								 | 
							
									"testing"
							 | 
						||
| 
								 | 
							
									"time"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									"github.com/ethereum/go-ethereum/accounts/keystore"
							 | 
						||
| 
								 | 
							
									"github.com/ethereum/go-ethereum/cmd/utils"
							 | 
						||
| 
								 | 
							
									"github.com/ethereum/go-ethereum/common"
							 | 
						||
| 
								 | 
							
									"github.com/ethereum/go-ethereum/common/hexutil"
							 | 
						||
| 
								 | 
							
									"github.com/ethereum/go-ethereum/core/types"
							 | 
						||
| 
								 | 
							
									"github.com/ethereum/go-ethereum/internal/ethapi"
							 | 
						||
| 
								 | 
							
									"github.com/ethereum/go-ethereum/rlp"
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//Used for testing
							 | 
						||
| 
								 | 
							
								type HeadlessUI struct {
							 | 
						||
| 
								 | 
							
									controller chan string
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (ui *HeadlessUI) OnSignerStartup(info StartupInfo) {
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (ui *HeadlessUI) OnApprovedTx(tx ethapi.SignTransactionResult) {
							 | 
						||
| 
								 | 
							
									fmt.Printf("OnApproved called")
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (ui *HeadlessUI) ApproveTx(request *SignTxRequest) (SignTxResponse, error) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									switch <-ui.controller {
							 | 
						||
| 
								 | 
							
									case "Y":
							 | 
						||
| 
								 | 
							
										return SignTxResponse{request.Transaction, true, <-ui.controller}, nil
							 | 
						||
| 
								 | 
							
									case "M": //Modify
							 | 
						||
| 
								 | 
							
										old := big.Int(request.Transaction.Value)
							 | 
						||
| 
								 | 
							
										newVal := big.NewInt(0).Add(&old, big.NewInt(1))
							 | 
						||
| 
								 | 
							
										request.Transaction.Value = hexutil.Big(*newVal)
							 | 
						||
| 
								 | 
							
										return SignTxResponse{request.Transaction, true, <-ui.controller}, nil
							 | 
						||
| 
								 | 
							
									default:
							 | 
						||
| 
								 | 
							
										return SignTxResponse{request.Transaction, false, ""}, nil
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								func (ui *HeadlessUI) ApproveSignData(request *SignDataRequest) (SignDataResponse, error) {
							 | 
						||
| 
								 | 
							
									if "Y" == <-ui.controller {
							 | 
						||
| 
								 | 
							
										return SignDataResponse{true, <-ui.controller}, nil
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return SignDataResponse{false, ""}, nil
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								func (ui *HeadlessUI) ApproveExport(request *ExportRequest) (ExportResponse, error) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return ExportResponse{<-ui.controller == "Y"}, nil
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								func (ui *HeadlessUI) ApproveImport(request *ImportRequest) (ImportResponse, error) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if "Y" == <-ui.controller {
							 | 
						||
| 
								 | 
							
										return ImportResponse{true, <-ui.controller, <-ui.controller}, nil
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return ImportResponse{false, "", ""}, nil
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								func (ui *HeadlessUI) ApproveListing(request *ListRequest) (ListResponse, error) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									switch <-ui.controller {
							 | 
						||
| 
								 | 
							
									case "A":
							 | 
						||
| 
								 | 
							
										return ListResponse{request.Accounts}, nil
							 | 
						||
| 
								 | 
							
									case "1":
							 | 
						||
| 
								 | 
							
										l := make([]Account, 1)
							 | 
						||
| 
								 | 
							
										l[0] = request.Accounts[1]
							 | 
						||
| 
								 | 
							
										return ListResponse{l}, nil
							 | 
						||
| 
								 | 
							
									default:
							 | 
						||
| 
								 | 
							
										return ListResponse{nil}, nil
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								func (ui *HeadlessUI) ApproveNewAccount(request *NewAccountRequest) (NewAccountResponse, error) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if "Y" == <-ui.controller {
							 | 
						||
| 
								 | 
							
										return NewAccountResponse{true, <-ui.controller}, nil
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return NewAccountResponse{false, ""}, nil
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								func (ui *HeadlessUI) ShowError(message string) {
							 | 
						||
| 
								 | 
							
									//stdout is used by communication
							 | 
						||
| 
								 | 
							
									fmt.Fprint(os.Stderr, message)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								func (ui *HeadlessUI) ShowInfo(message string) {
							 | 
						||
| 
								 | 
							
									//stdout is used by communication
							 | 
						||
| 
								 | 
							
									fmt.Fprint(os.Stderr, message)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func tmpDirName(t *testing.T) string {
							 | 
						||
| 
								 | 
							
									d, err := ioutil.TempDir("", "eth-keystore-test")
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										t.Fatal(err)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									d, err = filepath.EvalSymlinks(d)
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										t.Fatal(err)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return d
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func setup(t *testing.T) (*SignerAPI, chan string) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									controller := make(chan string, 10)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									db, err := NewAbiDBFromFile("../../cmd/clef/4byte.json")
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										utils.Fatalf(err.Error())
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									var (
							 | 
						||
| 
								 | 
							
										ui  = &HeadlessUI{controller}
							 | 
						||
| 
								 | 
							
										api = NewSignerAPI(
							 | 
						||
| 
								 | 
							
											1,
							 | 
						||
| 
								 | 
							
											tmpDirName(t),
							 | 
						||
| 
								 | 
							
											true,
							 | 
						||
| 
								 | 
							
											ui,
							 | 
						||
| 
								 | 
							
											db,
							 | 
						||
| 
								 | 
							
											true)
							 | 
						||
| 
								 | 
							
									)
							 | 
						||
| 
								 | 
							
									return api, controller
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								func createAccount(control chan string, api *SignerAPI, t *testing.T) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									control <- "Y"
							 | 
						||
| 
								 | 
							
									control <- "apassword"
							 | 
						||
| 
								 | 
							
									_, err := api.New(context.Background())
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										t.Fatal(err)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									// Some time to allow changes to propagate
							 | 
						||
| 
								 | 
							
									time.Sleep(250 * time.Millisecond)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								func failCreateAccount(control chan string, api *SignerAPI, t *testing.T) {
							 | 
						||
| 
								 | 
							
									control <- "N"
							 | 
						||
| 
								 | 
							
									acc, err := api.New(context.Background())
							 | 
						||
| 
								 | 
							
									if err != ErrRequestDenied {
							 | 
						||
| 
								 | 
							
										t.Fatal(err)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if acc.Address != (common.Address{}) {
							 | 
						||
| 
								 | 
							
										t.Fatal("Empty address should be returned")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								func list(control chan string, api *SignerAPI, t *testing.T) []Account {
							 | 
						||
| 
								 | 
							
									control <- "A"
							 | 
						||
| 
								 | 
							
									list, err := api.List(context.Background())
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										t.Fatal(err)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return list
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func TestNewAcc(t *testing.T) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									api, control := setup(t)
							 | 
						||
| 
								 | 
							
									verifyNum := func(num int) {
							 | 
						||
| 
								 | 
							
										if list := list(control, api, t); len(list) != num {
							 | 
						||
| 
								 | 
							
											t.Errorf("Expected %d accounts, got %d", num, len(list))
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									// Testing create and create-deny
							 | 
						||
| 
								 | 
							
									createAccount(control, api, t)
							 | 
						||
| 
								 | 
							
									createAccount(control, api, t)
							 | 
						||
| 
								 | 
							
									failCreateAccount(control, api, t)
							 | 
						||
| 
								 | 
							
									failCreateAccount(control, api, t)
							 | 
						||
| 
								 | 
							
									createAccount(control, api, t)
							 | 
						||
| 
								 | 
							
									failCreateAccount(control, api, t)
							 | 
						||
| 
								 | 
							
									createAccount(control, api, t)
							 | 
						||
| 
								 | 
							
									failCreateAccount(control, api, t)
							 | 
						||
| 
								 | 
							
									verifyNum(4)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// Testing listing:
							 | 
						||
| 
								 | 
							
									// Listing one Account
							 | 
						||
| 
								 | 
							
									control <- "1"
							 | 
						||
| 
								 | 
							
									list, err := api.List(context.Background())
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										t.Fatal(err)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if len(list) != 1 {
							 | 
						||
| 
								 | 
							
										t.Fatalf("List should only show one Account")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									// Listing denied
							 | 
						||
| 
								 | 
							
									control <- "Nope"
							 | 
						||
| 
								 | 
							
									list, err = api.List(context.Background())
							 | 
						||
| 
								 | 
							
									if len(list) != 0 {
							 | 
						||
| 
								 | 
							
										t.Fatalf("List should be empty")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if err != ErrRequestDenied {
							 | 
						||
| 
								 | 
							
										t.Fatal("Expected deny")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func TestSignData(t *testing.T) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									api, control := setup(t)
							 | 
						||
| 
								 | 
							
									//Create two accounts
							 | 
						||
| 
								 | 
							
									createAccount(control, api, t)
							 | 
						||
| 
								 | 
							
									createAccount(control, api, t)
							 | 
						||
| 
								 | 
							
									control <- "1"
							 | 
						||
| 
								 | 
							
									list, err := api.List(context.Background())
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										t.Fatal(err)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									a := common.NewMixedcaseAddress(list[0].Address)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									control <- "Y"
							 | 
						||
| 
								 | 
							
									control <- "wrongpassword"
							 | 
						||
| 
								 | 
							
									h, err := api.Sign(context.Background(), a, []byte("EHLO world"))
							 | 
						||
| 
								 | 
							
									if h != nil {
							 | 
						||
| 
								 | 
							
										t.Errorf("Expected nil-data, got %x", h)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if err != keystore.ErrDecrypt {
							 | 
						||
| 
								 | 
							
										t.Errorf("Expected ErrLocked! %v", err)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									control <- "No way"
							 | 
						||
| 
								 | 
							
									h, err = api.Sign(context.Background(), a, []byte("EHLO world"))
							 | 
						||
| 
								 | 
							
									if h != nil {
							 | 
						||
| 
								 | 
							
										t.Errorf("Expected nil-data, got %x", h)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if err != ErrRequestDenied {
							 | 
						||
| 
								 | 
							
										t.Errorf("Expected ErrRequestDenied! %v", err)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									control <- "Y"
							 | 
						||
| 
								 | 
							
									control <- "apassword"
							 | 
						||
| 
								 | 
							
									h, err = api.Sign(context.Background(), a, []byte("EHLO world"))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										t.Fatal(err)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if h == nil || len(h) != 65 {
							 | 
						||
| 
								 | 
							
										t.Errorf("Expected 65 byte signature (got %d bytes)", len(h))
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								func mkTestTx(from common.MixedcaseAddress) SendTxArgs {
							 | 
						||
| 
								 | 
							
									to := common.NewMixedcaseAddress(common.HexToAddress("0x1337"))
							 | 
						||
| 
								 | 
							
									gas := hexutil.Uint64(21000)
							 | 
						||
| 
								 | 
							
									gasPrice := (hexutil.Big)(*big.NewInt(2000000000))
							 | 
						||
| 
								 | 
							
									value := (hexutil.Big)(*big.NewInt(1e18))
							 | 
						||
| 
								 | 
							
									nonce := (hexutil.Uint64)(0)
							 | 
						||
| 
								 | 
							
									data := hexutil.Bytes(common.Hex2Bytes("01020304050607080a"))
							 | 
						||
| 
								 | 
							
									tx := SendTxArgs{
							 | 
						||
| 
								 | 
							
										From:     from,
							 | 
						||
| 
								 | 
							
										To:       &to,
							 | 
						||
| 
								 | 
							
										Gas:      gas,
							 | 
						||
| 
								 | 
							
										GasPrice: gasPrice,
							 | 
						||
| 
								 | 
							
										Value:    value,
							 | 
						||
| 
								 | 
							
										Data:     &data,
							 | 
						||
| 
								 | 
							
										Nonce:    nonce}
							 | 
						||
| 
								 | 
							
									return tx
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func TestSignTx(t *testing.T) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									var (
							 | 
						||
| 
								 | 
							
										list      Accounts
							 | 
						||
| 
								 | 
							
										res, res2 *ethapi.SignTransactionResult
							 | 
						||
| 
								 | 
							
										err       error
							 | 
						||
| 
								 | 
							
									)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									api, control := setup(t)
							 | 
						||
| 
								 | 
							
									createAccount(control, api, t)
							 | 
						||
| 
								 | 
							
									control <- "A"
							 | 
						||
| 
								 | 
							
									list, err = api.List(context.Background())
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										t.Fatal(err)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									a := common.NewMixedcaseAddress(list[0].Address)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									methodSig := "test(uint)"
							 | 
						||
| 
								 | 
							
									tx := mkTestTx(a)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									control <- "Y"
							 | 
						||
| 
								 | 
							
									control <- "wrongpassword"
							 | 
						||
| 
								 | 
							
									res, err = api.SignTransaction(context.Background(), tx, &methodSig)
							 | 
						||
| 
								 | 
							
									if res != nil {
							 | 
						||
| 
								 | 
							
										t.Errorf("Expected nil-response, got %v", res)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if err != keystore.ErrDecrypt {
							 | 
						||
| 
								 | 
							
										t.Errorf("Expected ErrLocked! %v", err)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									control <- "No way"
							 | 
						||
| 
								 | 
							
									res, err = api.SignTransaction(context.Background(), tx, &methodSig)
							 | 
						||
| 
								 | 
							
									if res != nil {
							 | 
						||
| 
								 | 
							
										t.Errorf("Expected nil-response, got %v", res)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if err != ErrRequestDenied {
							 | 
						||
| 
								 | 
							
										t.Errorf("Expected ErrRequestDenied! %v", err)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									control <- "Y"
							 | 
						||
| 
								 | 
							
									control <- "apassword"
							 | 
						||
| 
								 | 
							
									res, err = api.SignTransaction(context.Background(), tx, &methodSig)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										t.Fatal(err)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									parsedTx := &types.Transaction{}
							 | 
						||
| 
								 | 
							
									rlp.Decode(bytes.NewReader(res.Raw), parsedTx)
							 | 
						||
| 
								 | 
							
									//The tx should NOT be modified by the UI
							 | 
						||
| 
								 | 
							
									if parsedTx.Value().Cmp(tx.Value.ToInt()) != 0 {
							 | 
						||
| 
								 | 
							
										t.Errorf("Expected value to be unchanged, expected %v got %v", tx.Value, parsedTx.Value())
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									control <- "Y"
							 | 
						||
| 
								 | 
							
									control <- "apassword"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									res2, err = api.SignTransaction(context.Background(), tx, &methodSig)
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										t.Fatal(err)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if !bytes.Equal(res.Raw, res2.Raw) {
							 | 
						||
| 
								 | 
							
										t.Error("Expected tx to be unmodified by UI")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									//The tx is modified by the UI
							 | 
						||
| 
								 | 
							
									control <- "M"
							 | 
						||
| 
								 | 
							
									control <- "apassword"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									res2, err = api.SignTransaction(context.Background(), tx, &methodSig)
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										t.Fatal(err)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									parsedTx2 := &types.Transaction{}
							 | 
						||
| 
								 | 
							
									rlp.Decode(bytes.NewReader(res.Raw), parsedTx2)
							 | 
						||
| 
								 | 
							
									//The tx should be modified by the UI
							 | 
						||
| 
								 | 
							
									if parsedTx2.Value().Cmp(tx.Value.ToInt()) != 0 {
							 | 
						||
| 
								 | 
							
										t.Errorf("Expected value to be unchanged, got %v", parsedTx.Value())
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if bytes.Equal(res.Raw, res2.Raw) {
							 | 
						||
| 
								 | 
							
										t.Error("Expected tx to be modified by UI")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								func TestAsyncronousResponses(t *testing.T){
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									//Set up one account
							 | 
						||
| 
								 | 
							
									api, control := setup(t)
							 | 
						||
| 
								 | 
							
									createAccount(control, api, t)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// Two transactions, the second one with larger value than the first
							 | 
						||
| 
								 | 
							
									tx1 := mkTestTx()
							 | 
						||
| 
								 | 
							
									newVal := big.NewInt(0).Add((*big.Int) (tx1.Value), big.NewInt(1))
							 | 
						||
| 
								 | 
							
									tx2 := mkTestTx()
							 | 
						||
| 
								 | 
							
									tx2.Value = (*hexutil.Big)(newVal)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									control <- "W" //wait
							 | 
						||
| 
								 | 
							
									control <- "Y" //
							 | 
						||
| 
								 | 
							
									control <- "apassword"
							 | 
						||
| 
								 | 
							
									control <- "Y" //
							 | 
						||
| 
								 | 
							
									control <- "apassword"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									var err error
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									h1, err := api.SignTransaction(context.Background(), common.HexToAddress("1111"), tx1, nil)
							 | 
						||
| 
								 | 
							
									h2, err := api.SignTransaction(context.Background(), common.HexToAddress("2222"), tx2, nil)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								*/
							 |