github.com/nnlgsakib/mind-dpos@v0.0.0-20230606105614-f3c8ca06f808/eth/backend.go (about) 1 // Copyright 2014 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 // Package eth implements the Ethereum protocol. 18 package eth 19 20 import ( 21 "errors" 22 "fmt" 23 "math/big" 24 "runtime" 25 "sync" 26 "sync/atomic" 27 28 "github.com/TTCECO/gttc/accounts" 29 "github.com/TTCECO/gttc/common" 30 "github.com/TTCECO/gttc/common/hexutil" 31 "github.com/TTCECO/gttc/consensus" 32 "github.com/TTCECO/gttc/consensus/alien" 33 "github.com/TTCECO/gttc/consensus/clique" 34 "github.com/TTCECO/gttc/consensus/ethash" 35 "github.com/TTCECO/gttc/core" 36 "github.com/TTCECO/gttc/core/bloombits" 37 "github.com/TTCECO/gttc/core/rawdb" 38 "github.com/TTCECO/gttc/core/types" 39 "github.com/TTCECO/gttc/core/vm" 40 "github.com/TTCECO/gttc/eth/downloader" 41 "github.com/TTCECO/gttc/eth/filters" 42 "github.com/TTCECO/gttc/eth/gasprice" 43 "github.com/TTCECO/gttc/ethdb" 44 "github.com/TTCECO/gttc/event" 45 "github.com/TTCECO/gttc/internal/ethapi" 46 "github.com/TTCECO/gttc/log" 47 "github.com/TTCECO/gttc/miner" 48 "github.com/TTCECO/gttc/node" 49 "github.com/TTCECO/gttc/p2p" 50 "github.com/TTCECO/gttc/params" 51 "github.com/TTCECO/gttc/rlp" 52 "github.com/TTCECO/gttc/rpc" 53 ) 54 55 type LesServer interface { 56 Start(srvr *p2p.Server) 57 Stop() 58 Protocols() []p2p.Protocol 59 SetBloomBitsIndexer(bbIndexer *core.ChainIndexer) 60 } 61 62 // Ethereum implements the Ethereum full node service. 63 type Ethereum struct { 64 config *Config 65 chainConfig *params.ChainConfig 66 67 // Channel for shutting down the service 68 shutdownChan chan bool // Channel for shutting down the Ethereum 69 70 // Handlers 71 txPool *core.TxPool 72 blockchain *core.BlockChain 73 protocolManager *ProtocolManager 74 lesServer LesServer 75 76 // DB interfaces 77 chainDb ethdb.Database // Block chain database 78 79 eventMux *event.TypeMux 80 engine consensus.Engine 81 accountManager *accounts.Manager 82 83 bloomRequests chan chan *bloombits.Retrieval // Channel receiving bloom data retrieval requests 84 bloomIndexer *core.ChainIndexer // Bloom indexer operating during block imports 85 86 APIBackend *EthAPIBackend 87 88 miner *miner.Miner 89 gasPrice *big.Int 90 etherbase common.Address 91 92 networkId uint64 93 netRPCService *ethapi.PublicNetAPI 94 95 lock sync.RWMutex // Protects the variadic fields (e.g. gas price and etherbase) 96 } 97 98 func (s *Ethereum) AddLesServer(ls LesServer) { 99 s.lesServer = ls 100 ls.SetBloomBitsIndexer(s.bloomIndexer) 101 } 102 103 // New creates a new Ethereum object (including the 104 // initialisation of the common Ethereum object) 105 func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { 106 if config.SyncMode == downloader.LightSync { 107 return nil, errors.New("can't run eth.Ethereum in light sync mode, use les.LightEthereum") 108 } 109 if !config.SyncMode.IsValid() { 110 return nil, fmt.Errorf("invalid sync mode %d", config.SyncMode) 111 } 112 chainDb, err := CreateDB(ctx, config, "chaindata") 113 if err != nil { 114 return nil, err 115 } 116 chainConfig, genesisHash, genesisErr := core.SetupGenesisBlock(chainDb, config.Genesis) 117 if _, ok := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !ok { 118 return nil, genesisErr 119 } 120 log.Info("Initialised chain configuration", "config", chainConfig) 121 if chainConfig.Alien != nil { 122 log.Info("Initialised alien configuration", "config", *chainConfig.Alien) 123 if config.NetworkId == 1 { //eth.DefaultConfig.NetworkId 124 // change default eth networkid to default ttc networkid 125 config.NetworkId = chainConfig.ChainId.Uint64() 126 } 127 } 128 eth := &Ethereum{ 129 config: config, 130 chainDb: chainDb, 131 chainConfig: chainConfig, 132 eventMux: ctx.EventMux, 133 accountManager: ctx.AccountManager, 134 engine: CreateConsensusEngine(ctx, &config.Ethash, chainConfig, chainDb), 135 shutdownChan: make(chan bool), 136 networkId: config.NetworkId, 137 gasPrice: config.GasPrice, 138 etherbase: config.Etherbase, 139 bloomRequests: make(chan chan *bloombits.Retrieval), 140 bloomIndexer: NewBloomIndexer(chainDb, params.BloomBitsBlocks), 141 } 142 143 log.Info("Initialising TTC protocol", "versions", ProtocolVersions, "network", config.NetworkId) 144 145 if !config.SkipBcVersionCheck { 146 bcVersion := rawdb.ReadDatabaseVersion(chainDb) 147 if bcVersion != core.BlockChainVersion && bcVersion != 0 { 148 return nil, fmt.Errorf("Blockchain DB version mismatch (%d / %d). Run geth upgradedb.\n", bcVersion, core.BlockChainVersion) 149 } 150 rawdb.WriteDatabaseVersion(chainDb, core.BlockChainVersion) 151 } 152 var ( 153 vmConfig = vm.Config{EnablePreimageRecording: config.EnablePreimageRecording} 154 cacheConfig = &core.CacheConfig{Disabled: config.NoPruning, TrieNodeLimit: config.TrieCache, TrieTimeLimit: config.TrieTimeout} 155 ) 156 eth.blockchain, err = core.NewBlockChain(chainDb, cacheConfig, eth.chainConfig, eth.engine, vmConfig) 157 if err != nil { 158 return nil, err 159 } 160 // Rewind the chain in case of an incompatible config upgrade. 161 if compat, ok := genesisErr.(*params.ConfigCompatError); ok { 162 log.Warn("Rewinding chain to upgrade configuration", "err", compat) 163 eth.blockchain.SetHead(compat.RewindTo) 164 rawdb.WriteChainConfig(chainDb, genesisHash, chainConfig) 165 } 166 eth.bloomIndexer.Start(eth.blockchain) 167 168 if config.TxPool.Journal != "" { 169 config.TxPool.Journal = ctx.ResolvePath(config.TxPool.Journal) 170 } 171 eth.txPool = core.NewTxPool(config.TxPool, eth.chainConfig, eth.blockchain) 172 173 if eth.protocolManager, err = NewProtocolManager(eth.chainConfig, config.SyncMode, config.NetworkId, eth.eventMux, eth.txPool, eth.engine, eth.blockchain, chainDb); err != nil { 174 return nil, err 175 } 176 eth.miner = miner.New(eth, eth.chainConfig, eth.EventMux(), eth.engine) 177 eth.miner.SetExtra(makeExtraData(config.ExtraData)) 178 179 eth.APIBackend = &EthAPIBackend{eth, nil} 180 gpoParams := config.GPO 181 if gpoParams.Default == nil { 182 gpoParams.Default = config.GasPrice 183 } 184 eth.APIBackend.gpo = gasprice.NewOracle(eth.APIBackend, gpoParams) 185 186 return eth, nil 187 } 188 189 func makeExtraData(extra []byte) []byte { 190 if len(extra) == 0 { 191 // create default extradata 192 extra, _ = rlp.EncodeToBytes([]interface{}{ 193 uint(params.VersionMajor<<16 | params.VersionMinor<<8 | params.VersionPatch), 194 "geth", 195 runtime.Version(), 196 runtime.GOOS, 197 }) 198 } 199 if uint64(len(extra)) > params.MaximumExtraDataSize { 200 log.Warn("Miner extra data exceed limit", "extra", hexutil.Bytes(extra), "limit", params.MaximumExtraDataSize) 201 extra = nil 202 } 203 return extra 204 } 205 206 // CreateDB creates the chain database. 207 func CreateDB(ctx *node.ServiceContext, config *Config, name string) (ethdb.Database, error) { 208 db, err := ctx.OpenDatabase(name, config.DatabaseCache, config.DatabaseHandles) 209 if err != nil { 210 return nil, err 211 } 212 if db, ok := db.(*ethdb.LDBDatabase); ok { 213 db.Meter("eth/db/chaindata/") 214 } 215 return db, nil 216 } 217 218 // CreateConsensusEngine creates the required type of consensus engine instance for an Ethereum service 219 func CreateConsensusEngine(ctx *node.ServiceContext, config *ethash.Config, chainConfig *params.ChainConfig, db ethdb.Database) consensus.Engine { 220 // If proof-of-authority is requested, set it up 221 if chainConfig.Clique != nil { 222 return clique.New(chainConfig.Clique, db) 223 } else if chainConfig.Alien != nil { 224 return alien.New(chainConfig.Alien, db) 225 } 226 // Otherwise assume proof-of-work 227 switch config.PowMode { 228 case ethash.ModeFake: 229 log.Warn("Ethash used in fake mode") 230 return ethash.NewFaker() 231 case ethash.ModeTest: 232 log.Warn("Ethash used in test mode") 233 return ethash.NewTester() 234 case ethash.ModeShared: 235 log.Warn("Ethash used in shared mode") 236 return ethash.NewShared() 237 default: 238 engine := ethash.New(ethash.Config{ 239 CacheDir: ctx.ResolvePath(config.CacheDir), 240 CachesInMem: config.CachesInMem, 241 CachesOnDisk: config.CachesOnDisk, 242 DatasetDir: config.DatasetDir, 243 DatasetsInMem: config.DatasetsInMem, 244 DatasetsOnDisk: config.DatasetsOnDisk, 245 }) 246 engine.SetThreads(-1) // Disable CPU mining 247 return engine 248 } 249 } 250 251 // APIs return the collection of RPC services the ethereum package offers. 252 // NOTE, some of these services probably need to be moved to somewhere else. 253 func (s *Ethereum) APIs() []rpc.API { 254 apis := ethapi.GetAPIs(s.APIBackend) 255 256 // Append any APIs exposed explicitly by the consensus engine 257 apis = append(apis, s.engine.APIs(s.BlockChain())...) 258 259 // Append all the local APIs and return 260 return append(apis, []rpc.API{ 261 { 262 Namespace: "eth", 263 Version: "1.0", 264 Service: NewPublicEthereumAPI(s), 265 Public: true, 266 }, { 267 Namespace: "eth", 268 Version: "1.0", 269 Service: NewPublicMinerAPI(s), 270 Public: true, 271 }, { 272 Namespace: "eth", 273 Version: "1.0", 274 Service: downloader.NewPublicDownloaderAPI(s.protocolManager.downloader, s.eventMux), 275 Public: true, 276 }, { 277 Namespace: "miner", 278 Version: "1.0", 279 Service: NewPrivateMinerAPI(s), 280 Public: false, 281 }, { 282 Namespace: "eth", 283 Version: "1.0", 284 Service: filters.NewPublicFilterAPI(s.APIBackend, false), 285 Public: true, 286 }, { 287 Namespace: "admin", 288 Version: "1.0", 289 Service: NewPrivateAdminAPI(s), 290 }, { 291 Namespace: "debug", 292 Version: "1.0", 293 Service: NewPublicDebugAPI(s), 294 Public: true, 295 }, { 296 Namespace: "debug", 297 Version: "1.0", 298 Service: NewPrivateDebugAPI(s.chainConfig, s), 299 }, { 300 Namespace: "net", 301 Version: "1.0", 302 Service: s.netRPCService, 303 Public: true, 304 }, 305 }...) 306 } 307 308 func (s *Ethereum) ResetWithGenesisBlock(gb *types.Block) { 309 s.blockchain.ResetWithGenesisBlock(gb) 310 } 311 312 func (s *Ethereum) Etherbase() (eb common.Address, err error) { 313 s.lock.RLock() 314 etherbase := s.etherbase 315 s.lock.RUnlock() 316 317 if etherbase != (common.Address{}) { 318 return etherbase, nil 319 } 320 if wallets := s.AccountManager().Wallets(); len(wallets) > 0 { 321 if accounts := wallets[0].Accounts(); len(accounts) > 0 { 322 etherbase := accounts[0].Address 323 324 s.lock.Lock() 325 s.etherbase = etherbase 326 s.lock.Unlock() 327 328 log.Info("Etherbase automatically configured", "address", etherbase) 329 return etherbase, nil 330 } 331 } 332 return common.Address{}, fmt.Errorf("etherbase must be explicitly specified") 333 } 334 335 // SetEtherbase sets the mining reward address. 336 func (s *Ethereum) SetEtherbase(etherbase common.Address) { 337 s.lock.Lock() 338 s.etherbase = etherbase 339 s.lock.Unlock() 340 341 s.miner.SetEtherbase(etherbase) 342 } 343 344 func (s *Ethereum) StartMining(local bool) error { 345 eb, err := s.Etherbase() 346 if err != nil { 347 log.Error("Cannot start mining without etherbase", "err", err) 348 return fmt.Errorf("etherbase missing: %v", err) 349 } 350 if clique, ok := s.engine.(*clique.Clique); ok { 351 wallet, err := s.accountManager.Find(accounts.Account{Address: eb}) 352 if wallet == nil || err != nil { 353 log.Error("Etherbase account unavailable locally", "err", err) 354 return fmt.Errorf("signer missing: %v", err) 355 } 356 clique.Authorize(eb, wallet.SignHash) 357 } 358 if alien, ok := s.engine.(*alien.Alien); ok { 359 wallet, err := s.accountManager.Find(accounts.Account{Address: eb}) 360 if wallet == nil || err != nil { 361 log.Error("Etherbase account unavailable locally", "err", err) 362 return fmt.Errorf("signer missing: %v", err) 363 } 364 alien.Authorize(eb, wallet.SignHash, wallet.SignTx) 365 } 366 if local { 367 // If local (CPU) mining is started, we can disable the transaction rejection 368 // mechanism introduced to speed sync times. CPU mining on mainnet is ludicrous 369 // so none will ever hit this path, whereas marking sync done on CPU mining 370 // will ensure that private networks work in single miner mode too. 371 atomic.StoreUint32(&s.protocolManager.acceptTxs, 1) 372 } 373 go s.miner.Start(eb) 374 return nil 375 } 376 377 func (s *Ethereum) StopMining() { s.miner.Stop() } 378 func (s *Ethereum) IsMining() bool { return s.miner.Mining() } 379 func (s *Ethereum) Miner() *miner.Miner { return s.miner } 380 381 func (s *Ethereum) AccountManager() *accounts.Manager { return s.accountManager } 382 func (s *Ethereum) BlockChain() *core.BlockChain { return s.blockchain } 383 func (s *Ethereum) TxPool() *core.TxPool { return s.txPool } 384 func (s *Ethereum) EventMux() *event.TypeMux { return s.eventMux } 385 func (s *Ethereum) Engine() consensus.Engine { return s.engine } 386 func (s *Ethereum) ChainDb() ethdb.Database { return s.chainDb } 387 func (s *Ethereum) IsListening() bool { return true } // Always listening 388 func (s *Ethereum) EthVersion() int { return int(s.protocolManager.SubProtocols[0].Version) } 389 func (s *Ethereum) NetVersion() uint64 { return s.networkId } 390 func (s *Ethereum) Downloader() *downloader.Downloader { return s.protocolManager.downloader } 391 392 // Protocols implements node.Service, returning all the currently configured 393 // network protocols to start. 394 func (s *Ethereum) Protocols() []p2p.Protocol { 395 if s.lesServer == nil { 396 return s.protocolManager.SubProtocols 397 } 398 return append(s.protocolManager.SubProtocols, s.lesServer.Protocols()...) 399 } 400 401 // Start implements node.Service, starting all internal goroutines needed by the 402 // Ethereum protocol implementation. 403 func (s *Ethereum) Start(srvr *p2p.Server) error { 404 // Start the bloom bits servicing goroutines 405 s.startBloomHandlers() 406 407 // Start the RPC service 408 s.netRPCService = ethapi.NewPublicNetAPI(srvr, s.NetVersion()) 409 410 // Figure out a max peers count based on the server limits 411 maxPeers := srvr.MaxPeers 412 if s.config.LightServ > 0 { 413 if s.config.LightPeers >= srvr.MaxPeers { 414 return fmt.Errorf("invalid peer config: light peer count (%d) >= total peer count (%d)", s.config.LightPeers, srvr.MaxPeers) 415 } 416 maxPeers -= s.config.LightPeers 417 } 418 // Start the networking layer and the light server if requested 419 s.protocolManager.Start(maxPeers) 420 if s.lesServer != nil { 421 s.lesServer.Start(srvr) 422 } 423 return nil 424 } 425 426 // Stop implements node.Service, terminating all internal goroutines used by the 427 // Ethereum protocol. 428 func (s *Ethereum) Stop() error { 429 s.bloomIndexer.Close() 430 s.blockchain.Stop() 431 s.protocolManager.Stop() 432 if s.lesServer != nil { 433 s.lesServer.Stop() 434 } 435 s.txPool.Stop() 436 s.miner.Stop() 437 s.eventMux.Stop() 438 439 s.chainDb.Close() 440 close(s.shutdownChan) 441 442 return nil 443 }