github.com/neatio-net/neatio@v1.7.3-0.20231114194659-f4d7a2226baa/chain/consensus/neatcon/node.go (about) 1 package neatcon 2 3 import ( 4 "io/ioutil" 5 "os" 6 "strings" 7 8 cmn "github.com/neatio-net/common-go" 9 cfg "github.com/neatio-net/config-go" 10 dbm "github.com/neatio-net/db-go" 11 "github.com/neatio-net/neatio/chain/consensus/neatcon/consensus" 12 "github.com/neatio-net/neatio/chain/consensus/neatcon/epoch" 13 "github.com/neatio-net/neatio/chain/consensus/neatcon/types" 14 "github.com/neatio-net/neatio/chain/core" 15 "github.com/neatio-net/neatio/chain/log" 16 "github.com/neatio-net/neatio/params" 17 ) 18 19 type Node struct { 20 cmn.BaseService 21 22 privValidator *types.PrivValidator 23 24 epochDB dbm.DB 25 26 evsw types.EventSwitch 27 consensusState *consensus.ConsensusState 28 consensusReactor *consensus.ConsensusReactor 29 30 cch core.CrossChainHelper 31 logger log.Logger 32 } 33 34 func NewNodeNotStart(backend *backend, config cfg.Config, chainConfig *params.ChainConfig, cch core.CrossChainHelper, genDoc *types.GenesisDoc) *Node { 35 var privValidator *types.PrivValidator 36 privValidatorFile := config.GetString("priv_validator_file") 37 if _, err := os.Stat(privValidatorFile); err == nil { 38 privValidator = types.LoadPrivValidator(privValidatorFile) 39 } 40 41 epochDB := dbm.NewDB("epoch", "leveldb", config.GetString("db_dir")) 42 ep := epoch.InitEpoch(epochDB, genDoc, backend.logger) 43 44 if privValidator != nil && ep.Validators.HasAddress(privValidator.Address[:]) { 45 backend.shouldStart = true 46 } else { 47 backend.shouldStart = false 48 } 49 50 consensusState := consensus.NewConsensusState(backend, config, chainConfig, cch, ep) 51 if privValidator != nil { 52 consensusState.SetPrivValidator(privValidator) 53 } 54 consensusReactor := consensus.NewConsensusReactor(consensusState) 55 56 eventSwitch := types.NewEventSwitch() 57 SetEventSwitch(eventSwitch, consensusReactor) 58 59 node := &Node{ 60 privValidator: privValidator, 61 62 epochDB: epochDB, 63 64 evsw: eventSwitch, 65 66 cch: cch, 67 68 consensusState: consensusState, 69 consensusReactor: consensusReactor, 70 71 logger: backend.logger, 72 } 73 node.BaseService = *cmn.NewBaseService(backend.logger, "Node", node) 74 75 return node 76 } 77 78 func (n *Node) OnStart() error { 79 80 n.logger.Info("(n *Node) OnStart()") 81 82 if n.privValidator == nil { 83 return ErrNoPrivValidator 84 } 85 86 _, err := n.evsw.Start() 87 if err != nil { 88 n.logger.Errorf("Failed to start switch: %v", err) 89 return err 90 } 91 92 _, err = n.consensusReactor.Start() 93 if err != nil { 94 n.evsw.Stop() 95 n.logger.Errorf("Failed to start Consensus Reactor. Error: %v", err) 96 return err 97 } 98 99 return nil 100 } 101 102 func (n *Node) OnStop() { 103 n.logger.Info("(n *Node) OnStop() called") 104 n.BaseService.OnStop() 105 106 n.evsw.Stop() 107 n.consensusReactor.Stop() 108 } 109 110 func (n *Node) RunForever() { 111 cmn.TrapSignal(func() { 112 n.Stop() 113 }) 114 } 115 116 func SetEventSwitch(evsw types.EventSwitch, eventables ...types.Eventable) { 117 for _, e := range eventables { 118 e.SetEventSwitch(evsw) 119 } 120 } 121 122 func (n *Node) ConsensusState() *consensus.ConsensusState { 123 return n.consensusState 124 } 125 126 func (n *Node) ConsensusReactor() *consensus.ConsensusReactor { 127 return n.consensusReactor 128 } 129 130 func (n *Node) EventSwitch() types.EventSwitch { 131 return n.evsw 132 } 133 134 func (n *Node) PrivValidator() *types.PrivValidator { 135 return n.privValidator 136 } 137 138 func ProtocolAndAddress(listenAddr string) (string, string) { 139 protocol, address := "tcp", listenAddr 140 parts := strings.SplitN(address, "://", 2) 141 if len(parts) == 2 { 142 protocol, address = parts[0], parts[1] 143 } 144 return protocol, address 145 } 146 147 func MakeNeatConNode(backend *backend, config cfg.Config, chainConfig *params.ChainConfig, cch core.CrossChainHelper) *Node { 148 149 var genDoc *types.GenesisDoc 150 genDocFile := config.GetString("genesis_file") 151 152 if !cmn.FileExists(genDocFile) { 153 if chainConfig.NeatChainId == params.MainnetChainConfig.NeatChainId { 154 genDoc, _ = types.GenesisDocFromJSON([]byte(types.MainnetGenesisJSON)) 155 } else if chainConfig.NeatChainId == params.TestnetChainConfig.NeatChainId { 156 genDoc, _ = types.GenesisDocFromJSON([]byte(types.TestnetGenesisJSON)) 157 } else { 158 return nil 159 } 160 } else { 161 genDoc = readGenesisFromFile(genDocFile) 162 } 163 config.Set("chain_id", genDoc.ChainID) 164 165 return NewNodeNotStart(backend, config, chainConfig, cch, genDoc) 166 } 167 168 func readGenesisFromFile(genDocFile string) *types.GenesisDoc { 169 jsonBlob, err := ioutil.ReadFile(genDocFile) 170 if err != nil { 171 cmn.Exit(cmn.Fmt("Couldn't read GenesisDoc file: %v", err)) 172 } 173 genDoc, err := types.GenesisDocFromJSON(jsonBlob) 174 if err != nil { 175 cmn.PanicSanity(cmn.Fmt("Genesis doc parse json error: %v", err)) 176 } 177 if genDoc.ChainID == "" { 178 cmn.PanicSanity(cmn.Fmt("Genesis doc %v must include non-empty chain_id", genDocFile)) 179 } 180 return genDoc 181 }