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 }