github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/contracts/chequebook/cheque_test.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 12:09:33</date>
    10  //</624342613247397888>
    11  
    12  
    13  package chequebook
    14  
    15  import (
    16  	"crypto/ecdsa"
    17  	"math/big"
    18  	"os"
    19  	"path/filepath"
    20  	"testing"
    21  	"time"
    22  
    23  	"github.com/ethereum/go-ethereum/accounts/abi/bind"
    24  	"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
    25  	"github.com/ethereum/go-ethereum/common"
    26  	"github.com/ethereum/go-ethereum/contracts/chequebook/contract"
    27  	"github.com/ethereum/go-ethereum/core"
    28  	"github.com/ethereum/go-ethereum/crypto"
    29  )
    30  
    31  var (
    32  	key0, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
    33  	key1, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
    34  	key2, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee")
    35  	addr0   = crypto.PubkeyToAddress(key0.PublicKey)
    36  	addr1   = crypto.PubkeyToAddress(key1.PublicKey)
    37  	addr2   = crypto.PubkeyToAddress(key2.PublicKey)
    38  )
    39  
    40  func newTestBackend() *backends.SimulatedBackend {
    41  	return backends.NewSimulatedBackend(core.GenesisAlloc{
    42  		addr0: {Balance: big.NewInt(1000000000)},
    43  		addr1: {Balance: big.NewInt(1000000000)},
    44  		addr2: {Balance: big.NewInt(1000000000)},
    45  	}, 10000000)
    46  }
    47  
    48  func deploy(prvKey *ecdsa.PrivateKey, amount *big.Int, backend *backends.SimulatedBackend) (common.Address, error) {
    49  	deployTransactor := bind.NewKeyedTransactor(prvKey)
    50  	deployTransactor.Value = amount
    51  	addr, _, _, err := contract.DeployChequebook(deployTransactor, backend)
    52  	if err != nil {
    53  		return common.Address{}, err
    54  	}
    55  	backend.Commit()
    56  	return addr, nil
    57  }
    58  
    59  func TestIssueAndReceive(t *testing.T) {
    60  	path := filepath.Join(os.TempDir(), "chequebook-test.json")
    61  	backend := newTestBackend()
    62  	addr0, err := deploy(key0, big.NewInt(0), backend)
    63  	if err != nil {
    64  		t.Fatalf("deploy contract: expected no error, got %v", err)
    65  	}
    66  	chbook, err := NewChequebook(path, addr0, key0, backend)
    67  	if err != nil {
    68  		t.Fatalf("expected no error, got %v", err)
    69  	}
    70  	chbook.sent[addr1] = new(big.Int).SetUint64(42)
    71  	amount := common.Big1
    72  
    73  	if _, err = chbook.Issue(addr1, amount); err == nil {
    74  		t.Fatalf("expected insufficient funds error, got none")
    75  	}
    76  
    77  	chbook.balance = new(big.Int).Set(common.Big1)
    78  	if chbook.Balance().Cmp(common.Big1) != 0 {
    79  		t.Fatalf("expected: %v, got %v", "0", chbook.Balance())
    80  	}
    81  
    82  	ch, err := chbook.Issue(addr1, amount)
    83  	if err != nil {
    84  		t.Fatalf("expected no error, got %v", err)
    85  	}
    86  
    87  	if chbook.Balance().Sign() != 0 {
    88  		t.Errorf("expected: %v, got %v", "0", chbook.Balance())
    89  	}
    90  
    91  	chbox, err := NewInbox(key1, addr0, addr1, &key0.PublicKey, backend)
    92  	if err != nil {
    93  		t.Fatalf("expected no error, got %v", err)
    94  	}
    95  
    96  	received, err := chbox.Receive(ch)
    97  	if err != nil {
    98  		t.Fatalf("expected no error, got %v", err)
    99  	}
   100  
   101  	if received.Cmp(big.NewInt(43)) != 0 {
   102  		t.Errorf("expected: %v, got %v", "43", received)
   103  	}
   104  
   105  }
   106  
   107  func TestCheckbookFile(t *testing.T) {
   108  	path := filepath.Join(os.TempDir(), "chequebook-test.json")
   109  	backend := newTestBackend()
   110  	chbook, err := NewChequebook(path, addr0, key0, backend)
   111  	if err != nil {
   112  		t.Fatalf("expected no error, got %v", err)
   113  	}
   114  	chbook.sent[addr1] = new(big.Int).SetUint64(42)
   115  	chbook.balance = new(big.Int).Set(common.Big1)
   116  
   117  	chbook.Save()
   118  
   119  	chbook, err = LoadChequebook(path, key0, backend, false)
   120  	if err != nil {
   121  		t.Fatalf("expected no error, got %v", err)
   122  	}
   123  	if chbook.Balance().Cmp(common.Big1) != 0 {
   124  		t.Errorf("expected: %v, got %v", "0", chbook.Balance())
   125  	}
   126  
   127  	var ch *Cheque
   128  	if ch, err = chbook.Issue(addr1, common.Big1); err != nil {
   129  		t.Fatalf("expected no error, got %v", err)
   130  	}
   131  	if ch.Amount.Cmp(new(big.Int).SetUint64(43)) != 0 {
   132  		t.Errorf("expected: %v, got %v", "0", ch.Amount)
   133  	}
   134  
   135  	err = chbook.Save()
   136  	if err != nil {
   137  		t.Fatalf("expected no error, got %v", err)
   138  	}
   139  }
   140  
   141  func TestVerifyErrors(t *testing.T) {
   142  	path0 := filepath.Join(os.TempDir(), "chequebook-test-0.json")
   143  	backend := newTestBackend()
   144  	contr0, err := deploy(key0, common.Big2, backend)
   145  	if err != nil {
   146  		t.Errorf("expected no error, got %v", err)
   147  	}
   148  	chbook0, err := NewChequebook(path0, contr0, key0, backend)
   149  	if err != nil {
   150  		t.Errorf("expected no error, got %v", err)
   151  	}
   152  
   153  	path1 := filepath.Join(os.TempDir(), "chequebook-test-1.json")
   154  	contr1, _ := deploy(key1, common.Big2, backend)
   155  	chbook1, err := NewChequebook(path1, contr1, key1, backend)
   156  	if err != nil {
   157  		t.Errorf("expected no error, got %v", err)
   158  	}
   159  
   160  	chbook0.sent[addr1] = new(big.Int).SetUint64(42)
   161  	chbook0.balance = new(big.Int).Set(common.Big2)
   162  	chbook1.balance = new(big.Int).Set(common.Big1)
   163  	amount := common.Big1
   164  	ch0, err := chbook0.Issue(addr1, amount)
   165  	if err != nil {
   166  		t.Fatalf("expected no error, got %v", err)
   167  	}
   168  
   169  	chbox, err := NewInbox(key1, contr0, addr1, &key0.PublicKey, backend)
   170  	if err != nil {
   171  		t.Fatalf("expected no error, got %v", err)
   172  	}
   173  
   174  	received, err := chbox.Receive(ch0)
   175  	if err != nil {
   176  		t.Fatalf("expected no error, got %v", err)
   177  	}
   178  
   179  	if received.Cmp(big.NewInt(43)) != 0 {
   180  		t.Errorf("expected: %v, got %v", "43", received)
   181  	}
   182  
   183  	ch1, err := chbook0.Issue(addr2, amount)
   184  	if err != nil {
   185  		t.Fatalf("expected no error, got %v", err)
   186  	}
   187  
   188  	received, err = chbox.Receive(ch1)
   189  	t.Logf("correct error: %v", err)
   190  	if err == nil {
   191  		t.Fatalf("expected receiver error, got none and value %v", received)
   192  	}
   193  
   194  	ch2, err := chbook1.Issue(addr1, amount)
   195  	if err != nil {
   196  		t.Fatalf("expected no error, got %v", err)
   197  	}
   198  	received, err = chbox.Receive(ch2)
   199  	t.Logf("correct error: %v", err)
   200  	if err == nil {
   201  		t.Fatalf("expected sender error, got none and value %v", received)
   202  	}
   203  
   204  	_, err = chbook1.Issue(addr1, new(big.Int).SetInt64(-1))
   205  	t.Logf("correct error: %v", err)
   206  	if err == nil {
   207  		t.Fatalf("expected incorrect amount error, got none")
   208  	}
   209  
   210  	received, err = chbox.Receive(ch0)
   211  	t.Logf("correct error: %v", err)
   212  	if err == nil {
   213  		t.Fatalf("expected incorrect amount error, got none and value %v", received)
   214  	}
   215  
   216  }
   217  
   218  func TestDeposit(t *testing.T) {
   219  	path0 := filepath.Join(os.TempDir(), "chequebook-test-0.json")
   220  	backend := newTestBackend()
   221  	contr0, _ := deploy(key0, new(big.Int), backend)
   222  
   223  	chbook, err := NewChequebook(path0, contr0, key0, backend)
   224  	if err != nil {
   225  		t.Errorf("expected no error, got %v", err)
   226  	}
   227  
   228  	balance := new(big.Int).SetUint64(42)
   229  	chbook.Deposit(balance)
   230  	backend.Commit()
   231  	if chbook.Balance().Cmp(balance) != 0 {
   232  		t.Fatalf("expected balance %v, got %v", balance, chbook.Balance())
   233  	}
   234  
   235  	amount := common.Big1
   236  	_, err = chbook.Issue(addr1, amount)
   237  	if err != nil {
   238  		t.Fatalf("expected no error, got %v", err)
   239  	}
   240  	backend.Commit()
   241  	exp := new(big.Int).SetUint64(41)
   242  	if chbook.Balance().Cmp(exp) != 0 {
   243  		t.Fatalf("expected balance %v, got %v", exp, chbook.Balance())
   244  	}
   245  
   246  //
   247  	chbook.AutoDeposit(0, balance, balance)
   248  	_, err = chbook.Issue(addr1, amount)
   249  	if err != nil {
   250  		t.Fatalf("expected no error, got %v", err)
   251  	}
   252  	backend.Commit()
   253  	_, err = chbook.Issue(addr1, amount)
   254  	if err != nil {
   255  		t.Fatalf("expected no error, got %v", err)
   256  	}
   257  	backend.Commit()
   258  	if chbook.Balance().Cmp(balance) != 0 {
   259  		t.Fatalf("expected balance %v, got %v", balance, chbook.Balance())
   260  	}
   261  
   262  //自动沉积
   263  	chbook.AutoDeposit(0, common.Big0, balance)
   264  	_, err = chbook.Issue(addr1, amount)
   265  	if err != nil {
   266  		t.Fatalf("expected no error, got %v", err)
   267  	}
   268  	backend.Commit()
   269  	_, err = chbook.Issue(addr1, amount)
   270  	if err != nil {
   271  		t.Fatalf("expected no error, got %v", err)
   272  	}
   273  	backend.Commit()
   274  
   275  	exp = new(big.Int).SetUint64(40)
   276  	if chbook.Balance().Cmp(exp) != 0 {
   277  		t.Fatalf("expected balance %v, got %v", exp, chbook.Balance())
   278  	}
   279  
   280  //autodeposit every 200ms if new cheque issued
   281  	interval := 200 * time.Millisecond
   282  	chbook.AutoDeposit(interval, common.Big1, balance)
   283  	_, err = chbook.Issue(addr1, amount)
   284  	if err != nil {
   285  		t.Fatalf("expected no error, got %v", err)
   286  	}
   287  	backend.Commit()
   288  	_, err = chbook.Issue(addr1, amount)
   289  	if err != nil {
   290  		t.Fatalf("expected no error, got %v", err)
   291  	}
   292  	backend.Commit()
   293  
   294  	exp = new(big.Int).SetUint64(38)
   295  	if chbook.Balance().Cmp(exp) != 0 {
   296  		t.Fatalf("expected balance %v, got %v", exp, chbook.Balance())
   297  	}
   298  
   299  	time.Sleep(3 * interval)
   300  	backend.Commit()
   301  	if chbook.Balance().Cmp(balance) != 0 {
   302  		t.Fatalf("expected balance %v, got %v", balance, chbook.Balance())
   303  	}
   304  
   305  	exp = new(big.Int).SetUint64(40)
   306  	chbook.AutoDeposit(4*interval, exp, balance)
   307  	_, err = chbook.Issue(addr1, amount)
   308  	if err != nil {
   309  		t.Fatalf("expected no error, got %v", err)
   310  	}
   311  	backend.Commit()
   312  	_, err = chbook.Issue(addr1, amount)
   313  	if err != nil {
   314  		t.Fatalf("expected no error, got %v", err)
   315  	}
   316  	time.Sleep(3 * interval)
   317  	backend.Commit()
   318  	if chbook.Balance().Cmp(exp) != 0 {
   319  		t.Fatalf("expected balance %v, got %v", exp, chbook.Balance())
   320  	}
   321  
   322  	_, err = chbook.Issue(addr1, amount)
   323  	if err != nil {
   324  		t.Fatalf("expected no error, got %v", err)
   325  	}
   326  	time.Sleep(1 * interval)
   327  	backend.Commit()
   328  
   329  	if chbook.Balance().Cmp(balance) != 0 {
   330  		t.Fatalf("expected balance %v, got %v", balance, chbook.Balance())
   331  	}
   332  
   333  	chbook.AutoDeposit(1*interval, common.Big0, balance)
   334  	chbook.Stop()
   335  
   336  	_, err = chbook.Issue(addr1, common.Big1)
   337  	if err != nil {
   338  		t.Fatalf("expected no error, got %v", err)
   339  	}
   340  	backend.Commit()
   341  
   342  	_, err = chbook.Issue(addr1, common.Big2)
   343  	if err != nil {
   344  		t.Fatalf("expected no error, got %v", err)
   345  	}
   346  
   347  	time.Sleep(1 * interval)
   348  	backend.Commit()
   349  
   350  	exp = new(big.Int).SetUint64(39)
   351  	if chbook.Balance().Cmp(exp) != 0 {
   352  		t.Fatalf("expected balance %v, got %v", exp, chbook.Balance())
   353  	}
   354  
   355  }
   356  
   357  func TestCash(t *testing.T) {
   358  	path := filepath.Join(os.TempDir(), "chequebook-test.json")
   359  	backend := newTestBackend()
   360  	contr0, _ := deploy(key0, common.Big2, backend)
   361  
   362  	chbook, err := NewChequebook(path, contr0, key0, backend)
   363  	if err != nil {
   364  		t.Errorf("expected no error, got %v", err)
   365  	}
   366  	chbook.sent[addr1] = new(big.Int).SetUint64(42)
   367  	amount := common.Big1
   368  	chbook.balance = new(big.Int).Set(common.Big1)
   369  	ch, err := chbook.Issue(addr1, amount)
   370  	if err != nil {
   371  		t.Fatalf("expected no error, got %v", err)
   372  	}
   373  	backend.Commit()
   374  	chbox, err := NewInbox(key1, contr0, addr1, &key0.PublicKey, backend)
   375  	if err != nil {
   376  		t.Fatalf("expected no error, got %v", err)
   377  	}
   378  
   379  //cashing latest cheque
   380  	if _, err = chbox.Receive(ch); err != nil {
   381  		t.Fatalf("expected no error, got %v", err)
   382  	}
   383  	if _, err = ch.Cash(chbook.session); err != nil {
   384  		t.Fatal("Cash failed:", err)
   385  	}
   386  	backend.Commit()
   387  
   388  	chbook.balance = new(big.Int).Set(common.Big3)
   389  	ch0, err := chbook.Issue(addr1, amount)
   390  	if err != nil {
   391  		t.Fatalf("expected no error, got %v", err)
   392  	}
   393  	backend.Commit()
   394  	ch1, err := chbook.Issue(addr1, amount)
   395  	if err != nil {
   396  		t.Fatalf("expected no error, got %v", err)
   397  	}
   398  	backend.Commit()
   399  
   400  	interval := 10 * time.Millisecond
   401  //用10ms间隔设置AutoCash
   402  	chbox.AutoCash(interval, nil)
   403  	_, err = chbox.Receive(ch0)
   404  	if err != nil {
   405  		t.Fatalf("expected no error, got %v", err)
   406  	}
   407  	_, err = chbox.Receive(ch1)
   408  	if err != nil {
   409  		t.Fatalf("expected no error, got %v", err)
   410  	}
   411  	backend.Commit()
   412  //after 3x interval time and 2 cheques received, exactly one cashing tx is sent
   413  	time.Sleep(4 * interval)
   414  	backend.Commit()
   415  
   416  //停止AutoCash后不再发送TX
   417  	ch2, err := chbook.Issue(addr1, amount)
   418  	if err != nil {
   419  		t.Fatalf("expected no error, got %v", err)
   420  	}
   421  	chbox.Stop()
   422  	_, err = chbox.Receive(ch2)
   423  	if err != nil {
   424  		t.Fatalf("expected no error, got %v", err)
   425  	}
   426  	time.Sleep(2 * interval)
   427  	backend.Commit()
   428  
   429  //autocash below 1
   430  	chbook.balance = big.NewInt(2)
   431  	chbox.AutoCash(0, common.Big1)
   432  
   433  	ch3, err := chbook.Issue(addr1, amount)
   434  	if err != nil {
   435  		t.Fatalf("expected no error, got %v", err)
   436  	}
   437  	backend.Commit()
   438  
   439  	ch4, err := chbook.Issue(addr1, amount)
   440  	if err != nil {
   441  		t.Fatalf("expected no error, got %v", err)
   442  	}
   443  	backend.Commit()
   444  
   445  	_, err = chbox.Receive(ch3)
   446  	if err != nil {
   447  		t.Fatalf("expected no error, got %v", err)
   448  	}
   449  	backend.Commit()
   450  	_, err = chbox.Receive(ch4)
   451  	if err != nil {
   452  		t.Fatalf("expected no error, got %v", err)
   453  	}
   454  	backend.Commit()
   455  
   456  //autochash on receipt when maxUncashed is 0
   457  	chbook.balance = new(big.Int).Set(common.Big2)
   458  	chbox.AutoCash(0, common.Big0)
   459  
   460  	ch5, err := chbook.Issue(addr1, amount)
   461  	if err != nil {
   462  		t.Fatalf("expected no error, got %v", err)
   463  	}
   464  	backend.Commit()
   465  
   466  	ch6, err := chbook.Issue(addr1, amount)
   467  	if err != nil {
   468  		t.Fatalf("expected no error, got %v", err)
   469  	}
   470  
   471  	_, err = chbox.Receive(ch5)
   472  	if err != nil {
   473  		t.Fatalf("expected no error, got %v", err)
   474  	}
   475  	backend.Commit()
   476  
   477  	_, err = chbox.Receive(ch6)
   478  	if err != nil {
   479  		t.Fatalf("expected no error, got %v", err)
   480  	}
   481  	backend.Commit()
   482  
   483  }
   484