backend.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508
  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. "os"
  23. "path/filepath"
  24. "regexp"
  25. "strings"
  26. "sync"
  27. "time"
  28. "github.com/ethereum/ethash"
  29. "github.com/ethereum/go-ethereum/accounts"
  30. "github.com/ethereum/go-ethereum/common"
  31. "github.com/ethereum/go-ethereum/common/httpclient"
  32. "github.com/ethereum/go-ethereum/common/registrar/ethreg"
  33. "github.com/ethereum/go-ethereum/core"
  34. "github.com/ethereum/go-ethereum/core/types"
  35. "github.com/ethereum/go-ethereum/core/vm"
  36. "github.com/ethereum/go-ethereum/eth/downloader"
  37. "github.com/ethereum/go-ethereum/eth/filters"
  38. "github.com/ethereum/go-ethereum/eth/gasprice"
  39. "github.com/ethereum/go-ethereum/ethdb"
  40. "github.com/ethereum/go-ethereum/event"
  41. "github.com/ethereum/go-ethereum/internal/ethapi"
  42. "github.com/ethereum/go-ethereum/logger"
  43. "github.com/ethereum/go-ethereum/logger/glog"
  44. "github.com/ethereum/go-ethereum/miner"
  45. "github.com/ethereum/go-ethereum/node"
  46. "github.com/ethereum/go-ethereum/p2p"
  47. "github.com/ethereum/go-ethereum/rpc"
  48. )
  49. const (
  50. epochLength = 30000
  51. ethashRevision = 23
  52. autoDAGcheckInterval = 10 * time.Hour
  53. autoDAGepochHeight = epochLength / 2
  54. )
  55. var (
  56. datadirInUseErrnos = map[uint]bool{11: true, 32: true, 35: true}
  57. portInUseErrRE = regexp.MustCompile("address already in use")
  58. )
  59. type Config struct {
  60. ChainConfig *core.ChainConfig // chain configuration
  61. NetworkId int // Network ID to use for selecting peers to connect to
  62. Genesis string // Genesis JSON to seed the chain database with
  63. FastSync bool // Enables the state download based fast synchronisation algorithm
  64. SkipBcVersionCheck bool // e.g. blockchain export
  65. DatabaseCache int
  66. DatabaseHandles int
  67. NatSpec bool
  68. DocRoot string
  69. AutoDAG bool
  70. PowTest bool
  71. PowShared bool
  72. ExtraData []byte
  73. Etherbase common.Address
  74. GasPrice *big.Int
  75. MinerThreads int
  76. SolcPath string
  77. GpoMinGasPrice *big.Int
  78. GpoMaxGasPrice *big.Int
  79. GpoFullBlockRatio int
  80. GpobaseStepDown int
  81. GpobaseStepUp int
  82. GpobaseCorrectionFactor int
  83. EnableJit bool
  84. ForceJit bool
  85. TestGenesisBlock *types.Block // Genesis block to seed the chain database with (testing only!)
  86. TestGenesisState ethdb.Database // Genesis state to seed the database with (testing only!)
  87. }
  88. // Ethereum implements the Ethereum full node service.
  89. type Ethereum struct {
  90. chainConfig *core.ChainConfig
  91. // Channel for shutting down the service
  92. shutdownChan chan bool // Channel for shutting down the ethereum
  93. stopDbUpgrade func() // stop chain db sequential key upgrade
  94. // Handlers
  95. txPool *core.TxPool
  96. txMu sync.Mutex
  97. blockchain *core.BlockChain
  98. protocolManager *ProtocolManager
  99. // DB interfaces
  100. chainDb ethdb.Database // Block chain database
  101. eventMux *event.TypeMux
  102. pow *ethash.Ethash
  103. httpclient *httpclient.HTTPClient
  104. accountManager *accounts.Manager
  105. apiBackend *EthApiBackend
  106. miner *miner.Miner
  107. Mining bool
  108. MinerThreads int
  109. AutoDAG bool
  110. autodagquit chan bool
  111. etherbase common.Address
  112. solcPath string
  113. NatSpec bool
  114. PowTest bool
  115. netVersionId int
  116. netRPCService *ethapi.PublicNetAPI
  117. }
  118. // New creates a new Ethereum object (including the
  119. // initialisation of the common Ethereum object)
  120. func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
  121. chainDb, err := createDB(ctx, config)
  122. if err != nil {
  123. return nil, err
  124. }
  125. stopDbUpgrade := upgradeSequentialKeys(chainDb)
  126. if err := SetupGenesisBlock(&chainDb, config); err != nil {
  127. return nil, err
  128. }
  129. pow, err := CreatePoW(config)
  130. if err != nil {
  131. return nil, err
  132. }
  133. eth := &Ethereum{
  134. chainDb: chainDb,
  135. eventMux: ctx.EventMux,
  136. accountManager: ctx.AccountManager,
  137. pow: pow,
  138. shutdownChan: make(chan bool),
  139. stopDbUpgrade: stopDbUpgrade,
  140. httpclient: httpclient.New(config.DocRoot),
  141. netVersionId: config.NetworkId,
  142. NatSpec: config.NatSpec,
  143. PowTest: config.PowTest,
  144. etherbase: config.Etherbase,
  145. MinerThreads: config.MinerThreads,
  146. AutoDAG: config.AutoDAG,
  147. solcPath: config.SolcPath,
  148. }
  149. if err := upgradeChainDatabase(chainDb); err != nil {
  150. return nil, err
  151. }
  152. if err := addMipmapBloomBins(chainDb); err != nil {
  153. return nil, err
  154. }
  155. glog.V(logger.Info).Infof("Protocol Versions: %v, Network Id: %v", ProtocolVersions, config.NetworkId)
  156. if !config.SkipBcVersionCheck {
  157. bcVersion := core.GetBlockChainVersion(chainDb)
  158. if bcVersion != core.BlockChainVersion && bcVersion != 0 {
  159. return nil, fmt.Errorf("Blockchain DB version mismatch (%d / %d). Run geth upgradedb.\n", bcVersion, core.BlockChainVersion)
  160. }
  161. core.WriteBlockChainVersion(chainDb, core.BlockChainVersion)
  162. }
  163. // load the genesis block or write a new one if no genesis
  164. // block is prenent in the database.
  165. genesis := core.GetBlock(chainDb, core.GetCanonicalHash(chainDb, 0), 0)
  166. if genesis == nil {
  167. genesis, err = core.WriteDefaultGenesisBlock(chainDb)
  168. if err != nil {
  169. return nil, err
  170. }
  171. glog.V(logger.Info).Infoln("WARNING: Wrote default ethereum genesis block")
  172. }
  173. if config.ChainConfig == nil {
  174. return nil, errors.New("missing chain config")
  175. }
  176. core.WriteChainConfig(chainDb, genesis.Hash(), config.ChainConfig)
  177. eth.chainConfig = config.ChainConfig
  178. eth.chainConfig.VmConfig = vm.Config{
  179. EnableJit: config.EnableJit,
  180. ForceJit: config.ForceJit,
  181. }
  182. eth.blockchain, err = core.NewBlockChain(chainDb, eth.chainConfig, eth.pow, eth.EventMux())
  183. if err != nil {
  184. if err == core.ErrNoGenesis {
  185. return nil, fmt.Errorf(`No chain found. Please initialise a new chain using the "init" subcommand.`)
  186. }
  187. return nil, err
  188. }
  189. newPool := core.NewTxPool(eth.chainConfig, eth.EventMux(), eth.blockchain.State, eth.blockchain.GasLimit)
  190. eth.txPool = newPool
  191. if eth.protocolManager, err = NewProtocolManager(eth.chainConfig, config.FastSync, config.NetworkId, eth.eventMux, eth.txPool, eth.pow, eth.blockchain, chainDb); err != nil {
  192. return nil, err
  193. }
  194. eth.miner = miner.New(eth, eth.chainConfig, eth.EventMux(), eth.pow)
  195. eth.miner.SetGasPrice(config.GasPrice)
  196. eth.miner.SetExtra(config.ExtraData)
  197. gpoParams := &gasprice.GpoParams{
  198. GpoMinGasPrice: config.GpoMinGasPrice,
  199. GpoMaxGasPrice: config.GpoMaxGasPrice,
  200. GpoFullBlockRatio: config.GpoFullBlockRatio,
  201. GpobaseStepDown: config.GpobaseStepDown,
  202. GpobaseStepUp: config.GpobaseStepUp,
  203. GpobaseCorrectionFactor: config.GpobaseCorrectionFactor,
  204. }
  205. gpo := gasprice.NewGasPriceOracle(eth.blockchain, chainDb, eth.eventMux, gpoParams)
  206. eth.apiBackend = &EthApiBackend{eth, gpo}
  207. return eth, nil
  208. }
  209. // createDB creates the chain database.
  210. func createDB(ctx *node.ServiceContext, config *Config) (ethdb.Database, error) {
  211. db, err := ctx.OpenDatabase("chaindata", config.DatabaseCache, config.DatabaseHandles)
  212. if db, ok := db.(*ethdb.LDBDatabase); ok {
  213. db.Meter("eth/db/chaindata/")
  214. }
  215. return db, err
  216. }
  217. // SetupGenesisBlock initializes the genesis block for an Ethereum service
  218. func SetupGenesisBlock(chainDb *ethdb.Database, config *Config) error {
  219. // Load up any custom genesis block if requested
  220. if len(config.Genesis) > 0 {
  221. block, err := core.WriteGenesisBlock(*chainDb, strings.NewReader(config.Genesis))
  222. if err != nil {
  223. return err
  224. }
  225. glog.V(logger.Info).Infof("Successfully wrote custom genesis block: %x", block.Hash())
  226. }
  227. // Load up a test setup if directly injected
  228. if config.TestGenesisState != nil {
  229. *chainDb = config.TestGenesisState
  230. }
  231. if config.TestGenesisBlock != nil {
  232. core.WriteTd(*chainDb, config.TestGenesisBlock.Hash(), config.TestGenesisBlock.NumberU64(), config.TestGenesisBlock.Difficulty())
  233. core.WriteBlock(*chainDb, config.TestGenesisBlock)
  234. core.WriteCanonicalHash(*chainDb, config.TestGenesisBlock.Hash(), config.TestGenesisBlock.NumberU64())
  235. core.WriteHeadBlockHash(*chainDb, config.TestGenesisBlock.Hash())
  236. }
  237. return nil
  238. }
  239. // CreatePoW creates the required type of PoW instance for an Ethereum service
  240. func CreatePoW(config *Config) (*ethash.Ethash, error) {
  241. switch {
  242. case config.PowTest:
  243. glog.V(logger.Info).Infof("ethash used in test mode")
  244. return ethash.NewForTesting()
  245. case config.PowShared:
  246. glog.V(logger.Info).Infof("ethash used in shared mode")
  247. return ethash.NewShared(), nil
  248. default:
  249. return ethash.New(), nil
  250. }
  251. }
  252. // APIs returns the collection of RPC services the ethereum package offers.
  253. // NOTE, some of these services probably need to be moved to somewhere else.
  254. func (s *Ethereum) APIs() []rpc.API {
  255. return append(ethapi.GetAPIs(s.apiBackend, s.solcPath), []rpc.API{
  256. {
  257. Namespace: "eth",
  258. Version: "1.0",
  259. Service: NewPublicEthereumAPI(s),
  260. Public: true,
  261. }, {
  262. Namespace: "eth",
  263. Version: "1.0",
  264. Service: NewPublicMinerAPI(s),
  265. Public: true,
  266. }, {
  267. Namespace: "eth",
  268. Version: "1.0",
  269. Service: downloader.NewPublicDownloaderAPI(s.protocolManager.downloader, s.eventMux),
  270. Public: true,
  271. }, {
  272. Namespace: "miner",
  273. Version: "1.0",
  274. Service: NewPrivateMinerAPI(s),
  275. Public: false,
  276. }, {
  277. Namespace: "eth",
  278. Version: "1.0",
  279. Service: filters.NewPublicFilterAPI(s.chainDb, s.eventMux),
  280. Public: true,
  281. }, {
  282. Namespace: "admin",
  283. Version: "1.0",
  284. Service: NewPrivateAdminAPI(s),
  285. }, {
  286. Namespace: "debug",
  287. Version: "1.0",
  288. Service: NewPublicDebugAPI(s),
  289. Public: true,
  290. }, {
  291. Namespace: "debug",
  292. Version: "1.0",
  293. Service: NewPrivateDebugAPI(s.chainConfig, s),
  294. }, {
  295. Namespace: "net",
  296. Version: "1.0",
  297. Service: s.netRPCService,
  298. Public: true,
  299. }, {
  300. Namespace: "admin",
  301. Version: "1.0",
  302. Service: ethreg.NewPrivateRegistarAPI(s.chainConfig, s.blockchain, s.chainDb, s.txPool, s.accountManager),
  303. },
  304. }...)
  305. }
  306. func (s *Ethereum) ResetWithGenesisBlock(gb *types.Block) {
  307. s.blockchain.ResetWithGenesisBlock(gb)
  308. }
  309. func (s *Ethereum) Etherbase() (eb common.Address, err error) {
  310. eb = s.etherbase
  311. if (eb == common.Address{}) {
  312. firstAccount, err := s.AccountManager().AccountByIndex(0)
  313. eb = firstAccount.Address
  314. if err != nil {
  315. return eb, fmt.Errorf("etherbase address must be explicitly specified")
  316. }
  317. }
  318. return eb, nil
  319. }
  320. // set in js console via admin interface or wrapper from cli flags
  321. func (self *Ethereum) SetEtherbase(etherbase common.Address) {
  322. self.etherbase = etherbase
  323. self.miner.SetEtherbase(etherbase)
  324. }
  325. func (s *Ethereum) StartMining(threads int) error {
  326. eb, err := s.Etherbase()
  327. if err != nil {
  328. err = fmt.Errorf("Cannot start mining without etherbase address: %v", err)
  329. glog.V(logger.Error).Infoln(err)
  330. return err
  331. }
  332. go s.miner.Start(eb, threads)
  333. return nil
  334. }
  335. func (s *Ethereum) StopMining() { s.miner.Stop() }
  336. func (s *Ethereum) IsMining() bool { return s.miner.Mining() }
  337. func (s *Ethereum) Miner() *miner.Miner { return s.miner }
  338. func (s *Ethereum) AccountManager() *accounts.Manager { return s.accountManager }
  339. func (s *Ethereum) BlockChain() *core.BlockChain { return s.blockchain }
  340. func (s *Ethereum) TxPool() *core.TxPool { return s.txPool }
  341. func (s *Ethereum) EventMux() *event.TypeMux { return s.eventMux }
  342. func (s *Ethereum) Pow() *ethash.Ethash { return s.pow }
  343. func (s *Ethereum) ChainDb() ethdb.Database { return s.chainDb }
  344. func (s *Ethereum) IsListening() bool { return true } // Always listening
  345. func (s *Ethereum) EthVersion() int { return int(s.protocolManager.SubProtocols[0].Version) }
  346. func (s *Ethereum) NetVersion() int { return s.netVersionId }
  347. func (s *Ethereum) Downloader() *downloader.Downloader { return s.protocolManager.downloader }
  348. // Protocols implements node.Service, returning all the currently configured
  349. // network protocols to start.
  350. func (s *Ethereum) Protocols() []p2p.Protocol {
  351. return s.protocolManager.SubProtocols
  352. }
  353. // Start implements node.Service, starting all internal goroutines needed by the
  354. // Ethereum protocol implementation.
  355. func (s *Ethereum) Start(srvr *p2p.Server) error {
  356. s.netRPCService = ethapi.NewPublicNetAPI(srvr, s.NetVersion())
  357. if s.AutoDAG {
  358. s.StartAutoDAG()
  359. }
  360. s.protocolManager.Start()
  361. return nil
  362. }
  363. // Stop implements node.Service, terminating all internal goroutines used by the
  364. // Ethereum protocol.
  365. func (s *Ethereum) Stop() error {
  366. if s.stopDbUpgrade != nil {
  367. s.stopDbUpgrade()
  368. }
  369. s.blockchain.Stop()
  370. s.protocolManager.Stop()
  371. s.txPool.Stop()
  372. s.miner.Stop()
  373. s.eventMux.Stop()
  374. s.StopAutoDAG()
  375. s.chainDb.Close()
  376. close(s.shutdownChan)
  377. return nil
  378. }
  379. // This function will wait for a shutdown and resumes main thread execution
  380. func (s *Ethereum) WaitForShutdown() {
  381. <-s.shutdownChan
  382. }
  383. // StartAutoDAG() spawns a go routine that checks the DAG every autoDAGcheckInterval
  384. // by default that is 10 times per epoch
  385. // in epoch n, if we past autoDAGepochHeight within-epoch blocks,
  386. // it calls ethash.MakeDAG to pregenerate the DAG for the next epoch n+1
  387. // if it does not exist yet as well as remove the DAG for epoch n-1
  388. // the loop quits if autodagquit channel is closed, it can safely restart and
  389. // stop any number of times.
  390. // For any more sophisticated pattern of DAG generation, use CLI subcommand
  391. // makedag
  392. func (self *Ethereum) StartAutoDAG() {
  393. if self.autodagquit != nil {
  394. return // already started
  395. }
  396. go func() {
  397. glog.V(logger.Info).Infof("Automatic pregeneration of ethash DAG ON (ethash dir: %s)", ethash.DefaultDir)
  398. var nextEpoch uint64
  399. timer := time.After(0)
  400. self.autodagquit = make(chan bool)
  401. for {
  402. select {
  403. case <-timer:
  404. glog.V(logger.Info).Infof("checking DAG (ethash dir: %s)", ethash.DefaultDir)
  405. currentBlock := self.BlockChain().CurrentBlock().NumberU64()
  406. thisEpoch := currentBlock / epochLength
  407. if nextEpoch <= thisEpoch {
  408. if currentBlock%epochLength > autoDAGepochHeight {
  409. if thisEpoch > 0 {
  410. previousDag, previousDagFull := dagFiles(thisEpoch - 1)
  411. os.Remove(filepath.Join(ethash.DefaultDir, previousDag))
  412. os.Remove(filepath.Join(ethash.DefaultDir, previousDagFull))
  413. glog.V(logger.Info).Infof("removed DAG for epoch %d (%s)", thisEpoch-1, previousDag)
  414. }
  415. nextEpoch = thisEpoch + 1
  416. dag, _ := dagFiles(nextEpoch)
  417. if _, err := os.Stat(dag); os.IsNotExist(err) {
  418. glog.V(logger.Info).Infof("Pregenerating DAG for epoch %d (%s)", nextEpoch, dag)
  419. err := ethash.MakeDAG(nextEpoch*epochLength, "") // "" -> ethash.DefaultDir
  420. if err != nil {
  421. glog.V(logger.Error).Infof("Error generating DAG for epoch %d (%s)", nextEpoch, dag)
  422. return
  423. }
  424. } else {
  425. glog.V(logger.Error).Infof("DAG for epoch %d (%s)", nextEpoch, dag)
  426. }
  427. }
  428. }
  429. timer = time.After(autoDAGcheckInterval)
  430. case <-self.autodagquit:
  431. return
  432. }
  433. }
  434. }()
  435. }
  436. // stopAutoDAG stops automatic DAG pregeneration by quitting the loop
  437. func (self *Ethereum) StopAutoDAG() {
  438. if self.autodagquit != nil {
  439. close(self.autodagquit)
  440. self.autodagquit = nil
  441. }
  442. glog.V(logger.Info).Infof("Automatic pregeneration of ethash DAG OFF (ethash dir: %s)", ethash.DefaultDir)
  443. }
  444. // HTTPClient returns the light http client used for fetching offchain docs
  445. // (natspec, source for verification)
  446. func (self *Ethereum) HTTPClient() *httpclient.HTTPClient {
  447. return self.httpclient
  448. }
  449. // dagFiles(epoch) returns the two alternative DAG filenames (not a path)
  450. // 1) <revision>-<hex(seedhash[8])> 2) full-R<revision>-<hex(seedhash[8])>
  451. func dagFiles(epoch uint64) (string, string) {
  452. seedHash, _ := ethash.GetSeedHash(epoch * epochLength)
  453. dag := fmt.Sprintf("full-R%d-%x", ethashRevision, seedHash[:8])
  454. return dag, "full-R" + dag
  455. }