github.com/m3shine/gochain@v2.2.26+incompatible/contracts/chequebook/cheque_test.go (about)

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