Commit ec1da284 authored by metacertain's avatar metacertain Committed by GitHub

Lastcheque endpoints (#735)

Add endpoints /chequebook/cheque/{peer} and /chequebook/cheque
parent 70770e1d
......@@ -9,10 +9,16 @@ import (
"net/http"
"github.com/ethersphere/bee/pkg/jsonhttp"
"github.com/ethersphere/bee/pkg/settlement/swap/chequebook"
"github.com/ethersphere/bee/pkg/swarm"
"github.com/gorilla/mux"
)
var (
errChequebookBalance = "cannot get chequebook balance"
errChequebookBalance = "cannot get chequebook balance"
errCantLastChequePeer = "cannot get last cheque for peer"
errCantLastCheque = "cannot get last cheque for all peers"
)
type chequebookBalanceResponse struct {
......@@ -24,6 +30,22 @@ type chequebookAddressResponse struct {
Address string `json:"chequebookaddress"`
}
type chequebookLastChequePeerResponse struct {
Beneficiary string `json:"beneficiary"`
Chequebook string `json:"chequebook"`
Payout *big.Int `json:"payout"`
}
type chequebookLastChequesPeerResponse struct {
Peer string `json:"peer"`
LastReceived *chequebookLastChequePeerResponse `json:"lastreceived"`
LastSent *chequebookLastChequePeerResponse `json:"lastsent"`
}
type chequebookLastChequesResponse struct {
LastCheques []chequebookLastChequesPeerResponse `json:"lastcheques"`
}
func (s *server) chequebookBalanceHandler(w http.ResponseWriter, r *http.Request) {
balance, err := s.Chequebook.Balance(r.Context())
if err != nil {
......@@ -48,3 +70,112 @@ func (s *server) chequebookAddressHandler(w http.ResponseWriter, r *http.Request
address := s.Chequebook.Address()
jsonhttp.OK(w, chequebookAddressResponse{Address: address.String()})
}
func (s *server) chequebookLastPeerHandler(w http.ResponseWriter, r *http.Request) {
addr := mux.Vars(r)["peer"]
peer, err := swarm.ParseHexAddress(addr)
if err != nil {
s.Logger.Debugf("debug api: chequebook cheque peer: invalid peer address %s: %v", addr, err)
s.Logger.Error("debug api: chequebook cheque peer: invalid peer address %s", addr)
jsonhttp.NotFound(w, errInvaliAddress)
return
}
var lastSentResponse *chequebookLastChequePeerResponse
lastSent, err := s.Swap.LastSentCheque(peer)
if err != nil && err != chequebook.ErrNoCheque {
s.Logger.Debugf("debug api: chequebook cheque peer: get peer %s last cheque: %v", peer.String(), err)
s.Logger.Errorf("debug api: chequebook cheque peer: can't get peer %s last cheque", peer.String())
jsonhttp.InternalServerError(w, errCantLastChequePeer)
return
}
if err == nil {
lastSentResponse = &chequebookLastChequePeerResponse{
Beneficiary: lastSent.Cheque.Beneficiary.String(),
Chequebook: lastSent.Cheque.Chequebook.String(),
Payout: lastSent.Cheque.CumulativePayout,
}
}
var lastReceivedResponse *chequebookLastChequePeerResponse
lastReceived, err := s.Swap.LastReceivedCheque(peer)
if err != nil && err != chequebook.ErrNoCheque {
s.Logger.Debugf("debug api: chequebook cheque peer: get peer %s last cheque: %v", peer.String(), err)
s.Logger.Errorf("debug api: chequebook cheque peer: can't get peer %s last cheque", peer.String())
jsonhttp.InternalServerError(w, errCantLastChequePeer)
return
}
if err == nil {
lastReceivedResponse = &chequebookLastChequePeerResponse{
Beneficiary: lastReceived.Cheque.Beneficiary.String(),
Chequebook: lastReceived.Cheque.Chequebook.String(),
Payout: lastReceived.Cheque.CumulativePayout,
}
}
jsonhttp.OK(w, chequebookLastChequesPeerResponse{
Peer: addr,
LastReceived: lastReceivedResponse,
LastSent: lastSentResponse,
})
}
func (s *server) chequebookAllLastHandler(w http.ResponseWriter, r *http.Request) {
lastchequessent, err := s.Swap.LastSentCheques()
if err != nil {
s.Logger.Debugf("debug api: chequebook cheque all: get all last cheques: %v", err)
s.Logger.Errorf("debug api: chequebook cheque all: can't get all last cheques")
jsonhttp.InternalServerError(w, errCantLastCheque)
return
}
lastchequesreceived, err := s.Swap.LastReceivedCheques()
if err != nil {
s.Logger.Debugf("debug api: chequebook cheque all: get all last cheques: %v", err)
s.Logger.Errorf("debug api: chequebook cheque all: can't get all last cheques")
jsonhttp.InternalServerError(w, errCantLastCheque)
return
}
lcr := make(map[string]chequebookLastChequesPeerResponse)
for i, j := range lastchequessent {
lcr[i] = chequebookLastChequesPeerResponse{
Peer: i,
LastSent: &chequebookLastChequePeerResponse{
Beneficiary: j.Cheque.Beneficiary.String(),
Chequebook: j.Cheque.Chequebook.String(),
Payout: j.Cheque.CumulativePayout,
},
LastReceived: nil,
}
}
for i, j := range lastchequesreceived {
if _, ok := lcr[i]; ok {
t := lcr[i]
t.LastReceived = &chequebookLastChequePeerResponse{
Beneficiary: j.Cheque.Beneficiary.String(),
Chequebook: j.Cheque.Chequebook.String(),
Payout: j.Cheque.CumulativePayout,
}
lcr[i] = t
} else {
lcr[i] = chequebookLastChequesPeerResponse{
Peer: i,
LastSent: nil,
LastReceived: &chequebookLastChequePeerResponse{
Beneficiary: j.Cheque.Beneficiary.String(),
Chequebook: j.Cheque.Chequebook.String(),
Payout: j.Cheque.CumulativePayout,
},
}
}
}
lcresponses := make([]chequebookLastChequesPeerResponse, len(lcr))
i := 0
for k := range lcr {
lcresponses[i] = lcr[k]
i++
}
jsonhttp.OK(w, chequebookLastChequesResponse{LastCheques: lcresponses})
}
......@@ -16,7 +16,11 @@ import (
"github.com/ethersphere/bee/pkg/debugapi"
"github.com/ethersphere/bee/pkg/jsonhttp"
"github.com/ethersphere/bee/pkg/jsonhttp/jsonhttptest"
"github.com/ethersphere/bee/pkg/settlement/swap/chequebook"
"github.com/ethersphere/bee/pkg/settlement/swap/chequebook/mock"
swapmock "github.com/ethersphere/bee/pkg/settlement/swap/mock"
"github.com/ethersphere/bee/pkg/swarm"
)
func TestChequebookBalance(t *testing.T) {
......@@ -121,3 +125,265 @@ func TestChequebookAddress(t *testing.T) {
}
}
func TestChequebookLastCheques(t *testing.T) {
addr1 := swarm.MustParseHexAddress("1000000000000000000000000000000000000000000000000000000000000000")
addr2 := swarm.MustParseHexAddress("2000000000000000000000000000000000000000000000000000000000000000")
addr3 := swarm.MustParseHexAddress("3000000000000000000000000000000000000000000000000000000000000000")
addr4 := swarm.MustParseHexAddress("4000000000000000000000000000000000000000000000000000000000000000")
addr5 := swarm.MustParseHexAddress("5000000000000000000000000000000000000000000000000000000000000000")
beneficiary := common.HexToAddress("0xfff5")
beneficiary1 := common.HexToAddress("0xfff0")
beneficiary2 := common.HexToAddress("0xfff1")
beneficiary3 := common.HexToAddress("0xfff2")
cumulativePayout1 := big.NewInt(700)
cumulativePayout2 := big.NewInt(900)
cumulativePayout3 := big.NewInt(600)
cumulativePayout4 := big.NewInt(550)
cumulativePayout5 := big.NewInt(400)
cumulativePayout6 := big.NewInt(720)
chequebookAddress1 := common.HexToAddress("0xeee1")
chequebookAddress2 := common.HexToAddress("0xeee2")
chequebookAddress3 := common.HexToAddress("0xeee3")
chequebookAddress4 := common.HexToAddress("0xeee4")
chequebookAddress5 := common.HexToAddress("0xeee5")
lastSentChequesFunc := func() (map[string]*chequebook.SignedCheque, error) {
lastSentCheques := make(map[string]*chequebook.SignedCheque, 3)
sig := make([]byte, 65)
lastSentCheques[addr1.String()] = &chequebook.SignedCheque{
Cheque: chequebook.Cheque{
Beneficiary: beneficiary1,
CumulativePayout: cumulativePayout1,
Chequebook: chequebookAddress1,
},
Signature: sig,
}
lastSentCheques[addr2.String()] = &chequebook.SignedCheque{
Cheque: chequebook.Cheque{
Beneficiary: beneficiary2,
CumulativePayout: cumulativePayout2,
Chequebook: chequebookAddress2,
},
Signature: sig,
}
lastSentCheques[addr3.String()] = &chequebook.SignedCheque{
Cheque: chequebook.Cheque{
Beneficiary: beneficiary3,
CumulativePayout: cumulativePayout3,
Chequebook: chequebookAddress3,
},
Signature: sig,
}
return lastSentCheques, nil
}
lastReceivedChequesFunc := func() (map[string]*chequebook.SignedCheque, error) {
lastReceivedCheques := make(map[string]*chequebook.SignedCheque, 3)
sig := make([]byte, 65)
lastReceivedCheques[addr1.String()] = &chequebook.SignedCheque{
Cheque: chequebook.Cheque{
Beneficiary: beneficiary,
CumulativePayout: cumulativePayout4,
Chequebook: chequebookAddress1,
},
Signature: sig,
}
lastReceivedCheques[addr4.String()] = &chequebook.SignedCheque{
Cheque: chequebook.Cheque{
Beneficiary: beneficiary,
CumulativePayout: cumulativePayout5,
Chequebook: chequebookAddress4,
},
Signature: sig,
}
lastReceivedCheques[addr5.String()] = &chequebook.SignedCheque{
Cheque: chequebook.Cheque{
Beneficiary: beneficiary,
CumulativePayout: cumulativePayout6,
Chequebook: chequebookAddress5,
},
Signature: sig,
}
return lastReceivedCheques, nil
}
testServer := newTestServer(t, testServerOptions{
SwapOpts: []swapmock.Option{swapmock.WithLastReceivedChequesFunc(lastReceivedChequesFunc), swapmock.WithLastSentChequesFunc(lastSentChequesFunc)},
})
lastchequesexpected := []debugapi.ChequebookLastChequesPeerResponse{
{
Peer: addr1.String(),
LastReceived: &debugapi.ChequebookLastChequePeerResponse{
Beneficiary: beneficiary.String(),
Chequebook: chequebookAddress1.String(),
Payout: cumulativePayout4,
},
LastSent: &debugapi.ChequebookLastChequePeerResponse{
Beneficiary: beneficiary1.String(),
Chequebook: chequebookAddress1.String(),
Payout: cumulativePayout1,
},
},
{
Peer: addr2.String(),
LastReceived: nil,
LastSent: &debugapi.ChequebookLastChequePeerResponse{
Beneficiary: beneficiary2.String(),
Chequebook: chequebookAddress2.String(),
Payout: cumulativePayout2,
},
},
{
Peer: addr3.String(),
LastReceived: nil,
LastSent: &debugapi.ChequebookLastChequePeerResponse{
Beneficiary: beneficiary3.String(),
Chequebook: chequebookAddress3.String(),
Payout: cumulativePayout3,
},
},
{
Peer: addr4.String(),
LastReceived: &debugapi.ChequebookLastChequePeerResponse{
Beneficiary: beneficiary.String(),
Chequebook: chequebookAddress4.String(),
Payout: cumulativePayout5,
},
LastSent: nil,
},
{
Peer: addr5.String(),
LastReceived: &debugapi.ChequebookLastChequePeerResponse{
Beneficiary: beneficiary.String(),
Chequebook: chequebookAddress5.String(),
Payout: cumulativePayout6,
},
LastSent: nil,
},
}
expected := &debugapi.ChequebookLastChequesResponse{
LastCheques: lastchequesexpected,
}
// We expect a list of items unordered by peer:
var got *debugapi.ChequebookLastChequesResponse
jsonhttptest.Request(t, testServer.Client, http.MethodGet, "/chequebook/cheque", http.StatusOK,
jsonhttptest.WithUnmarshalJSONResponse(&got),
)
if !LastChequesEqual(got, expected) {
t.Fatalf("Got: \n %+v \n\n Expected: \n %+v \n\n", got, expected)
}
}
func TestChequebookLastChequesPeer(t *testing.T) {
addr := swarm.MustParseHexAddress("1000000000000000000000000000000000000000000000000000000000000000")
beneficiary0 := common.HexToAddress("0xfff5")
beneficiary1 := common.HexToAddress("0xfff0")
cumulativePayout1 := big.NewInt(700)
cumulativePayout2 := big.NewInt(900)
chequebookAddress := common.HexToAddress("0xeee1")
sig := make([]byte, 65)
lastSentChequeFunc := func(swarm.Address) (*chequebook.SignedCheque, error) {
sig := make([]byte, 65)
lastSentCheque := &chequebook.SignedCheque{
Cheque: chequebook.Cheque{
Beneficiary: beneficiary1,
CumulativePayout: cumulativePayout1,
Chequebook: chequebookAddress,
},
Signature: sig,
}
return lastSentCheque, nil
}
lastReceivedChequeFunc := func(swarm.Address) (*chequebook.SignedCheque, error) {
lastReceivedCheque := &chequebook.SignedCheque{
Cheque: chequebook.Cheque{
Beneficiary: beneficiary0,
CumulativePayout: cumulativePayout2,
Chequebook: chequebookAddress,
},
Signature: sig,
}
return lastReceivedCheque, nil
}
testServer := newTestServer(t, testServerOptions{
SwapOpts: []swapmock.Option{swapmock.WithLastReceivedChequeFunc(lastReceivedChequeFunc), swapmock.WithLastSentChequeFunc(lastSentChequeFunc)},
})
expected := &debugapi.ChequebookLastChequesPeerResponse{
Peer: addr.String(),
LastReceived: &debugapi.ChequebookLastChequePeerResponse{
Beneficiary: beneficiary0.String(),
Chequebook: chequebookAddress.String(),
Payout: cumulativePayout2,
},
LastSent: &debugapi.ChequebookLastChequePeerResponse{
Beneficiary: beneficiary1.String(),
Chequebook: chequebookAddress.String(),
Payout: cumulativePayout1,
},
}
var got *debugapi.ChequebookLastChequesPeerResponse
jsonhttptest.Request(t, testServer.Client, http.MethodGet, "/chequebook/cheque/"+addr.String(), http.StatusOK,
jsonhttptest.WithUnmarshalJSONResponse(&got),
)
if !reflect.DeepEqual(got, expected) {
t.Fatalf("Got: \n %+v \n\n Expected: \n %+v \n\n", got, expected)
}
}
func LastChequesEqual(a, b *debugapi.ChequebookLastChequesResponse) bool {
var state bool
for akeys := range a.LastCheques {
state = false
for bkeys := range b.LastCheques {
if reflect.DeepEqual(a.LastCheques[akeys], b.LastCheques[bkeys]) {
state = true
break
}
}
if !state {
return false
}
}
for bkeys := range b.LastCheques {
state = false
for akeys := range a.LastCheques {
if reflect.DeepEqual(a.LastCheques[akeys], b.LastCheques[bkeys]) {
state = true
break
}
}
if !state {
return false
}
}
return true
}
......@@ -13,6 +13,7 @@ import (
"github.com/ethersphere/bee/pkg/p2p"
"github.com/ethersphere/bee/pkg/pingpong"
"github.com/ethersphere/bee/pkg/settlement"
"github.com/ethersphere/bee/pkg/settlement/swap"
"github.com/ethersphere/bee/pkg/settlement/swap/chequebook"
"github.com/ethersphere/bee/pkg/storage"
"github.com/ethersphere/bee/pkg/swarm"
......@@ -41,11 +42,12 @@ type server struct {
Settlement settlement.Interface
ChequebookEnabled bool
Chequebook chequebook.Service
Swap swap.ApiInterface
metricsRegistry *prometheus.Registry
http.Handler
metricsRegistry *prometheus.Registry
}
func New(overlay swarm.Address, publicKey ecdsa.PublicKey, p2p p2p.DebugService, pingpong pingpong.Interface, topologyDriver topology.Driver, storer storage.Storer, logger logging.Logger, tracer *tracing.Tracer, tags *tags.Tags, accounting accounting.Interface, settlement settlement.Interface, chequebookEnabled bool, chequebook chequebook.Service) Service {
func New(overlay swarm.Address, publicKey ecdsa.PublicKey, p2p p2p.DebugService, pingpong pingpong.Interface, topologyDriver topology.Driver, storer storage.Storer, logger logging.Logger, tracer *tracing.Tracer, tags *tags.Tags, accounting accounting.Interface, settlement settlement.Interface, chequebookEnabled bool, swap swap.ApiInterface, chequebook chequebook.Service) Service {
s := &server{
Overlay: overlay,
PublicKey: publicKey,
......@@ -61,6 +63,7 @@ func New(overlay swarm.Address, publicKey ecdsa.PublicKey, p2p p2p.DebugService,
metricsRegistry: newMetricsRegistry(),
ChequebookEnabled: chequebookEnabled,
Chequebook: chequebook,
Swap: swap,
}
s.setupRouting()
......
......@@ -20,6 +20,7 @@ import (
"github.com/ethersphere/bee/pkg/resolver"
settlementmock "github.com/ethersphere/bee/pkg/settlement/pseudosettle/mock"
chequebookmock "github.com/ethersphere/bee/pkg/settlement/swap/chequebook/mock"
swapmock "github.com/ethersphere/bee/pkg/settlement/swap/mock"
"github.com/ethersphere/bee/pkg/storage"
"github.com/ethersphere/bee/pkg/swarm"
"github.com/ethersphere/bee/pkg/tags"
......@@ -40,6 +41,7 @@ type testServerOptions struct {
AccountingOpts []accountingmock.Option
SettlementOpts []settlementmock.Option
ChequebookOpts []chequebookmock.Option
SwapOpts []swapmock.Option
}
type testServer struct {
......@@ -52,7 +54,8 @@ func newTestServer(t *testing.T, o testServerOptions) *testServer {
acc := accountingmock.NewAccounting(o.AccountingOpts...)
settlement := settlementmock.NewSettlement(o.SettlementOpts...)
chequebook := chequebookmock.NewChequebook(o.ChequebookOpts...)
s := debugapi.New(o.Overlay, o.PublicKey, o.P2P, o.Pingpong, topologyDriver, o.Storer, logging.New(ioutil.Discard, 0), nil, o.Tags, acc, settlement, true, chequebook)
swapserv := swapmock.NewApiInterface(o.SwapOpts...)
s := debugapi.New(o.Overlay, o.PublicKey, o.P2P, o.Pingpong, topologyDriver, o.Storer, logging.New(ioutil.Discard, 0), nil, o.Tags, acc, settlement, true, swapserv, chequebook)
ts := httptest.NewServer(s)
t.Cleanup(ts.Close)
......
......@@ -5,19 +5,22 @@
package debugapi
type (
StatusResponse = statusResponse
PingpongResponse = pingpongResponse
PeerConnectResponse = peerConnectResponse
PeersResponse = peersResponse
AddressesResponse = addressesResponse
WelcomeMessageRequest = welcomeMessageRequest
WelcomeMessageResponse = welcomeMessageResponse
BalancesResponse = balancesResponse
BalanceResponse = balanceResponse
SettlementResponse = settlementResponse
SettlementsResponse = settlementsResponse
ChequebookBalanceResponse = chequebookBalanceResponse
ChequebookAddressResponse = chequebookAddressResponse
StatusResponse = statusResponse
PingpongResponse = pingpongResponse
PeerConnectResponse = peerConnectResponse
PeersResponse = peersResponse
AddressesResponse = addressesResponse
WelcomeMessageRequest = welcomeMessageRequest
WelcomeMessageResponse = welcomeMessageResponse
BalancesResponse = balancesResponse
BalanceResponse = balanceResponse
SettlementResponse = settlementResponse
SettlementsResponse = settlementsResponse
ChequebookBalanceResponse = chequebookBalanceResponse
ChequebookAddressResponse = chequebookAddressResponse
ChequebookLastChequePeerResponse = chequebookLastChequePeerResponse
ChequebookLastChequesResponse = chequebookLastChequesResponse
ChequebookLastChequesPeerResponse = chequebookLastChequesPeerResponse
)
var (
......
......@@ -102,8 +102,15 @@ func (s *server) setupRouting() {
router.Handle("/chequebook/address", jsonhttp.MethodHandler{
"GET": http.HandlerFunc(s.chequebookAddressHandler),
})
}
router.Handle("/chequebook/cheque/{peer}", jsonhttp.MethodHandler{
"GET": http.HandlerFunc(s.chequebookLastPeerHandler),
})
router.Handle("/chequebook/cheque", jsonhttp.MethodHandler{
"GET": http.HandlerFunc(s.chequebookAllLastHandler),
})
}
baseRouter.Handle("/", web.ChainHandlers(
logging.NewHTTPAccessLogHandler(s.Logger, logrus.InfoLevel, "debug api access"),
handlers.CompressHandler,
......
......@@ -43,7 +43,7 @@ import (
"github.com/ethersphere/bee/pkg/recovery"
"github.com/ethersphere/bee/pkg/resolver/multiresolver"
"github.com/ethersphere/bee/pkg/retrieval"
"github.com/ethersphere/bee/pkg/settlement"
settlement "github.com/ethersphere/bee/pkg/settlement"
"github.com/ethersphere/bee/pkg/settlement/pseudosettle"
"github.com/ethersphere/bee/pkg/settlement/swap"
"github.com/ethersphere/bee/pkg/settlement/swap/chequebook"
......@@ -274,10 +274,12 @@ func NewBee(addr string, swarmAddress swarm.Address, publicKey ecdsa.PublicKey,
}
var settlement settlement.Interface
var swapService *swap.Service
if o.SwapEnable {
swapProtocol := swapprotocol.New(p2ps, logger, overlayEthAddress)
swapAddressBook := swap.NewAddressbook(stateStore)
swapService := swap.New(swapProtocol, logger, stateStore, chequebookService, chequeStore, swapAddressBook, networkID)
swapService = swap.New(swapProtocol, logger, stateStore, chequebookService, chequeStore, swapAddressBook, networkID)
swapProtocol.SetSwap(swapService)
if err = p2ps.AddProtocol(swapProtocol.Protocol()); err != nil {
return nil, fmt.Errorf("swap protocol: %w", err)
......@@ -430,7 +432,8 @@ func NewBee(addr string, swarmAddress swarm.Address, publicKey ecdsa.PublicKey,
if o.DebugAPIAddr != "" {
// Debug API server
debugAPIService := debugapi.New(swarmAddress, publicKey, p2ps, pingPong, kad, storer, logger, tracer, tagg, acc, settlement, o.SwapEnable, chequebookService)
debugAPIService := debugapi.New(swarmAddress, publicKey, p2ps, pingPong, kad, storer, logger, tracer, tagg, acc, settlement, o.SwapEnable, swapService, chequebookService)
// register metrics from components
debugAPIService.MustRegisterMetrics(p2ps.Metrics()...)
debugAPIService.MustRegisterMetrics(pingPong.Metrics()...)
......
// Copyright 2020 The Swarm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package mock
import (
"context"
"github.com/ethereum/go-ethereum/common"
"github.com/ethersphere/bee/pkg/settlement"
"github.com/ethersphere/bee/pkg/settlement/swap"
"github.com/ethersphere/bee/pkg/settlement/swap/chequebook"
"github.com/ethersphere/bee/pkg/swarm"
)
type Service struct {
settlementSentFunc func(swarm.Address) (uint64, error)
settlementRecvFunc func(swarm.Address) (uint64, error)
settlementsSentFunc func() (map[string]uint64, error)
settlementsRecvFunc func() (map[string]uint64, error)
receiveChequeFunc func(context.Context, swarm.Address, *chequebook.SignedCheque) error
payFunc func(context.Context, swarm.Address, uint64) error
setPaymentObserverFunc func(observer settlement.PaymentObserver)
handshakeFunc func(swarm.Address, common.Address) error
lastSentChequeFunc func(swarm.Address) (*chequebook.SignedCheque, error)
lastSentChequesFunc func() (map[string]*chequebook.SignedCheque, error)
lastReceivedChequeFunc func(swarm.Address) (*chequebook.SignedCheque, error)
lastReceivedChequesFunc func() (map[string]*chequebook.SignedCheque, error)
}
// WithsettlementFunc sets the mock settlement function
func WithSettlementSentFunc(f func(swarm.Address) (uint64, error)) Option {
return optionFunc(func(s *Service) {
s.settlementSentFunc = f
})
}
func WithSettlementRecvFunc(f func(swarm.Address) (uint64, error)) Option {
return optionFunc(func(s *Service) {
s.settlementRecvFunc = f
})
}
// WithsettlementsFunc sets the mock settlements function
func WithSettlementsSentFunc(f func() (map[string]uint64, error)) Option {
return optionFunc(func(s *Service) {
s.settlementsSentFunc = f
})
}
func WithSettlementsRecvFunc(f func() (map[string]uint64, error)) Option {
return optionFunc(func(s *Service) {
s.settlementsRecvFunc = f
})
}
func WithReceiveChequeFunc(f func(context.Context, swarm.Address, *chequebook.SignedCheque) error) Option {
return optionFunc(func(s *Service) {
s.receiveChequeFunc = f
})
}
func WithPayFunc(f func(context.Context, swarm.Address, uint64) error) Option {
return optionFunc(func(s *Service) {
s.payFunc = f
})
}
// WithsettlementsFunc sets the mock settlements function
func WithSetPaymentObserverFunc(f func(observer settlement.PaymentObserver)) Option {
return optionFunc(func(s *Service) {
s.setPaymentObserverFunc = f
})
}
func WithHandshakeFunc(f func(swarm.Address, common.Address) error) Option {
return optionFunc(func(s *Service) {
s.handshakeFunc = f
})
}
func WithLastSentChequeFunc(f func(swarm.Address) (*chequebook.SignedCheque, error)) Option {
return optionFunc(func(s *Service) {
s.lastSentChequeFunc = f
})
}
func WithLastSentChequesFunc(f func() (map[string]*chequebook.SignedCheque, error)) Option {
return optionFunc(func(s *Service) {
s.lastSentChequesFunc = f
})
}
func WithLastReceivedChequeFunc(f func(swarm.Address) (*chequebook.SignedCheque, error)) Option {
return optionFunc(func(s *Service) {
s.lastReceivedChequeFunc = f
})
}
func WithLastReceivedChequesFunc(f func() (map[string]*chequebook.SignedCheque, error)) Option {
return optionFunc(func(s *Service) {
s.lastReceivedChequesFunc = f
})
}
// New creates the mock swap implementation
func New(opts ...Option) settlement.Interface {
mock := new(Service)
for _, o := range opts {
o.apply(mock)
}
return mock
}
func NewApiInterface(opts ...Option) swap.ApiInterface {
mock := new(Service)
for _, o := range opts {
o.apply(mock)
}
return mock
}
// ReceiveCheque is the mock ReceiveCheque function of swap.
func (s *Service) ReceiveCheque(ctx context.Context, peer swarm.Address, cheque *chequebook.SignedCheque) (err error) {
if s.receiveChequeFunc != nil {
return s.receiveChequeFunc(ctx, peer, cheque)
}
return nil
}
// Pay is the mock Pay function of swap.
func (s *Service) Pay(ctx context.Context, peer swarm.Address, amount uint64) error {
if s.payFunc != nil {
return s.payFunc(ctx, peer, amount)
}
return nil
}
// SetPaymentObserver is the mock SetPaymentObserver function of swap.
func (s *Service) SetPaymentObserver(observer settlement.PaymentObserver) {
if s.setPaymentObserverFunc != nil {
s.setPaymentObserverFunc(observer)
}
}
// TotalSent is the mock TotalSent function of swap.
func (s *Service) TotalSent(peer swarm.Address) (totalSent uint64, err error) {
if s.settlementSentFunc != nil {
return s.settlementSentFunc(peer)
}
return 0, nil
}
// TotalReceived is the mock TotalReceived function of swap.
func (s *Service) TotalReceived(peer swarm.Address) (totalReceived uint64, err error) {
if s.settlementRecvFunc != nil {
return s.settlementRecvFunc(peer)
}
return 0, nil
}
// SettlementsSent is the mock SettlementsSent function of swap.
func (s *Service) SettlementsSent() (map[string]uint64, error) {
if s.settlementsSentFunc != nil {
return s.settlementsSentFunc()
}
result := make(map[string]uint64)
return result, nil
}
// SettlementsReceived is the mock SettlementsReceived function of swap.
func (s *Service) SettlementsReceived() (map[string]uint64, error) {
if s.settlementsRecvFunc != nil {
return s.settlementsRecvFunc()
}
result := make(map[string]uint64)
return result, nil
}
// Handshake is called by the swap protocol when a handshake is received.
func (s *Service) Handshake(peer swarm.Address, beneficiary common.Address) error {
if s.handshakeFunc != nil {
return s.handshakeFunc(peer, beneficiary)
}
return nil
}
func (s *Service) LastSentCheque(address swarm.Address) (*chequebook.SignedCheque, error) {
if s.lastSentChequeFunc != nil {
return s.lastSentChequeFunc(address)
}
return nil, nil
}
func (s *Service) LastSentCheques() (map[string]*chequebook.SignedCheque, error) {
if s.lastSentChequesFunc != nil {
return s.lastSentChequesFunc()
}
return nil, nil
}
func (s *Service) LastReceivedCheque(address swarm.Address) (*chequebook.SignedCheque, error) {
if s.lastReceivedChequeFunc != nil {
return s.lastReceivedChequeFunc(address)
}
return nil, nil
}
func (s *Service) LastReceivedCheques() (map[string]*chequebook.SignedCheque, error) {
if s.lastReceivedChequesFunc != nil {
return s.lastReceivedChequesFunc()
}
return nil, nil
}
// Option is the option passed to the mock settlement service
type Option interface {
apply(*Service)
}
type optionFunc func(*Service)
func (f optionFunc) apply(r *Service) { f(r) }
......@@ -28,6 +28,17 @@ var (
ErrUnknownBeneficary = errors.New("unknown beneficiary for peer")
)
type ApiInterface interface {
// LastSentCheque returns the last sent cheque for the peer
LastSentCheque(peer swarm.Address) (*chequebook.SignedCheque, error)
// LastSentCheques returns the list of last sent cheques for all peers
LastSentCheques() (map[string]*chequebook.SignedCheque, error)
// LastReceivedCheque returns the last received cheque for the peer
LastReceivedCheque(peer swarm.Address) (*chequebook.SignedCheque, error)
// LastReceivedCheques returns the list of last received cheques for all peers
LastReceivedCheques() (map[string]*chequebook.SignedCheque, error)
}
// Service is the implementation of the swap settlement layer.
type Service struct {
proto swapprotocol.Interface
......@@ -212,3 +223,73 @@ func (s *Service) Handshake(peer swarm.Address, beneficiary common.Address) erro
}
return nil
}
// LastSentCheque returns the last sent cheque for the peer
func (s *Service) LastSentCheque(peer swarm.Address) (*chequebook.SignedCheque, error) {
common, known, err := s.addressbook.Beneficiary(peer)
if err != nil {
return nil, err
}
if !known {
return nil, chequebook.ErrNoCheque
}
return s.chequebook.LastCheque(common)
}
// LastReceivedCheque returns the last received cheque for the peer
func (s *Service) LastReceivedCheque(peer swarm.Address) (*chequebook.SignedCheque, error) {
common, known, err := s.addressbook.Chequebook(peer)
if err != nil {
return nil, err
}
if !known {
return nil, chequebook.ErrNoCheque
}
return s.chequeStore.LastCheque(common)
}
// LastSentCheques returns the list of last sent cheques for all peers
func (s *Service) LastSentCheques() (map[string]*chequebook.SignedCheque, error) {
lastcheques, err := s.chequebook.LastCheques()
if err != nil {
return nil, err
}
resultmap := make(map[string]*chequebook.SignedCheque, len(lastcheques))
for i, j := range lastcheques {
addr, known, err := s.addressbook.BeneficiaryPeer(i)
if err == nil && known {
resultmap[addr.String()] = j
}
}
return resultmap, nil
}
// LastReceivedCheques returns the list of last received cheques for all peers
func (s *Service) LastReceivedCheques() (map[string]*chequebook.SignedCheque, error) {
lastcheques, err := s.chequeStore.LastCheques()
if err != nil {
return nil, err
}
resultmap := make(map[string]*chequebook.SignedCheque, len(lastcheques))
for i, j := range lastcheques {
addr, known, err := s.addressbook.ChequebookPeer(i)
if err == nil && known {
resultmap[addr.String()] = j
}
}
return resultmap, nil
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment