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

Distinguish no balance for peer (#696)

parent 06ce0488
......@@ -76,6 +76,8 @@ var (
ErrDisconnectThresholdExceeded = errors.New("disconnect threshold exceeded")
// 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")
// 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
......@@ -107,8 +109,10 @@ func (a *Accounting) Reserve(peer swarm.Address, price uint64) error {
currentBalance, err := a.Balance(peer)
if err != nil {
if !errors.Is(err, ErrPeerNoBalance) {
return fmt.Errorf("failed to load balance: %w", err)
}
}
expectedDebt := -(currentBalance - int64(accountingPeer.reservedBalance))
if expectedDebt < 0 {
......@@ -157,8 +161,10 @@ func (a *Accounting) Credit(peer swarm.Address, price uint64) error {
currentBalance, err := a.Balance(peer)
if err != nil {
if !errors.Is(err, ErrPeerNoBalance) {
return fmt.Errorf("failed to load balance: %w", err)
}
}
nextBalance := currentBalance - int64(price)
......@@ -194,8 +200,10 @@ func (a *Accounting) Credit(peer swarm.Address, price uint64) error {
func (a *Accounting) settle(peer swarm.Address, balance *accountingPeer) error {
oldBalance, err := a.Balance(peer)
if err != nil {
if !errors.Is(err, ErrPeerNoBalance) {
return fmt.Errorf("failed to load balance: %w", err)
}
}
// 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
......@@ -237,8 +245,10 @@ func (a *Accounting) Debit(peer swarm.Address, price uint64) error {
currentBalance, err := a.Balance(peer)
if err != nil {
if !errors.Is(err, ErrPeerNoBalance) {
return fmt.Errorf("failed to load balance: %w", err)
}
}
nextBalance := currentBalance + int64(price)
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) {
err = a.store.Get(peerBalanceKey(peer), &balance)
if err != nil {
if errors.Is(err, storage.ErrNotFound) {
return 0, nil
return 0, ErrPeerNoBalance
}
return 0, err
}
......@@ -349,8 +359,10 @@ func (a *Accounting) NotifyPayment(peer swarm.Address, amount uint64) error {
currentBalance, err := a.Balance(peer)
if err != nil {
if !errors.Is(err, ErrPeerNoBalance) {
return err
}
}
nextBalance := currentBalance - int64(amount)
// don't allow a payment to put use more into debt than the tolerance
......
......@@ -5,8 +5,10 @@
package debugapi
import (
"errors"
"net/http"
"github.com/ethersphere/bee/pkg/accounting"
"github.com/ethersphere/bee/pkg/jsonhttp"
"github.com/ethersphere/bee/pkg/swarm"
"github.com/gorilla/mux"
......@@ -15,6 +17,7 @@ import (
var (
errCantBalances = "Cannot get balances"
errCantBalance = "Cannot get balance"
errNoBalance = "No balance for peer"
errInvaliAddress = "Invalid address"
)
......@@ -61,6 +64,10 @@ func (s *server) peerBalanceHandler(w http.ResponseWriter, r *http.Request) {
balance, err := s.Accounting.Balance(peer)
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.Errorf("debug api: balances peer: can't get peer %s balance", peer.String())
jsonhttp.InternalServerError(w, errCantBalance)
......
......@@ -10,6 +10,7 @@ import (
"reflect"
"testing"
"github.com/ethersphere/bee/pkg/accounting"
"github.com/ethersphere/bee/pkg/accounting/mock"
"github.com/ethersphere/bee/pkg/debugapi"
"github.com/ethersphere/bee/pkg/jsonhttp"
......@@ -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) {
peer := "bad peer address"
......
......@@ -21,6 +21,7 @@ type (
var (
ErrCantBalance = errCantBalance
ErrCantBalances = errCantBalances
ErrNoBalance = errNoBalance
ErrCantSettlementsPeer = errCantSettlementsPeer
ErrCantSettlements = errCantSettlements
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