Files
3a9331169b Update avalanchego to v1.9.0-fuji (#472)
Co-authored-by: dhrubabasu <[email protected]>
Co-authored-by: Patrick O'Grady <[email protected]>
Co-authored-by: Stephen <[email protected]>
2022-10-02 20:20:49 -04:00

137 lines
3.7 KiB
Go

// (c) 2021, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package api
import (
"context"
"net/http"
"time"
"github.com/ava-labs/ortelius/cfg"
"github.com/ava-labs/ortelius/models"
"github.com/ava-labs/ortelius/services"
"github.com/ava-labs/ortelius/services/indexes/avax"
"github.com/ava-labs/ortelius/servicesctrl"
"github.com/ava-labs/ortelius/stream/consumers"
"github.com/ava-labs/ortelius/utils"
"github.com/gocraft/web"
"go.uber.org/zap"
)
// Server is an HTTP server configured with various ortelius APIs
type Server struct {
sc *servicesctrl.Control
server *http.Server
}
// NewServer creates a new *Server based on the given config
func NewServer(sc *servicesctrl.Control, conf cfg.Config) (*Server, error) {
router, err := newRouter(sc, conf)
if err != nil {
return nil, err
}
// Set address prefix to use the configured network
models.SetBech32HRP(conf.NetworkID)
return &Server{
sc: sc,
server: &http.Server{
Addr: conf.ListenAddr,
ReadTimeout: 5 * time.Second,
WriteTimeout: cfg.HTTPWriteTimeout,
IdleTimeout: 15 * time.Second,
Handler: router,
ReadHeaderTimeout: 5 * time.Second,
},
}, err
}
// Listen begins listening for new socket connections and blocks until closed
func (s *Server) Listen() error {
s.sc.Log.Info("server listening",
zap.String("addr", s.server.Addr),
)
return s.server.ListenAndServe()
}
// Close shuts the server down
func (s *Server) Close() error {
s.sc.Log.Info("Server shutting down")
ctx, cancelFn := context.WithTimeout(context.Background(), 10*time.Second)
defer cancelFn()
return s.server.Shutdown(ctx)
}
func newRouter(sc *servicesctrl.Control, conf cfg.Config) (*web.Router, error) {
sc.Log.Info("creating new router",
zap.Stringer("chainID", sc.GenesisContainer.XChainID),
)
indexBytes, err := newIndexResponse(conf.NetworkID, sc.GenesisContainer.XChainID, sc.GenesisContainer.AvaxAssetID)
if err != nil {
return nil, err
}
legacyIndexResponse, err := newLegacyIndexResponse(conf.NetworkID, sc.GenesisContainer.XChainID, sc.GenesisContainer.AvaxAssetID)
if err != nil {
return nil, err
}
// Create connections and readers
connections, err := sc.DatabaseRO()
if err != nil {
return nil, err
}
cache := utils.NewCache()
delayCache := utils.NewDelayCache(cache)
consumersmap := make(map[string]services.Consumer)
for chid, chain := range conf.Chains {
consumer, err := consumers.IndexerConsumer(conf.NetworkID, chain.VMType, chid)
if err != nil {
return nil, err
}
consumersmap[chid] = consumer
}
consumercchain, err := consumers.IndexerConsumerCChain(conf.NetworkID, conf.CchainID)
if err != nil {
return nil, err
}
avaxReader, err := avax.NewReader(conf.NetworkID, connections, consumersmap, consumercchain, sc)
if err != nil {
return nil, err
}
ctx := Context{sc: sc}
// Build router
router := web.New(ctx).
Middleware(newContextSetter(sc, conf.NetworkID, connections, delayCache)).
Middleware((*Context).setHeaders).
Get("/", func(c *Context, resp web.ResponseWriter, _ *web.Request) {
if _, err := resp.Write(indexBytes); err != nil {
sc.Log.Warn("response write failed",
zap.Error(err),
)
}
}).
NotFound((*Context).notFoundHandler).
Middleware(func(c *Context, w web.ResponseWriter, r *web.Request, next web.NextMiddlewareFunc) {
c.avaxReader = avaxReader
c.avaxAssetID = sc.GenesisContainer.AvaxAssetID
next(w, r)
})
AddV2Routes(&ctx, router, "/v2", indexBytes, nil)
// Legacy routes.
AddV2Routes(&ctx, router, "/x", legacyIndexResponse, &sc.GenesisContainer.XChainID)
AddV2Routes(&ctx, router, "/X", legacyIndexResponse, &sc.GenesisContainer.XChainID)
return router, nil
}