github.com/ethersphere/bee/v2@v2.2.0/pkg/api/settlements.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 api
     6  
     7  import (
     8  	"errors"
     9  	"math/big"
    10  	"net/http"
    11  
    12  	"github.com/ethersphere/bee/v2/pkg/bigint"
    13  	"github.com/ethersphere/bee/v2/pkg/jsonhttp"
    14  	"github.com/ethersphere/bee/v2/pkg/postage/postagecontract"
    15  	"github.com/ethersphere/bee/v2/pkg/settlement"
    16  	"github.com/ethersphere/bee/v2/pkg/swarm"
    17  	"github.com/gorilla/mux"
    18  )
    19  
    20  const (
    21  	errCantSettlements     = "can not get settlements"
    22  	errCantSettlementsPeer = "can not get settlements for peer"
    23  )
    24  
    25  type settlementResponse struct {
    26  	Peer               string         `json:"peer"`
    27  	SettlementReceived *bigint.BigInt `json:"received"`
    28  	SettlementSent     *bigint.BigInt `json:"sent"`
    29  }
    30  
    31  type settlementsResponse struct {
    32  	TotalSettlementReceived *bigint.BigInt       `json:"totalReceived"`
    33  	TotalSettlementSent     *bigint.BigInt       `json:"totalSent"`
    34  	Settlements             []settlementResponse `json:"settlements"`
    35  }
    36  
    37  func (s *Service) settlementsHandler(w http.ResponseWriter, _ *http.Request) {
    38  	logger := s.logger.WithName("get_settlements").Build()
    39  
    40  	settlementsSent, err := s.swap.SettlementsSent()
    41  	if errors.Is(err, postagecontract.ErrChainDisabled) {
    42  		logger.Debug("sent settlements failed", "error", err)
    43  		logger.Error(nil, "sent settlements failed")
    44  		jsonhttp.MethodNotAllowed(w, err)
    45  		return
    46  	}
    47  	if err != nil {
    48  		logger.Debug("sent settlements failed", "error", err)
    49  		logger.Error(nil, "sent settlements failed")
    50  		jsonhttp.InternalServerError(w, errCantSettlements)
    51  		return
    52  	}
    53  	settlementsReceived, err := s.swap.SettlementsReceived()
    54  	if err != nil {
    55  		logger.Debug("get received settlements failed", "error", err)
    56  		logger.Error(nil, "get received settlements failed")
    57  		jsonhttp.InternalServerError(w, errCantSettlements)
    58  		return
    59  	}
    60  
    61  	totalReceived := big.NewInt(0)
    62  	totalSent := big.NewInt(0)
    63  
    64  	settlementResponses := make(map[string]settlementResponse)
    65  
    66  	for a, b := range settlementsSent {
    67  		settlementResponses[a] = settlementResponse{
    68  			Peer:               a,
    69  			SettlementSent:     bigint.Wrap(b),
    70  			SettlementReceived: bigint.Wrap(big.NewInt(0)),
    71  		}
    72  		totalSent.Add(b, totalSent)
    73  	}
    74  
    75  	for a, b := range settlementsReceived {
    76  		if _, ok := settlementResponses[a]; ok {
    77  			t := settlementResponses[a]
    78  			t.SettlementReceived = bigint.Wrap(b)
    79  			settlementResponses[a] = t
    80  		} else {
    81  			settlementResponses[a] = settlementResponse{
    82  				Peer:               a,
    83  				SettlementSent:     bigint.Wrap(big.NewInt(0)),
    84  				SettlementReceived: bigint.Wrap(b),
    85  			}
    86  		}
    87  		totalReceived.Add(b, totalReceived)
    88  	}
    89  
    90  	settlementResponsesArray := make([]settlementResponse, len(settlementResponses))
    91  	i := 0
    92  	for k := range settlementResponses {
    93  		settlementResponsesArray[i] = settlementResponses[k]
    94  		i++
    95  	}
    96  
    97  	jsonhttp.OK(w, settlementsResponse{TotalSettlementReceived: bigint.Wrap(totalReceived), TotalSettlementSent: bigint.Wrap(totalSent), Settlements: settlementResponsesArray})
    98  }
    99  
   100  func (s *Service) peerSettlementsHandler(w http.ResponseWriter, r *http.Request) {
   101  	logger := s.logger.WithName("get_settlement").Build()
   102  
   103  	paths := struct {
   104  		Peer swarm.Address `map:"peer" validate:"required"`
   105  	}{}
   106  	if response := s.mapStructure(mux.Vars(r), &paths); response != nil {
   107  		response("invalid path params", logger, w)
   108  		return
   109  	}
   110  
   111  	peerexists := false
   112  
   113  	received, err := s.swap.TotalReceived(paths.Peer)
   114  	if errors.Is(err, postagecontract.ErrChainDisabled) {
   115  		logger.Debug("get total received failed", "peer_address", paths.Peer, "error", err)
   116  		logger.Error(nil, "get total received failed", "peer_address", paths.Peer)
   117  		jsonhttp.MethodNotAllowed(w, err)
   118  		return
   119  	}
   120  	if err != nil {
   121  		if !errors.Is(err, settlement.ErrPeerNoSettlements) {
   122  			logger.Debug("get total received failed", "peer_address", paths.Peer, "error", err)
   123  			logger.Error(nil, "get total received failed", "peer_address", paths.Peer)
   124  			jsonhttp.InternalServerError(w, errCantSettlementsPeer)
   125  			return
   126  		} else {
   127  			received = big.NewInt(0)
   128  		}
   129  	}
   130  
   131  	if err == nil {
   132  		peerexists = true
   133  	}
   134  
   135  	sent, err := s.swap.TotalSent(paths.Peer)
   136  	if err != nil {
   137  		if !errors.Is(err, settlement.ErrPeerNoSettlements) {
   138  			logger.Debug("get total sent failed", "peer_address", paths.Peer, "error", err)
   139  			logger.Error(nil, "get total sent failed", "peer_address", paths.Peer)
   140  			jsonhttp.InternalServerError(w, errCantSettlementsPeer)
   141  			return
   142  		} else {
   143  			sent = big.NewInt(0)
   144  		}
   145  	}
   146  
   147  	if err == nil {
   148  		peerexists = true
   149  	}
   150  
   151  	if !peerexists {
   152  		jsonhttp.NotFound(w, settlement.ErrPeerNoSettlements)
   153  		return
   154  	}
   155  
   156  	jsonhttp.OK(w, settlementResponse{
   157  		Peer:               paths.Peer.String(),
   158  		SettlementReceived: bigint.Wrap(received),
   159  		SettlementSent:     bigint.Wrap(sent),
   160  	})
   161  }
   162  
   163  func (s *Service) settlementsHandlerPseudosettle(w http.ResponseWriter, _ *http.Request) {
   164  	logger := s.logger.WithName("get_timesettlements").Build()
   165  
   166  	settlementsSent, err := s.pseudosettle.SettlementsSent()
   167  	if err != nil {
   168  		jsonhttp.InternalServerError(w, errCantSettlements)
   169  		logger.Debug("sent settlements failed", "error", err)
   170  		logger.Error(nil, "sent settlements failed")
   171  		return
   172  	}
   173  	settlementsReceived, err := s.pseudosettle.SettlementsReceived()
   174  	if err != nil {
   175  		jsonhttp.InternalServerError(w, errCantSettlements)
   176  		logger.Debug("get received settlements failed", "error", err)
   177  		logger.Error(nil, "get received settlements failed")
   178  		return
   179  	}
   180  
   181  	totalReceived := big.NewInt(0)
   182  	totalSent := big.NewInt(0)
   183  
   184  	settlementResponses := make(map[string]settlementResponse)
   185  
   186  	for a, b := range settlementsSent {
   187  		settlementResponses[a] = settlementResponse{
   188  			Peer:               a,
   189  			SettlementSent:     bigint.Wrap(b),
   190  			SettlementReceived: bigint.Wrap(big.NewInt(0)),
   191  		}
   192  		totalSent.Add(b, totalSent)
   193  	}
   194  
   195  	for a, b := range settlementsReceived {
   196  		if _, ok := settlementResponses[a]; ok {
   197  			t := settlementResponses[a]
   198  			t.SettlementReceived = bigint.Wrap(b)
   199  			settlementResponses[a] = t
   200  		} else {
   201  			settlementResponses[a] = settlementResponse{
   202  				Peer:               a,
   203  				SettlementSent:     bigint.Wrap(big.NewInt(0)),
   204  				SettlementReceived: bigint.Wrap(b),
   205  			}
   206  		}
   207  		totalReceived.Add(b, totalReceived)
   208  	}
   209  
   210  	settlementResponsesArray := make([]settlementResponse, len(settlementResponses))
   211  	i := 0
   212  	for k := range settlementResponses {
   213  		settlementResponsesArray[i] = settlementResponses[k]
   214  		i++
   215  	}
   216  
   217  	jsonhttp.OK(w, settlementsResponse{TotalSettlementReceived: bigint.Wrap(totalReceived), TotalSettlementSent: bigint.Wrap(totalSent), Settlements: settlementResponsesArray})
   218  }