github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/signer/core/api_test.go (about)

     1  
     2  //此源码被清华学神尹成大魔王专业翻译分析并修改
     3  //尹成QQ77025077
     4  //尹成微信18510341407
     5  //尹成所在QQ群721929980
     6  //尹成邮箱 yinc13@mails.tsinghua.edu.cn
     7  //尹成毕业于清华大学,微软区块链领域全球最有价值专家
     8  //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620
     9  //版权所有2018 Go Ethereum作者
    10  //此文件是Go以太坊的一部分。
    11  //
    12  //Go以太坊是免费软件:您可以重新发布和/或修改它
    13  //根据GNU通用公共许可证的条款
    14  //自由软件基金会,或者许可证的第3版,或者
    15  //(由您选择)任何更高版本。
    16  //
    17  //Go以太坊的分布希望它会有用,
    18  //但没有任何保证;甚至没有
    19  //适销性或特定用途的适用性。见
    20  //GNU通用公共许可证了解更多详细信息。
    21  //
    22  //你应该已经收到一份GNU通用公共许可证的副本
    23  //一起去以太坊吧。如果没有,请参见<http://www.gnu.org/licenses/>。
    24  //
    25  package core
    26  
    27  import (
    28  	"bytes"
    29  	"context"
    30  	"fmt"
    31  	"io/ioutil"
    32  	"math/big"
    33  	"os"
    34  	"path/filepath"
    35  	"testing"
    36  	"time"
    37  
    38  	"github.com/ethereum/go-ethereum/accounts/keystore"
    39  	"github.com/ethereum/go-ethereum/cmd/utils"
    40  	"github.com/ethereum/go-ethereum/common"
    41  	"github.com/ethereum/go-ethereum/common/hexutil"
    42  	"github.com/ethereum/go-ethereum/core/types"
    43  	"github.com/ethereum/go-ethereum/internal/ethapi"
    44  	"github.com/ethereum/go-ethereum/rlp"
    45  )
    46  
    47  //用于测试
    48  type HeadlessUI struct {
    49  	controller chan string
    50  }
    51  
    52  func (ui *HeadlessUI) OnSignerStartup(info StartupInfo) {
    53  }
    54  
    55  func (ui *HeadlessUI) OnApprovedTx(tx ethapi.SignTransactionResult) {
    56  	fmt.Printf("OnApproved called")
    57  }
    58  
    59  func (ui *HeadlessUI) ApproveTx(request *SignTxRequest) (SignTxResponse, error) {
    60  
    61  	switch <-ui.controller {
    62  	case "Y":
    63  		return SignTxResponse{request.Transaction, true, <-ui.controller}, nil
    64  case "M": //修改
    65  		old := big.Int(request.Transaction.Value)
    66  		newVal := big.NewInt(0).Add(&old, big.NewInt(1))
    67  		request.Transaction.Value = hexutil.Big(*newVal)
    68  		return SignTxResponse{request.Transaction, true, <-ui.controller}, nil
    69  	default:
    70  		return SignTxResponse{request.Transaction, false, ""}, nil
    71  	}
    72  }
    73  func (ui *HeadlessUI) ApproveSignData(request *SignDataRequest) (SignDataResponse, error) {
    74  	if "Y" == <-ui.controller {
    75  		return SignDataResponse{true, <-ui.controller}, nil
    76  	}
    77  	return SignDataResponse{false, ""}, nil
    78  }
    79  func (ui *HeadlessUI) ApproveExport(request *ExportRequest) (ExportResponse, error) {
    80  
    81  	return ExportResponse{<-ui.controller == "Y"}, nil
    82  
    83  }
    84  func (ui *HeadlessUI) ApproveImport(request *ImportRequest) (ImportResponse, error) {
    85  
    86  	if "Y" == <-ui.controller {
    87  		return ImportResponse{true, <-ui.controller, <-ui.controller}, nil
    88  	}
    89  	return ImportResponse{false, "", ""}, nil
    90  }
    91  func (ui *HeadlessUI) ApproveListing(request *ListRequest) (ListResponse, error) {
    92  
    93  	switch <-ui.controller {
    94  	case "A":
    95  		return ListResponse{request.Accounts}, nil
    96  	case "1":
    97  		l := make([]Account, 1)
    98  		l[0] = request.Accounts[1]
    99  		return ListResponse{l}, nil
   100  	default:
   101  		return ListResponse{nil}, nil
   102  	}
   103  }
   104  func (ui *HeadlessUI) ApproveNewAccount(request *NewAccountRequest) (NewAccountResponse, error) {
   105  
   106  	if "Y" == <-ui.controller {
   107  		return NewAccountResponse{true, <-ui.controller}, nil
   108  	}
   109  	return NewAccountResponse{false, ""}, nil
   110  }
   111  func (ui *HeadlessUI) ShowError(message string) {
   112  //stdout用于通信
   113  	fmt.Fprint(os.Stderr, message)
   114  }
   115  func (ui *HeadlessUI) ShowInfo(message string) {
   116  //stdout用于通信
   117  	fmt.Fprint(os.Stderr, message)
   118  }
   119  
   120  func tmpDirName(t *testing.T) string {
   121  	d, err := ioutil.TempDir("", "eth-keystore-test")
   122  	if err != nil {
   123  		t.Fatal(err)
   124  	}
   125  	d, err = filepath.EvalSymlinks(d)
   126  	if err != nil {
   127  		t.Fatal(err)
   128  	}
   129  	return d
   130  }
   131  
   132  func setup(t *testing.T) (*SignerAPI, chan string) {
   133  
   134  	controller := make(chan string, 10)
   135  
   136  	db, err := NewAbiDBFromFile("../../cmd/clef/4byte.json")
   137  	if err != nil {
   138  		utils.Fatalf(err.Error())
   139  	}
   140  	var (
   141  		ui  = &HeadlessUI{controller}
   142  		api = NewSignerAPI(
   143  			1,
   144  			tmpDirName(t),
   145  			true,
   146  			ui,
   147  			db,
   148  			true)
   149  	)
   150  	return api, controller
   151  }
   152  func createAccount(control chan string, api *SignerAPI, t *testing.T) {
   153  
   154  	control <- "Y"
   155  	control <- "apassword"
   156  	_, err := api.New(context.Background())
   157  	if err != nil {
   158  		t.Fatal(err)
   159  	}
   160  //允许传播更改的一段时间
   161  	time.Sleep(250 * time.Millisecond)
   162  }
   163  func failCreateAccount(control chan string, api *SignerAPI, t *testing.T) {
   164  	control <- "N"
   165  	acc, err := api.New(context.Background())
   166  	if err != ErrRequestDenied {
   167  		t.Fatal(err)
   168  	}
   169  	if acc.Address != (common.Address{}) {
   170  		t.Fatal("Empty address should be returned")
   171  	}
   172  }
   173  func list(control chan string, api *SignerAPI, t *testing.T) []Account {
   174  	control <- "A"
   175  	list, err := api.List(context.Background())
   176  	if err != nil {
   177  		t.Fatal(err)
   178  	}
   179  	return list
   180  }
   181  
   182  func TestNewAcc(t *testing.T) {
   183  
   184  	api, control := setup(t)
   185  	verifyNum := func(num int) {
   186  		if list := list(control, api, t); len(list) != num {
   187  			t.Errorf("Expected %d accounts, got %d", num, len(list))
   188  		}
   189  	}
   190  //测试创建和创建拒绝
   191  	createAccount(control, api, t)
   192  	createAccount(control, api, t)
   193  	failCreateAccount(control, api, t)
   194  	failCreateAccount(control, api, t)
   195  	createAccount(control, api, t)
   196  	failCreateAccount(control, api, t)
   197  	createAccount(control, api, t)
   198  	failCreateAccount(control, api, t)
   199  	verifyNum(4)
   200  
   201  //测试列表:
   202  //列出一个帐户
   203  	control <- "1"
   204  	list, err := api.List(context.Background())
   205  	if err != nil {
   206  		t.Fatal(err)
   207  	}
   208  	if len(list) != 1 {
   209  		t.Fatalf("List should only show one Account")
   210  	}
   211  //拒绝上市
   212  	control <- "Nope"
   213  	list, err = api.List(context.Background())
   214  	if len(list) != 0 {
   215  		t.Fatalf("List should be empty")
   216  	}
   217  	if err != ErrRequestDenied {
   218  		t.Fatal("Expected deny")
   219  	}
   220  }
   221  
   222  func TestSignData(t *testing.T) {
   223  
   224  	api, control := setup(t)
   225  //创建两个帐户
   226  	createAccount(control, api, t)
   227  	createAccount(control, api, t)
   228  	control <- "1"
   229  	list, err := api.List(context.Background())
   230  	if err != nil {
   231  		t.Fatal(err)
   232  	}
   233  	a := common.NewMixedcaseAddress(list[0].Address)
   234  
   235  	control <- "Y"
   236  	control <- "wrongpassword"
   237  	h, err := api.Sign(context.Background(), a, []byte("EHLO world"))
   238  	if h != nil {
   239  		t.Errorf("Expected nil-data, got %x", h)
   240  	}
   241  	if err != keystore.ErrDecrypt {
   242  		t.Errorf("Expected ErrLocked! %v", err)
   243  	}
   244  
   245  	control <- "No way"
   246  	h, err = api.Sign(context.Background(), a, []byte("EHLO world"))
   247  	if h != nil {
   248  		t.Errorf("Expected nil-data, got %x", h)
   249  	}
   250  	if err != ErrRequestDenied {
   251  		t.Errorf("Expected ErrRequestDenied! %v", err)
   252  	}
   253  
   254  	control <- "Y"
   255  	control <- "apassword"
   256  	h, err = api.Sign(context.Background(), a, []byte("EHLO world"))
   257  
   258  	if err != nil {
   259  		t.Fatal(err)
   260  	}
   261  	if h == nil || len(h) != 65 {
   262  		t.Errorf("Expected 65 byte signature (got %d bytes)", len(h))
   263  	}
   264  }
   265  func mkTestTx(from common.MixedcaseAddress) SendTxArgs {
   266  	to := common.NewMixedcaseAddress(common.HexToAddress("0x1337"))
   267  	gas := hexutil.Uint64(21000)
   268  	gasPrice := (hexutil.Big)(*big.NewInt(2000000000))
   269  	value := (hexutil.Big)(*big.NewInt(1e18))
   270  	nonce := (hexutil.Uint64)(0)
   271  	data := hexutil.Bytes(common.Hex2Bytes("01020304050607080a"))
   272  	tx := SendTxArgs{
   273  		From:     from,
   274  		To:       &to,
   275  		Gas:      gas,
   276  		GasPrice: gasPrice,
   277  		Value:    value,
   278  		Data:     &data,
   279  		Nonce:    nonce}
   280  	return tx
   281  }
   282  
   283  func TestSignTx(t *testing.T) {
   284  
   285  	var (
   286  		list      Accounts
   287  		res, res2 *ethapi.SignTransactionResult
   288  		err       error
   289  	)
   290  
   291  	api, control := setup(t)
   292  	createAccount(control, api, t)
   293  	control <- "A"
   294  	list, err = api.List(context.Background())
   295  	if err != nil {
   296  		t.Fatal(err)
   297  	}
   298  	a := common.NewMixedcaseAddress(list[0].Address)
   299  
   300  	methodSig := "test(uint)"
   301  	tx := mkTestTx(a)
   302  
   303  	control <- "Y"
   304  	control <- "wrongpassword"
   305  	res, err = api.SignTransaction(context.Background(), tx, &methodSig)
   306  	if res != nil {
   307  		t.Errorf("Expected nil-response, got %v", res)
   308  	}
   309  	if err != keystore.ErrDecrypt {
   310  		t.Errorf("Expected ErrLocked! %v", err)
   311  	}
   312  
   313  	control <- "No way"
   314  	res, err = api.SignTransaction(context.Background(), tx, &methodSig)
   315  	if res != nil {
   316  		t.Errorf("Expected nil-response, got %v", res)
   317  	}
   318  	if err != ErrRequestDenied {
   319  		t.Errorf("Expected ErrRequestDenied! %v", err)
   320  	}
   321  
   322  	control <- "Y"
   323  	control <- "apassword"
   324  	res, err = api.SignTransaction(context.Background(), tx, &methodSig)
   325  
   326  	if err != nil {
   327  		t.Fatal(err)
   328  	}
   329  	parsedTx := &types.Transaction{}
   330  	rlp.Decode(bytes.NewReader(res.Raw), parsedTx)
   331  //用户界面不应修改Tx
   332  	if parsedTx.Value().Cmp(tx.Value.ToInt()) != 0 {
   333  		t.Errorf("Expected value to be unchanged, expected %v got %v", tx.Value, parsedTx.Value())
   334  	}
   335  	control <- "Y"
   336  	control <- "apassword"
   337  
   338  	res2, err = api.SignTransaction(context.Background(), tx, &methodSig)
   339  	if err != nil {
   340  		t.Fatal(err)
   341  	}
   342  	if !bytes.Equal(res.Raw, res2.Raw) {
   343  		t.Error("Expected tx to be unmodified by UI")
   344  	}
   345  
   346  //Tx由用户界面修改
   347  	control <- "M"
   348  	control <- "apassword"
   349  
   350  	res2, err = api.SignTransaction(context.Background(), tx, &methodSig)
   351  	if err != nil {
   352  		t.Fatal(err)
   353  	}
   354  
   355  	parsedTx2 := &types.Transaction{}
   356  	rlp.Decode(bytes.NewReader(res.Raw), parsedTx2)
   357  //用户界面应修改Tx
   358  	if parsedTx2.Value().Cmp(tx.Value.ToInt()) != 0 {
   359  		t.Errorf("Expected value to be unchanged, got %v", parsedTx.Value())
   360  	}
   361  
   362  	if bytes.Equal(res.Raw, res2.Raw) {
   363  		t.Error("Expected tx to be modified by UI")
   364  	}
   365  
   366  }
   367  
   368  /*
   369  func测试同步响应(t*testing.t)
   370  
   371   //设置一个帐户
   372   API,控件:=设置(T)
   373   创建帐户(控件、API、T)
   374  
   375   //两个事务,第二个事务的值大于第一个事务的值
   376   tx1:=mktestx()。
   377   newval:=big.newint(0).add((*big.int)(tx1.value),big.newint(1))
   378   tx2:=mktestx()。
   379   tx2.value=(*hexUtil.big)(newval)
   380  
   381   控件<-“w”//等待
   382   控制<-“Y”//
   383   控件<-“apassword”
   384   控制<-“Y”//
   385   控件<-“apassword”
   386  
   387   无功误差
   388  
   389   h1,err:=api.signTransaction(context.background(),common.hextoAddress(“1111”),tx1,nil)
   390   h2,错误:=api.signTransaction(context.background(),common.hextoAddress(“2222”),tx2,nil)
   391  
   392  
   393   }
   394  **/
   395