From f5ba590137fd78d429654e46f4dcc316c588c320 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ljubi=C5=A1a=20Ga=C4=8Devi=C4=87?= <35105035+gacevicljubisa@users.noreply.github.com> Date: Tue, 29 Oct 2024 10:18:19 +0100 Subject: [PATCH] fix(api): add api initialization notice (#4869) --- pkg/api/api.go | 1 + pkg/api/api_test.go | 23 +- pkg/api/router.go | 309 ++++++++++++++------------- pkg/api/router_test.go | 448 +++++++++++++++++++++++++++++++++++++++ pkg/jsonhttp/handlers.go | 1 - pkg/node/devnode.go | 23 +- pkg/node/node.go | 6 +- 7 files changed, 633 insertions(+), 178 deletions(-) create mode 100644 pkg/api/router_test.go diff --git a/pkg/api/api.go b/pkg/api/api.go index 4568ad96bf5..ce90a1004f6 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -179,6 +179,7 @@ type Service struct { ethereumAddress common.Address chequebookEnabled bool swapEnabled bool + fullAPIEnabled bool topologyDriver topology.Driver p2p p2p.DebugService diff --git a/pkg/api/api_test.go b/pkg/api/api_test.go index 7bd20c07e87..596327783e6 100644 --- a/pkg/api/api_test.go +++ b/pkg/api/api_test.go @@ -131,6 +131,9 @@ type testServerOptions struct { NodeStatus *status.Service PinIntegrity api.PinIntegrity WhitelistedAddr string + FullAPIDisabled bool + ChequebookDisabled bool + SwapDisabled bool } func newTestServer(t *testing.T, o testServerOptions) (*http.Client, *websocket.Conn, string, *chanStorer) { @@ -179,7 +182,7 @@ func newTestServer(t *testing.T, o testServerOptions) (*http.Client, *websocket. erc20 := erc20mock.New(o.Erc20Opts...) backend := backendmock.New(o.BackendOpts...) - var extraOpts = api.ExtraOptions{ + extraOpts := api.ExtraOptions{ TopologyDriver: topologyDriver, Accounting: acc, Pseudosettle: recipient, @@ -207,7 +210,7 @@ func newTestServer(t *testing.T, o testServerOptions) (*http.Client, *websocket. o.BeeMode = api.FullMode } - s := api.New(o.PublicKey, o.PSSPublicKey, o.EthereumAddress, []string{o.WhitelistedAddr}, o.Logger, transaction, o.BatchStore, o.BeeMode, true, true, backend, o.CORSAllowedOrigins, inmemstore.New()) + s := api.New(o.PublicKey, o.PSSPublicKey, o.EthereumAddress, []string{o.WhitelistedAddr}, o.Logger, transaction, o.BatchStore, o.BeeMode, !o.ChequebookDisabled, !o.SwapDisabled, backend, o.CORSAllowedOrigins, inmemstore.New()) testutil.CleanupCloser(t, s) s.SetP2P(o.P2P) @@ -231,9 +234,10 @@ func newTestServer(t *testing.T, o testServerOptions) (*http.Client, *websocket. WsPingPeriod: o.WsPingPeriod, }, extraOpts, 1, erc20) - s.MountTechnicalDebug() - s.MountDebug() - s.MountAPI() + s.Mount() + if !o.FullAPIDisabled { + s.EnableFullAPI() + } if o.DirectUpload { chanStore = newChanStore(o.Storer.PusherFeed()) @@ -316,7 +320,7 @@ func TestParseName(t *testing.T) { const bzzHash = "89c17d0d8018a19057314aa035e61c9d23c47581a61dd3a79a7839692c617e4d" log := log.Noop - var errInvalidNameOrAddress = errors.New("invalid name or bzz address") + errInvalidNameOrAddress := errors.New("invalid name or bzz address") testCases := []struct { desc string @@ -377,7 +381,8 @@ func TestParseName(t *testing.T) { s := api.New(pk.PublicKey, pk.PublicKey, common.Address{}, nil, log, nil, nil, 1, false, false, nil, []string{"*"}, inmemstore.New()) s.Configure(signer, nil, api.Options{}, api.ExtraOptions{Resolver: tC.res}, 1, nil) - s.MountAPI() + s.Mount() + s.EnableFullAPI() tC := tC t.Run(tC.desc, func(t *testing.T) { @@ -503,9 +508,7 @@ func TestPostageHeaderError(t *testing.T) { func TestOptions(t *testing.T) { t.Parallel() - var ( - client, _, _, _ = newTestServer(t, testServerOptions{}) - ) + client, _, _, _ := newTestServer(t, testServerOptions{}) for _, tc := range []struct { endpoint string expectedMethods string // expectedMethods contains HTTP methods like GET, POST, HEAD, PATCH, DELETE, OPTIONS. These are in alphabetical sorted order diff --git a/pkg/api/router.go b/pkg/api/router.go index d7511c1c52e..14c9ab05ee6 100644 --- a/pkg/api/router.go +++ b/pkg/api/router.go @@ -25,41 +25,37 @@ const ( rootPath = "/" + apiVersion ) -func (s *Service) MountTechnicalDebug() { +func (s *Service) Mount() { + if s == nil { + return + } + router := mux.NewRouter() + router.NotFoundHandler = http.HandlerFunc(jsonhttp.NotFoundHandler) + s.router = router s.mountTechnicalDebug() - - s.Handler = web.ChainHandlers( - httpaccess.NewHTTPAccessLogHandler(s.logger, s.tracer, "api access"), - handlers.CompressHandler, - s.corsHandler, - web.NoCacheHeadersHandler, - web.FinalHandler(router), - ) -} - -func (s *Service) MountDebug() { s.mountBusinessDebug() + s.mountAPI() s.Handler = web.ChainHandlers( httpaccess.NewHTTPAccessLogHandler(s.logger, s.tracer, "api access"), handlers.CompressHandler, s.corsHandler, web.NoCacheHeadersHandler, - web.FinalHandler(s.router), + web.FinalHandler(router), ) } -func (s *Service) MountAPI() { - if s.router == nil { - s.router = mux.NewRouter() - s.router.NotFoundHandler = http.HandlerFunc(jsonhttp.NotFoundHandler) +// EnableFullAPI will enable all available endpoints, because some endpoints are not available during syncing. +func (s *Service) EnableFullAPI() { + if s == nil { + return } - s.mountAPI() + s.fullAPIEnabled = true compressHandler := func(h http.Handler) http.Handler { downloadEndpoints := []string{ @@ -140,11 +136,11 @@ func (s *Service) mountTechnicalDebug() { u.Path += "/" http.Redirect(w, r, u.String(), http.StatusPermanentRedirect) })) + s.router.Handle("/debug/pprof/cmdline", http.HandlerFunc(pprof.Cmdline)) s.router.Handle("/debug/pprof/profile", http.HandlerFunc(pprof.Profile)) s.router.Handle("/debug/pprof/symbol", http.HandlerFunc(pprof.Symbol)) s.router.Handle("/debug/pprof/trace", http.HandlerFunc(pprof.Trace)) - s.router.PathPrefix("/debug/pprof/").Handler(http.HandlerFunc(pprof.Index)) s.router.Handle("/debug/vars", expvar.Handler()) @@ -154,12 +150,14 @@ func (s *Service) mountTechnicalDebug() { web.FinalHandlerFunc(s.loggerGetHandler), ), }) + s.router.Handle("/loggers/{exp}", jsonhttp.MethodHandler{ "GET": web.ChainHandlers( httpaccess.NewHTTPAccessSuppressLogHandler(), web.FinalHandlerFunc(s.loggerGetHandler), ), }) + s.router.Handle("/loggers/{exp}/{verbosity}", jsonhttp.MethodHandler{ "PUT": web.ChainHandlers( httpaccess.NewHTTPAccessSuppressLogHandler(), @@ -178,6 +176,36 @@ func (s *Service) mountTechnicalDebug() { )) } +func (s *Service) checkRouteAvailability(handler http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if !s.fullAPIEnabled { + jsonhttp.ServiceUnavailable(w, "Node is syncing. This endpoint is unavailable. Try again later.") + return + } + handler.ServeHTTP(w, r) + }) +} + +func (s *Service) checkSwapAvailability(handler http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if !s.swapEnabled { + jsonhttp.NotImplemented(w, "Swap is disabled. This endpoint is unavailable.") + return + } + handler.ServeHTTP(w, r) + }) +} + +func (s *Service) checkChequebookAvailability(handler http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if !s.chequebookEnabled { + jsonhttp.NotImplemented(w, "Chequebook is disabled. This endpoint is unavailable.") + return + } + handler.ServeHTTP(w, r) + }) +} + func (s *Service) mountAPI() { subdomainRouter := s.router.Host("{subdomain:.*}.swarm.localhost").Subrouter() @@ -197,8 +225,9 @@ func (s *Service) mountAPI() { // handle is a helper closure which simplifies the router setup. handle := func(path string, handler http.Handler) { - s.router.Handle(path, handler) - s.router.Handle(rootPath+path, handler) + routeHandler := s.checkRouteAvailability(handler) + s.router.Handle(path, routeHandler) + s.router.Handle(rootPath+path, routeHandler) } handle("/bytes", jsonhttp.MethodHandler{ @@ -275,18 +304,12 @@ func (s *Service) mountAPI() { }) handle("/grantee", jsonhttp.MethodHandler{ - "POST": web.ChainHandlers( - web.FinalHandlerFunc(s.actCreateGranteesHandler), - ), + "POST": http.HandlerFunc(s.actCreateGranteesHandler), }) handle("/grantee/{address}", jsonhttp.MethodHandler{ - "GET": web.ChainHandlers( - web.FinalHandlerFunc(s.actListGranteesHandler), - ), - "PATCH": web.ChainHandlers( - web.FinalHandlerFunc(s.actGrantRevokeHandler), - ), + "GET": http.HandlerFunc(s.actListGranteesHandler), + "PATCH": http.HandlerFunc(s.actGrantRevokeHandler), }) handle("/bzz/{address}", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -308,90 +331,65 @@ func (s *Service) mountAPI() { ), }) - handle("/pss/send/{topic}/{targets}", web.ChainHandlers( - web.FinalHandler(jsonhttp.MethodHandler{ - "POST": web.ChainHandlers( - jsonhttp.NewMaxBodyBytesHandler(swarm.ChunkSize), - web.FinalHandlerFunc(s.pssPostHandler), - ), - })), - ) + handle("/pss/send/{topic}/{targets}", jsonhttp.MethodHandler{ + "POST": web.ChainHandlers( + jsonhttp.NewMaxBodyBytesHandler(swarm.ChunkSize), + web.FinalHandlerFunc(s.pssPostHandler), + ), + }) - handle("/pss/subscribe/{topic}", web.ChainHandlers( - web.FinalHandlerFunc(s.pssWsHandler), - )) + handle("/pss/subscribe/{topic}", http.HandlerFunc(s.pssWsHandler)) - handle("/tags", web.ChainHandlers( - web.FinalHandler(jsonhttp.MethodHandler{ - "GET": http.HandlerFunc(s.listTagsHandler), - "POST": web.ChainHandlers( - jsonhttp.NewMaxBodyBytesHandler(1024), - web.FinalHandlerFunc(s.createTagHandler), - ), - })), - ) + handle("/tags", jsonhttp.MethodHandler{ + "GET": http.HandlerFunc(s.listTagsHandler), + "POST": web.ChainHandlers( + jsonhttp.NewMaxBodyBytesHandler(1024), + web.FinalHandlerFunc(s.createTagHandler), + ), + }) - handle("/tags/{id}", web.ChainHandlers( - web.FinalHandler(jsonhttp.MethodHandler{ - "GET": http.HandlerFunc(s.getTagHandler), - "DELETE": http.HandlerFunc(s.deleteTagHandler), - "PATCH": web.ChainHandlers( - jsonhttp.NewMaxBodyBytesHandler(1024), - web.FinalHandlerFunc(s.doneSplitHandler), - ), - })), - ) + handle("/tags/{id}", jsonhttp.MethodHandler{ + "GET": http.HandlerFunc(s.getTagHandler), + "DELETE": http.HandlerFunc(s.deleteTagHandler), + "PATCH": web.ChainHandlers( + jsonhttp.NewMaxBodyBytesHandler(1024), + web.FinalHandlerFunc(s.doneSplitHandler), + ), + }) - handle("/pins", web.ChainHandlers( - web.FinalHandler(jsonhttp.MethodHandler{ - "GET": http.HandlerFunc(s.listPinnedRootHashes), - })), - ) + handle("/pins", jsonhttp.MethodHandler{ + "GET": http.HandlerFunc(s.listPinnedRootHashes), + }) - handle("/pins/check", web.ChainHandlers( - web.FinalHandler(jsonhttp.MethodHandler{ - "GET": http.HandlerFunc(s.pinIntegrityHandler), - }), - )) + handle("/pins/check", jsonhttp.MethodHandler{ + "GET": http.HandlerFunc(s.pinIntegrityHandler), + }) - handle("/pins/{reference}", web.ChainHandlers( - web.FinalHandler(jsonhttp.MethodHandler{ - "GET": http.HandlerFunc(s.getPinnedRootHash), - "POST": http.HandlerFunc(s.pinRootHash), - "DELETE": http.HandlerFunc(s.unpinRootHash), - })), + handle("/pins/{reference}", jsonhttp.MethodHandler{ + "GET": http.HandlerFunc(s.getPinnedRootHash), + "POST": http.HandlerFunc(s.pinRootHash), + "DELETE": http.HandlerFunc(s.unpinRootHash), + }, ) handle("/stewardship/{address}", jsonhttp.MethodHandler{ - "GET": web.ChainHandlers( - web.FinalHandlerFunc(s.stewardshipGetHandler), - ), - "PUT": web.ChainHandlers( - web.FinalHandlerFunc(s.stewardshipPutHandler), - ), + "GET": http.HandlerFunc(s.stewardshipGetHandler), + "PUT": http.HandlerFunc(s.stewardshipPutHandler), }) - - handle("/readiness", web.ChainHandlers( - httpaccess.NewHTTPAccessSuppressLogHandler(), - web.FinalHandlerFunc(s.readinessHandler), - )) - - handle("/health", web.ChainHandlers( - httpaccess.NewHTTPAccessSuppressLogHandler(), - web.FinalHandlerFunc(s.healthHandler), - )) } func (s *Service) mountBusinessDebug() { handle := func(path string, handler http.Handler) { - s.router.Handle(path, handler) - s.router.Handle(rootPath+path, handler) + routeHandler := s.checkRouteAvailability(handler) + s.router.Handle(path, routeHandler) + s.router.Handle(rootPath+path, routeHandler) } if s.transaction != nil { handle("/transactions", jsonhttp.MethodHandler{ "GET": http.HandlerFunc(s.transactionListHandler), }) + handle("/transactions/{hash}", jsonhttp.MethodHandler{ "GET": http.HandlerFunc(s.transactionDetailHandler), "POST": http.HandlerFunc(s.transactionResendHandler), @@ -423,10 +421,6 @@ func (s *Service) mountBusinessDebug() { "DELETE": http.HandlerFunc(s.peerDisconnectHandler), }) - //handle("/chunks/{address}", jsonhttp.MethodHandler{ - // "GET": http.HandlerFunc(s.hasChunkHandler), - //}) - handle("/topology", jsonhttp.MethodHandler{ "GET": http.HandlerFunc(s.topologyHandler), }) @@ -459,67 +453,96 @@ func (s *Service) mountBusinessDebug() { "GET": http.HandlerFunc(s.settlementsHandlerPseudosettle), }) - if s.swapEnabled { - handle("/settlements", jsonhttp.MethodHandler{ + handle("/settlements", web.ChainHandlers( + s.checkSwapAvailability, + web.FinalHandler(jsonhttp.MethodHandler{ "GET": http.HandlerFunc(s.settlementsHandler), - }) + }), + )) - handle("/settlements/{peer}", jsonhttp.MethodHandler{ + handle("/settlements/{peer}", web.ChainHandlers( + s.checkSwapAvailability, + web.FinalHandler(jsonhttp.MethodHandler{ "GET": http.HandlerFunc(s.peerSettlementsHandler), - }) + }), + )) - handle("/chequebook/cheque/{peer}", jsonhttp.MethodHandler{ + handle("/chequebook/cheque/{peer}", web.ChainHandlers( + s.checkSwapAvailability, + web.FinalHandler(jsonhttp.MethodHandler{ "GET": http.HandlerFunc(s.chequebookLastPeerHandler), - }) + }), + )) - handle("/chequebook/cheque", jsonhttp.MethodHandler{ + handle("/chequebook/cheque", web.ChainHandlers( + s.checkSwapAvailability, + web.FinalHandler(jsonhttp.MethodHandler{ "GET": http.HandlerFunc(s.chequebookAllLastHandler), - }) + }), + )) - handle("/chequebook/cashout/{peer}", jsonhttp.MethodHandler{ + handle("/chequebook/cashout/{peer}", web.ChainHandlers( + s.checkSwapAvailability, + web.FinalHandler(jsonhttp.MethodHandler{ "GET": http.HandlerFunc(s.swapCashoutStatusHandler), "POST": web.ChainHandlers( s.gasConfigMiddleware("swap cashout"), web.FinalHandlerFunc(s.swapCashoutHandler), ), - }) - } + }), + )) - if s.chequebookEnabled { - handle("/chequebook/balance", jsonhttp.MethodHandler{ + handle("/chequebook/balance", web.ChainHandlers( + s.checkChequebookAvailability, + web.FinalHandler(jsonhttp.MethodHandler{ "GET": http.HandlerFunc(s.chequebookBalanceHandler), - }) + }), + )) - handle("/chequebook/address", jsonhttp.MethodHandler{ + handle("/chequebook/address", web.ChainHandlers( + s.checkChequebookAvailability, + web.FinalHandler(jsonhttp.MethodHandler{ "GET": http.HandlerFunc(s.chequebookAddressHandler), - }) + }), + )) - handle("/chequebook/deposit", jsonhttp.MethodHandler{ + handle("/chequebook/deposit", web.ChainHandlers( + s.checkChequebookAvailability, + web.FinalHandler(jsonhttp.MethodHandler{ "POST": web.ChainHandlers( s.gasConfigMiddleware("chequebook deposit"), web.FinalHandlerFunc(s.chequebookDepositHandler), ), - }) + }), + )) - handle("/chequebook/withdraw", jsonhttp.MethodHandler{ + handle("/chequebook/withdraw", web.ChainHandlers( + s.checkChequebookAvailability, + web.FinalHandler(jsonhttp.MethodHandler{ "POST": web.ChainHandlers( s.gasConfigMiddleware("chequebook withdraw"), web.FinalHandlerFunc(s.chequebookWithdrawHandler), ), - }) + }), + )) - handle("/wallet", jsonhttp.MethodHandler{ + handle("/wallet", web.ChainHandlers( + s.checkChequebookAvailability, + web.FinalHandler(jsonhttp.MethodHandler{ "GET": http.HandlerFunc(s.walletHandler), - }) - if s.swapEnabled { - handle("/wallet/withdraw/{coin}", jsonhttp.MethodHandler{ - "POST": web.ChainHandlers( - s.gasConfigMiddleware("wallet withdraw"), - web.FinalHandlerFunc(s.walletWithdrawHandler), - ), - }) - } - } + }), + )) + + handle("/wallet/withdraw/{coin}", web.ChainHandlers( + s.checkChequebookAvailability, + s.checkSwapAvailability, + web.FinalHandler(jsonhttp.MethodHandler{ + "POST": web.ChainHandlers( + s.gasConfigMiddleware("wallet withdraw"), + web.FinalHandlerFunc(s.walletWithdrawHandler), + ), + }), + )) handle("/stamps", web.ChainHandlers( s.postageSyncStatusCheckHandler, @@ -569,26 +592,14 @@ func (s *Service) mountBusinessDebug() { })), ) - handle("/batches", web.ChainHandlers( - web.FinalHandler(jsonhttp.MethodHandler{ - "GET": http.HandlerFunc(s.postageGetAllBatchesHandler), - })), - ) + handle("/batches", jsonhttp.MethodHandler{ + "GET": http.HandlerFunc(s.postageGetAllBatchesHandler), + }) handle("/accounting", jsonhttp.MethodHandler{ "GET": http.HandlerFunc(s.accountingInfoHandler), }) - handle("/readiness", web.ChainHandlers( - httpaccess.NewHTTPAccessSuppressLogHandler(), - web.FinalHandlerFunc(s.readinessHandler), - )) - - handle("/health", web.ChainHandlers( - httpaccess.NewHTTPAccessSuppressLogHandler(), - web.FinalHandlerFunc(s.healthHandler), - )) - handle("/stake/withdrawable", web.ChainHandlers( s.stakingAccessHandler, s.gasConfigMiddleware("get or withdraw withdrawable stake"), @@ -642,9 +653,7 @@ func (s *Service) mountBusinessDebug() { ), }) - handle("/rchash/{depth}/{anchor1}/{anchor2}", web.ChainHandlers( - web.FinalHandler(jsonhttp.MethodHandler{ - "GET": http.HandlerFunc(s.rchash), - }), - )) + handle("/rchash/{depth}/{anchor1}/{anchor2}", jsonhttp.MethodHandler{ + "GET": http.HandlerFunc(s.rchash), + }) } diff --git a/pkg/api/router_test.go b/pkg/api/router_test.go new file mode 100644 index 00000000000..6f3e89d5eeb --- /dev/null +++ b/pkg/api/router_test.go @@ -0,0 +1,448 @@ +// Copyright 2024 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 api_test + +import ( + "net/http" + "strings" + "testing" + + "github.com/ethersphere/bee/v2/pkg/jsonhttp/jsonhttptest" +) + +func TestEndpointOptions(t *testing.T) { + t.Parallel() + + testCases := []struct { + name string + serverOptions testServerOptions + expectedStatuses []struct { + route string + expectedMethods []string + expectedStatus int + } + }{ + { + name: "full_api_enabled", + serverOptions: testServerOptions{ + FullAPIDisabled: false, + SwapDisabled: false, + ChequebookDisabled: false, + }, + expectedStatuses: []struct { + route string + expectedMethods []string + expectedStatus int + }{ + // routes from mountTechnicalDebug + {"/node", []string{"GET"}, http.StatusNoContent}, + {"/addresses", []string{"GET"}, http.StatusNoContent}, + {"/chainstate", []string{"GET"}, http.StatusNoContent}, + {"/debugstore", []string{"GET"}, http.StatusNoContent}, + {"/loggers", []string{"GET"}, http.StatusNoContent}, + {"/loggers/some-exp", []string{"GET"}, http.StatusNoContent}, + {"/loggers/some-exp/1", []string{"PUT"}, http.StatusNoContent}, + {"/readiness", nil, http.StatusBadRequest}, + {"/health", nil, http.StatusOK}, + {"/metrics", nil, http.StatusOK}, + {"/not_found", nil, http.StatusNotFound}, + + // routes from mountAPI + {"/", nil, http.StatusOK}, + {"/robots.txt", nil, http.StatusOK}, + {"/bytes", []string{"POST"}, http.StatusNoContent}, + {"/bytes/{address}", []string{"GET", "HEAD"}, http.StatusNoContent}, + {"/chunks", []string{"POST"}, http.StatusNoContent}, + {"/chunks/stream", nil, http.StatusBadRequest}, + {"/chunks/{address}", []string{"GET", "HEAD"}, http.StatusNoContent}, + {"/envelope/{address}", []string{"POST"}, http.StatusNoContent}, + {"/soc/{owner}/{id}", []string{"GET", "POST"}, http.StatusNoContent}, + {"/feeds/{owner}/{topic}", []string{"GET", "POST"}, http.StatusNoContent}, + {"/bzz", []string{"POST"}, http.StatusNoContent}, + {"/grantee", []string{"POST"}, http.StatusNoContent}, + {"/grantee/{address}", []string{"GET", "PATCH"}, http.StatusNoContent}, + {"/bzz/{address}", []string{"GET"}, http.StatusNoContent}, + {"/bzz/{address}/{path:.*}", []string{"GET", "HEAD"}, http.StatusNoContent}, + {"/pss/send/{topic}/{targets}", []string{"POST"}, http.StatusNoContent}, + {"/pss/subscribe/{topic}", nil, http.StatusBadRequest}, + {"/tags", []string{"GET", "POST"}, http.StatusNoContent}, + {"/tags/{id}", []string{"GET", "DELETE", "PATCH"}, http.StatusNoContent}, + {"/pins", []string{"GET"}, http.StatusNoContent}, + {"/pins/check", []string{"GET"}, http.StatusNoContent}, + {"/pins/{reference}", []string{"GET", "POST", "DELETE"}, http.StatusNoContent}, + {"/stewardship/{address}", []string{"GET", "PUT"}, http.StatusNoContent}, + + // routes from mountBusinessDebug + {"/transactions", []string{"GET"}, http.StatusNoContent}, + {"/transactions/{hash}", []string{"GET", "POST", "DELETE"}, http.StatusNoContent}, + {"/peers", []string{"GET"}, http.StatusNoContent}, + {"/pingpong/{address}", []string{"POST"}, http.StatusNoContent}, + {"/reservestate", []string{"GET"}, http.StatusNoContent}, + {"/connect/{multi-address:.+}", []string{"POST"}, http.StatusNoContent}, + {"/blocklist", []string{"GET"}, http.StatusNoContent}, + {"/peers/{address}", []string{"DELETE"}, http.StatusNoContent}, + {"/topology", []string{"GET"}, http.StatusNoContent}, + {"/welcome-message", []string{"GET", "POST"}, http.StatusNoContent}, + {"/balances", []string{"GET"}, http.StatusNoContent}, + {"/balances/{peer}", []string{"GET"}, http.StatusNoContent}, + {"/consumed", []string{"GET"}, http.StatusNoContent}, + {"/consumed/{peer}", []string{"GET"}, http.StatusNoContent}, + {"/timesettlements", []string{"GET"}, http.StatusNoContent}, + {"/settlements", []string{"GET"}, http.StatusNoContent}, + {"/settlements/{peer}", []string{"GET"}, http.StatusNoContent}, + {"/chequebook/cheque/{peer}", []string{"GET"}, http.StatusNoContent}, + {"/chequebook/cheque", []string{"GET"}, http.StatusNoContent}, + {"/chequebook/cashout/{peer}", []string{"GET", "POST"}, http.StatusNoContent}, + {"/chequebook/balance", []string{"GET"}, http.StatusNoContent}, + {"/chequebook/address", []string{"GET"}, http.StatusNoContent}, + {"/chequebook/deposit", []string{"POST"}, http.StatusNoContent}, + {"/chequebook/withdraw", []string{"POST"}, http.StatusNoContent}, + {"/wallet", []string{"GET"}, http.StatusNoContent}, + {"/wallet/withdraw/{coin}", []string{"POST"}, http.StatusNoContent}, + {"/stamps", []string{"GET"}, http.StatusNoContent}, + {"/stamps/{batch_id}", []string{"GET"}, http.StatusNoContent}, + {"/stamps/{batch_id}/buckets", []string{"GET"}, http.StatusNoContent}, + {"/stamps/{amount}/{depth}", []string{"POST"}, http.StatusNoContent}, + {"/stamps/topup/{batch_id}/{amount}", []string{"PATCH"}, http.StatusNoContent}, + {"/stamps/dilute/{batch_id}/{depth}", []string{"PATCH"}, http.StatusNoContent}, + {"/batches", []string{"GET"}, http.StatusNoContent}, + {"/accounting", []string{"GET"}, http.StatusNoContent}, + {"/stake/withdrawable", []string{"GET", "DELETE"}, http.StatusNoContent}, + {"/stake/{amount}", []string{"POST"}, http.StatusNoContent}, + {"/stake", []string{"GET", "DELETE"}, http.StatusNoContent}, + {"/redistributionstate", []string{"GET"}, http.StatusNoContent}, + {"/status", []string{"GET"}, http.StatusNoContent}, + {"/status/peers", []string{"GET"}, http.StatusNoContent}, + {"/status/neighborhoods", []string{"GET"}, http.StatusNoContent}, + {"/rchash/{depth}/{anchor1}/{anchor2}", []string{"GET"}, http.StatusNoContent}, + }, + }, + { + name: "full_api_disabled", + serverOptions: testServerOptions{ + FullAPIDisabled: true, + SwapDisabled: false, + ChequebookDisabled: false, + }, + expectedStatuses: []struct { + route string + expectedMethods []string + expectedStatus int + }{ + // routes from mountTechnicalDebug + {"/node", []string{"GET"}, http.StatusNoContent}, + {"/addresses", []string{"GET"}, http.StatusNoContent}, + {"/chainstate", []string{"GET"}, http.StatusNoContent}, + {"/debugstore", []string{"GET"}, http.StatusNoContent}, + {"/loggers", []string{"GET"}, http.StatusNoContent}, + {"/loggers/some-exp", []string{"GET"}, http.StatusNoContent}, + {"/loggers/some-exp/1", []string{"PUT"}, http.StatusNoContent}, + {"/readiness", nil, http.StatusBadRequest}, + {"/health", nil, http.StatusOK}, + {"/metrics", nil, http.StatusOK}, + {"/not_found", nil, http.StatusNotFound}, + + // routes from mountAPI + {"/", nil, http.StatusOK}, + {"/robots.txt", nil, http.StatusOK}, + {"/bytes", nil, http.StatusServiceUnavailable}, + {"/bytes/{address}", nil, http.StatusServiceUnavailable}, + {"/chunks", nil, http.StatusServiceUnavailable}, + {"/chunks/stream", nil, http.StatusServiceUnavailable}, + {"/chunks/{address}", nil, http.StatusServiceUnavailable}, + {"/envelope/{address}", nil, http.StatusServiceUnavailable}, + {"/soc/{owner}/{id}", nil, http.StatusServiceUnavailable}, + {"/feeds/{owner}/{topic}", nil, http.StatusServiceUnavailable}, + {"/bzz", nil, http.StatusServiceUnavailable}, + {"/grantee", nil, http.StatusServiceUnavailable}, + {"/grantee/{address}", nil, http.StatusServiceUnavailable}, + {"/bzz/{address}", nil, http.StatusServiceUnavailable}, + {"/bzz/{address}/{path:.*}", nil, http.StatusServiceUnavailable}, + {"/pss/send/{topic}/{targets}", nil, http.StatusServiceUnavailable}, + {"/pss/subscribe/{topic}", nil, http.StatusServiceUnavailable}, + {"/tags", nil, http.StatusServiceUnavailable}, + {"/tags/{id}", nil, http.StatusServiceUnavailable}, + {"/pins", nil, http.StatusServiceUnavailable}, + {"/pins/check", nil, http.StatusServiceUnavailable}, + {"/pins/{reference}", nil, http.StatusServiceUnavailable}, + {"/stewardship/{address}", nil, http.StatusServiceUnavailable}, + + // routes from mountBusinessDebug + {"/transactions", nil, http.StatusServiceUnavailable}, + {"/transactions/{hash}", nil, http.StatusServiceUnavailable}, + {"/peers", nil, http.StatusServiceUnavailable}, + {"/pingpong/{address}", nil, http.StatusServiceUnavailable}, + {"/reservestate", nil, http.StatusServiceUnavailable}, + {"/connect/{multi-address:.+}", nil, http.StatusServiceUnavailable}, + {"/blocklist", nil, http.StatusServiceUnavailable}, + {"/peers/{address}", nil, http.StatusServiceUnavailable}, + {"/topology", nil, http.StatusServiceUnavailable}, + {"/welcome-message", nil, http.StatusServiceUnavailable}, + {"/balances", nil, http.StatusServiceUnavailable}, + {"/balances/{peer}", nil, http.StatusServiceUnavailable}, + {"/consumed", nil, http.StatusServiceUnavailable}, + {"/consumed/{peer}", nil, http.StatusServiceUnavailable}, + {"/timesettlements", nil, http.StatusServiceUnavailable}, + {"/settlements", nil, http.StatusServiceUnavailable}, + {"/settlements/{peer}", nil, http.StatusServiceUnavailable}, + {"/chequebook/cheque/{peer}", nil, http.StatusServiceUnavailable}, + {"/chequebook/cheque", nil, http.StatusServiceUnavailable}, + {"/chequebook/cashout/{peer}", nil, http.StatusServiceUnavailable}, + {"/chequebook/balance", nil, http.StatusServiceUnavailable}, + {"/chequebook/address", nil, http.StatusServiceUnavailable}, + {"/chequebook/deposit", nil, http.StatusServiceUnavailable}, + {"/chequebook/withdraw", nil, http.StatusServiceUnavailable}, + {"/wallet", nil, http.StatusServiceUnavailable}, + {"/wallet/withdraw/{coin}", nil, http.StatusServiceUnavailable}, + {"/stamps", nil, http.StatusServiceUnavailable}, + {"/stamps/{batch_id}", nil, http.StatusServiceUnavailable}, + {"/stamps/{batch_id}/buckets", nil, http.StatusServiceUnavailable}, + {"/stamps/{amount}/{depth}", nil, http.StatusServiceUnavailable}, + {"/stamps/topup/{batch_id}/{amount}", nil, http.StatusServiceUnavailable}, + {"/stamps/dilute/{batch_id}/{depth}", nil, http.StatusServiceUnavailable}, + {"/batches", nil, http.StatusServiceUnavailable}, + {"/accounting", nil, http.StatusServiceUnavailable}, + {"/stake/withdrawable", nil, http.StatusServiceUnavailable}, + {"/stake/{amount}", nil, http.StatusServiceUnavailable}, + {"/stake", nil, http.StatusServiceUnavailable}, + {"/redistributionstate", nil, http.StatusServiceUnavailable}, + {"/status", nil, http.StatusServiceUnavailable}, + {"/status/peers", nil, http.StatusServiceUnavailable}, + {"/status/neighborhoods", nil, http.StatusServiceUnavailable}, + {"/rchash/{depth}/{anchor1}/{anchor2}", nil, http.StatusServiceUnavailable}, + }, + }, + { + name: "swap_disabled", + serverOptions: testServerOptions{ + FullAPIDisabled: false, + SwapDisabled: true, + ChequebookDisabled: false, + }, + expectedStatuses: []struct { + route string + expectedMethods []string + expectedStatus int + }{ + // routes from mountTechnicalDebug + {"/node", []string{"GET"}, http.StatusNoContent}, + {"/addresses", []string{"GET"}, http.StatusNoContent}, + {"/chainstate", []string{"GET"}, http.StatusNoContent}, + {"/debugstore", []string{"GET"}, http.StatusNoContent}, + {"/loggers", []string{"GET"}, http.StatusNoContent}, + {"/loggers/some-exp", []string{"GET"}, http.StatusNoContent}, + {"/loggers/some-exp/1", []string{"PUT"}, http.StatusNoContent}, + {"/readiness", nil, http.StatusBadRequest}, + {"/health", nil, http.StatusOK}, + {"/metrics", nil, http.StatusOK}, + {"/not_found", nil, http.StatusNotFound}, + + // routes from mountAPI + {"/", nil, http.StatusOK}, + {"/robots.txt", nil, http.StatusOK}, + {"/bytes", []string{"POST"}, http.StatusNoContent}, + {"/bytes/{address}", []string{"GET", "HEAD"}, http.StatusNoContent}, + {"/chunks", []string{"POST"}, http.StatusNoContent}, + {"/chunks/stream", nil, http.StatusBadRequest}, + {"/chunks/{address}", []string{"GET", "HEAD"}, http.StatusNoContent}, + {"/envelope/{address}", []string{"POST"}, http.StatusNoContent}, + {"/soc/{owner}/{id}", []string{"GET", "POST"}, http.StatusNoContent}, + {"/feeds/{owner}/{topic}", []string{"GET", "POST"}, http.StatusNoContent}, + {"/bzz", []string{"POST"}, http.StatusNoContent}, + {"/grantee", []string{"POST"}, http.StatusNoContent}, + {"/grantee/{address}", []string{"GET", "PATCH"}, http.StatusNoContent}, + {"/bzz/{address}", []string{"GET"}, http.StatusNoContent}, + {"/bzz/{address}/{path:.*}", []string{"GET", "HEAD"}, http.StatusNoContent}, + {"/pss/send/{topic}/{targets}", []string{"POST"}, http.StatusNoContent}, + {"/pss/subscribe/{topic}", nil, http.StatusBadRequest}, + {"/tags", []string{"GET", "POST"}, http.StatusNoContent}, + {"/tags/{id}", []string{"GET", "DELETE", "PATCH"}, http.StatusNoContent}, + {"/pins", []string{"GET"}, http.StatusNoContent}, + {"/pins/check", []string{"GET"}, http.StatusNoContent}, + {"/pins/{reference}", []string{"GET", "POST", "DELETE"}, http.StatusNoContent}, + {"/stewardship/{address}", []string{"GET", "PUT"}, http.StatusNoContent}, + + // routes from mountBusinessDebug + {"/transactions", []string{"GET"}, http.StatusNoContent}, + {"/transactions/{hash}", []string{"GET", "POST", "DELETE"}, http.StatusNoContent}, + {"/peers", []string{"GET"}, http.StatusNoContent}, + {"/pingpong/{address}", []string{"POST"}, http.StatusNoContent}, + {"/reservestate", []string{"GET"}, http.StatusNoContent}, + {"/connect/{multi-address:.+}", []string{"POST"}, http.StatusNoContent}, + {"/blocklist", []string{"GET"}, http.StatusNoContent}, + {"/peers/{address}", []string{"DELETE"}, http.StatusNoContent}, + {"/topology", []string{"GET"}, http.StatusNoContent}, + {"/welcome-message", []string{"GET", "POST"}, http.StatusNoContent}, + {"/balances", []string{"GET"}, http.StatusNoContent}, + {"/balances/{peer}", []string{"GET"}, http.StatusNoContent}, + {"/consumed", []string{"GET"}, http.StatusNoContent}, + {"/consumed/{peer}", []string{"GET"}, http.StatusNoContent}, + {"/timesettlements", []string{"GET"}, http.StatusNoContent}, + {"/settlements", nil, http.StatusNotImplemented}, + {"/settlements/{peer}", nil, http.StatusNotImplemented}, + {"/chequebook/cheque/{peer}", nil, http.StatusNotImplemented}, + {"/chequebook/cheque", nil, http.StatusNotImplemented}, + {"/chequebook/cashout/{peer}", nil, http.StatusNotImplemented}, + {"/chequebook/balance", []string{"GET"}, http.StatusNoContent}, + {"/chequebook/address", []string{"GET"}, http.StatusNoContent}, + {"/chequebook/deposit", []string{"POST"}, http.StatusNoContent}, + {"/chequebook/withdraw", []string{"POST"}, http.StatusNoContent}, + {"/wallet", []string{"GET"}, http.StatusNoContent}, + {"/wallet/withdraw/{coin}", nil, http.StatusNotImplemented}, + {"/stamps", []string{"GET"}, http.StatusNoContent}, + {"/stamps/{batch_id}", []string{"GET"}, http.StatusNoContent}, + {"/stamps/{batch_id}/buckets", []string{"GET"}, http.StatusNoContent}, + {"/stamps/{amount}/{depth}", []string{"POST"}, http.StatusNoContent}, + {"/stamps/topup/{batch_id}/{amount}", []string{"PATCH"}, http.StatusNoContent}, + {"/stamps/dilute/{batch_id}/{depth}", []string{"PATCH"}, http.StatusNoContent}, + {"/batches", []string{"GET"}, http.StatusNoContent}, + {"/accounting", []string{"GET"}, http.StatusNoContent}, + {"/stake/withdrawable", []string{"GET", "DELETE"}, http.StatusNoContent}, + {"/stake/{amount}", []string{"POST"}, http.StatusNoContent}, + {"/stake", []string{"GET", "DELETE"}, http.StatusNoContent}, + {"/redistributionstate", []string{"GET"}, http.StatusNoContent}, + {"/status", []string{"GET"}, http.StatusNoContent}, + {"/status/peers", []string{"GET"}, http.StatusNoContent}, + {"/status/neighborhoods", []string{"GET"}, http.StatusNoContent}, + {"/rchash/{depth}/{anchor1}/{anchor2}", []string{"GET"}, http.StatusNoContent}, + }, + }, + { + name: "chechebook_disabled", + serverOptions: testServerOptions{ + FullAPIDisabled: false, + SwapDisabled: false, + ChequebookDisabled: true, + }, + expectedStatuses: []struct { + route string + expectedMethods []string + expectedStatus int + }{ + // routes from mountTechnicalDebug + {"/node", []string{"GET"}, http.StatusNoContent}, + {"/addresses", []string{"GET"}, http.StatusNoContent}, + {"/chainstate", []string{"GET"}, http.StatusNoContent}, + {"/debugstore", []string{"GET"}, http.StatusNoContent}, + {"/loggers", []string{"GET"}, http.StatusNoContent}, + {"/loggers/some-exp", []string{"GET"}, http.StatusNoContent}, + {"/loggers/some-exp/1", []string{"PUT"}, http.StatusNoContent}, + {"/readiness", nil, http.StatusBadRequest}, + {"/health", nil, http.StatusOK}, + {"/metrics", nil, http.StatusOK}, + {"/not_found", nil, http.StatusNotFound}, + + // routes from mountAPI + {"/", nil, http.StatusOK}, + {"/robots.txt", nil, http.StatusOK}, + {"/bytes", []string{"POST"}, http.StatusNoContent}, + {"/bytes/{address}", []string{"GET", "HEAD"}, http.StatusNoContent}, + {"/chunks", []string{"POST"}, http.StatusNoContent}, + {"/chunks/stream", nil, http.StatusBadRequest}, + {"/chunks/{address}", []string{"GET", "HEAD"}, http.StatusNoContent}, + {"/envelope/{address}", []string{"POST"}, http.StatusNoContent}, + {"/soc/{owner}/{id}", []string{"GET", "POST"}, http.StatusNoContent}, + {"/feeds/{owner}/{topic}", []string{"GET", "POST"}, http.StatusNoContent}, + {"/bzz", []string{"POST"}, http.StatusNoContent}, + {"/grantee", []string{"POST"}, http.StatusNoContent}, + {"/grantee/{address}", []string{"GET", "PATCH"}, http.StatusNoContent}, + {"/bzz/{address}", []string{"GET"}, http.StatusNoContent}, + {"/bzz/{address}/{path:.*}", []string{"GET", "HEAD"}, http.StatusNoContent}, + {"/pss/send/{topic}/{targets}", []string{"POST"}, http.StatusNoContent}, + {"/pss/subscribe/{topic}", nil, http.StatusBadRequest}, + {"/tags", []string{"GET", "POST"}, http.StatusNoContent}, + {"/tags/{id}", []string{"GET", "DELETE", "PATCH"}, http.StatusNoContent}, + {"/pins", []string{"GET"}, http.StatusNoContent}, + {"/pins/check", []string{"GET"}, http.StatusNoContent}, + {"/pins/{reference}", []string{"GET", "POST", "DELETE"}, http.StatusNoContent}, + {"/stewardship/{address}", []string{"GET", "PUT"}, http.StatusNoContent}, + + // routes from mountBusinessDebug + {"/transactions", []string{"GET"}, http.StatusNoContent}, + {"/transactions/{hash}", []string{"GET", "POST", "DELETE"}, http.StatusNoContent}, + {"/peers", []string{"GET"}, http.StatusNoContent}, + {"/pingpong/{address}", []string{"POST"}, http.StatusNoContent}, + {"/reservestate", []string{"GET"}, http.StatusNoContent}, + {"/connect/{multi-address:.+}", []string{"POST"}, http.StatusNoContent}, + {"/blocklist", []string{"GET"}, http.StatusNoContent}, + {"/peers/{address}", []string{"DELETE"}, http.StatusNoContent}, + {"/topology", []string{"GET"}, http.StatusNoContent}, + {"/welcome-message", []string{"GET", "POST"}, http.StatusNoContent}, + {"/balances", []string{"GET"}, http.StatusNoContent}, + {"/balances/{peer}", []string{"GET"}, http.StatusNoContent}, + {"/consumed", []string{"GET"}, http.StatusNoContent}, + {"/consumed/{peer}", []string{"GET"}, http.StatusNoContent}, + {"/timesettlements", []string{"GET"}, http.StatusNoContent}, + {"/settlements", []string{"GET"}, http.StatusNoContent}, + {"/settlements/{peer}", []string{"GET"}, http.StatusNoContent}, + {"/chequebook/cheque/{peer}", []string{"GET"}, http.StatusNoContent}, + {"/chequebook/cheque", []string{"GET"}, http.StatusNoContent}, + {"/chequebook/cashout/{peer}", []string{"GET", "POST"}, http.StatusNoContent}, + {"/chequebook/balance", nil, http.StatusNotImplemented}, + {"/chequebook/address", nil, http.StatusNotImplemented}, + {"/chequebook/deposit", nil, http.StatusNotImplemented}, + {"/chequebook/withdraw", nil, http.StatusNotImplemented}, + {"/wallet", nil, http.StatusNotImplemented}, + {"/wallet/withdraw/{coin}", nil, http.StatusNotImplemented}, + {"/stamps", []string{"GET"}, http.StatusNoContent}, + {"/stamps/{batch_id}", []string{"GET"}, http.StatusNoContent}, + {"/stamps/{batch_id}/buckets", []string{"GET"}, http.StatusNoContent}, + {"/stamps/{amount}/{depth}", []string{"POST"}, http.StatusNoContent}, + {"/stamps/topup/{batch_id}/{amount}", []string{"PATCH"}, http.StatusNoContent}, + {"/stamps/dilute/{batch_id}/{depth}", []string{"PATCH"}, http.StatusNoContent}, + {"/batches", []string{"GET"}, http.StatusNoContent}, + {"/accounting", []string{"GET"}, http.StatusNoContent}, + {"/stake/withdrawable", []string{"GET", "DELETE"}, http.StatusNoContent}, + {"/stake/{amount}", []string{"POST"}, http.StatusNoContent}, + {"/stake", []string{"GET", "DELETE"}, http.StatusNoContent}, + {"/redistributionstate", []string{"GET"}, http.StatusNoContent}, + {"/status", []string{"GET"}, http.StatusNoContent}, + {"/status/peers", []string{"GET"}, http.StatusNoContent}, + {"/status/neighborhoods", []string{"GET"}, http.StatusNoContent}, + {"/rchash/{depth}/{anchor1}/{anchor2}", []string{"GET"}, http.StatusNoContent}, + }, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + + testServer, _, _, _ := newTestServer(t, tc.serverOptions) + + routeToName := func(route string) string { + if route == "/" { + return "root" + } + return strings.ReplaceAll(route, "/", "_") + } + + for _, tt := range tc.expectedStatuses { + t.Run(tc.name+routeToName(tt.route), func(t *testing.T) { + resp := jsonhttptest.Request(t, testServer, http.MethodOptions, tt.route, tt.expectedStatus) + + allowHeader := resp.Get("Allow") + actualMethods := strings.Split(allowHeader, ", ") + + for _, expectedMethod := range tt.expectedMethods { + if !contains(actualMethods, expectedMethod) { + t.Errorf("expected method %s not found for route %s", expectedMethod, tt.route) + } + } + }) + } + }) + } +} + +func contains(slice []string, item string) bool { + for _, s := range slice { + if s == item { + return true + } + } + return false +} diff --git a/pkg/jsonhttp/handlers.go b/pkg/jsonhttp/handlers.go index 5a954b9d26a..77e63d20f13 100644 --- a/pkg/jsonhttp/handlers.go +++ b/pkg/jsonhttp/handlers.go @@ -45,7 +45,6 @@ func HandleMethods(methods map[string]http.Handler, body string, contentType str w.Header().Set("Content-Type", contentType) w.WriteHeader(http.StatusMethodNotAllowed) fmt.Fprintln(w, body) - } func NotFoundHandler(w http.ResponseWriter, _ *http.Request) { diff --git a/pkg/node/devnode.go b/pkg/node/devnode.go index 5439fe2d2a7..9d34f1aaa57 100644 --- a/pkg/node/devnode.go +++ b/pkg/node/devnode.go @@ -137,7 +137,7 @@ func NewDevBee(logger log.Logger, o *DevOptions) (b *DevBee, err error) { return nil, fmt.Errorf("blockchain address: %w", err) } - var mockTransaction = transactionmock.New(transactionmock.WithPendingTransactionsFunc(func() ([]common.Hash, error) { + mockTransaction := transactionmock.New(transactionmock.WithPendingTransactionsFunc(func() ([]common.Hash, error) { return []common.Hash{common.HexToHash("abcd")}, nil }), transactionmock.WithResendTransactionFunc(func(ctx context.Context, txHash common.Hash) error { return nil @@ -303,13 +303,11 @@ func NewDevBee(logger log.Logger, o *DevOptions) (b *DevBee, err error) { )) ) - var ( - // syncStatusFn mocks sync status because complete sync is required in order to curl certain apis e.g. /stamps. - // this allows accessing those apis by passing true to isDone in devNode. - syncStatusFn = func() (isDone bool, err error) { - return true, nil - } - ) + // syncStatusFn mocks sync status because complete sync is required in order to curl certain apis e.g. /stamps. + // this allows accessing those apis by passing true to isDone in devNode. + syncStatusFn := func() (isDone bool, err error) { + return true, nil + } mockFeeds := factory.New(localStore.Download(true)) mockResolver := resolverMock.NewResolver() @@ -351,7 +349,7 @@ func NewDevBee(logger log.Logger, o *DevOptions) (b *DevBee, err error) { SyncStatus: syncStatusFn, } - var erc20 = erc20mock.New( + erc20 := erc20mock.New( erc20mock.WithBalanceOfFunc(func(ctx context.Context, address common.Address) (*big.Int, error) { return big.NewInt(0), nil }), @@ -366,10 +364,9 @@ func NewDevBee(logger log.Logger, o *DevOptions) (b *DevBee, err error) { CORSAllowedOrigins: o.CORSAllowedOrigins, WsPingPeriod: 60 * time.Second, }, debugOpts, 1, erc20) - apiService.MountTechnicalDebug() - apiService.MountDebug() - apiService.MountAPI() + apiService.Mount() + apiService.EnableFullAPI() apiService.SetProbe(probe) apiService.SetP2P(p2ps) apiService.SetSwarmAddress(&swarmAddress) @@ -444,7 +441,6 @@ func pong(_ context.Context, _ swarm.Address, _ ...string) (rtt time.Duration, e } func randomAddress() (swarm.Address, error) { - b := make([]byte, 32) _, err := rand.Read(b) @@ -453,5 +449,4 @@ func randomAddress() (swarm.Address, error) { } return swarm.NewAddress(b), nil - } diff --git a/pkg/node/node.go b/pkg/node/node.go index 6db098c78b6..09f24712056 100644 --- a/pkg/node/node.go +++ b/pkg/node/node.go @@ -450,7 +450,8 @@ func NewBee( o.CORSAllowedOrigins, stamperStore, ) - apiService.MountTechnicalDebug() + + apiService.Mount() apiService.SetProbe(probe) apiService.SetSwarmAddress(&swarmAddress) @@ -1178,8 +1179,7 @@ func NewBee( WsPingPeriod: 60 * time.Second, }, extraOpts, chainID, erc20Service) - apiService.MountDebug() - apiService.MountAPI() + apiService.EnableFullAPI() apiService.SetRedistributionAgent(agent) }