github.com/iotexproject/iotex-core@v1.14.1-rc1/chainservice/chainservice.go (about) 1 // Copyright (c) 2019 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 chainservice 7 8 import ( 9 "context" 10 11 "github.com/libp2p/go-libp2p-core/peer" 12 "github.com/pkg/errors" 13 "github.com/prometheus/client_golang/prometheus" 14 "google.golang.org/protobuf/proto" 15 16 "github.com/iotexproject/iotex-election/committee" 17 "github.com/iotexproject/iotex-proto/golang/iotexrpc" 18 "github.com/iotexproject/iotex-proto/golang/iotextypes" 19 20 "github.com/iotexproject/iotex-core/action" 21 "github.com/iotexproject/iotex-core/action/protocol" 22 "github.com/iotexproject/iotex-core/action/protocol/poll" 23 "github.com/iotexproject/iotex-core/action/protocol/staking" 24 "github.com/iotexproject/iotex-core/actpool" 25 "github.com/iotexproject/iotex-core/api" 26 "github.com/iotexproject/iotex-core/blockchain" 27 "github.com/iotexproject/iotex-core/blockchain/block" 28 "github.com/iotexproject/iotex-core/blockchain/blockdao" 29 "github.com/iotexproject/iotex-core/blockindex" 30 "github.com/iotexproject/iotex-core/blockindex/contractstaking" 31 "github.com/iotexproject/iotex-core/blocksync" 32 "github.com/iotexproject/iotex-core/consensus" 33 "github.com/iotexproject/iotex-core/nodeinfo" 34 "github.com/iotexproject/iotex-core/p2p" 35 "github.com/iotexproject/iotex-core/pkg/lifecycle" 36 "github.com/iotexproject/iotex-core/pkg/log" 37 "github.com/iotexproject/iotex-core/pkg/util/blockutil" 38 "github.com/iotexproject/iotex-core/server/itx/nodestats" 39 "github.com/iotexproject/iotex-core/state/factory" 40 ) 41 42 var ( 43 _blockchainFullnessMtc = prometheus.NewGaugeVec( 44 prometheus.GaugeOpts{ 45 Name: "iotex_blockchain_fullness", 46 Help: "Blockchain fullness statistics", 47 }, 48 []string{"message_type"}, 49 ) 50 ) 51 52 func init() { 53 prometheus.MustRegister(_blockchainFullnessMtc) 54 } 55 56 // ChainService is a blockchain service with all blockchain components. 57 type ChainService struct { 58 lifecycle lifecycle.Lifecycle 59 actpool actpool.ActPool 60 blocksync blocksync.BlockSync 61 consensus consensus.Consensus 62 chain blockchain.Blockchain 63 factory factory.Factory 64 blockdao blockdao.BlockDAO 65 p2pAgent p2p.Agent 66 electionCommittee committee.Committee 67 // TODO: explorer dependency deleted at #1085, need to api related params 68 indexer blockindex.Indexer 69 bfIndexer blockindex.BloomFilterIndexer 70 candidateIndexer *poll.CandidateIndexer 71 candBucketsIndexer *staking.CandidatesBucketsIndexer 72 sgdIndexer blockindex.SGDRegistry 73 contractStakingIndexer *contractstaking.Indexer 74 registry *protocol.Registry 75 nodeInfoManager *nodeinfo.InfoManager 76 apiStats *nodestats.APILocalStats 77 blockTimeCalculator *blockutil.BlockTimeCalculator 78 } 79 80 // Start starts the server 81 func (cs *ChainService) Start(ctx context.Context) error { 82 return cs.lifecycle.OnStartSequentially(ctx) 83 } 84 85 // Stop stops the server 86 func (cs *ChainService) Stop(ctx context.Context) error { 87 return cs.lifecycle.OnStopSequentially(ctx) 88 } 89 90 // ReportFullness switch on or off block sync 91 func (cs *ChainService) ReportFullness(_ context.Context, messageType iotexrpc.MessageType, fullness float32) { 92 _blockchainFullnessMtc.WithLabelValues(iotexrpc.MessageType_name[int32(messageType)]).Set(float64(fullness)) 93 } 94 95 // HandleAction handles incoming action request. 96 func (cs *ChainService) HandleAction(ctx context.Context, actPb *iotextypes.Action) error { 97 act, err := (&action.Deserializer{}).SetEvmNetworkID(cs.chain.EvmNetworkID()).ActionToSealedEnvelope(actPb) 98 if err != nil { 99 return err 100 } 101 ctx = protocol.WithRegistry(ctx, cs.registry) 102 err = cs.actpool.Add(ctx, act) 103 if err != nil { 104 log.L().Debug(err.Error()) 105 } 106 return err 107 } 108 109 // HandleBlock handles incoming block request. 110 func (cs *ChainService) HandleBlock(ctx context.Context, peer string, pbBlock *iotextypes.Block) error { 111 blk, err := block.NewDeserializer(cs.chain.EvmNetworkID()).FromBlockProto(pbBlock) 112 if err != nil { 113 return err 114 } 115 ctx, err = cs.chain.Context(ctx) 116 if err != nil { 117 return err 118 } 119 return cs.blocksync.ProcessBlock(ctx, peer, blk) 120 } 121 122 // HandleSyncRequest handles incoming sync request. 123 func (cs *ChainService) HandleSyncRequest(ctx context.Context, peer peer.AddrInfo, sync *iotexrpc.BlockSync) error { 124 return cs.blocksync.ProcessSyncRequest(ctx, peer, sync.Start, sync.End) 125 } 126 127 // HandleConsensusMsg handles incoming consensus message. 128 func (cs *ChainService) HandleConsensusMsg(msg *iotextypes.ConsensusMessage) error { 129 return cs.consensus.HandleConsensusMsg(msg) 130 } 131 132 // HandleNodeInfo handles nodeinfo message. 133 func (cs *ChainService) HandleNodeInfo(ctx context.Context, peer string, msg *iotextypes.NodeInfo) error { 134 cs.nodeInfoManager.HandleNodeInfo(ctx, peer, msg) 135 return nil 136 } 137 138 // HandleNodeInfoRequest handles request node info message 139 func (cs *ChainService) HandleNodeInfoRequest(ctx context.Context, peer peer.AddrInfo, msg *iotextypes.NodeInfoRequest) error { 140 return cs.nodeInfoManager.HandleNodeInfoRequest(ctx, peer) 141 } 142 143 // ChainID returns ChainID. 144 func (cs *ChainService) ChainID() uint32 { return cs.chain.ChainID() } 145 146 // Blockchain returns the Blockchain 147 func (cs *ChainService) Blockchain() blockchain.Blockchain { 148 return cs.chain 149 } 150 151 // StateFactory returns the state factory 152 func (cs *ChainService) StateFactory() factory.Factory { 153 return cs.factory 154 } 155 156 // BlockDAO returns the blockdao 157 func (cs *ChainService) BlockDAO() blockdao.BlockDAO { 158 return cs.blockdao 159 } 160 161 // ActionPool returns the Action pool 162 func (cs *ChainService) ActionPool() actpool.ActPool { 163 return cs.actpool 164 } 165 166 // Consensus returns the consensus instance 167 func (cs *ChainService) Consensus() consensus.Consensus { 168 return cs.consensus 169 } 170 171 // BlockSync returns the block syncer 172 func (cs *ChainService) BlockSync() blocksync.BlockSync { 173 return cs.blocksync 174 } 175 176 // NodeInfoManager returns the delegate manager 177 func (cs *ChainService) NodeInfoManager() *nodeinfo.InfoManager { 178 return cs.nodeInfoManager 179 } 180 181 // Registry returns a pointer to the registry 182 func (cs *ChainService) Registry() *protocol.Registry { return cs.registry } 183 184 // NewAPIServer creates a new api server 185 func (cs *ChainService) NewAPIServer(cfg api.Config, plugins map[int]interface{}) (*api.ServerV2, error) { 186 if cfg.GRPCPort == 0 && cfg.HTTPPort == 0 { 187 return nil, nil 188 } 189 p2pAgent := cs.p2pAgent 190 apiServerOptions := []api.Option{ 191 api.WithBroadcastOutbound(func(ctx context.Context, chainID uint32, msg proto.Message) error { 192 return p2pAgent.BroadcastOutbound(ctx, msg) 193 }), 194 api.WithNativeElection(cs.electionCommittee), 195 api.WithAPIStats(cs.apiStats), 196 api.WithSGDIndexer(cs.sgdIndexer), 197 } 198 199 svr, err := api.NewServerV2( 200 cfg, 201 cs.chain, 202 cs.blocksync, 203 cs.factory, 204 cs.blockdao, 205 cs.indexer, 206 cs.bfIndexer, 207 cs.actpool, 208 cs.registry, 209 cs.blockTimeCalculator.CalculateBlockTime, 210 apiServerOptions..., 211 ) 212 if err != nil { 213 return nil, errors.Wrap(err, "failed to create API server") 214 } 215 216 return svr, nil 217 }