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) }