github.com/sberex/go-sberex@v1.8.2-0.20181113200658-ed96ac38f7d7/contracts/chequebook/cheque_test.go (about)

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