github.com/iotexproject/iotex-core@v1.14.1-rc1/api/serverV2.go (about)

     1  // Copyright (c) 2022 IoTeX Foundation
     2  // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability
     3  // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed.
     4  // This source code is governed by Apache License 2.0 that can be found in the LICENSE file.
     5  
     6  package api
     7  
     8  import (
     9  	"context"
    10  
    11  	"github.com/pkg/errors"
    12  	"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
    13  	tracesdk "go.opentelemetry.io/otel/sdk/trace"
    14  	"golang.org/x/time/rate"
    15  
    16  	"github.com/iotexproject/iotex-core/action/protocol"
    17  	"github.com/iotexproject/iotex-core/action/protocol/execution/evm"
    18  	"github.com/iotexproject/iotex-core/actpool"
    19  	"github.com/iotexproject/iotex-core/blockchain"
    20  	"github.com/iotexproject/iotex-core/blockchain/block"
    21  	"github.com/iotexproject/iotex-core/blockchain/blockdao"
    22  	"github.com/iotexproject/iotex-core/blockindex"
    23  	"github.com/iotexproject/iotex-core/blocksync"
    24  	"github.com/iotexproject/iotex-core/pkg/tracer"
    25  	"github.com/iotexproject/iotex-core/state/factory"
    26  )
    27  
    28  // ServerV2 provides api for user to interact with blockchain data
    29  type ServerV2 struct {
    30  	core         CoreService
    31  	grpcServer   *GRPCServer
    32  	httpSvr      *HTTPServer
    33  	websocketSvr *HTTPServer
    34  	tracer       *tracesdk.TracerProvider
    35  }
    36  
    37  // NewServerV2 creates a new server with coreService and GRPC Server
    38  func NewServerV2(
    39  	cfg Config,
    40  	chain blockchain.Blockchain,
    41  	bs blocksync.BlockSync,
    42  	sf factory.Factory,
    43  	dao blockdao.BlockDAO,
    44  	indexer blockindex.Indexer,
    45  	bfIndexer blockindex.BloomFilterIndexer,
    46  	actPool actpool.ActPool,
    47  	registry *protocol.Registry,
    48  	getBlockTime evm.GetBlockTime,
    49  	opts ...Option,
    50  ) (*ServerV2, error) {
    51  	coreAPI, err := newCoreService(cfg, chain, bs, sf, dao, indexer, bfIndexer, actPool, registry, getBlockTime, opts...)
    52  	if err != nil {
    53  		return nil, err
    54  	}
    55  	web3Handler := NewWeb3Handler(coreAPI, cfg.RedisCacheURL, cfg.BatchRequestLimit)
    56  
    57  	tp, err := tracer.NewProvider(
    58  		tracer.WithServiceName(cfg.Tracer.ServiceName),
    59  		tracer.WithEndpoint(cfg.Tracer.EndPoint),
    60  		tracer.WithInstanceID(cfg.Tracer.InstanceID),
    61  		tracer.WithSamplingRatio(cfg.Tracer.SamplingRatio),
    62  	)
    63  	if err != nil {
    64  		return nil, errors.Wrapf(err, "cannot config tracer provider")
    65  	}
    66  
    67  	wrappedWeb3Handler := otelhttp.NewHandler(newHTTPHandler(web3Handler), "web3.jsonrpc")
    68  
    69  	limiter := rate.NewLimiter(rate.Limit(cfg.WebsocketRateLimit), 1)
    70  	wrappedWebsocketHandler := otelhttp.NewHandler(NewWebsocketHandler(web3Handler, limiter), "web3.websocket")
    71  
    72  	return &ServerV2{
    73  		core:         coreAPI,
    74  		grpcServer:   NewGRPCServer(coreAPI, cfg.GRPCPort),
    75  		httpSvr:      NewHTTPServer("", cfg.HTTPPort, wrappedWeb3Handler),
    76  		websocketSvr: NewHTTPServer("", cfg.WebSocketPort, wrappedWebsocketHandler),
    77  		tracer:       tp,
    78  	}, nil
    79  }
    80  
    81  // Start starts the CoreService and the GRPC server
    82  func (svr *ServerV2) Start(ctx context.Context) error {
    83  	if err := svr.core.Start(ctx); err != nil {
    84  		return err
    85  	}
    86  	if svr.grpcServer != nil {
    87  		if err := svr.grpcServer.Start(ctx); err != nil {
    88  			return err
    89  		}
    90  	}
    91  	if svr.httpSvr != nil {
    92  		if err := svr.httpSvr.Start(ctx); err != nil {
    93  			return err
    94  		}
    95  	}
    96  	if svr.websocketSvr != nil {
    97  		if err := svr.websocketSvr.Start(ctx); err != nil {
    98  			return err
    99  		}
   100  	}
   101  	return nil
   102  }
   103  
   104  // Stop stops the GRPC server and the CoreService
   105  func (svr *ServerV2) Stop(ctx context.Context) error {
   106  	if svr.tracer != nil {
   107  		if err := svr.tracer.Shutdown(ctx); err != nil {
   108  			return errors.Wrap(err, "failed to shutdown api tracer")
   109  		}
   110  	}
   111  	if svr.websocketSvr != nil {
   112  		if err := svr.websocketSvr.Stop(ctx); err != nil {
   113  			return err
   114  		}
   115  	}
   116  	if svr.httpSvr != nil {
   117  		if err := svr.httpSvr.Stop(ctx); err != nil {
   118  			return err
   119  		}
   120  	}
   121  	if svr.grpcServer != nil {
   122  		if err := svr.grpcServer.Stop(ctx); err != nil {
   123  			return err
   124  		}
   125  	}
   126  	if err := svr.core.Stop(ctx); err != nil {
   127  		return err
   128  	}
   129  	return nil
   130  }
   131  
   132  // ReceiveBlock receives the new block
   133  func (svr *ServerV2) ReceiveBlock(blk *block.Block) error {
   134  	return svr.core.ReceiveBlock(blk)
   135  }
   136  
   137  // CoreService returns the coreservice of the api
   138  func (svr *ServerV2) CoreService() CoreService {
   139  	return svr.core
   140  }