aboutsummaryrefslogtreecommitdiffstats
path: root/eth/backend.go
diff options
context:
space:
mode:
Diffstat (limited to 'eth/backend.go')
-rw-r--r--eth/backend.go266
1 files changed, 126 insertions, 140 deletions
diff --git a/eth/backend.go b/eth/backend.go
index 006523484..c8a9af6ee 100644
--- a/eth/backend.go
+++ b/eth/backend.go
@@ -39,8 +39,10 @@ import (
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/eth/downloader"
"github.com/ethereum/go-ethereum/eth/filters"
+ "github.com/ethereum/go-ethereum/eth/gasprice"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
+ "github.com/ethereum/go-ethereum/internal/ethapi"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/miner"
@@ -101,95 +103,86 @@ type Config struct {
TestGenesisState ethdb.Database // Genesis state to seed the database with (testing only!)
}
+// Ethereum implements the Ethereum full node service.
type Ethereum struct {
- chainConfig *core.ChainConfig
+ chainConfig *core.ChainConfig
+ // Channel for shutting down the service
shutdownChan chan bool // Channel for shutting down the ethereum
stopDbUpgrade func() // stop chain db sequential key upgrade
-
- // DB interfaces
- chainDb ethdb.Database // Block chain database
- dappDb ethdb.Database // Dapp database
-
// Handlers
txPool *core.TxPool
txMu sync.Mutex
blockchain *core.BlockChain
- accountManager *accounts.Manager
- pow *ethash.Ethash
protocolManager *ProtocolManager
- SolcPath string
- solc *compiler.Solidity
- gpo *GasPriceOracle
+ // DB interfaces
+ chainDb ethdb.Database // Block chain database
+ dappDb ethdb.Database // Dapp database
- GpoMinGasPrice *big.Int
- GpoMaxGasPrice *big.Int
- GpoFullBlockRatio int
- GpobaseStepDown int
- GpobaseStepUp int
- GpobaseCorrectionFactor int
+ eventMux *event.TypeMux
+ pow *ethash.Ethash
+ httpclient *httpclient.HTTPClient
+ accountManager *accounts.Manager
- httpclient *httpclient.HTTPClient
+ apiBackend *EthApiBackend
- eventMux *event.TypeMux
- miner *miner.Miner
+ miner *miner.Miner
+ Mining bool
+ MinerThreads int
+ AutoDAG bool
+ autodagquit chan bool
+ etherbase common.Address
+ solcPath string
+ solc *compiler.Solidity
- Mining bool
- MinerThreads int
NatSpec bool
- AutoDAG bool
PowTest bool
- autodagquit chan bool
- etherbase common.Address
netVersionId int
- netRPCService *PublicNetAPI
+ netRPCService *ethapi.PublicNetAPI
}
+// New creates a new Ethereum object (including the
+// initialisation of the common Ethereum object)
func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
- // Open the chain database and perform any upgrades needed
- chainDb, err := ctx.OpenDatabase("chaindata", config.DatabaseCache, config.DatabaseHandles)
+ chainDb, dappDb, err := CreateDBs(ctx, config)
if err != nil {
return nil, err
}
- if db, ok := chainDb.(*ethdb.LDBDatabase); ok {
- db.Meter("eth/db/chaindata/")
- }
- if err := upgradeChainDatabase(chainDb); err != nil {
- return nil, err
- }
- if err := addMipmapBloomBins(chainDb); err != nil {
+ stopDbUpgrade := upgradeSequentialKeys(chainDb)
+ if err := SetupGenesisBlock(&chainDb, config); err != nil {
return nil, err
}
- stopDbUpgrade := upgradeSequentialKeys(chainDb)
-
- dappDb, err := ctx.OpenDatabase("dapp", config.DatabaseCache, config.DatabaseHandles)
+ pow, err := CreatePoW(config)
if err != nil {
return nil, err
}
- if db, ok := dappDb.(*ethdb.LDBDatabase); ok {
- db.Meter("eth/db/dapp/")
- }
- glog.V(logger.Info).Infof("Protocol Versions: %v, Network Id: %v", ProtocolVersions, config.NetworkId)
- // Load up any custom genesis block if requested
- if len(config.Genesis) > 0 {
- block, err := core.WriteGenesisBlock(chainDb, strings.NewReader(config.Genesis))
- if err != nil {
- return nil, err
- }
- glog.V(logger.Info).Infof("Successfully wrote custom genesis block: %x", block.Hash())
+ eth := &Ethereum{
+ chainDb: chainDb,
+ dappDb: dappDb,
+ eventMux: ctx.EventMux,
+ accountManager: config.AccountManager,
+ pow: pow,
+ shutdownChan: make(chan bool),
+ stopDbUpgrade: stopDbUpgrade,
+ httpclient: httpclient.New(config.DocRoot),
+ netVersionId: config.NetworkId,
+ NatSpec: config.NatSpec,
+ PowTest: config.PowTest,
+ etherbase: config.Etherbase,
+ MinerThreads: config.MinerThreads,
+ AutoDAG: config.AutoDAG,
+ solcPath: config.SolcPath,
}
- // Load up a test setup if directly injected
- if config.TestGenesisState != nil {
- chainDb = config.TestGenesisState
+ if err := upgradeChainDatabase(chainDb); err != nil {
+ return nil, err
}
- if config.TestGenesisBlock != nil {
- core.WriteTd(chainDb, config.TestGenesisBlock.Hash(), config.TestGenesisBlock.NumberU64(), config.TestGenesisBlock.Difficulty())
- core.WriteBlock(chainDb, config.TestGenesisBlock)
- core.WriteCanonicalHash(chainDb, config.TestGenesisBlock.Hash(), config.TestGenesisBlock.NumberU64())
- core.WriteHeadBlockHash(chainDb, config.TestGenesisBlock.Hash())
+ if err := addMipmapBloomBins(chainDb); err != nil {
+ return nil, err
}
+ glog.V(logger.Info).Infof("Protocol Versions: %v, Network Id: %v", ProtocolVersions, config.NetworkId)
+
if !config.SkipBcVersionCheck {
bcVersion := core.GetBlockChainVersion(chainDb)
if bcVersion != config.BlockChainVersion && bcVersion != 0 {
@@ -197,44 +190,6 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
}
core.WriteBlockChainVersion(chainDb, config.BlockChainVersion)
}
- glog.V(logger.Info).Infof("Blockchain DB Version: %d", config.BlockChainVersion)
-
- eth := &Ethereum{
- shutdownChan: make(chan bool),
- stopDbUpgrade: stopDbUpgrade,
- chainDb: chainDb,
- dappDb: dappDb,
- eventMux: ctx.EventMux,
- accountManager: config.AccountManager,
- etherbase: config.Etherbase,
- netVersionId: config.NetworkId,
- NatSpec: config.NatSpec,
- MinerThreads: config.MinerThreads,
- SolcPath: config.SolcPath,
- AutoDAG: config.AutoDAG,
- PowTest: config.PowTest,
- GpoMinGasPrice: config.GpoMinGasPrice,
- GpoMaxGasPrice: config.GpoMaxGasPrice,
- GpoFullBlockRatio: config.GpoFullBlockRatio,
- GpobaseStepDown: config.GpobaseStepDown,
- GpobaseStepUp: config.GpobaseStepUp,
- GpobaseCorrectionFactor: config.GpobaseCorrectionFactor,
- httpclient: httpclient.New(config.DocRoot),
- }
- switch {
- case config.PowTest:
- glog.V(logger.Info).Infof("ethash used in test mode")
- eth.pow, err = ethash.NewForTesting()
- if err != nil {
- return nil, err
- }
- case config.PowShared:
- glog.V(logger.Info).Infof("ethash used in shared mode")
- eth.pow = ethash.NewShared()
-
- default:
- eth.pow = ethash.New()
- }
// load the genesis block or write a new one if no genesis
// block is prenent in the database.
@@ -250,6 +205,8 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
if config.ChainConfig == nil {
return nil, errors.New("missing chain config")
}
+ core.WriteChainConfig(chainDb, genesis.Hash(), config.ChainConfig)
+
eth.chainConfig = config.ChainConfig
eth.chainConfig.VmConfig = vm.Config{
EnableJit: config.EnableJit,
@@ -263,8 +220,6 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
}
return nil, err
}
- eth.gpo = NewGasPriceOracle(eth)
-
newPool := core.NewTxPool(eth.chainConfig, eth.EventMux(), eth.blockchain.State, eth.blockchain.GasLimit)
eth.txPool = newPool
@@ -275,13 +230,83 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
eth.miner.SetGasPrice(config.GasPrice)
eth.miner.SetExtra(config.ExtraData)
+ gpoParams := &gasprice.GpoParams{
+ GpoMinGasPrice: config.GpoMinGasPrice,
+ GpoMaxGasPrice: config.GpoMaxGasPrice,
+ GpoFullBlockRatio: config.GpoFullBlockRatio,
+ GpobaseStepDown: config.GpobaseStepDown,
+ GpobaseStepUp: config.GpobaseStepUp,
+ GpobaseCorrectionFactor: config.GpobaseCorrectionFactor,
+ }
+ gpo := gasprice.NewGasPriceOracle(eth.blockchain, chainDb, eth.eventMux, gpoParams)
+ eth.apiBackend = &EthApiBackend{eth, gpo}
+
return eth, nil
}
+// CreateDBs creates the chain and dapp databases for an Ethereum service
+func CreateDBs(ctx *node.ServiceContext, config *Config) (chainDb, dappDb ethdb.Database, err error) {
+ // Open the chain database and perform any upgrades needed
+ chainDb, err = ctx.OpenDatabase("chaindata", config.DatabaseCache, config.DatabaseHandles)
+ if err != nil {
+ return nil, nil, err
+ }
+ if db, ok := chainDb.(*ethdb.LDBDatabase); ok {
+ db.Meter("eth/db/chaindata/")
+ }
+
+ dappDb, err = ctx.OpenDatabase("dapp", config.DatabaseCache, config.DatabaseHandles)
+ if err != nil {
+ return nil, nil, err
+ }
+ if db, ok := dappDb.(*ethdb.LDBDatabase); ok {
+ db.Meter("eth/db/dapp/")
+ }
+ return
+}
+
+// SetupGenesisBlock initializes the genesis block for an Ethereum service
+func SetupGenesisBlock(chainDb *ethdb.Database, config *Config) error {
+ // Load up any custom genesis block if requested
+ if len(config.Genesis) > 0 {
+ block, err := core.WriteGenesisBlock(*chainDb, strings.NewReader(config.Genesis))
+ if err != nil {
+ return err
+ }
+ glog.V(logger.Info).Infof("Successfully wrote custom genesis block: %x", block.Hash())
+ }
+ // Load up a test setup if directly injected
+ if config.TestGenesisState != nil {
+ *chainDb = config.TestGenesisState
+ }
+ if config.TestGenesisBlock != nil {
+ core.WriteTd(*chainDb, config.TestGenesisBlock.Hash(), config.TestGenesisBlock.NumberU64(), config.TestGenesisBlock.Difficulty())
+ core.WriteBlock(*chainDb, config.TestGenesisBlock)
+ core.WriteCanonicalHash(*chainDb, config.TestGenesisBlock.Hash(), config.TestGenesisBlock.NumberU64())
+ core.WriteHeadBlockHash(*chainDb, config.TestGenesisBlock.Hash())
+ }
+ return nil
+}
+
+// CreatePoW creates the required type of PoW instance for an Ethereum service
+func CreatePoW(config *Config) (*ethash.Ethash, error) {
+ switch {
+ case config.PowTest:
+ glog.V(logger.Info).Infof("ethash used in test mode")
+ return ethash.NewForTesting()
+ case config.PowShared:
+ glog.V(logger.Info).Infof("ethash used in shared mode")
+ return ethash.NewShared(), nil
+
+ default:
+ return ethash.New(), nil
+ }
+}
+
// APIs returns the collection of RPC services the ethereum package offers.
// NOTE, some of these services probably need to be moved to somewhere else.
func (s *Ethereum) APIs() []rpc.API {
- return []rpc.API{
+ return append(ethapi.GetAPIs(s.apiBackend, &s.solcPath, &s.solc), []rpc.API{
{
Namespace: "eth",
Version: "1.0",
@@ -290,26 +315,6 @@ func (s *Ethereum) APIs() []rpc.API {
}, {
Namespace: "eth",
Version: "1.0",
- Service: NewPublicAccountAPI(s.accountManager),
- Public: true,
- }, {
- Namespace: "personal",
- Version: "1.0",
- Service: NewPrivateAccountAPI(s),
- Public: false,
- }, {
- Namespace: "eth",
- Version: "1.0",
- Service: NewPublicBlockChainAPI(s.chainConfig, s.blockchain, s.miner, s.chainDb, s.gpo, s.eventMux, s.accountManager),
- Public: true,
- }, {
- Namespace: "eth",
- Version: "1.0",
- Service: NewPublicTransactionPoolAPI(s),
- Public: true,
- }, {
- Namespace: "eth",
- Version: "1.0",
Service: NewPublicMinerAPI(s),
Public: true,
}, {
@@ -323,11 +328,6 @@ func (s *Ethereum) APIs() []rpc.API {
Service: NewPrivateMinerAPI(s),
Public: false,
}, {
- Namespace: "txpool",
- Version: "1.0",
- Service: NewPublicTxPoolAPI(s),
- Public: true,
- }, {
Namespace: "eth",
Version: "1.0",
Service: filters.NewPublicFilterAPI(s.chainDb, s.eventMux),
@@ -355,7 +355,7 @@ func (s *Ethereum) APIs() []rpc.API {
Version: "1.0",
Service: ethreg.NewPrivateRegistarAPI(s.chainConfig, s.blockchain, s.chainDb, s.txPool, s.accountManager),
},
- }
+ }...)
}
func (s *Ethereum) ResetWithGenesisBlock(gb *types.Block) {
@@ -388,6 +388,7 @@ func (s *Ethereum) AccountManager() *accounts.Manager { return s.accountManager
func (s *Ethereum) BlockChain() *core.BlockChain { return s.blockchain }
func (s *Ethereum) TxPool() *core.TxPool { return s.txPool }
func (s *Ethereum) EventMux() *event.TypeMux { return s.eventMux }
+func (s *Ethereum) Pow() *ethash.Ethash { return s.pow }
func (s *Ethereum) ChainDb() ethdb.Database { return s.chainDb }
func (s *Ethereum) DappDb() ethdb.Database { return s.dappDb }
func (s *Ethereum) IsListening() bool { return true } // Always listening
@@ -404,11 +405,11 @@ func (s *Ethereum) Protocols() []p2p.Protocol {
// Start implements node.Service, starting all internal goroutines needed by the
// Ethereum protocol implementation.
func (s *Ethereum) Start(srvr *p2p.Server) error {
+ s.netRPCService = ethapi.NewPublicNetAPI(srvr, s.NetVersion())
if s.AutoDAG {
s.StartAutoDAG()
}
s.protocolManager.Start()
- s.netRPCService = NewPublicNetAPI(srvr, s.NetVersion())
return nil
}
@@ -507,21 +508,6 @@ func (self *Ethereum) HTTPClient() *httpclient.HTTPClient {
return self.httpclient
}
-func (self *Ethereum) Solc() (*compiler.Solidity, error) {
- var err error
- if self.solc == nil {
- self.solc, err = compiler.New(self.SolcPath)
- }
- return self.solc, err
-}
-
-// set in js console via admin interface or wrapper from cli flags
-func (self *Ethereum) SetSolc(solcPath string) (*compiler.Solidity, error) {
- self.SolcPath = solcPath
- self.solc = nil
- return self.Solc()
-}
-
// dagFiles(epoch) returns the two alternative DAG filenames (not a path)
// 1) <revision>-<hex(seedhash[8])> 2) full-R<revision>-<hex(seedhash[8])>
func dagFiles(epoch uint64) (string, string) {