Commit 11fd5688 authored by Peter Mrekaj's avatar Peter Mrekaj Committed by GitHub

feat: use default stamp issuer on missing postage batch id header (#2175)

Allows setting the default stamp issuer which will be used in the
case when the 'Swarm-Postage-Batch-Id' header is missing.
parent ac1c8f61
......@@ -69,13 +69,14 @@ const (
)
var (
errInvalidNameOrAddress = errors.New("invalid name or bzz address")
errNoResolver = errors.New("no resolver connected")
errInvalidRequest = errors.New("could not validate request")
errInvalidContentType = errors.New("invalid content-type")
errDirectoryStore = errors.New("could not store directory")
errFileStore = errors.New("could not store file")
errInvalidPostageBatch = errors.New("invalid postage batch id")
errInvalidNameOrAddress = errors.New("invalid name or bzz address")
errNoResolver = errors.New("no resolver connected")
errInvalidRequest = errors.New("could not validate request")
errInvalidContentType = errors.New("invalid content-type")
errDirectoryStore = errors.New("could not store directory")
errFileStore = errors.New("could not store file")
errInvalidPostageBatch = errors.New("invalid postage batch id")
errSwarmPostageBatchIDHeaderNotFound = fmt.Errorf("header %s not found", SwarmPostageBatchIdHeader)
)
// Service is the API service interface.
......@@ -237,7 +238,7 @@ func requestPostageBatchId(r *http.Request) ([]byte, error) {
return b, nil
}
return nil, errInvalidPostageBatch
return nil, errSwarmPostageBatchIDHeaderNotFound
}
func (s *server) newTracingHandler(spanName string) func(h http.Handler) http.Handler {
......
......@@ -284,7 +284,7 @@ func TestPostageHeaderError(t *testing.T) {
for _, endpoint := range endpoints {
t.Run(endpoint+": empty batch", func(t *testing.T) {
hexbatch := hex.EncodeToString(batchEmpty)
expCode := http.StatusBadRequest
expCode := http.StatusCreated
jsonhttptest.Request(t, client, http.MethodPost, "/"+endpoint, expCode,
jsonhttptest.WithRequestHeader(api.SwarmPostageBatchIdHeader, hexbatch),
jsonhttptest.WithRequestHeader(api.ContentTypeHeader, "application/octet-stream"),
......
......@@ -52,7 +52,10 @@ func (s *server) bytesUploadHandler(w http.ResponseWriter, r *http.Request) {
ctx := sctx.SetTag(r.Context(), tag)
batch, err := requestPostageBatchId(r)
if err != nil {
switch {
case errors.Is(err, errSwarmPostageBatchIDHeaderNotFound) && s.post.DefaultIssuer() != nil:
batch = s.post.DefaultIssuer().ID()
case err != nil:
logger.Debugf("bytes upload: postage batch id:%v", err)
logger.Error("bytes upload: postage batch id")
jsonhttp.BadRequest(w, nil)
......
......@@ -46,7 +46,10 @@ func (s *server) bzzUploadHandler(w http.ResponseWriter, r *http.Request) {
}
batch, err := requestPostageBatchId(r)
if err != nil {
switch {
case errors.Is(err, errSwarmPostageBatchIDHeaderNotFound) && s.post.DefaultIssuer() != nil:
batch = s.post.DefaultIssuer().ID()
case err != nil:
logger.Debugf("bzz upload: postage batch id: %v", err)
logger.Error("bzz upload: postage batch id")
jsonhttp.BadRequest(w, "invalid postage batch id")
......
......@@ -86,7 +86,10 @@ func (s *server) chunkUploadHandler(w http.ResponseWriter, r *http.Request) {
}
batch, err := requestPostageBatchId(r)
if err != nil {
switch {
case errors.Is(err, errSwarmPostageBatchIDHeaderNotFound) && s.post.DefaultIssuer() != nil:
batch = s.post.DefaultIssuer().ID()
case err != nil:
s.logger.Debugf("chunk upload: postage batch id: %v", err)
s.logger.Error("chunk upload: postage batch id")
jsonhttp.BadRequest(w, "invalid postage batch id")
......
......@@ -142,7 +142,10 @@ func (s *server) feedPostHandler(w http.ResponseWriter, r *http.Request) {
}
batch, err := requestPostageBatchId(r)
if err != nil {
switch {
case errors.Is(err, errSwarmPostageBatchIDHeaderNotFound) && s.post.DefaultIssuer() != nil:
batch = s.post.DefaultIssuer().ID()
case err != nil:
s.logger.Debugf("feed put: postage batch id: %v", err)
s.logger.Error("feed put: postage batch id")
jsonhttp.BadRequest(w, "invalid postage batch id")
......
......@@ -212,9 +212,9 @@ func TestFeed_Post(t *testing.T) {
jsonhttptest.WithRequestHeader(api.SwarmPostageBatchIdHeader, hexbatch),
)
})
t.Run("bad request - batch empty", func(t *testing.T) {
t.Run("ok - batch empty", func(t *testing.T) {
hexbatch := hex.EncodeToString(batchEmpty)
jsonhttptest.Request(t, client, http.MethodPost, url, http.StatusBadRequest,
jsonhttptest.Request(t, client, http.MethodPost, url, http.StatusCreated,
jsonhttptest.WithRequestHeader(api.SwarmPostageBatchIdHeader, hexbatch),
)
})
......
......@@ -78,7 +78,10 @@ func (s *server) pssPostHandler(w http.ResponseWriter, r *http.Request) {
return
}
batch, err := requestPostageBatchId(r)
if err != nil {
switch {
case errors.Is(err, errSwarmPostageBatchIDHeaderNotFound) && s.post.DefaultIssuer() != nil:
batch = s.post.DefaultIssuer().ID()
case err != nil:
s.logger.Debugf("pss: postage batch id: %v", err)
s.logger.Error("pss: postage batch id")
jsonhttp.BadRequest(w, "invalid postage batch id")
......
......@@ -235,9 +235,9 @@ func TestPssSend(t *testing.T) {
jsonhttptest.WithRequestBody(bytes.NewReader(payload)),
)
})
t.Run("bad request - batch empty", func(t *testing.T) {
t.Run("ok batch - batch empty", func(t *testing.T) {
hexbatch := hex.EncodeToString(batchEmpty)
jsonhttptest.Request(t, client, http.MethodPost, "/pss/send/to/12", http.StatusBadRequest,
jsonhttptest.Request(t, client, http.MethodPost, "/pss/send/to/12", http.StatusCreated,
jsonhttptest.WithRequestHeader(api.SwarmPostageBatchIdHeader, hexbatch),
jsonhttptest.WithRequestBody(bytes.NewReader(payload)),
)
......
......@@ -128,7 +128,10 @@ func (s *server) socUploadHandler(w http.ResponseWriter, r *http.Request) {
return
}
batch, err := requestPostageBatchId(r)
if err != nil {
switch {
case errors.Is(err, errSwarmPostageBatchIDHeaderNotFound) && s.post.DefaultIssuer() != nil:
batch = s.post.DefaultIssuer().ID()
case err != nil:
s.logger.Debugf("soc upload: postage batch id: %v", err)
s.logger.Error("soc upload: postage batch id")
jsonhttp.BadRequest(w, "invalid postage batch id")
......
......@@ -161,10 +161,10 @@ func TestSOC(t *testing.T) {
jsonhttptest.WithRequestBody(bytes.NewReader(s.WrappedChunk.Data())),
)
})
t.Run("err - batch empty", func(t *testing.T) {
t.Run("ok - batch empty", func(t *testing.T) {
s := testingsoc.GenerateMockSOC(t, testData)
hexbatch := hex.EncodeToString(batchEmpty)
jsonhttptest.Request(t, client, http.MethodPost, socResource(hex.EncodeToString(s.Owner), hex.EncodeToString(s.ID), hex.EncodeToString(s.Signature)), http.StatusBadRequest,
jsonhttptest.Request(t, client, http.MethodPost, socResource(hex.EncodeToString(s.Owner), hex.EncodeToString(s.ID), hex.EncodeToString(s.Signature)), http.StatusCreated,
jsonhttptest.WithRequestHeader(api.SwarmPostageBatchIdHeader, hexbatch),
jsonhttptest.WithRequestBody(bytes.NewReader(s.WrappedChunk.Data())),
)
......
......@@ -14,6 +14,7 @@ import (
"github.com/ethersphere/bee/pkg/bigint"
"github.com/ethersphere/bee/pkg/jsonhttp"
"github.com/ethersphere/bee/pkg/postage"
"github.com/ethersphere/bee/pkg/postage/postagecontract"
"github.com/ethersphere/bee/pkg/sctx"
"github.com/gorilla/mux"
......@@ -161,6 +162,32 @@ func (s *Service) postageGetStampHandler(w http.ResponseWriter, r *http.Request)
jsonhttp.OK(w, &resp)
}
// postageSetDefaultStampIssuerHandler sets the default postage stamps issuer.
func (s *Service) postageSetDefaultStampIssuerHandler(w http.ResponseWriter, r *http.Request) {
idStr := mux.Vars(r)["id"]
if idStr == "" || len(idStr) != 64 {
s.logger.Error("get stamp issuer: invalid batchID")
jsonhttp.BadRequest(w, "invalid batchID")
return
}
id, err := hex.DecodeString(idStr)
if err != nil {
s.logger.Error("set stamp issuer: invalid batchID: %v", err)
s.logger.Error("set stamp issuer: invalid batchID")
jsonhttp.BadRequest(w, "invalid batchID")
return
}
switch err := s.post.SetDefaultIssuer(id); {
case errors.Is(err, postage.ErrNotFound):
jsonhttp.NotFound(w, nil)
case err != nil:
s.logger.Debugf("debug api: set default stamp issuer: %v", err)
jsonhttp.InternalServerError(w, err)
}
}
type reserveStateResponse struct {
Radius uint8 `json:"radius"`
StorageRadius uint8 `json:"storageRadius"`
......
......@@ -201,6 +201,12 @@ func (s *Service) newRouter() *mux.Router {
})),
)
router.Handle("/stamps/default/{id}", web.ChainHandlers(
web.FinalHandler(jsonhttp.MethodHandler{
"PUT": http.HandlerFunc(s.postageSetDefaultStampIssuerHandler),
})),
)
return router
}
......
......@@ -65,6 +65,17 @@ func (m *mockPostage) GetStampIssuer(id []byte) (*postage.StampIssuer, error) {
return nil, errors.New("stampissuer not found")
}
// SetDefaultIssuer sets the default stamps issuer.
func (m *mockPostage) SetDefaultIssuer([]byte) error {
// Noop, the default is m.i.
return nil
}
// DefaultIssuer returns the default stamps issuer.
func (m *mockPostage) DefaultIssuer() *postage.StampIssuer {
return m.i
}
func (m *mockPostage) IssuerUsable(_ *postage.StampIssuer) bool {
return true
}
......
......@@ -34,6 +34,8 @@ type Service interface {
StampIssuers() []*StampIssuer
GetStampIssuer([]byte) (*StampIssuer, error)
IssuerUsable(*StampIssuer) bool
SetDefaultIssuer([]byte) error
DefaultIssuer() *StampIssuer
BatchCreationListener
io.Closer
}
......@@ -41,11 +43,12 @@ type Service interface {
// service handles postage batches
// stores the active batches.
type service struct {
lock sync.Mutex
store storage.StateStorer
postageStore Storer
chainID int64
issuers []*StampIssuer
lock sync.Mutex
store storage.StateStorer
postageStore Storer
chainID int64
issuers []*StampIssuer
defaultStampIssuer *StampIssuer
}
// NewService constructs a new Service.
......@@ -87,6 +90,24 @@ func (ps *service) Add(st *StampIssuer) {
ps.issuers = append(ps.issuers, st)
}
// SetDefaultIssuer sets the default stamps issuer.
func (ps *service) SetDefaultIssuer(id []byte) error {
si, err := ps.GetStampIssuer(id)
if err != nil {
return err
}
ps.lock.Lock()
ps.defaultStampIssuer = si
ps.lock.Unlock()
return nil
}
// DefaultIssuer returns the default stamps issuer.
func (ps *service) DefaultIssuer() *StampIssuer {
return ps.defaultStampIssuer
}
// Handle implements the BatchCreationListener interface. This is fired on receiving
// a batch creation event from the blockchain listener to ensure that if a stamp
// issuer was not created initially, we will create it here.
......
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