github.com/ethersphere/bee/v2@v2.2.0/pkg/settlement/swap/mock/swap.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 mock
     6  
     7  import (
     8  	"context"
     9  	"math/big"
    10  
    11  	"github.com/ethereum/go-ethereum/common"
    12  
    13  	"github.com/ethersphere/bee/v2/pkg/settlement/swap"
    14  	"github.com/ethersphere/bee/v2/pkg/settlement/swap/chequebook"
    15  	"github.com/ethersphere/bee/v2/pkg/settlement/swap/swapprotocol"
    16  	"github.com/ethersphere/bee/v2/pkg/swarm"
    17  )
    18  
    19  type Service struct {
    20  	settlementsSent map[string]*big.Int
    21  	settlementsRecv map[string]*big.Int
    22  
    23  	settlementSentFunc func(swarm.Address) (*big.Int, error)
    24  	settlementRecvFunc func(swarm.Address) (*big.Int, error)
    25  
    26  	settlementsSentFunc func() (map[string]*big.Int, error)
    27  	settlementsRecvFunc func() (map[string]*big.Int, error)
    28  
    29  	deductionByPeers  map[string]struct{}
    30  	deductionForPeers map[string]struct{}
    31  
    32  	receiveChequeFunc   func(context.Context, swarm.Address, *chequebook.SignedCheque, *big.Int, *big.Int) error
    33  	payFunc             func(context.Context, swarm.Address, *big.Int)
    34  	handshakeFunc       func(swarm.Address, common.Address) error
    35  	lastSentChequeFunc  func(swarm.Address) (*chequebook.SignedCheque, error)
    36  	lastSentChequesFunc func() (map[string]*chequebook.SignedCheque, error)
    37  
    38  	lastReceivedChequeFunc  func(swarm.Address) (*chequebook.SignedCheque, error)
    39  	lastReceivedChequesFunc func() (map[string]*chequebook.SignedCheque, error)
    40  
    41  	cashChequeFunc    func(ctx context.Context, peer swarm.Address) (common.Hash, error)
    42  	cashoutStatusFunc func(ctx context.Context, peer swarm.Address) (*chequebook.CashoutStatus, error)
    43  }
    44  
    45  // WithSettlementSentFunc sets the mock settlement function
    46  func WithSettlementSentFunc(f func(swarm.Address) (*big.Int, error)) Option {
    47  	return optionFunc(func(s *Service) {
    48  		s.settlementSentFunc = f
    49  	})
    50  }
    51  
    52  func WithSettlementRecvFunc(f func(swarm.Address) (*big.Int, error)) Option {
    53  	return optionFunc(func(s *Service) {
    54  		s.settlementRecvFunc = f
    55  	})
    56  }
    57  
    58  // WithSettlementsSentFunc sets the mock settlements function
    59  func WithSettlementsSentFunc(f func() (map[string]*big.Int, error)) Option {
    60  	return optionFunc(func(s *Service) {
    61  		s.settlementsSentFunc = f
    62  	})
    63  }
    64  
    65  func WithSettlementsRecvFunc(f func() (map[string]*big.Int, error)) Option {
    66  	return optionFunc(func(s *Service) {
    67  		s.settlementsRecvFunc = f
    68  	})
    69  }
    70  
    71  func WithReceiveChequeFunc(f func(context.Context, swarm.Address, *chequebook.SignedCheque, *big.Int, *big.Int) error) Option {
    72  	return optionFunc(func(s *Service) {
    73  		s.receiveChequeFunc = f
    74  	})
    75  }
    76  
    77  func WithPayFunc(f func(context.Context, swarm.Address, *big.Int)) Option {
    78  	return optionFunc(func(s *Service) {
    79  		s.payFunc = f
    80  	})
    81  }
    82  
    83  func WithHandshakeFunc(f func(swarm.Address, common.Address) error) Option {
    84  	return optionFunc(func(s *Service) {
    85  		s.handshakeFunc = f
    86  	})
    87  }
    88  
    89  func WithLastSentChequeFunc(f func(swarm.Address) (*chequebook.SignedCheque, error)) Option {
    90  	return optionFunc(func(s *Service) {
    91  		s.lastSentChequeFunc = f
    92  	})
    93  }
    94  
    95  func WithLastSentChequesFunc(f func() (map[string]*chequebook.SignedCheque, error)) Option {
    96  	return optionFunc(func(s *Service) {
    97  		s.lastSentChequesFunc = f
    98  	})
    99  }
   100  
   101  func WithLastReceivedChequeFunc(f func(swarm.Address) (*chequebook.SignedCheque, error)) Option {
   102  	return optionFunc(func(s *Service) {
   103  		s.lastReceivedChequeFunc = f
   104  	})
   105  }
   106  
   107  func WithLastReceivedChequesFunc(f func() (map[string]*chequebook.SignedCheque, error)) Option {
   108  	return optionFunc(func(s *Service) {
   109  		s.lastReceivedChequesFunc = f
   110  	})
   111  }
   112  
   113  func WithCashChequeFunc(f func(ctx context.Context, peer swarm.Address) (common.Hash, error)) Option {
   114  	return optionFunc(func(s *Service) {
   115  		s.cashChequeFunc = f
   116  	})
   117  }
   118  
   119  func WithCashoutStatusFunc(f func(ctx context.Context, peer swarm.Address) (*chequebook.CashoutStatus, error)) Option {
   120  	return optionFunc(func(s *Service) {
   121  		s.cashoutStatusFunc = f
   122  	})
   123  }
   124  
   125  // New creates the mock swap implementation
   126  func New(opts ...Option) swap.Interface {
   127  	mock := new(Service)
   128  	mock.settlementsSent = make(map[string]*big.Int)
   129  	mock.settlementsRecv = make(map[string]*big.Int)
   130  	for _, o := range opts {
   131  		o.apply(mock)
   132  	}
   133  	return mock
   134  }
   135  
   136  func NewSwap(opts ...Option) swapprotocol.Swap {
   137  	mock := new(Service)
   138  	mock.settlementsSent = make(map[string]*big.Int)
   139  	mock.settlementsRecv = make(map[string]*big.Int)
   140  	mock.deductionByPeers = make(map[string]struct{})
   141  	mock.deductionForPeers = make(map[string]struct{})
   142  
   143  	for _, o := range opts {
   144  		o.apply(mock)
   145  	}
   146  	return mock
   147  }
   148  
   149  // Pay is the mock Pay function of swap.
   150  func (s *Service) Pay(ctx context.Context, peer swarm.Address, amount *big.Int) {
   151  	if s.payFunc != nil {
   152  		s.payFunc(ctx, peer, amount)
   153  		return
   154  	}
   155  	if settlement, ok := s.settlementsSent[peer.String()]; ok {
   156  		s.settlementsSent[peer.String()] = big.NewInt(0).Add(settlement, amount)
   157  	} else {
   158  		s.settlementsSent[peer.String()] = amount
   159  	}
   160  }
   161  
   162  // TotalSent is the mock TotalSent function of swap.
   163  func (s *Service) TotalSent(peer swarm.Address) (totalSent *big.Int, err error) {
   164  	if s.settlementSentFunc != nil {
   165  		return s.settlementSentFunc(peer)
   166  	}
   167  	if v, ok := s.settlementsSent[peer.String()]; ok {
   168  		return v, nil
   169  	}
   170  	return big.NewInt(0), nil
   171  }
   172  
   173  // TotalReceived is the mock TotalReceived function of swap.
   174  func (s *Service) TotalReceived(peer swarm.Address) (totalReceived *big.Int, err error) {
   175  	if s.settlementRecvFunc != nil {
   176  		return s.settlementRecvFunc(peer)
   177  	}
   178  	if v, ok := s.settlementsRecv[peer.String()]; ok {
   179  		return v, nil
   180  	}
   181  	return big.NewInt(0), nil
   182  }
   183  
   184  // SettlementsSent is the mock SettlementsSent function of swap.
   185  func (s *Service) SettlementsSent() (map[string]*big.Int, error) {
   186  	if s.settlementsSentFunc != nil {
   187  		return s.settlementsSentFunc()
   188  	}
   189  	return s.settlementsSent, nil
   190  }
   191  
   192  // SettlementsReceived is the mock SettlementsReceived function of swap.
   193  func (s *Service) SettlementsReceived() (map[string]*big.Int, error) {
   194  	if s.settlementsRecvFunc != nil {
   195  		return s.settlementsRecvFunc()
   196  	}
   197  	return s.settlementsRecv, nil
   198  }
   199  
   200  // Handshake is called by the swap protocol when a handshake is received.
   201  func (s *Service) Handshake(peer swarm.Address, beneficiary common.Address) error {
   202  	if s.handshakeFunc != nil {
   203  		return s.handshakeFunc(peer, beneficiary)
   204  	}
   205  	return nil
   206  }
   207  
   208  func (s *Service) LastSentCheque(address swarm.Address) (*chequebook.SignedCheque, error) {
   209  	if s.lastSentChequeFunc != nil {
   210  		return s.lastSentChequeFunc(address)
   211  	}
   212  	return nil, nil
   213  }
   214  
   215  func (s *Service) LastSentCheques() (map[string]*chequebook.SignedCheque, error) {
   216  	if s.lastSentChequesFunc != nil {
   217  		return s.lastSentChequesFunc()
   218  	}
   219  	return nil, nil
   220  }
   221  
   222  func (s *Service) LastReceivedCheque(address swarm.Address) (*chequebook.SignedCheque, error) {
   223  	if s.lastReceivedChequeFunc != nil {
   224  		return s.lastReceivedChequeFunc(address)
   225  	}
   226  	return nil, nil
   227  }
   228  
   229  func (s *Service) LastReceivedCheques() (map[string]*chequebook.SignedCheque, error) {
   230  	if s.lastReceivedChequesFunc != nil {
   231  		return s.lastReceivedChequesFunc()
   232  	}
   233  	return nil, nil
   234  }
   235  
   236  func (s *Service) CashCheque(ctx context.Context, peer swarm.Address) (common.Hash, error) {
   237  	if s.cashChequeFunc != nil {
   238  		return s.cashChequeFunc(ctx, peer)
   239  	}
   240  	return common.Hash{}, nil
   241  }
   242  
   243  func (s *Service) CashoutStatus(ctx context.Context, peer swarm.Address) (*chequebook.CashoutStatus, error) {
   244  	if s.cashoutStatusFunc != nil {
   245  		return s.cashoutStatusFunc(ctx, peer)
   246  	}
   247  	return nil, nil
   248  }
   249  
   250  func (s *Service) ReceiveCheque(ctx context.Context, peer swarm.Address, cheque *chequebook.SignedCheque, exchangeRate, deduction *big.Int) (err error) {
   251  	defer func() {
   252  		if err == nil {
   253  			s.deductionForPeers[peer.String()] = struct{}{}
   254  		}
   255  	}()
   256  	if s.receiveChequeFunc != nil {
   257  		return s.receiveChequeFunc(ctx, peer, cheque, exchangeRate, deduction)
   258  	}
   259  
   260  	return nil
   261  }
   262  
   263  func (s *Service) GetDeductionForPeer(peer swarm.Address) (bool, error) {
   264  	if _, ok := s.deductionForPeers[peer.String()]; ok {
   265  		return true, nil
   266  	}
   267  	return false, nil
   268  }
   269  
   270  func (s *Service) GetDeductionByPeer(peer swarm.Address) (bool, error) {
   271  	if _, ok := s.deductionByPeers[peer.String()]; ok {
   272  		return true, nil
   273  	}
   274  	return false, nil
   275  }
   276  
   277  func (s *Service) AddDeductionByPeer(peer swarm.Address) error {
   278  	s.deductionByPeers[peer.String()] = struct{}{}
   279  	return nil
   280  }
   281  
   282  // Option is the option passed to the mock settlement service
   283  type Option interface {
   284  	apply(*Service)
   285  }
   286  
   287  type optionFunc func(*Service)
   288  
   289  func (f optionFunc) apply(r *Service) { f(r) }