Commit 3d9bcfd1 authored by Ralph Pichler's avatar Ralph Pichler Committed by GitHub

feat: early tx api (#2210)

parent c491d247
......@@ -66,7 +66,7 @@ type Service struct {
// to expose /addresses, /health endpoints, Go metrics and pprof. It is useful to expose
// these endpoints before all dependencies are configured and injected to have
// access to basic debugging tools and /health endpoint.
func New(publicKey, pssPublicKey ecdsa.PublicKey, ethereumAddress common.Address, logger logging.Logger, tracer *tracing.Tracer, corsAllowedOrigins []string) *Service {
func New(publicKey, pssPublicKey ecdsa.PublicKey, ethereumAddress common.Address, logger logging.Logger, tracer *tracing.Tracer, corsAllowedOrigins []string, transaction transaction.Service) *Service {
s := new(Service)
s.publicKey = publicKey
s.pssPublicKey = pssPublicKey
......@@ -75,6 +75,7 @@ func New(publicKey, pssPublicKey ecdsa.PublicKey, ethereumAddress common.Address
s.tracer = tracer
s.corsAllowedOrigins = corsAllowedOrigins
s.metricsRegistry = newMetricsRegistry()
s.transaction = transaction
s.setRouter(s.newBasicRouter())
......@@ -84,7 +85,7 @@ func New(publicKey, pssPublicKey ecdsa.PublicKey, ethereumAddress common.Address
// 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(overlay swarm.Address, p2p p2p.DebugService, pingpong pingpong.Interface, topologyDriver topology.Driver, lightNodes *lightnode.Container, storer storage.Storer, tags *tags.Tags, accounting accounting.Interface, pseudosettle settlement.Interface, chequebookEnabled bool, swap swap.Interface, chequebook chequebook.Service, batchStore postage.Storer, transaction transaction.Service, post postage.Service, postageContract postagecontract.Interface) {
func (s *Service) Configure(overlay swarm.Address, p2p p2p.DebugService, pingpong pingpong.Interface, topologyDriver topology.Driver, lightNodes *lightnode.Container, storer storage.Storer, tags *tags.Tags, accounting accounting.Interface, pseudosettle settlement.Interface, chequebookEnabled bool, swap swap.Interface, chequebook chequebook.Service, batchStore postage.Storer, post postage.Service, postageContract postagecontract.Interface) {
s.p2p = p2p
s.pingpong = pingpong
s.topologyDriver = topologyDriver
......@@ -97,7 +98,6 @@ func (s *Service) Configure(overlay swarm.Address, p2p p2p.DebugService, pingpon
s.lightNodes = lightNodes
s.batchStore = batchStore
s.pseudosettle = pseudosettle
s.transaction = transaction
s.overlay = &overlay
s.post = post
s.postageContract = postageContract
......
......@@ -86,8 +86,8 @@ func newTestServer(t *testing.T, o testServerOptions) *testServer {
swapserv := swapmock.New(o.SwapOpts...)
transaction := transactionmock.New(o.TransactionOpts...)
ln := lightnode.NewContainer(o.Overlay)
s := debugapi.New(o.PublicKey, o.PSSPublicKey, o.EthereumAddress, logging.New(ioutil.Discard, 0), nil, o.CORSAllowedOrigins)
s.Configure(o.Overlay, o.P2P, o.Pingpong, topologyDriver, ln, o.Storer, o.Tags, acc, settlement, true, swapserv, chequebook, o.BatchStore, transaction, o.Post, o.PostageContract)
s := debugapi.New(o.PublicKey, o.PSSPublicKey, o.EthereumAddress, logging.New(ioutil.Discard, 0), nil, o.CORSAllowedOrigins, transaction)
s.Configure(o.Overlay, o.P2P, o.Pingpong, topologyDriver, ln, o.Storer, o.Tags, acc, settlement, true, swapserv, chequebook, o.BatchStore, o.Post, o.PostageContract)
ts := httptest.NewServer(s)
t.Cleanup(ts.Close)
......@@ -154,7 +154,7 @@ func TestServer_Configure(t *testing.T) {
swapserv := swapmock.New(o.SwapOpts...)
ln := lightnode.NewContainer(o.Overlay)
transaction := transactionmock.New(o.TransactionOpts...)
s := debugapi.New(o.PublicKey, o.PSSPublicKey, o.EthereumAddress, logging.New(ioutil.Discard, 0), nil, nil)
s := debugapi.New(o.PublicKey, o.PSSPublicKey, o.EthereumAddress, logging.New(ioutil.Discard, 0), nil, nil, transaction)
ts := httptest.NewServer(s)
t.Cleanup(ts.Close)
......@@ -185,7 +185,7 @@ func TestServer_Configure(t *testing.T) {
}),
)
s.Configure(o.Overlay, o.P2P, o.Pingpong, topologyDriver, ln, o.Storer, o.Tags, acc, settlement, true, swapserv, chequebook, nil, transaction, mockpost.New(), nil)
s.Configure(o.Overlay, o.P2P, o.Pingpong, topologyDriver, ln, o.Storer, o.Tags, acc, settlement, true, swapserv, chequebook, nil, mockpost.New(), nil)
testBasicRouter(t, client)
jsonhttptest.Request(t, client, http.MethodGet, "/readiness", http.StatusOK,
......
......@@ -59,6 +59,17 @@ func (s *Service) newBasicRouter() *mux.Router {
"GET": http.HandlerFunc(s.addressesHandler),
})
if s.transaction != nil {
router.Handle("/transactions", jsonhttp.MethodHandler{
"GET": http.HandlerFunc(s.transactionListHandler),
})
router.Handle("/transactions/{hash}", jsonhttp.MethodHandler{
"GET": http.HandlerFunc(s.transactionDetailHandler),
"POST": http.HandlerFunc(s.transactionResendHandler),
"DELETE": http.HandlerFunc(s.transactionCancelHandler),
})
}
return router
}
......@@ -171,15 +182,6 @@ func (s *Service) newRouter() *mux.Router {
})
}
router.Handle("/transactions", jsonhttp.MethodHandler{
"GET": http.HandlerFunc(s.transactionListHandler),
})
router.Handle("/transactions/{hash}", jsonhttp.MethodHandler{
"GET": http.HandlerFunc(s.transactionDetailHandler),
"POST": http.HandlerFunc(s.transactionResendHandler),
"DELETE": http.HandlerFunc(s.transactionCancelHandler),
})
router.Handle("/tags/{id}", jsonhttp.MethodHandler{
"GET": http.HandlerFunc(s.getTagHandler),
})
......
......@@ -66,18 +66,6 @@ func InitChain(
return nil, common.Address{}, 0, nil, nil, fmt.Errorf("new transaction service: %w", err)
}
// Sync the with the given Ethereum backend:
isSynced, _, err := transaction.IsSynced(ctx, backend, maxDelay)
if err != nil {
return nil, common.Address{}, 0, nil, nil, fmt.Errorf("is synced: %w", err)
}
if !isSynced {
logger.Infof("waiting to sync with the Ethereum backend")
err := transaction.WaitSynced(logger, ctx, backend, maxDelay)
if err != nil {
return nil, common.Address{}, 0, nil, nil, fmt.Errorf("waiting backend sync: %w", err)
}
}
return backend, overlayEthAddress, chainID.Int64(), transactionMonitor, transactionService, nil
}
......
......@@ -197,6 +197,35 @@ func NewBee(addr string, publicKey *ecdsa.PublicKey, signer crypto.Signer, netwo
addressbook := addressbook.New(stateStore)
var (
swapBackend *ethclient.Client
overlayEthAddress common.Address
chainID int64
transactionService transaction.Service
transactionMonitor transaction.Monitor
chequebookFactory chequebook.Factory
chequebookService chequebook.Service
chequeStore chequebook.ChequeStore
cashoutService chequebook.CashoutService
pollingInterval = time.Duration(o.BlockTime) * time.Second
)
if !o.Standalone {
swapBackend, overlayEthAddress, chainID, transactionMonitor, transactionService, err = InitChain(
p2pCtx,
logger,
stateStore,
o.SwapEndpoint,
signer,
pollingInterval,
)
if err != nil {
return nil, fmt.Errorf("init chain: %w", err)
}
b.ethClientCloser = swapBackend.Close
b.transactionCloser = tracerCloser
b.transactionMonitorCloser = transactionMonitor
}
var debugAPIService *debugapi.Service
if o.DebugAPIAddr != "" {
overlayEthAddress, err := signer.EthereumAddress()
......@@ -204,7 +233,7 @@ func NewBee(addr string, publicKey *ecdsa.PublicKey, signer crypto.Signer, netwo
return nil, fmt.Errorf("eth address: %w", err)
}
// set up basic debug api endpoints for debugging and /health endpoint
debugAPIService = debugapi.New(*publicKey, pssPrivateKey.PublicKey, overlayEthAddress, logger, tracer, o.CORSAllowedOrigins)
debugAPIService = debugapi.New(*publicKey, pssPrivateKey.PublicKey, overlayEthAddress, logger, tracer, o.CORSAllowedOrigins, transactionService)
debugAPIListener, err := net.Listen("tcp", o.DebugAPIAddr)
if err != nil {
......@@ -230,33 +259,20 @@ func NewBee(addr string, publicKey *ecdsa.PublicKey, signer crypto.Signer, netwo
b.debugAPIServer = debugAPIServer
}
var (
swapBackend *ethclient.Client
overlayEthAddress common.Address
chainID int64
transactionService transaction.Service
transactionMonitor transaction.Monitor
chequebookFactory chequebook.Factory
chequebookService chequebook.Service
chequeStore chequebook.ChequeStore
cashoutService chequebook.CashoutService
pollingInterval = time.Duration(o.BlockTime) * time.Second
)
if !o.Standalone {
swapBackend, overlayEthAddress, chainID, transactionMonitor, transactionService, err = InitChain(
p2pCtx,
logger,
stateStore,
o.SwapEndpoint,
signer,
pollingInterval,
)
// Sync the with the given Ethereum backend:
isSynced, _, err := transaction.IsSynced(p2pCtx, swapBackend, maxDelay)
if err != nil {
return nil, fmt.Errorf("init chain: %w", err)
return nil, fmt.Errorf("is synced: %w", err)
}
if !isSynced {
logger.Infof("waiting to sync with the Ethereum backend")
err := transaction.WaitSynced(logger, p2pCtx, swapBackend, maxDelay)
if err != nil {
return nil, fmt.Errorf("waiting backend sync: %w", err)
}
}
b.ethClientCloser = swapBackend.Close
b.transactionCloser = tracerCloser
b.transactionMonitorCloser = transactionMonitor
}
if o.SwapEnable {
......@@ -751,7 +767,7 @@ func NewBee(addr string, publicKey *ecdsa.PublicKey, signer crypto.Signer, netwo
}
// inject dependencies and configure full debug api http path routes
debugAPIService.Configure(swarmAddress, p2ps, pingPong, kad, lightNodes, storer, tagService, acc, pseudosettleService, o.SwapEnable, swapService, chequebookService, batchStore, transactionService, post, postageContractService)
debugAPIService.Configure(swarmAddress, p2ps, pingPong, kad, lightNodes, storer, tagService, acc, pseudosettleService, o.SwapEnable, swapService, chequebookService, batchStore, post, postageContractService)
}
if err := kad.Start(p2pCtx); err != nil {
......
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