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

Distinguish no balance for peer (#696)

parent 06ce0488
...@@ -76,6 +76,8 @@ var ( ...@@ -76,6 +76,8 @@ var (
ErrDisconnectThresholdExceeded = errors.New("disconnect threshold exceeded") ErrDisconnectThresholdExceeded = errors.New("disconnect threshold exceeded")
// ErrInvalidPaymentTolerance is the error returned if the payment tolerance is too high compared to the payment threshold // ErrInvalidPaymentTolerance is the error returned if the payment tolerance is too high compared to the payment threshold
ErrInvalidPaymentTolerance = errors.New("payment tolerance must be less than half the payment threshold") ErrInvalidPaymentTolerance = errors.New("payment tolerance must be less than half the payment threshold")
// ErrPeerNoBalance is the error returned if no balance in store exists for a peer
ErrPeerNoBalance = errors.New("no balance for peer")
) )
// NewAccounting creates a new Accounting instance with the provided options // NewAccounting creates a new Accounting instance with the provided options
...@@ -107,8 +109,10 @@ func (a *Accounting) Reserve(peer swarm.Address, price uint64) error { ...@@ -107,8 +109,10 @@ func (a *Accounting) Reserve(peer swarm.Address, price uint64) error {
currentBalance, err := a.Balance(peer) currentBalance, err := a.Balance(peer)
if err != nil { if err != nil {
if !errors.Is(err, ErrPeerNoBalance) {
return fmt.Errorf("failed to load balance: %w", err) return fmt.Errorf("failed to load balance: %w", err)
} }
}
expectedDebt := -(currentBalance - int64(accountingPeer.reservedBalance)) expectedDebt := -(currentBalance - int64(accountingPeer.reservedBalance))
if expectedDebt < 0 { if expectedDebt < 0 {
...@@ -157,8 +161,10 @@ func (a *Accounting) Credit(peer swarm.Address, price uint64) error { ...@@ -157,8 +161,10 @@ func (a *Accounting) Credit(peer swarm.Address, price uint64) error {
currentBalance, err := a.Balance(peer) currentBalance, err := a.Balance(peer)
if err != nil { if err != nil {
if !errors.Is(err, ErrPeerNoBalance) {
return fmt.Errorf("failed to load balance: %w", err) return fmt.Errorf("failed to load balance: %w", err)
} }
}
nextBalance := currentBalance - int64(price) nextBalance := currentBalance - int64(price)
...@@ -194,8 +200,10 @@ func (a *Accounting) Credit(peer swarm.Address, price uint64) error { ...@@ -194,8 +200,10 @@ func (a *Accounting) Credit(peer swarm.Address, price uint64) error {
func (a *Accounting) settle(peer swarm.Address, balance *accountingPeer) error { func (a *Accounting) settle(peer swarm.Address, balance *accountingPeer) error {
oldBalance, err := a.Balance(peer) oldBalance, err := a.Balance(peer)
if err != nil { if err != nil {
if !errors.Is(err, ErrPeerNoBalance) {
return fmt.Errorf("failed to load balance: %w", err) return fmt.Errorf("failed to load balance: %w", err)
} }
}
// don't do anything if there is no actual debt // don't do anything if there is no actual debt
// this might be the case if the peer owes us and the total reserve for a peer exceeds the payment treshhold // this might be the case if the peer owes us and the total reserve for a peer exceeds the payment treshhold
...@@ -237,8 +245,10 @@ func (a *Accounting) Debit(peer swarm.Address, price uint64) error { ...@@ -237,8 +245,10 @@ func (a *Accounting) Debit(peer swarm.Address, price uint64) error {
currentBalance, err := a.Balance(peer) currentBalance, err := a.Balance(peer)
if err != nil { if err != nil {
if !errors.Is(err, ErrPeerNoBalance) {
return fmt.Errorf("failed to load balance: %w", err) return fmt.Errorf("failed to load balance: %w", err)
} }
}
nextBalance := currentBalance + int64(price) nextBalance := currentBalance + int64(price)
a.logger.Tracef("debiting peer %v with price %d, new balance is %d", peer, price, nextBalance) a.logger.Tracef("debiting peer %v with price %d, new balance is %d", peer, price, nextBalance)
...@@ -265,7 +275,7 @@ func (a *Accounting) Balance(peer swarm.Address) (balance int64, err error) { ...@@ -265,7 +275,7 @@ func (a *Accounting) Balance(peer swarm.Address) (balance int64, err error) {
err = a.store.Get(peerBalanceKey(peer), &balance) err = a.store.Get(peerBalanceKey(peer), &balance)
if err != nil { if err != nil {
if errors.Is(err, storage.ErrNotFound) { if errors.Is(err, storage.ErrNotFound) {
return 0, nil return 0, ErrPeerNoBalance
} }
return 0, err return 0, err
} }
...@@ -349,8 +359,10 @@ func (a *Accounting) NotifyPayment(peer swarm.Address, amount uint64) error { ...@@ -349,8 +359,10 @@ func (a *Accounting) NotifyPayment(peer swarm.Address, amount uint64) error {
currentBalance, err := a.Balance(peer) currentBalance, err := a.Balance(peer)
if err != nil { if err != nil {
if !errors.Is(err, ErrPeerNoBalance) {
return err return err
} }
}
nextBalance := currentBalance - int64(amount) nextBalance := currentBalance - int64(amount)
// don't allow a payment to put use more into debt than the tolerance // don't allow a payment to put use more into debt than the tolerance
......
...@@ -5,8 +5,10 @@ ...@@ -5,8 +5,10 @@
package debugapi package debugapi
import ( import (
"errors"
"net/http" "net/http"
"github.com/ethersphere/bee/pkg/accounting"
"github.com/ethersphere/bee/pkg/jsonhttp" "github.com/ethersphere/bee/pkg/jsonhttp"
"github.com/ethersphere/bee/pkg/swarm" "github.com/ethersphere/bee/pkg/swarm"
"github.com/gorilla/mux" "github.com/gorilla/mux"
...@@ -15,6 +17,7 @@ import ( ...@@ -15,6 +17,7 @@ import (
var ( var (
errCantBalances = "Cannot get balances" errCantBalances = "Cannot get balances"
errCantBalance = "Cannot get balance" errCantBalance = "Cannot get balance"
errNoBalance = "No balance for peer"
errInvaliAddress = "Invalid address" errInvaliAddress = "Invalid address"
) )
...@@ -61,6 +64,10 @@ func (s *server) peerBalanceHandler(w http.ResponseWriter, r *http.Request) { ...@@ -61,6 +64,10 @@ func (s *server) peerBalanceHandler(w http.ResponseWriter, r *http.Request) {
balance, err := s.Accounting.Balance(peer) balance, err := s.Accounting.Balance(peer)
if err != nil { if err != nil {
if errors.Is(err, accounting.ErrPeerNoBalance) {
jsonhttp.NotFound(w, errNoBalance)
return
}
s.Logger.Debugf("debug api: balances peer: get peer %s balance: %v", peer.String(), err) s.Logger.Debugf("debug api: balances peer: get peer %s balance: %v", peer.String(), err)
s.Logger.Errorf("debug api: balances peer: can't get peer %s balance", peer.String()) s.Logger.Errorf("debug api: balances peer: can't get peer %s balance", peer.String())
jsonhttp.InternalServerError(w, errCantBalance) jsonhttp.InternalServerError(w, errCantBalance)
......
...@@ -10,6 +10,7 @@ import ( ...@@ -10,6 +10,7 @@ import (
"reflect" "reflect"
"testing" "testing"
"github.com/ethersphere/bee/pkg/accounting"
"github.com/ethersphere/bee/pkg/accounting/mock" "github.com/ethersphere/bee/pkg/accounting/mock"
"github.com/ethersphere/bee/pkg/debugapi" "github.com/ethersphere/bee/pkg/debugapi"
"github.com/ethersphere/bee/pkg/jsonhttp" "github.com/ethersphere/bee/pkg/jsonhttp"
...@@ -110,6 +111,23 @@ func TestBalancesPeersError(t *testing.T) { ...@@ -110,6 +111,23 @@ func TestBalancesPeersError(t *testing.T) {
) )
} }
func TestBalancesPeersNoBalance(t *testing.T) {
peer := "bff2c89e85e78c38bd89fca1acc996afb876c21bf5a8482ad798ce15f1c223fa"
balanceFunc := func(swarm.Address) (int64, error) {
return 0, accounting.ErrPeerNoBalance
}
testServer := newTestServer(t, testServerOptions{
AccountingOpts: []mock.Option{mock.WithBalanceFunc(balanceFunc)},
})
jsonhttptest.Request(t, testServer.Client, http.MethodGet, "/balances/"+peer, http.StatusNotFound,
jsonhttptest.WithExpectedJSONResponse(jsonhttp.StatusResponse{
Message: debugapi.ErrNoBalance,
Code: http.StatusNotFound,
}),
)
}
func TestBalancesInvalidAddress(t *testing.T) { func TestBalancesInvalidAddress(t *testing.T) {
peer := "bad peer address" peer := "bad peer address"
......
...@@ -21,6 +21,7 @@ type ( ...@@ -21,6 +21,7 @@ type (
var ( var (
ErrCantBalance = errCantBalance ErrCantBalance = errCantBalance
ErrCantBalances = errCantBalances ErrCantBalances = errCantBalances
ErrNoBalance = errNoBalance
ErrCantSettlementsPeer = errCantSettlementsPeer ErrCantSettlementsPeer = errCantSettlementsPeer
ErrCantSettlements = errCantSettlements ErrCantSettlements = errCantSettlements
ErrInvaliAddress = errInvaliAddress ErrInvaliAddress = errInvaliAddress
......
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