From 470ea716f9fa5d46aecc921c83ea52ec3f9807af Mon Sep 17 00:00:00 2001 From: Esad Akar Date: Wed, 21 Apr 2021 21:27:46 +0300 Subject: [PATCH] reserve state debug api (#1586) --- pkg/debugapi/debugapi.go | 5 ++++- pkg/debugapi/debugapi_test.go | 6 ++++-- pkg/debugapi/postage.go | 15 ++++++++++++++ pkg/debugapi/postage_test.go | 31 ++++++++++++++++++++++++++++ pkg/debugapi/router.go | 4 ++++ pkg/node/node.go | 2 +- pkg/postage/batchstore/mock/store.go | 12 +++++++++++ pkg/postage/batchstore/store.go | 9 ++++++++ pkg/postage/interface.go | 1 + pkg/postage/reservestate.go | 14 +++++++++++++ 10 files changed, 95 insertions(+), 4 deletions(-) create mode 100644 pkg/debugapi/postage.go create mode 100644 pkg/debugapi/postage_test.go create mode 100644 pkg/postage/reservestate.go diff --git a/pkg/debugapi/debugapi.go b/pkg/debugapi/debugapi.go index dd44aa86b3c..c465b75ff3e 100644 --- a/pkg/debugapi/debugapi.go +++ b/pkg/debugapi/debugapi.go @@ -17,6 +17,7 @@ import ( "github.com/ethersphere/bee/pkg/logging" "github.com/ethersphere/bee/pkg/p2p" "github.com/ethersphere/bee/pkg/pingpong" + "github.com/ethersphere/bee/pkg/postage" "github.com/ethersphere/bee/pkg/settlement" "github.com/ethersphere/bee/pkg/settlement/swap" "github.com/ethersphere/bee/pkg/settlement/swap/chequebook" @@ -46,6 +47,7 @@ type Service struct { chequebookEnabled bool chequebook chequebook.Service swap swap.ApiInterface + batchStore postage.Storer corsAllowedOrigins []string metricsRegistry *prometheus.Registry // handler is changed in the Configure method @@ -76,7 +78,7 @@ func New(overlay swarm.Address, publicKey, pssPublicKey ecdsa.PublicKey, ethereu // Configure injects required dependencies and configuration parameters and // constructs HTTP routes that depend on them. It is intended and safe to call // this method only once. -func (s *Service) Configure(p2p p2p.DebugService, pingpong pingpong.Interface, topologyDriver topology.Driver, storer storage.Storer, tags *tags.Tags, accounting accounting.Interface, settlement settlement.Interface, chequebookEnabled bool, swap swap.ApiInterface, chequebook chequebook.Service) { +func (s *Service) Configure(p2p p2p.DebugService, pingpong pingpong.Interface, topologyDriver topology.Driver, storer storage.Storer, tags *tags.Tags, accounting accounting.Interface, settlement settlement.Interface, chequebookEnabled bool, swap swap.ApiInterface, chequebook chequebook.Service, batchStore postage.Storer) { s.p2p = p2p s.pingpong = pingpong s.topologyDriver = topologyDriver @@ -87,6 +89,7 @@ func (s *Service) Configure(p2p p2p.DebugService, pingpong pingpong.Interface, t s.chequebookEnabled = chequebookEnabled s.chequebook = chequebook s.swap = swap + s.batchStore = batchStore s.setRouter(s.newRouter()) } diff --git a/pkg/debugapi/debugapi_test.go b/pkg/debugapi/debugapi_test.go index ddd7c5945fd..a9684541f69 100644 --- a/pkg/debugapi/debugapi_test.go +++ b/pkg/debugapi/debugapi_test.go @@ -24,6 +24,7 @@ import ( "github.com/ethersphere/bee/pkg/p2p/mock" p2pmock "github.com/ethersphere/bee/pkg/p2p/mock" "github.com/ethersphere/bee/pkg/pingpong" + "github.com/ethersphere/bee/pkg/postage" "github.com/ethersphere/bee/pkg/resolver" chequebookmock "github.com/ethersphere/bee/pkg/settlement/swap/chequebook/mock" swapmock "github.com/ethersphere/bee/pkg/settlement/swap/mock" @@ -51,6 +52,7 @@ type testServerOptions struct { SettlementOpts []swapmock.Option ChequebookOpts []chequebookmock.Option SwapOpts []swapmock.Option + BatchStore postage.Storer } type testServer struct { @@ -65,7 +67,7 @@ func newTestServer(t *testing.T, o testServerOptions) *testServer { chequebook := chequebookmock.NewChequebook(o.ChequebookOpts...) swapserv := swapmock.NewApiInterface(o.SwapOpts...) s := debugapi.New(o.Overlay, o.PublicKey, o.PSSPublicKey, o.EthereumAddress, logging.New(ioutil.Discard, 0), nil, o.CORSAllowedOrigins) - s.Configure(o.P2P, o.Pingpong, topologyDriver, o.Storer, o.Tags, acc, settlement, true, swapserv, chequebook) + s.Configure(o.P2P, o.Pingpong, topologyDriver, o.Storer, o.Tags, acc, settlement, true, swapserv, chequebook, o.BatchStore) ts := httptest.NewServer(s) t.Cleanup(ts.Close) @@ -162,7 +164,7 @@ func TestServer_Configure(t *testing.T) { }), ) - s.Configure(o.P2P, o.Pingpong, topologyDriver, o.Storer, o.Tags, acc, settlement, true, swapserv, chequebook) + s.Configure(o.P2P, o.Pingpong, topologyDriver, o.Storer, o.Tags, acc, settlement, true, swapserv, chequebook, nil) testBasicRouter(t, client) jsonhttptest.Request(t, client, http.MethodGet, "/readiness", http.StatusOK, diff --git a/pkg/debugapi/postage.go b/pkg/debugapi/postage.go new file mode 100644 index 00000000000..1b900987efa --- /dev/null +++ b/pkg/debugapi/postage.go @@ -0,0 +1,15 @@ +// Copyright 2021 The Swarm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package debugapi + +import ( + "net/http" + + "github.com/ethersphere/bee/pkg/jsonhttp" +) + +func (s *Service) reserveStateHandler(w http.ResponseWriter, r *http.Request) { + jsonhttp.OK(w, s.batchStore.GetReserveState()) +} diff --git a/pkg/debugapi/postage_test.go b/pkg/debugapi/postage_test.go new file mode 100644 index 00000000000..6ea8ca5013d --- /dev/null +++ b/pkg/debugapi/postage_test.go @@ -0,0 +1,31 @@ +// Copyright 2021 The Swarm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package debugapi_test + +import ( + "net/http" + "testing" + + "github.com/ethersphere/bee/pkg/jsonhttp/jsonhttptest" + "github.com/ethersphere/bee/pkg/postage" + "github.com/ethersphere/bee/pkg/postage/batchstore/mock" +) + +func TestReservestate(t *testing.T) { + + ts := newTestServer(t, testServerOptions{ + BatchStore: mock.New(mock.WithReserveState(&postage.Reservestate{ + Radius: 5, + })), + }) + + t.Run("ok", func(t *testing.T) { + jsonhttptest.Request(t, ts.Client, http.MethodGet, "/reservestate", http.StatusOK, + jsonhttptest.WithExpectedJSONResponse(&postage.Reservestate{ + Radius: 5, + }), + ) + }) +} diff --git a/pkg/debugapi/router.go b/pkg/debugapi/router.go index 63148b2a99c..2b9d01075c6 100644 --- a/pkg/debugapi/router.go +++ b/pkg/debugapi/router.go @@ -77,6 +77,10 @@ func (s *Service) newRouter() *mux.Router { "POST": http.HandlerFunc(s.pingpongHandler), }) + router.Handle("/reservestate", jsonhttp.MethodHandler{ + "GET": http.HandlerFunc(s.reserveStateHandler), + }) + router.Handle("/connect/{multi-address:.+}", jsonhttp.MethodHandler{ "POST": http.HandlerFunc(s.peerConnectHandler), }) diff --git a/pkg/node/node.go b/pkg/node/node.go index 09e0236b925..ea9fd2d077b 100644 --- a/pkg/node/node.go +++ b/pkg/node/node.go @@ -591,7 +591,7 @@ func NewBee(addr string, swarmAddress swarm.Address, publicKey ecdsa.PublicKey, } // inject dependencies and configure full debug api http path routes - debugAPIService.Configure(p2ps, pingPong, kad, storer, tagService, acc, settlement, o.SwapEnable, swapService, chequebookService) + debugAPIService.Configure(p2ps, pingPong, kad, storer, tagService, acc, settlement, o.SwapEnable, swapService, chequebookService, batchStore) } if err := kad.Start(p2pCtx); err != nil { diff --git a/pkg/postage/batchstore/mock/store.go b/pkg/postage/batchstore/mock/store.go index 6eccfe56ac2..b894139f8bc 100644 --- a/pkg/postage/batchstore/mock/store.go +++ b/pkg/postage/batchstore/mock/store.go @@ -16,6 +16,7 @@ var _ postage.Storer = (*BatchStore)(nil) // BatchStore is a mock BatchStorer type BatchStore struct { + rs *postage.Reservestate cs *postage.ChainState id []byte batch *postage.Batch @@ -39,6 +40,13 @@ func New(opts ...Option) *BatchStore { return bs } +// WithChainState will set the initial chainstate in the ChainStore mock. +func WithReserveState(rs *postage.Reservestate) Option { + return func(bs *BatchStore) { + bs.rs = rs + } +} + // WithChainState will set the initial chainstate in the ChainStore mock. func WithChainState(cs *postage.ChainState) Option { return func(bs *BatchStore) { @@ -111,3 +119,7 @@ func (bs *BatchStore) PutChainState(cs *postage.ChainState) error { bs.cs = cs return nil } + +func (bs *BatchStore) GetReserveState() *postage.Reservestate { + return bs.rs +} diff --git a/pkg/postage/batchstore/store.go b/pkg/postage/batchstore/store.go index ae860437195..4a0aacb9340 100644 --- a/pkg/postage/batchstore/store.go +++ b/pkg/postage/batchstore/store.go @@ -61,6 +61,15 @@ func New(st storage.StateStorer, unreserveFunc unreserveFn) (postage.Storer, err return &store{st, cs, rs, unreserveFunc, newMetrics()}, nil } +func (s *store) GetReserveState() *postage.Reservestate { + return &postage.Reservestate{ + Radius: s.rs.Radius, + Available: s.rs.Available, + Outer: new(big.Int).Set(s.rs.Outer), + Inner: new(big.Int).Set(s.rs.Inner), + } +} + // Get returns a batch from the batchstore with the given ID. func (s *store) Get(id []byte) (*postage.Batch, error) { b := &postage.Batch{} diff --git a/pkg/postage/interface.go b/pkg/postage/interface.go index fbe9fa381d9..7367514df9b 100644 --- a/pkg/postage/interface.go +++ b/pkg/postage/interface.go @@ -26,6 +26,7 @@ type Storer interface { Put(*Batch, *big.Int, uint8) error PutChainState(*ChainState) error GetChainState() *ChainState + GetReserveState() *Reservestate } // Listener provides a blockchain event iterator. diff --git a/pkg/postage/reservestate.go b/pkg/postage/reservestate.go new file mode 100644 index 00000000000..4dcf76c840c --- /dev/null +++ b/pkg/postage/reservestate.go @@ -0,0 +1,14 @@ +// Copyright 2021 The Swarm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package postage + +import "math/big" + +type Reservestate struct { + Radius uint8 `json:"radius"` + Available int64 `json:"available"` + Outer *big.Int `json:"outer"` // lower value limit for outer layer = the further half of chunks + Inner *big.Int `json:"inner"` +}