github.com/ethersphere/bee/v2@v2.2.0/pkg/api/envelope.go (about) 1 // Copyright 2024 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 "encoding/hex" 9 "errors" 10 "net/http" 11 12 "github.com/ethersphere/bee/v2/pkg/jsonhttp" 13 "github.com/ethersphere/bee/v2/pkg/postage" 14 "github.com/ethersphere/bee/v2/pkg/swarm" 15 "github.com/gorilla/mux" 16 ) 17 18 type postEnvelopeResponse struct { 19 Issuer string `json:"issuer"` // Ethereum address of the postage batch owner 20 Index string `json:"index"` // used index of the Postage Batch 21 Timestamp string `json:"timestamp"` // timestamp of the postage stamp 22 Signature string `json:"signature"` // postage stamp signature 23 } 24 25 // envelopePostHandler generates new postage stamp for requested chunk address 26 func (s *Service) envelopePostHandler(w http.ResponseWriter, r *http.Request) { 27 logger := s.logger.WithName("post_envelope").Build() 28 29 headers := struct { 30 BatchID []byte `map:"Swarm-Postage-Batch-Id" validate:"required"` 31 }{} 32 if response := s.mapStructure(r.Header, &headers); response != nil { 33 response("invalid header params", logger, w) 34 return 35 } 36 37 paths := struct { 38 Address swarm.Address `map:"address" validate:"required"` 39 }{} 40 if response := s.mapStructure(mux.Vars(r), &paths); response != nil { 41 response("invalid path params", logger, w) 42 return 43 } 44 45 stamper, save, err := s.getStamper(headers.BatchID) 46 if err != nil { 47 logger.Debug("get stamper failed", "error", err) 48 logger.Error(err, "get stamper failed") 49 switch { 50 case errors.Is(err, errBatchUnusable) || errors.Is(err, postage.ErrNotUsable): 51 jsonhttp.UnprocessableEntity(w, "batch not usable yet or does not exist") 52 case errors.Is(err, postage.ErrNotFound): 53 jsonhttp.NotFound(w, "batch with id not found") 54 case errors.Is(err, errInvalidPostageBatch): 55 jsonhttp.BadRequest(w, "invalid batch id") 56 default: 57 jsonhttp.InternalServerError(w, nil) 58 } 59 return 60 } 61 62 stamp, err := stamper.Stamp(paths.Address) 63 if err != nil { 64 logger.Debug("split write all failed", "error", err) 65 logger.Error(nil, "split write all failed") 66 switch { 67 case errors.Is(err, postage.ErrBucketFull): 68 jsonhttp.PaymentRequired(w, "batch is overissued") 69 default: 70 jsonhttp.InternalServerError(w, "stamping failed") 71 } 72 return 73 } 74 err = save() 75 if err != nil { 76 jsonhttp.InternalServerError(w, "failed to save stamp issuer") 77 return 78 } 79 80 issuer, err := s.signer.EthereumAddress() 81 if err != nil { 82 jsonhttp.InternalServerError(w, "signer ethereum address") 83 return 84 } 85 jsonhttp.Created(w, postEnvelopeResponse{ 86 Issuer: issuer.Hex(), 87 Index: hex.EncodeToString(stamp.Index()), 88 Timestamp: hex.EncodeToString(stamp.Timestamp()), 89 Signature: hex.EncodeToString(stamp.Sig()), 90 }) 91 }