github.com/ethersphere/bee/v2@v2.2.0/pkg/settlement/swap/swap_test.go (about)

     1  // Copyright 2020 The Swarm Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package swap_test
     6  
     7  import (
     8  	"context"
     9  	"errors"
    10  	"math/big"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/ethereum/go-ethereum/common"
    15  	"github.com/ethersphere/bee/v2/pkg/crypto"
    16  	"github.com/ethersphere/bee/v2/pkg/log"
    17  	"github.com/ethersphere/bee/v2/pkg/settlement/swap"
    18  	"github.com/ethersphere/bee/v2/pkg/settlement/swap/chequebook"
    19  	mockchequebook "github.com/ethersphere/bee/v2/pkg/settlement/swap/chequebook/mock"
    20  	mockchequestore "github.com/ethersphere/bee/v2/pkg/settlement/swap/chequestore/mock"
    21  	"github.com/ethersphere/bee/v2/pkg/settlement/swap/swapprotocol"
    22  	mockstore "github.com/ethersphere/bee/v2/pkg/statestore/mock"
    23  	"github.com/ethersphere/bee/v2/pkg/swarm"
    24  )
    25  
    26  type swapProtocolMock struct {
    27  	emitCheque func(context.Context, swarm.Address, common.Address, *big.Int, swapprotocol.IssueFunc) (*big.Int, error)
    28  }
    29  
    30  func (m *swapProtocolMock) EmitCheque(ctx context.Context, peer swarm.Address, beneficiary common.Address, value *big.Int, issueFunc swapprotocol.IssueFunc) (*big.Int, error) {
    31  	if m.emitCheque != nil {
    32  		return m.emitCheque(ctx, peer, beneficiary, value, issueFunc)
    33  	}
    34  	return nil, errors.New("not implemented")
    35  }
    36  
    37  type testObserver struct {
    38  	receivedCalled chan notifyPaymentReceivedCall
    39  	sentCalled     chan notifyPaymentSentCall
    40  }
    41  
    42  type notifyPaymentReceivedCall struct {
    43  	peer   swarm.Address
    44  	amount *big.Int
    45  }
    46  
    47  type notifyPaymentSentCall struct {
    48  	peer   swarm.Address
    49  	amount *big.Int
    50  	err    error
    51  }
    52  
    53  func newTestObserver() *testObserver {
    54  	return &testObserver{
    55  		receivedCalled: make(chan notifyPaymentReceivedCall, 1),
    56  		sentCalled:     make(chan notifyPaymentSentCall, 1),
    57  	}
    58  }
    59  
    60  func (t *testObserver) PeerDebt(peer swarm.Address) (*big.Int, error) {
    61  	return nil, nil
    62  }
    63  
    64  func (t *testObserver) NotifyPaymentReceived(peer swarm.Address, amount *big.Int) error {
    65  	t.receivedCalled <- notifyPaymentReceivedCall{
    66  		peer:   peer,
    67  		amount: amount,
    68  	}
    69  	return nil
    70  }
    71  
    72  func (t *testObserver) NotifyRefreshmentSent(peer swarm.Address, attemptedAmount, amount *big.Int, timestamp int64, allegedInterval int64, receivedError error) {
    73  }
    74  
    75  func (t *testObserver) NotifyRefreshmentReceived(peer swarm.Address, amount *big.Int, time int64) error {
    76  	return nil
    77  }
    78  
    79  func (t *testObserver) NotifyPaymentSent(peer swarm.Address, amount *big.Int, err error) {
    80  	t.sentCalled <- notifyPaymentSentCall{
    81  		peer:   peer,
    82  		amount: amount,
    83  		err:    err,
    84  	}
    85  }
    86  
    87  func (t *testObserver) Connect(peer swarm.Address, full bool) {
    88  
    89  }
    90  
    91  func (t *testObserver) Disconnect(peer swarm.Address) {
    92  
    93  }
    94  
    95  type addressbookMock struct {
    96  	migratePeer     func(oldPeer, newPeer swarm.Address) error
    97  	beneficiary     func(peer swarm.Address) (beneficiary common.Address, known bool, err error)
    98  	chequebook      func(peer swarm.Address) (chequebookAddress common.Address, known bool, err error)
    99  	beneficiaryPeer func(beneficiary common.Address) (peer swarm.Address, known bool, err error)
   100  	chequebookPeer  func(chequebook common.Address) (peer swarm.Address, known bool, err error)
   101  	putBeneficiary  func(peer swarm.Address, beneficiary common.Address) error
   102  	putChequebook   func(peer swarm.Address, chequebook common.Address) error
   103  	addDeductionFor func(peer swarm.Address) error
   104  	addDeductionBy  func(peer swarm.Address) error
   105  	getDeductionFor func(peer swarm.Address) (bool, error)
   106  	getDeductionBy  func(peer swarm.Address) (bool, error)
   107  }
   108  
   109  func (m *addressbookMock) MigratePeer(oldPeer, newPeer swarm.Address) error {
   110  	return m.migratePeer(oldPeer, newPeer)
   111  }
   112  func (m *addressbookMock) Beneficiary(peer swarm.Address) (beneficiary common.Address, known bool, err error) {
   113  	return m.beneficiary(peer)
   114  }
   115  func (m *addressbookMock) Chequebook(peer swarm.Address) (chequebookAddress common.Address, known bool, err error) {
   116  	return m.chequebook(peer)
   117  }
   118  func (m *addressbookMock) BeneficiaryPeer(beneficiary common.Address) (peer swarm.Address, known bool, err error) {
   119  	return m.beneficiaryPeer(beneficiary)
   120  }
   121  func (m *addressbookMock) ChequebookPeer(chequebook common.Address) (peer swarm.Address, known bool, err error) {
   122  	return m.chequebookPeer(chequebook)
   123  }
   124  func (m *addressbookMock) PutBeneficiary(peer swarm.Address, beneficiary common.Address) error {
   125  	return m.putBeneficiary(peer, beneficiary)
   126  }
   127  func (m *addressbookMock) PutChequebook(peer swarm.Address, chequebook common.Address) error {
   128  	return m.putChequebook(peer, chequebook)
   129  }
   130  func (m *addressbookMock) AddDeductionFor(peer swarm.Address) error {
   131  	return m.addDeductionFor(peer)
   132  }
   133  func (m *addressbookMock) AddDeductionBy(peer swarm.Address) error {
   134  	return m.addDeductionBy(peer)
   135  }
   136  func (m *addressbookMock) GetDeductionFor(peer swarm.Address) (bool, error) {
   137  	return m.getDeductionFor(peer)
   138  }
   139  func (m *addressbookMock) GetDeductionBy(peer swarm.Address) (bool, error) {
   140  	return m.getDeductionBy(peer)
   141  }
   142  
   143  type cashoutMock struct {
   144  	cashCheque    func(ctx context.Context, chequebook common.Address, recipient common.Address) (common.Hash, error)
   145  	cashoutStatus func(ctx context.Context, chequebookAddress common.Address) (*chequebook.CashoutStatus, error)
   146  }
   147  
   148  func (m *cashoutMock) CashCheque(ctx context.Context, chequebook, recipient common.Address) (common.Hash, error) {
   149  	return m.cashCheque(ctx, chequebook, recipient)
   150  }
   151  func (m *cashoutMock) CashoutStatus(ctx context.Context, chequebookAddress common.Address) (*chequebook.CashoutStatus, error) {
   152  	return m.cashoutStatus(ctx, chequebookAddress)
   153  }
   154  
   155  func TestReceiveCheque(t *testing.T) {
   156  	t.Parallel()
   157  
   158  	logger := log.Noop
   159  	store := mockstore.NewStateStore()
   160  	chequebookService := mockchequebook.NewChequebook()
   161  	amount := big.NewInt(50)
   162  	exchangeRate := big.NewInt(10)
   163  	deduction := big.NewInt(10)
   164  	chequebookAddress := common.HexToAddress("0xcd")
   165  
   166  	peer := swarm.MustParseHexAddress("abcd")
   167  	cheque := &chequebook.SignedCheque{
   168  		Cheque: chequebook.Cheque{
   169  			Beneficiary:      common.HexToAddress("0xab"),
   170  			CumulativePayout: big.NewInt(10),
   171  			Chequebook:       chequebookAddress,
   172  		},
   173  		Signature: []byte{},
   174  	}
   175  
   176  	chequeStore := mockchequestore.NewChequeStore(
   177  		mockchequestore.WithReceiveChequeFunc(func(ctx context.Context, c *chequebook.SignedCheque, e *big.Int, d *big.Int) (*big.Int, error) {
   178  			if !cheque.Equal(c) {
   179  				t.Fatalf("passed wrong cheque to store. wanted %v, got %v", cheque, c)
   180  			}
   181  			if exchangeRate.Cmp(e) != 0 {
   182  				t.Fatalf("passed wrong exchange rate to store. wanted %v, got %v", exchangeRate, e)
   183  			}
   184  			if deduction.Cmp(e) != 0 {
   185  				t.Fatalf("passed wrong deduction to store. wanted %v, got %v", deduction, d)
   186  			}
   187  			return amount, nil
   188  		}),
   189  	)
   190  
   191  	peerDeductionFor := false
   192  
   193  	networkID := uint64(1)
   194  	addressbook := &addressbookMock{
   195  		chequebook: func(p swarm.Address) (common.Address, bool, error) {
   196  			if !peer.Equal(p) {
   197  				t.Fatal("querying chequebook for wrong peer")
   198  			}
   199  			return chequebookAddress, true, nil
   200  		},
   201  		putChequebook: func(p swarm.Address, chequebook common.Address) (err error) {
   202  			if !peer.Equal(p) {
   203  				t.Fatal("storing chequebook for wrong peer")
   204  			}
   205  			if chequebook != chequebookAddress {
   206  				t.Fatal("storing wrong chequebook")
   207  			}
   208  			return nil
   209  		},
   210  		addDeductionFor: func(p swarm.Address) error {
   211  			peerDeductionFor = true
   212  			if !peer.Equal(p) {
   213  				t.Fatal("storing deduction for wrong peer")
   214  			}
   215  			return nil
   216  		},
   217  	}
   218  
   219  	observer := newTestObserver()
   220  
   221  	swap := swap.New(
   222  		&swapProtocolMock{},
   223  		logger,
   224  		store,
   225  		chequebookService,
   226  		chequeStore,
   227  		addressbook,
   228  		networkID,
   229  		&cashoutMock{},
   230  		observer,
   231  		common.Address{},
   232  	)
   233  
   234  	err := swap.ReceiveCheque(context.Background(), peer, cheque, exchangeRate, deduction)
   235  	if err != nil {
   236  		t.Fatal(err)
   237  	}
   238  
   239  	expectedAmount := big.NewInt(4)
   240  
   241  	select {
   242  	case call := <-observer.receivedCalled:
   243  		if call.amount.Cmp(expectedAmount) != 0 {
   244  			t.Fatalf("observer called with wrong amount. got %d, want %d", call.amount, expectedAmount)
   245  		}
   246  
   247  		if !call.peer.Equal(peer) {
   248  			t.Fatalf("observer called with wrong peer. got %v, want %v", call.peer, peer)
   249  		}
   250  
   251  	case <-time.After(time.Second):
   252  		t.Fatal("expected observer to be called")
   253  	}
   254  
   255  	if !peerDeductionFor {
   256  		t.Fatal("add deduction for peer not called")
   257  	}
   258  
   259  }
   260  
   261  func TestReceiveChequeReject(t *testing.T) {
   262  	t.Parallel()
   263  
   264  	logger := log.Noop
   265  	store := mockstore.NewStateStore()
   266  	chequebookService := mockchequebook.NewChequebook()
   267  	chequebookAddress := common.HexToAddress("0xcd")
   268  	exchangeRate := big.NewInt(10)
   269  	deduction := big.NewInt(10)
   270  
   271  	peer := swarm.MustParseHexAddress("abcd")
   272  	cheque := &chequebook.SignedCheque{
   273  		Cheque: chequebook.Cheque{
   274  			Beneficiary:      common.HexToAddress("0xab"),
   275  			CumulativePayout: big.NewInt(10),
   276  			Chequebook:       chequebookAddress,
   277  		},
   278  		Signature: []byte{},
   279  	}
   280  
   281  	var errReject = errors.New("reject")
   282  
   283  	chequeStore := mockchequestore.NewChequeStore(
   284  		mockchequestore.WithReceiveChequeFunc(func(ctx context.Context, c *chequebook.SignedCheque, e *big.Int, d *big.Int) (*big.Int, error) {
   285  			return nil, errReject
   286  		}),
   287  	)
   288  	networkID := uint64(1)
   289  	addressbook := &addressbookMock{
   290  		chequebook: func(p swarm.Address) (common.Address, bool, error) {
   291  			return chequebookAddress, true, nil
   292  		},
   293  	}
   294  
   295  	observer := newTestObserver()
   296  
   297  	swap := swap.New(
   298  		&swapProtocolMock{},
   299  		logger,
   300  		store,
   301  		chequebookService,
   302  		chequeStore,
   303  		addressbook,
   304  		networkID,
   305  		&cashoutMock{},
   306  		observer,
   307  		common.Address{},
   308  	)
   309  
   310  	err := swap.ReceiveCheque(context.Background(), peer, cheque, exchangeRate, deduction)
   311  	if err == nil {
   312  		t.Fatal("accepted invalid cheque")
   313  	}
   314  	if !errors.Is(err, errReject) {
   315  		t.Fatalf("wrong error. wanted %v, got %v", errReject, err)
   316  	}
   317  
   318  	select {
   319  	case <-observer.receivedCalled:
   320  		t.Fatalf("observer called by error.")
   321  	default:
   322  	}
   323  
   324  }
   325  
   326  func TestReceiveChequeWrongChequebook(t *testing.T) {
   327  	t.Parallel()
   328  
   329  	logger := log.Noop
   330  	store := mockstore.NewStateStore()
   331  	chequebookService := mockchequebook.NewChequebook()
   332  	chequebookAddress := common.HexToAddress("0xcd")
   333  	exchangeRate := big.NewInt(10)
   334  	deduction := big.NewInt(10)
   335  
   336  	peer := swarm.MustParseHexAddress("abcd")
   337  	cheque := &chequebook.SignedCheque{
   338  		Cheque: chequebook.Cheque{
   339  			Beneficiary:      common.HexToAddress("0xab"),
   340  			CumulativePayout: big.NewInt(10),
   341  			Chequebook:       chequebookAddress,
   342  		},
   343  		Signature: []byte{},
   344  	}
   345  
   346  	chequeStore := mockchequestore.NewChequeStore()
   347  	networkID := uint64(1)
   348  	addressbook := &addressbookMock{
   349  		chequebook: func(p swarm.Address) (common.Address, bool, error) {
   350  			return common.HexToAddress("0xcfff"), true, nil
   351  		},
   352  	}
   353  
   354  	observer := newTestObserver()
   355  	swapService := swap.New(
   356  		&swapProtocolMock{},
   357  		logger,
   358  		store,
   359  		chequebookService,
   360  		chequeStore,
   361  		addressbook,
   362  		networkID,
   363  		&cashoutMock{},
   364  		observer,
   365  		common.Address{},
   366  	)
   367  
   368  	err := swapService.ReceiveCheque(context.Background(), peer, cheque, exchangeRate, deduction)
   369  	if err == nil {
   370  		t.Fatal("accepted invalid cheque")
   371  	}
   372  	if !errors.Is(err, swap.ErrWrongChequebook) {
   373  		t.Fatalf("wrong error. wanted %v, got %v", swap.ErrWrongChequebook, err)
   374  	}
   375  
   376  	select {
   377  	case <-observer.receivedCalled:
   378  		t.Fatalf("observer called by error.")
   379  	default:
   380  	}
   381  
   382  }
   383  
   384  func TestPay(t *testing.T) {
   385  	t.Parallel()
   386  
   387  	logger := log.Noop
   388  	store := mockstore.NewStateStore()
   389  
   390  	amount := big.NewInt(50)
   391  	beneficiary := common.HexToAddress("0xcd")
   392  	peer := swarm.MustParseHexAddress("abcd")
   393  
   394  	networkID := uint64(1)
   395  	addressbook := &addressbookMock{
   396  		beneficiary: func(p swarm.Address) (common.Address, bool, error) {
   397  			if !peer.Equal(p) {
   398  				t.Fatal("querying beneficiary for wrong peer")
   399  			}
   400  			return beneficiary, true, nil
   401  		},
   402  	}
   403  
   404  	observer := newTestObserver()
   405  
   406  	var emitCalled bool
   407  	swap := swap.New(
   408  		&swapProtocolMock{
   409  			emitCheque: func(ctx context.Context, p swarm.Address, b common.Address, a *big.Int, issueFunc swapprotocol.IssueFunc) (*big.Int, error) {
   410  				if !peer.Equal(p) {
   411  					t.Fatal("sending to wrong peer")
   412  				}
   413  				if b != beneficiary {
   414  					t.Fatal("issuing for wrong beneficiary")
   415  				}
   416  				if amount.Cmp(a) != 0 {
   417  					t.Fatal("issuing with wrong amount")
   418  				}
   419  				emitCalled = true
   420  				return amount, nil
   421  			},
   422  		},
   423  		logger,
   424  		store,
   425  		mockchequebook.NewChequebook(),
   426  		mockchequestore.NewChequeStore(),
   427  		addressbook,
   428  		networkID,
   429  		&cashoutMock{},
   430  		observer,
   431  		common.Address{},
   432  	)
   433  
   434  	swap.Pay(context.Background(), peer, amount)
   435  
   436  	if !emitCalled {
   437  		t.Fatal("swap protocol was not called")
   438  	}
   439  }
   440  
   441  func TestPayIssueError(t *testing.T) {
   442  	t.Parallel()
   443  
   444  	logger := log.Noop
   445  	store := mockstore.NewStateStore()
   446  
   447  	amount := big.NewInt(50)
   448  	beneficiary := common.HexToAddress("0xcd")
   449  
   450  	peer := swarm.MustParseHexAddress("abcd")
   451  	errReject := errors.New("reject")
   452  	networkID := uint64(1)
   453  	addressbook := &addressbookMock{
   454  		beneficiary: func(p swarm.Address) (common.Address, bool, error) {
   455  			if !peer.Equal(p) {
   456  				t.Fatal("querying beneficiary for wrong peer")
   457  			}
   458  			return beneficiary, true, nil
   459  		},
   460  	}
   461  
   462  	swap := swap.New(
   463  		&swapProtocolMock{
   464  			emitCheque: func(c context.Context, a1 swarm.Address, a2 common.Address, i *big.Int, issueFunc swapprotocol.IssueFunc) (*big.Int, error) {
   465  				return nil, errReject
   466  			},
   467  		},
   468  		logger,
   469  		store,
   470  		mockchequebook.NewChequebook(),
   471  		mockchequestore.NewChequeStore(),
   472  		addressbook,
   473  		networkID,
   474  		&cashoutMock{},
   475  		nil,
   476  		common.Address{},
   477  	)
   478  
   479  	observer := newTestObserver()
   480  	swap.SetAccounting(observer)
   481  
   482  	swap.Pay(context.Background(), peer, amount)
   483  	select {
   484  	case call := <-observer.sentCalled:
   485  
   486  		if !call.peer.Equal(peer) {
   487  			t.Fatalf("observer called with wrong peer. got %v, want %v", call.peer, peer)
   488  		}
   489  		if !errors.Is(call.err, errReject) {
   490  			t.Fatalf("wrong error. wanted %v, got %v", errReject, call.err)
   491  		}
   492  
   493  	case <-time.After(time.Second):
   494  		t.Fatal("expected observer to be called")
   495  	}
   496  
   497  }
   498  
   499  func TestPayUnknownBeneficiary(t *testing.T) {
   500  	t.Parallel()
   501  
   502  	logger := log.Noop
   503  	store := mockstore.NewStateStore()
   504  
   505  	amount := big.NewInt(50)
   506  	peer := swarm.MustParseHexAddress("abcd")
   507  	networkID := uint64(1)
   508  	addressbook := &addressbookMock{
   509  		beneficiary: func(p swarm.Address) (common.Address, bool, error) {
   510  			if !peer.Equal(p) {
   511  				t.Fatal("querying beneficiary for wrong peer")
   512  			}
   513  			return common.Address{}, false, nil
   514  		},
   515  	}
   516  
   517  	observer := newTestObserver()
   518  
   519  	swapService := swap.New(
   520  		&swapProtocolMock{},
   521  		logger,
   522  		store,
   523  		mockchequebook.NewChequebook(),
   524  		mockchequestore.NewChequeStore(),
   525  		addressbook,
   526  		networkID,
   527  		&cashoutMock{},
   528  		observer,
   529  		common.Address{},
   530  	)
   531  
   532  	swapService.Pay(context.Background(), peer, amount)
   533  
   534  	select {
   535  	case call := <-observer.sentCalled:
   536  		if !call.peer.Equal(peer) {
   537  			t.Fatalf("observer called with wrong peer. got %v, want %v", call.peer, peer)
   538  		}
   539  		if !errors.Is(call.err, swap.ErrUnknownBeneficary) {
   540  			t.Fatalf("wrong error. wanted %v, got %v", swap.ErrUnknownBeneficary, call.err)
   541  		}
   542  
   543  	case <-time.After(time.Second):
   544  		t.Fatal("expected observer to be called")
   545  	}
   546  }
   547  
   548  func TestHandshake(t *testing.T) {
   549  	t.Parallel()
   550  
   551  	logger := log.Noop
   552  	store := mockstore.NewStateStore()
   553  
   554  	beneficiary := common.HexToAddress("0xcd")
   555  	networkID := uint64(1)
   556  	txHash := common.HexToHash("0x1")
   557  
   558  	peer, err := crypto.NewOverlayFromEthereumAddress(beneficiary[:], networkID, txHash.Bytes())
   559  
   560  	if err != nil {
   561  		t.Fatalf("crypto.NewOverlayFromEthereumAddress(...): unexpected error: %v", err)
   562  	}
   563  
   564  	var putCalled bool
   565  	swapService := swap.New(
   566  		&swapProtocolMock{},
   567  		logger,
   568  		store,
   569  		mockchequebook.NewChequebook(),
   570  		mockchequestore.NewChequeStore(),
   571  		&addressbookMock{
   572  			beneficiary: func(p swarm.Address) (common.Address, bool, error) {
   573  				return beneficiary, true, nil
   574  			},
   575  			beneficiaryPeer: func(common.Address) (peer swarm.Address, known bool, err error) {
   576  				return peer, true, nil
   577  			},
   578  			migratePeer: func(oldPeer, newPeer swarm.Address) error {
   579  				return nil
   580  			},
   581  			putBeneficiary: func(p swarm.Address, b common.Address) error {
   582  				putCalled = true
   583  				return nil
   584  			},
   585  		},
   586  		networkID,
   587  		&cashoutMock{},
   588  		nil,
   589  		common.Address{},
   590  	)
   591  
   592  	err = swapService.Handshake(peer, beneficiary)
   593  	if err != nil {
   594  		t.Fatal(err)
   595  	}
   596  
   597  	if putCalled {
   598  		t.Fatal("beneficiary was saved again")
   599  	}
   600  }
   601  
   602  func TestHandshakeNewPeer(t *testing.T) {
   603  	t.Parallel()
   604  
   605  	logger := log.Noop
   606  	store := mockstore.NewStateStore()
   607  
   608  	beneficiary := common.HexToAddress("0xcd")
   609  	trx := common.HexToHash("0x1")
   610  	networkID := uint64(1)
   611  	peer, err := crypto.NewOverlayFromEthereumAddress(beneficiary[:], networkID, trx.Bytes())
   612  
   613  	if err != nil {
   614  		t.Fatalf("crypto.NewOverlayFromEthereumAddress(...): unexpected error: %v", err)
   615  	}
   616  
   617  	var putCalled bool
   618  	swapService := swap.New(
   619  		&swapProtocolMock{},
   620  		logger,
   621  		store,
   622  		mockchequebook.NewChequebook(),
   623  		mockchequestore.NewChequeStore(),
   624  		&addressbookMock{
   625  			beneficiary: func(p swarm.Address) (common.Address, bool, error) {
   626  				return beneficiary, false, nil
   627  			},
   628  			beneficiaryPeer: func(beneficiary common.Address) (swarm.Address, bool, error) {
   629  				return peer, true, nil
   630  			},
   631  			migratePeer: func(oldPeer, newPeer swarm.Address) error {
   632  				return nil
   633  			},
   634  			putBeneficiary: func(p swarm.Address, b common.Address) error {
   635  				putCalled = true
   636  				return nil
   637  			},
   638  		},
   639  		networkID,
   640  		&cashoutMock{},
   641  		nil,
   642  		common.Address{},
   643  	)
   644  
   645  	err = swapService.Handshake(peer, beneficiary)
   646  	if err != nil {
   647  		t.Fatal(err)
   648  	}
   649  
   650  	if !putCalled {
   651  		t.Fatal("beneficiary was not saved")
   652  	}
   653  }
   654  
   655  func TestMigratePeer(t *testing.T) {
   656  	t.Parallel()
   657  
   658  	logger := log.Noop
   659  	store := mockstore.NewStateStore()
   660  
   661  	beneficiary := common.HexToAddress("0xcd")
   662  	trx := common.HexToHash("0x1")
   663  	networkID := uint64(1)
   664  	peer, err := crypto.NewOverlayFromEthereumAddress(beneficiary[:], networkID, trx.Bytes())
   665  
   666  	if err != nil {
   667  		t.Fatalf("crypto.NewOverlayFromEthereumAddress(...): unexpected error: %v", err)
   668  	}
   669  
   670  	swapService := swap.New(
   671  		&swapProtocolMock{},
   672  		logger,
   673  		store,
   674  		mockchequebook.NewChequebook(),
   675  		mockchequestore.NewChequeStore(),
   676  		&addressbookMock{
   677  			beneficiaryPeer: func(beneficiary common.Address) (swarm.Address, bool, error) {
   678  				return swarm.MustParseHexAddress("00112233"), true, nil
   679  			},
   680  			migratePeer: func(oldPeer, newPeer swarm.Address) error {
   681  				return nil
   682  			},
   683  		},
   684  		networkID,
   685  		&cashoutMock{},
   686  		nil,
   687  		common.Address{},
   688  	)
   689  
   690  	err = swapService.Handshake(peer, beneficiary)
   691  	if err != nil {
   692  		t.Fatal(err)
   693  	}
   694  }
   695  
   696  func TestCashout(t *testing.T) {
   697  	t.Parallel()
   698  
   699  	logger := log.Noop
   700  	store := mockstore.NewStateStore()
   701  
   702  	theirChequebookAddress := common.HexToAddress("ffff")
   703  	ourChequebookAddress := common.HexToAddress("fffa")
   704  	peer := swarm.MustParseHexAddress("abcd")
   705  	txHash := common.HexToHash("eeee")
   706  	addressbook := &addressbookMock{
   707  		chequebook: func(p swarm.Address) (common.Address, bool, error) {
   708  			if !peer.Equal(p) {
   709  				t.Fatal("querying chequebook for wrong peer")
   710  			}
   711  			return theirChequebookAddress, true, nil
   712  		},
   713  	}
   714  
   715  	swapService := swap.New(
   716  		&swapProtocolMock{},
   717  		logger,
   718  		store,
   719  		mockchequebook.NewChequebook(),
   720  		mockchequestore.NewChequeStore(),
   721  		addressbook,
   722  		uint64(1),
   723  		&cashoutMock{
   724  			cashCheque: func(ctx context.Context, c common.Address, r common.Address) (common.Hash, error) {
   725  				if c != theirChequebookAddress {
   726  					t.Fatalf("not cashing with the right chequebook. wanted %v, got %v", theirChequebookAddress, c)
   727  				}
   728  				if r != ourChequebookAddress {
   729  					t.Fatalf("not cashing with the right recipient. wanted %v, got %v", ourChequebookAddress, r)
   730  				}
   731  				return txHash, nil
   732  			},
   733  		},
   734  		nil,
   735  		ourChequebookAddress,
   736  	)
   737  
   738  	returnedHash, err := swapService.CashCheque(context.Background(), peer)
   739  	if err != nil {
   740  		t.Fatal(err)
   741  	}
   742  
   743  	if returnedHash != txHash {
   744  		t.Fatalf("go wrong tx hash. wanted %v, got %v", txHash, returnedHash)
   745  	}
   746  }
   747  
   748  func TestCashoutStatus(t *testing.T) {
   749  	t.Parallel()
   750  
   751  	logger := log.Noop
   752  	store := mockstore.NewStateStore()
   753  
   754  	theirChequebookAddress := common.HexToAddress("ffff")
   755  	peer := swarm.MustParseHexAddress("abcd")
   756  	addressbook := &addressbookMock{
   757  		chequebook: func(p swarm.Address) (common.Address, bool, error) {
   758  			if !peer.Equal(p) {
   759  				t.Fatal("querying chequebook for wrong peer")
   760  			}
   761  			return theirChequebookAddress, true, nil
   762  		},
   763  	}
   764  
   765  	expectedStatus := &chequebook.CashoutStatus{}
   766  
   767  	swapService := swap.New(
   768  		&swapProtocolMock{},
   769  		logger,
   770  		store,
   771  		mockchequebook.NewChequebook(),
   772  		mockchequestore.NewChequeStore(),
   773  		addressbook,
   774  		uint64(1),
   775  		&cashoutMock{
   776  			cashoutStatus: func(ctx context.Context, c common.Address) (*chequebook.CashoutStatus, error) {
   777  				if c != theirChequebookAddress {
   778  					t.Fatalf("getting status for wrong chequebook. wanted %v, got %v", theirChequebookAddress, c)
   779  				}
   780  				return expectedStatus, nil
   781  			},
   782  		},
   783  		nil,
   784  		common.Address{},
   785  	)
   786  
   787  	returnedStatus, err := swapService.CashoutStatus(context.Background(), peer)
   788  	if err != nil {
   789  		t.Fatal(err)
   790  	}
   791  
   792  	if expectedStatus != returnedStatus {
   793  		t.Fatalf("go wrong status. wanted %v, got %v", expectedStatus, returnedStatus)
   794  	}
   795  }
   796  
   797  func TestStateStoreKeys(t *testing.T) {
   798  	t.Parallel()
   799  
   800  	address := common.HexToAddress("0xabcd")
   801  	swarmAddress := swarm.MustParseHexAddress("deff")
   802  
   803  	expected := "swap_chequebook_peer_deff"
   804  	if swap.PeerKey(swarmAddress) != expected {
   805  		t.Fatalf("wrong peer key. wanted %s, got %s", expected, swap.PeerKey(swarmAddress))
   806  	}
   807  
   808  	expected = "swap_peer_chequebook_000000000000000000000000000000000000abcd"
   809  	if swap.ChequebookPeerKey(address) != expected {
   810  		t.Fatalf("wrong peer key. wanted %s, got %s", expected, swap.ChequebookPeerKey(address))
   811  	}
   812  
   813  	expected = "swap_peer_beneficiary_deff"
   814  	if swap.PeerBeneficiaryKey(swarmAddress) != expected {
   815  		t.Fatalf("wrong peer beneficiary key. wanted %s, got %s", expected, swap.PeerBeneficiaryKey(swarmAddress))
   816  	}
   817  
   818  	expected = "swap_beneficiary_peer_000000000000000000000000000000000000abcd"
   819  	if swap.BeneficiaryPeerKey(address) != expected {
   820  		t.Fatalf("wrong beneficiary peer key. wanted %s, got %s", expected, swap.BeneficiaryPeerKey(address))
   821  	}
   822  
   823  	expected = "swap_deducted_by_peer_deff"
   824  	if swap.PeerDeductedByKey(swarmAddress) != expected {
   825  		t.Fatalf("wrong peer deducted by key. wanted %s, got %s", expected, swap.PeerDeductedByKey(swarmAddress))
   826  	}
   827  
   828  	expected = "swap_deducted_for_peer_deff"
   829  	if swap.PeerDeductedForKey(swarmAddress) != expected {
   830  		t.Fatalf("wrong peer deducted for key. wanted %s, got %s", expected, swap.PeerDeductedForKey(swarmAddress))
   831  	}
   832  }