backend.go 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889
  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. // Package eth implements the Ethereum protocol.
  17. package eth
  18. import (
  19. "errors"
  20. "fmt"
  21. "math/big"
  22. "net/http"
  23. "os"
  24. "runtime"
  25. "sync"
  26. "sync/atomic"
  27. "time"
  28. "github.com/ethereum/go-ethereum/accounts"
  29. "github.com/ethereum/go-ethereum/common"
  30. "github.com/ethereum/go-ethereum/common/hexutil"
  31. "github.com/ethereum/go-ethereum/consensus"
  32. "github.com/ethereum/go-ethereum/consensus/clique"
  33. "github.com/ethereum/go-ethereum/core"
  34. "github.com/ethereum/go-ethereum/core/bloombits"
  35. "github.com/ethereum/go-ethereum/core/rawdb"
  36. "github.com/ethereum/go-ethereum/core/state/pruner"
  37. "github.com/ethereum/go-ethereum/core/types"
  38. "github.com/ethereum/go-ethereum/core/vm"
  39. "github.com/ethereum/go-ethereum/crypto"
  40. "github.com/ethereum/go-ethereum/eth/downloader"
  41. "github.com/ethereum/go-ethereum/eth/ethconfig"
  42. "github.com/ethereum/go-ethereum/eth/filters"
  43. "github.com/ethereum/go-ethereum/eth/gasprice"
  44. "github.com/ethereum/go-ethereum/eth/protocols/eth"
  45. qlightproto "github.com/ethereum/go-ethereum/eth/protocols/qlight"
  46. "github.com/ethereum/go-ethereum/eth/protocols/snap"
  47. "github.com/ethereum/go-ethereum/ethdb"
  48. "github.com/ethereum/go-ethereum/event"
  49. "github.com/ethereum/go-ethereum/internal/ethapi"
  50. "github.com/ethereum/go-ethereum/log"
  51. "github.com/ethereum/go-ethereum/miner"
  52. "github.com/ethereum/go-ethereum/node"
  53. "github.com/ethereum/go-ethereum/p2p"
  54. "github.com/ethereum/go-ethereum/p2p/dnsdisc"
  55. "github.com/ethereum/go-ethereum/p2p/enode"
  56. "github.com/ethereum/go-ethereum/params"
  57. "github.com/ethereum/go-ethereum/plugin"
  58. "github.com/ethereum/go-ethereum/plugin/security"
  59. "github.com/ethereum/go-ethereum/private"
  60. "github.com/ethereum/go-ethereum/qlight"
  61. "github.com/ethereum/go-ethereum/rlp"
  62. "github.com/ethereum/go-ethereum/rpc"
  63. )
  64. // Config contains the configuration options of the ETH protocol.
  65. // Deprecated: use ethconfig.Config instead.
  66. type Config = ethconfig.Config
  67. // Ethereum implements the Ethereum full node service.
  68. type Ethereum struct {
  69. config *ethconfig.Config
  70. // Handlers
  71. txPool *core.TxPool
  72. blockchain *core.BlockChain
  73. handler *handler
  74. ethDialCandidates enode.Iterator
  75. snapDialCandidates enode.Iterator
  76. // DB interfaces
  77. chainDb ethdb.Database // Block chain database
  78. eventMux *event.TypeMux
  79. engine consensus.Engine
  80. accountManager *accounts.Manager
  81. bloomRequests chan chan *bloombits.Retrieval // Channel receiving bloom data retrieval requests
  82. bloomIndexer *core.ChainIndexer // Bloom indexer operating during block imports
  83. closeBloomHandler chan struct{}
  84. APIBackend *EthAPIBackend
  85. miner *miner.Miner
  86. gasPrice *big.Int
  87. etherbase common.Address
  88. networkID uint64
  89. netRPCService *ethapi.PublicNetAPI
  90. p2pServer *p2p.Server
  91. lock sync.RWMutex // Protects the variadic fields (e.g. gas price and etherbase)
  92. // Quorum - consensus as eth-service (e.g. raft)
  93. consensusServicePendingLogsFeed *event.Feed
  94. qlightServerHandler *handler
  95. qlightP2pServer *p2p.Server
  96. qlightTokenHolder *qlight.TokenHolder
  97. }
  98. // New creates a new Ethereum object (including the
  99. // initialisation of the common Ethereum object)
  100. func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
  101. // Ensure configuration values are compatible and sane
  102. if config.SyncMode == downloader.LightSync {
  103. return nil, errors.New("can't run eth.Ethereum in light sync mode, use les.LightEthereum")
  104. }
  105. if !config.SyncMode.IsValid() {
  106. return nil, fmt.Errorf("invalid sync mode %d", config.SyncMode)
  107. }
  108. if config.Miner.GasPrice == nil || config.Miner.GasPrice.Cmp(common.Big0) <= 0 {
  109. log.Warn("Sanitizing invalid miner gas price", "provided", config.Miner.GasPrice, "updated", ethconfig.Defaults.Miner.GasPrice)
  110. config.Miner.GasPrice = new(big.Int).Set(ethconfig.Defaults.Miner.GasPrice)
  111. }
  112. if config.NoPruning && config.TrieDirtyCache > 0 {
  113. if config.SnapshotCache > 0 {
  114. config.TrieCleanCache += config.TrieDirtyCache * 3 / 5
  115. config.SnapshotCache += config.TrieDirtyCache * 2 / 5
  116. } else {
  117. config.TrieCleanCache += config.TrieDirtyCache
  118. }
  119. config.TrieDirtyCache = 0
  120. }
  121. log.Info("Allocated trie memory caches", "clean", common.StorageSize(config.TrieCleanCache)*1024*1024, "dirty", common.StorageSize(config.TrieDirtyCache)*1024*1024)
  122. // Transfer mining-related config to the ethash config.
  123. ethashConfig := config.Ethash
  124. ethashConfig.NotifyFull = config.Miner.NotifyFull
  125. // Assemble the Ethereum object
  126. chainDb, err := stack.OpenDatabaseWithFreezer("chaindata", config.DatabaseCache, config.DatabaseHandles, config.DatabaseFreezer, "eth/db/chaindata/", false)
  127. if err != nil {
  128. return nil, err
  129. }
  130. chainConfig, genesisHash, genesisErr := core.SetupGenesisBlockWithOverride(chainDb, config.Genesis, config.OverrideBerlin)
  131. if _, ok := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !ok {
  132. return nil, genesisErr
  133. }
  134. log.Info("Initialised chain configuration", "config", chainConfig)
  135. if err := pruner.RecoverPruning(stack.ResolvePath(""), chainDb, stack.ResolvePath(config.TrieCleanCacheJournal)); err != nil {
  136. log.Error("Failed to recover state", "error", err)
  137. }
  138. if chainConfig.IsQuorum {
  139. // changes to manipulate the chain id for migration from 2.0.2 and below version to 2.0.3
  140. // version of Quorum - this is applicable for v2.0.3 onwards
  141. if (chainConfig.ChainID != nil && chainConfig.ChainID.Int64() == 1) || config.NetworkId == 1 {
  142. return nil, errors.New("Cannot have chain id or network id as 1.")
  143. }
  144. if config.QuorumChainConfig.PrivacyMarkerEnabled() && chainConfig.PrivacyPrecompileBlock == nil {
  145. return nil, errors.New("Privacy marker transactions require privacyPrecompileBlock to be set in genesis.json")
  146. }
  147. if chainConfig.Istanbul != nil && (chainConfig.IBFT != nil || chainConfig.QBFT != nil) {
  148. return nil, errors.New("the attributes config.Istanbul and config.[IBFT|QBFT] are mutually exclusive on the genesis file")
  149. }
  150. if chainConfig.IBFT != nil && chainConfig.QBFT != nil {
  151. return nil, errors.New("the attributes config.IBFT and config.QBFT are mutually exclusive on the genesis file")
  152. }
  153. }
  154. if !rawdb.GetIsQuorumEIP155Activated(chainDb) && chainConfig.ChainID != nil {
  155. //Upon starting the node, write the flag to disallow changing ChainID/EIP155 block after HF
  156. rawdb.WriteQuorumEIP155Activation(chainDb)
  157. }
  158. eth := &Ethereum{
  159. config: config,
  160. chainDb: chainDb,
  161. eventMux: stack.EventMux(),
  162. accountManager: stack.AccountManager(),
  163. engine: ethconfig.CreateConsensusEngine(stack, chainConfig, config, config.Miner.Notify, config.Miner.Noverify, chainDb),
  164. closeBloomHandler: make(chan struct{}),
  165. networkID: config.NetworkId,
  166. gasPrice: config.Miner.GasPrice,
  167. etherbase: config.Miner.Etherbase,
  168. bloomRequests: make(chan chan *bloombits.Retrieval),
  169. bloomIndexer: core.NewBloomIndexer(chainDb, params.BloomBitsBlocks, params.BloomConfirms),
  170. p2pServer: stack.Server(),
  171. // Quorum
  172. qlightP2pServer: stack.QServer(),
  173. consensusServicePendingLogsFeed: new(event.Feed),
  174. }
  175. // Quorum: Set protocol Name/Version
  176. // keep `var protocolName = "eth"` as is, and only update the quorum consensus specific protocol
  177. // This is used to enable the eth service to return multiple devp2p subprotocols.
  178. // Previously, for istanbul/64 istnbul/99 and clique (v2.6) `protocolName` would be overridden and
  179. // set to the consensus subprotocol name instead of "eth", meaning the node would no longer
  180. // communicate over the "eth" subprotocol, e.g. "eth" or "istanbul/99" but not eth" and "istanbul/99".
  181. // With this change, support is added so that the "eth" subprotocol remains and optionally a consensus subprotocol
  182. // can be added allowing the node to communicate over "eth" and an optional consensus subprotocol, e.g. "eth" and "istanbul/100"
  183. if chainConfig.IsQuorum {
  184. quorumProtocol := eth.engine.Protocol()
  185. // set the quorum specific consensus devp2p subprotocol, eth subprotocol remains set to protocolName as in upstream geth.
  186. quorumConsensusProtocolName = quorumProtocol.Name
  187. quorumConsensusProtocolVersions = quorumProtocol.Versions
  188. quorumConsensusProtocolLengths = quorumProtocol.Lengths
  189. }
  190. // force to set the istanbul etherbase to node key address
  191. if chainConfig.Istanbul != nil || chainConfig.IBFT != nil || chainConfig.QBFT != nil {
  192. eth.etherbase = crypto.PubkeyToAddress(stack.GetNodeKey().PublicKey)
  193. }
  194. bcVersion := rawdb.ReadDatabaseVersion(chainDb)
  195. var dbVer = "<nil>"
  196. if bcVersion != nil {
  197. dbVer = fmt.Sprintf("%d", *bcVersion)
  198. }
  199. log.Info("Initialising Ethereum protocol", "network", config.NetworkId, "dbversion", dbVer)
  200. if chainConfig.IsQuorum {
  201. log.Info("Initialising Quorum consensus protocol", "name", quorumConsensusProtocolName, "versions", quorumConsensusProtocolVersions, "network", config.NetworkId, "dbversion", dbVer)
  202. }
  203. if !config.SkipBcVersionCheck {
  204. if bcVersion != nil && *bcVersion > core.BlockChainVersion {
  205. return nil, fmt.Errorf("database version is v%d, Geth %s only supports v%d", *bcVersion, params.VersionWithMeta, core.BlockChainVersion)
  206. } else if bcVersion == nil || *bcVersion < core.BlockChainVersion {
  207. if bcVersion != nil { // only print warning on upgrade, not on init
  208. log.Warn("Upgrade blockchain database version", "from", dbVer, "to", core.BlockChainVersion)
  209. }
  210. rawdb.WriteDatabaseVersion(chainDb, core.BlockChainVersion)
  211. }
  212. }
  213. var (
  214. vmConfig = vm.Config{
  215. EnablePreimageRecording: config.EnablePreimageRecording,
  216. EWASMInterpreter: config.EWASMInterpreter,
  217. EVMInterpreter: config.EVMInterpreter,
  218. }
  219. cacheConfig = &core.CacheConfig{
  220. TrieCleanLimit: config.TrieCleanCache,
  221. TrieCleanJournal: stack.ResolvePath(config.TrieCleanCacheJournal),
  222. TrieCleanRejournal: config.TrieCleanCacheRejournal,
  223. TrieCleanNoPrefetch: config.NoPrefetch,
  224. TrieDirtyLimit: config.TrieDirtyCache,
  225. TrieDirtyDisabled: config.NoPruning,
  226. TrieTimeLimit: config.TrieTimeout,
  227. SnapshotLimit: config.SnapshotCache,
  228. Preimages: config.Preimages,
  229. }
  230. )
  231. newBlockChainFunc := core.NewBlockChain
  232. if config.QuorumChainConfig.MultiTenantEnabled() {
  233. newBlockChainFunc = core.NewMultitenantBlockChain
  234. }
  235. eth.blockchain, err = newBlockChainFunc(chainDb, cacheConfig, chainConfig, eth.engine, vmConfig, eth.shouldPreserve, &config.TxLookupLimit, &config.QuorumChainConfig)
  236. if err != nil {
  237. return nil, err
  238. }
  239. defer func() {
  240. if p := recover(); p != nil {
  241. log.Error("panic occurred", "err", p)
  242. err := eth.Stop()
  243. if err != nil {
  244. log.Error("error while closing", "err", err)
  245. }
  246. os.Exit(1)
  247. }
  248. }()
  249. // Rewind the chain in case of an incompatible config upgrade.
  250. if compat, ok := genesisErr.(*params.ConfigCompatError); ok {
  251. log.Warn("Rewinding chain to upgrade configuration", "err", compat)
  252. eth.blockchain.SetHead(compat.RewindTo)
  253. rawdb.WriteChainConfig(chainDb, genesisHash, chainConfig)
  254. }
  255. eth.bloomIndexer.Start(eth.blockchain)
  256. if config.TxPool.Journal != "" {
  257. config.TxPool.Journal = stack.ResolvePath(config.TxPool.Journal)
  258. }
  259. eth.txPool = core.NewTxPool(config.TxPool, chainConfig, eth.blockchain)
  260. // Permit the downloader to use the trie cache allowance during fast sync
  261. cacheLimit := cacheConfig.TrieCleanLimit + cacheConfig.TrieDirtyLimit + cacheConfig.SnapshotLimit
  262. checkpoint := config.Checkpoint
  263. if checkpoint == nil {
  264. checkpoint = params.TrustedCheckpoints[genesisHash]
  265. }
  266. if eth.config.QuorumLightClient.Enabled() {
  267. clientCache, err := qlight.NewClientCache(chainDb)
  268. if eth.config.QuorumLightClient.TokenEnabled {
  269. switch eth.config.QuorumLightClient.TokenManagement {
  270. case "client-security-plugin":
  271. log.Info("Starting qlight client with auth token enabled without external API and token from argument, plugin has to be provided")
  272. eth.qlightTokenHolder, err = qlight.NewTokenHolder(config.QuorumLightClient.PSI, stack.PluginManager())
  273. if err != nil {
  274. return nil, fmt.Errorf("new token holder: %w", err)
  275. }
  276. eth.qlightTokenHolder.SetCurrentToken(eth.config.QuorumLightClient.TokenValue)
  277. case "none":
  278. log.Warn("Starting qlight client with auth token enabled but without a token management strategy. This is for development purposes only.")
  279. eth.qlightTokenHolder, err = qlight.NewTokenHolder(config.QuorumLightClient.PSI, nil)
  280. if err != nil {
  281. return nil, fmt.Errorf("new token holder: %w", err)
  282. }
  283. eth.qlightTokenHolder.SetCurrentToken(eth.config.QuorumLightClient.TokenValue)
  284. case "external":
  285. log.Info("Starting qlight client with auth token enabled and `external` token management strategy.")
  286. eth.qlightTokenHolder, err = qlight.NewTokenHolder(config.QuorumLightClient.PSI, nil)
  287. if err != nil {
  288. return nil, fmt.Errorf("new token holder: %w", err)
  289. }
  290. default:
  291. return nil, fmt.Errorf("Invalid value %s for `qlight.client.token.management`", eth.config.QuorumLightClient.TokenManagement)
  292. }
  293. }
  294. if err != nil {
  295. return nil, err
  296. }
  297. if eth.handler, err = newQLightClientHandler(&handlerConfig{
  298. Database: chainDb,
  299. Chain: eth.blockchain,
  300. TxPool: eth.txPool,
  301. Network: config.NetworkId,
  302. Sync: config.SyncMode,
  303. BloomCache: uint64(cacheLimit),
  304. EventMux: eth.eventMux,
  305. Checkpoint: checkpoint,
  306. AuthorizationList: config.AuthorizationList,
  307. RaftMode: config.RaftMode,
  308. Engine: eth.engine,
  309. psi: config.QuorumLightClient.PSI,
  310. privateClientCache: clientCache,
  311. tokenHolder: eth.qlightTokenHolder,
  312. }); err != nil {
  313. return nil, err
  314. }
  315. if eth.qlightTokenHolder != nil {
  316. eth.qlightTokenHolder.SetPeerUpdater(eth.handler.peers)
  317. }
  318. eth.blockchain.SetPrivateStateRootHashValidator(clientCache)
  319. } else {
  320. if eth.handler, err = newHandler(&handlerConfig{
  321. Database: chainDb,
  322. Chain: eth.blockchain,
  323. TxPool: eth.txPool,
  324. Network: config.NetworkId,
  325. Sync: config.SyncMode,
  326. BloomCache: uint64(cacheLimit),
  327. EventMux: eth.eventMux,
  328. Checkpoint: checkpoint,
  329. AuthorizationList: config.AuthorizationList,
  330. RaftMode: config.RaftMode,
  331. Engine: eth.engine,
  332. tokenHolder: eth.qlightTokenHolder,
  333. }); err != nil {
  334. return nil, err
  335. }
  336. if eth.config.QuorumLightServer {
  337. authManProvider := func() security.AuthenticationManager {
  338. _, authManager, _ := stack.GetSecuritySupports()
  339. return authManager
  340. }
  341. if eth.qlightServerHandler, err = newQLightServerHandler(&handlerConfig{
  342. Database: chainDb,
  343. Chain: eth.blockchain,
  344. TxPool: eth.txPool,
  345. Network: config.NetworkId,
  346. Sync: config.SyncMode,
  347. BloomCache: uint64(cacheLimit),
  348. EventMux: eth.eventMux,
  349. Checkpoint: checkpoint,
  350. AuthorizationList: config.AuthorizationList,
  351. RaftMode: config.RaftMode,
  352. Engine: eth.engine,
  353. authProvider: qlight.NewAuthProvider(eth.blockchain.PrivateStateManager(), authManProvider),
  354. privateBlockDataResolver: qlight.NewPrivateBlockDataResolver(eth.blockchain.PrivateStateManager(), private.P),
  355. }); err != nil {
  356. return nil, err
  357. }
  358. }
  359. }
  360. eth.miner = miner.New(eth, &config.Miner, chainConfig, eth.EventMux(), eth.engine, eth.isLocalBlock)
  361. eth.miner.SetExtra(makeExtraData(config.Miner.ExtraData, eth.blockchain.Config().IsQuorum))
  362. // Quorum
  363. hexNodeId := fmt.Sprintf("%x", crypto.FromECDSAPub(&stack.GetNodeKey().PublicKey)[1:])
  364. node, err := enode.ParseV4(hexNodeId)
  365. if err != nil {
  366. return nil, err
  367. }
  368. // End Quorum
  369. if eth.config.QuorumLightClient.Enabled() {
  370. var (
  371. proxyClient *rpc.Client
  372. err error
  373. )
  374. // setup rpc client TLS context
  375. if eth.config.QuorumLightClient.RPCTLS {
  376. tlsConfig, err := qlight.NewTLSConfig(&qlight.TLSConfig{
  377. InsecureSkipVerify: eth.config.QuorumLightClient.RPCTLSInsecureSkipVerify,
  378. CACertFileName: eth.config.QuorumLightClient.RPCTLSCACert,
  379. CertFileName: eth.config.QuorumLightClient.RPCTLSCert,
  380. KeyFileName: eth.config.QuorumLightClient.RPCTLSKey,
  381. })
  382. if err != nil {
  383. return nil, err
  384. }
  385. customHttpClient := &http.Client{
  386. Transport: http.DefaultTransport,
  387. }
  388. customHttpClient.Transport.(*http.Transport).TLSClientConfig = tlsConfig
  389. proxyClient, err = rpc.DialHTTPWithClient(eth.config.QuorumLightClient.ServerNodeRPC, customHttpClient)
  390. if err != nil {
  391. return nil, err
  392. }
  393. } else {
  394. proxyClient, err = rpc.Dial(eth.config.QuorumLightClient.ServerNodeRPC)
  395. if err != nil {
  396. return nil, err
  397. }
  398. }
  399. if eth.config.QuorumLightClient.TokenEnabled {
  400. proxyClient = proxyClient.WithHTTPCredentials(eth.qlightTokenHolder.HttpCredentialsProvider)
  401. }
  402. if len(eth.config.QuorumLightClient.PSI) > 0 {
  403. proxyClient = proxyClient.WithPSI(types.PrivateStateIdentifier(eth.config.QuorumLightClient.PSI))
  404. }
  405. // TODO qlight - need to find a better way to inject the rpc client into the tx manager
  406. rpcClientSetter, ok := private.P.(private.HasRPCClient)
  407. if ok {
  408. rpcClientSetter.SetRPCClient(proxyClient)
  409. }
  410. eth.APIBackend = &EthAPIBackend{stack.Config().ExtRPCEnabled(), stack.Config().AllowUnprotectedTxs, eth, nil, node.ID(), config.EVMCallTimeOut, proxyClient}
  411. } else {
  412. eth.APIBackend = &EthAPIBackend{stack.Config().ExtRPCEnabled(), stack.Config().AllowUnprotectedTxs, eth, nil, node.ID(), config.EVMCallTimeOut, nil}
  413. }
  414. if eth.APIBackend.allowUnprotectedTxs {
  415. log.Info("Unprotected transactions allowed")
  416. }
  417. gpoParams := config.GPO
  418. if gpoParams.Default == nil {
  419. gpoParams.Default = config.Miner.GasPrice
  420. }
  421. eth.APIBackend.gpo = gasprice.NewOracle(eth.APIBackend, gpoParams)
  422. // Setup DNS discovery iterators.
  423. dnsclient := dnsdisc.NewClient(dnsdisc.Config{})
  424. eth.ethDialCandidates, err = dnsclient.NewIterator(eth.config.EthDiscoveryURLs...)
  425. if err != nil {
  426. return nil, err
  427. }
  428. eth.snapDialCandidates, err = dnsclient.NewIterator(eth.config.SnapDiscoveryURLs...)
  429. if err != nil {
  430. return nil, err
  431. }
  432. // Start the RPC service
  433. eth.netRPCService = ethapi.NewPublicNetAPI(eth.p2pServer, config.NetworkId)
  434. // Register the backend on the node
  435. stack.RegisterAPIs(eth.APIs())
  436. if eth.config.QuorumLightClient.Enabled() && eth.config.QuorumLightClient.TokenEnabled &&
  437. eth.config.QuorumLightClient.TokenManagement == "external" {
  438. stack.RegisterAPIs(eth.QLightClientAPIs())
  439. }
  440. stack.RegisterProtocols(eth.Protocols())
  441. if eth.config.QuorumLightServer {
  442. stack.RegisterQProtocols(eth.QProtocols())
  443. }
  444. stack.RegisterLifecycle(eth)
  445. // Check for unclean shutdown
  446. if uncleanShutdowns, discards, err := rawdb.PushUncleanShutdownMarker(chainDb); err != nil {
  447. log.Error("Could not update unclean-shutdown-marker list", "error", err)
  448. } else {
  449. if discards > 0 {
  450. log.Warn("Old unclean shutdowns found", "count", discards)
  451. }
  452. for _, tstamp := range uncleanShutdowns {
  453. t := time.Unix(int64(tstamp), 0)
  454. log.Warn("Unclean shutdown detected", "booted", t,
  455. "age", common.PrettyAge(t))
  456. }
  457. }
  458. return eth, nil
  459. }
  460. func makeExtraData(extra []byte, isQuorum bool) []byte {
  461. if len(extra) == 0 {
  462. // create default extradata
  463. extra, _ = rlp.EncodeToBytes([]interface{}{
  464. uint(params.VersionMajor<<16 | params.VersionMinor<<8 | params.VersionPatch),
  465. "geth",
  466. runtime.Version(),
  467. runtime.GOOS,
  468. })
  469. }
  470. if uint64(len(extra)) > params.GetMaximumExtraDataSize(isQuorum) {
  471. log.Warn("Miner extra data exceed limit", "extra", hexutil.Bytes(extra), "limit", params.GetMaximumExtraDataSize(isQuorum))
  472. extra = nil
  473. }
  474. return extra
  475. }
  476. func (s *Ethereum) QLightClientAPIs() []rpc.API {
  477. return []rpc.API{
  478. {
  479. Namespace: "qlight",
  480. Version: "1.0",
  481. Service: qlight.NewPrivateQLightAPI(s.handler.peers, s.APIBackend.proxyClient),
  482. Public: false,
  483. },
  484. }
  485. }
  486. // APIs return the collection of RPC services the ethereum package offers.
  487. // NOTE, some of these services probably need to be moved to somewhere else.
  488. func (s *Ethereum) APIs() []rpc.API {
  489. apis := ethapi.GetAPIs(s.APIBackend)
  490. // Append any APIs exposed explicitly by the consensus engine
  491. apis = append(apis, s.engine.APIs(s.BlockChain())...)
  492. // Append all the local APIs and return
  493. apis = append(apis, []rpc.API{
  494. {
  495. Namespace: "eth",
  496. Version: "1.0",
  497. Service: NewPublicEthereumAPI(s),
  498. Public: true,
  499. }, {
  500. Namespace: "eth",
  501. Version: "1.0",
  502. Service: NewPublicMinerAPI(s),
  503. Public: true,
  504. }, {
  505. Namespace: "eth",
  506. Version: "1.0",
  507. Service: downloader.NewPublicDownloaderAPI(s.handler.downloader, s.eventMux),
  508. Public: true,
  509. }, {
  510. Namespace: "miner",
  511. Version: "1.0",
  512. Service: NewPrivateMinerAPI(s),
  513. Public: false,
  514. }, {
  515. Namespace: "eth",
  516. Version: "1.0",
  517. Service: filters.NewPublicFilterAPI(s.APIBackend, false, 5*time.Minute),
  518. Public: true,
  519. }, {
  520. Namespace: "admin",
  521. Version: "1.0",
  522. Service: NewPrivateAdminAPI(s),
  523. }, {
  524. Namespace: "debug",
  525. Version: "1.0",
  526. Service: NewPublicDebugAPI(s),
  527. Public: true,
  528. }, {
  529. Namespace: "debug",
  530. Version: "1.0",
  531. Service: NewPrivateDebugAPI(s),
  532. }, {
  533. Namespace: "net",
  534. Version: "1.0",
  535. Service: s.netRPCService,
  536. Public: true,
  537. },
  538. }...)
  539. return apis
  540. }
  541. func (s *Ethereum) ResetWithGenesisBlock(gb *types.Block) {
  542. s.blockchain.ResetWithGenesisBlock(gb)
  543. }
  544. func (s *Ethereum) Etherbase() (eb common.Address, err error) {
  545. s.lock.RLock()
  546. etherbase := s.etherbase
  547. s.lock.RUnlock()
  548. if etherbase != (common.Address{}) {
  549. return etherbase, nil
  550. }
  551. if wallets := s.AccountManager().Wallets(); len(wallets) > 0 {
  552. if accounts := wallets[0].Accounts(); len(accounts) > 0 {
  553. etherbase := accounts[0].Address
  554. s.lock.Lock()
  555. s.etherbase = etherbase
  556. s.lock.Unlock()
  557. log.Info("Etherbase automatically configured", "address", etherbase)
  558. return etherbase, nil
  559. }
  560. }
  561. return common.Address{}, fmt.Errorf("etherbase must be explicitly specified")
  562. }
  563. // isLocalBlock checks whether the specified block is mined
  564. // by local miner accounts.
  565. //
  566. // We regard two types of accounts as local miner account: etherbase
  567. // and accounts specified via `txpool.locals` flag.
  568. func (s *Ethereum) isLocalBlock(block *types.Block) bool {
  569. author, err := s.engine.Author(block.Header())
  570. if err != nil {
  571. log.Warn("Failed to retrieve block author", "number", block.NumberU64(), "hash", block.Hash(), "err", err)
  572. return false
  573. }
  574. // Check whether the given address is etherbase.
  575. s.lock.RLock()
  576. etherbase := s.etherbase
  577. s.lock.RUnlock()
  578. if author == etherbase {
  579. return true
  580. }
  581. // Check whether the given address is specified by `txpool.local`
  582. // CLI flag.
  583. for _, account := range s.config.TxPool.Locals {
  584. if account == author {
  585. return true
  586. }
  587. }
  588. return false
  589. }
  590. // shouldPreserve checks whether we should preserve the given block
  591. // during the chain reorg depending on whether the author of block
  592. // is a local account.
  593. func (s *Ethereum) shouldPreserve(block *types.Block) bool {
  594. // The reason we need to disable the self-reorg preserving for clique
  595. // is it can be probable to introduce a deadlock.
  596. //
  597. // e.g. If there are 7 available signers
  598. //
  599. // r1 A
  600. // r2 B
  601. // r3 C
  602. // r4 D
  603. // r5 A [X] F G
  604. // r6 [X]
  605. //
  606. // In the round5, the inturn signer E is offline, so the worst case
  607. // is A, F and G sign the block of round5 and reject the block of opponents
  608. // and in the round6, the last available signer B is offline, the whole
  609. // network is stuck.
  610. if _, ok := s.engine.(*clique.Clique); ok {
  611. return false
  612. }
  613. return s.isLocalBlock(block)
  614. }
  615. // SetEtherbase sets the mining reward address.
  616. // Quorum: method now has a return value
  617. func (s *Ethereum) SetEtherbase(etherbase common.Address) bool {
  618. //Quorum
  619. consensusAlgo := s.handler.getConsensusAlgorithm()
  620. if consensusAlgo == "istanbul" || consensusAlgo == "clique" || consensusAlgo == "raft" {
  621. log.Error("Cannot set etherbase with selected consensus mechanism")
  622. return false
  623. }
  624. //End-Quorum
  625. s.lock.Lock()
  626. s.etherbase = etherbase
  627. s.lock.Unlock()
  628. s.miner.SetEtherbase(etherbase)
  629. return true
  630. }
  631. // StartMining starts the miner with the given number of CPU threads. If mining
  632. // is already running, this method adjust the number of threads allowed to use
  633. // and updates the minimum price required by the transaction pool.
  634. func (s *Ethereum) StartMining(threads int) error {
  635. // Update the thread count within the consensus engine
  636. type threaded interface {
  637. SetThreads(threads int)
  638. }
  639. if th, ok := s.engine.(threaded); ok {
  640. log.Info("Updated mining threads", "threads", threads)
  641. if threads == 0 {
  642. threads = -1 // Disable the miner from within
  643. }
  644. th.SetThreads(threads)
  645. }
  646. // If the miner was not running, initialize it
  647. if !s.IsMining() {
  648. // Propagate the initial price point to the transaction pool
  649. s.lock.RLock()
  650. price := s.gasPrice
  651. s.lock.RUnlock()
  652. s.txPool.SetGasPrice(price)
  653. // Configure the local mining address
  654. eb, err := s.Etherbase()
  655. if err != nil {
  656. log.Error("Cannot start mining without etherbase", "err", err)
  657. return fmt.Errorf("etherbase missing: %v", err)
  658. }
  659. if clique, ok := s.engine.(*clique.Clique); ok {
  660. wallet, err := s.accountManager.Find(accounts.Account{Address: eb})
  661. if wallet == nil || err != nil {
  662. log.Error("Etherbase account unavailable locally", "err", err)
  663. return fmt.Errorf("signer missing: %v", err)
  664. }
  665. clique.Authorize(eb, wallet.SignData)
  666. }
  667. // If mining is started, we can disable the transaction rejection mechanism
  668. // introduced to speed sync times.
  669. atomic.StoreUint32(&s.handler.acceptTxs, 1)
  670. go s.miner.Start(eb)
  671. }
  672. return nil
  673. }
  674. // StopMining terminates the miner, both at the consensus engine level as well as
  675. // at the block creation level.
  676. func (s *Ethereum) StopMining() {
  677. // Update the thread count within the consensus engine
  678. type threaded interface {
  679. SetThreads(threads int)
  680. }
  681. if th, ok := s.engine.(threaded); ok {
  682. th.SetThreads(-1)
  683. }
  684. // Stop the block creating itself
  685. s.miner.Stop()
  686. }
  687. func (s *Ethereum) IsMining() bool { return s.miner.Mining() }
  688. func (s *Ethereum) Miner() *miner.Miner { return s.miner }
  689. func (s *Ethereum) AccountManager() *accounts.Manager { return s.accountManager }
  690. func (s *Ethereum) BlockChain() *core.BlockChain { return s.blockchain }
  691. func (s *Ethereum) TxPool() *core.TxPool { return s.txPool }
  692. func (s *Ethereum) EventMux() *event.TypeMux { return s.eventMux }
  693. func (s *Ethereum) Engine() consensus.Engine { return s.engine }
  694. func (s *Ethereum) ChainDb() ethdb.Database { return s.chainDb }
  695. func (s *Ethereum) IsListening() bool { return true } // Always listening
  696. func (s *Ethereum) Downloader() *downloader.Downloader { return s.handler.downloader }
  697. func (s *Ethereum) Synced() bool { return atomic.LoadUint32(&s.handler.acceptTxs) == 1 }
  698. func (s *Ethereum) ArchiveMode() bool { return s.config.NoPruning }
  699. func (s *Ethereum) BloomIndexer() *core.ChainIndexer { return s.bloomIndexer }
  700. // Quorum
  701. // adds quorum specific protocols to the Protocols() function which in the associated upstream geth version returns
  702. // only one subprotocol, "eth", and the supported versions of the "eth" protocol.
  703. // Quorum uses the eth service to run configurable consensus protocols, e.g. istanbul. Thru release v20.10.0
  704. // the "eth" subprotocol would be replaced with a modified subprotocol, e.g. "istanbul/99" which would contain all the "eth"
  705. // messages + the istanbul message and be communicated over the consensus specific subprotocol ("istanbul"), and
  706. // not over "eth".
  707. // Now the eth service supports multiple protocols, e.g. "eth" and an optional consensus
  708. // protocol, e.g. "istanbul/100".
  709. // /Quorum
  710. // Protocols returns all the currently configured
  711. // network protocols to start.
  712. func (s *Ethereum) Protocols() []p2p.Protocol {
  713. if s.config.QuorumLightClient.Enabled() {
  714. protos := qlightproto.MakeProtocolsClient((*qlightClientHandler)(s.handler), s.networkID, s.ethDialCandidates)
  715. return protos
  716. }
  717. protos := eth.MakeProtocols((*ethHandler)(s.handler), s.networkID, s.ethDialCandidates)
  718. if s.config.SnapshotCache > 0 {
  719. protos = append(protos, snap.MakeProtocols((*snapHandler)(s.handler), s.snapDialCandidates)...)
  720. }
  721. // /Quorum
  722. // add additional quorum consensus protocol if set and if not set to "eth", e.g. istanbul
  723. if quorumConsensusProtocolName != "" && quorumConsensusProtocolName != eth.ProtocolName {
  724. quorumProtos := s.quorumConsensusProtocols((*ethHandler)(s.handler), s.networkID, s.ethDialCandidates)
  725. protos = append(protos, quorumProtos...)
  726. }
  727. // /end Quorum
  728. return protos
  729. }
  730. func (s *Ethereum) QProtocols() []p2p.Protocol {
  731. protos := qlightproto.MakeProtocolsServer((*qlightServerHandler)(s.qlightServerHandler), s.networkID, s.ethDialCandidates)
  732. return protos
  733. }
  734. // Start implements node.Lifecycle, starting all internal goroutines needed by the
  735. // Ethereum protocol implementation.
  736. func (s *Ethereum) Start() error {
  737. eth.StartENRUpdater(s.blockchain, s.p2pServer.LocalNode())
  738. // Start the bloom bits servicing goroutines
  739. s.startBloomHandlers(params.BloomBitsBlocks)
  740. // Figure out a max peers count based on the server limits
  741. maxPeers := s.p2pServer.MaxPeers
  742. if s.config.LightServ > 0 {
  743. if s.config.LightPeers >= s.p2pServer.MaxPeers {
  744. return fmt.Errorf("invalid peer config: light peer count (%d) >= total peer count (%d)", s.config.LightPeers, s.p2pServer.MaxPeers)
  745. }
  746. maxPeers -= s.config.LightPeers
  747. }
  748. // Start the networking layer and the light server if requested
  749. if s.config.QuorumLightClient.Enabled() {
  750. s.handler.StartQLightClient()
  751. } else {
  752. s.handler.Start(maxPeers)
  753. if s.qlightServerHandler != nil {
  754. s.qlightServerHandler.StartQLightServer(s.qlightP2pServer.MaxPeers)
  755. }
  756. }
  757. return nil
  758. }
  759. // Stop implements node.Lifecycle, terminating all internal goroutines used by the
  760. // Ethereum protocol.
  761. func (s *Ethereum) Stop() error {
  762. // Stop all the peer-related stuff first.
  763. if s.config.QuorumLightClient.Enabled() {
  764. s.handler.StopQLightClient()
  765. } else {
  766. if s.qlightServerHandler != nil {
  767. s.qlightServerHandler.StopQLightServer()
  768. }
  769. s.ethDialCandidates.Close()
  770. s.snapDialCandidates.Close()
  771. s.handler.Stop()
  772. }
  773. // Then stop everything else.
  774. s.bloomIndexer.Close()
  775. close(s.closeBloomHandler)
  776. s.txPool.Stop()
  777. s.miner.Stop()
  778. s.blockchain.Stop()
  779. s.engine.Close()
  780. rawdb.PopUncleanShutdownMarker(s.chainDb)
  781. s.chainDb.Close()
  782. s.eventMux.Stop()
  783. return nil
  784. }
  785. func (s *Ethereum) CalcGasLimit(block *types.Block) uint64 {
  786. minGasLimit := params.DefaultMinGasLimit
  787. if s != nil && s.config != nil && s.config.Genesis != nil {
  788. minGasLimit = s.config.Genesis.Config.GetMinerMinGasLimit(block.Number(), params.DefaultMinGasLimit)
  789. }
  790. return core.CalcGasLimit(block, minGasLimit, s.config.Miner.GasFloor, s.config.Miner.GasCeil)
  791. }
  792. // (Quorum)
  793. // ConsensusServicePendingLogsFeed returns an event.Feed. When the consensus protocol does not use eth.worker (e.g. raft), the event.Feed should be used to send logs from transactions included in the pending block
  794. func (s *Ethereum) ConsensusServicePendingLogsFeed() *event.Feed {
  795. return s.consensusServicePendingLogsFeed
  796. }
  797. // (Quorum)
  798. // SubscribePendingLogs starts delivering logs from transactions included in the consensus engine's pending block to the given channel.
  799. func (s *Ethereum) SubscribePendingLogs(ch chan<- []*types.Log) event.Subscription {
  800. if s.config.RaftMode {
  801. return s.consensusServicePendingLogsFeed.Subscribe(ch)
  802. }
  803. return s.miner.SubscribePendingLogs(ch)
  804. }
  805. // NotifyRegisteredPluginService will ask to refresh the plugin service
  806. // (Quorum)
  807. func (s *Ethereum) NotifyRegisteredPluginService(pluginManager *plugin.PluginManager) error {
  808. if s.qlightTokenHolder == nil {
  809. return nil
  810. }
  811. switch s.config.QuorumLightClient.TokenManagement {
  812. case "client-security-plugin":
  813. return s.qlightTokenHolder.RefreshPlugin(pluginManager)
  814. }
  815. return nil
  816. }