// Copyright 2014 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
// Package eth implements the Ethereum protocol.
package eth
import (
"errors"
"fmt"
"math/big"
"runtime"
"sync"
"sync/atomic"
"github.com/ava-labs/coreth/consensus/dummy"
mycore "github.com/ava-labs/coreth/core"
"github.com/ava-labs/coreth/internal/ethapi"
"github.com/ava-labs/coreth/miner"
"github.com/ava-labs/coreth/node"
"github.com/ava-labs/go-ethereum/accounts"
"github.com/ava-labs/go-ethereum/accounts/abi/bind"
"github.com/ava-labs/go-ethereum/common"
"github.com/ava-labs/go-ethereum/common/hexutil"
"github.com/ava-labs/go-ethereum/consensus"
"github.com/ava-labs/go-ethereum/consensus/clique"
"github.com/ava-labs/go-ethereum/consensus/ethash"
"github.com/ava-labs/go-ethereum/core"
"github.com/ava-labs/go-ethereum/core/bloombits"
"github.com/ava-labs/go-ethereum/core/rawdb"
"github.com/ava-labs/go-ethereum/core/types"
"github.com/ava-labs/go-ethereum/core/vm"
"github.com/ava-labs/go-ethereum/eth/downloader"
"github.com/ava-labs/go-ethereum/eth/filters"
"github.com/ava-labs/go-ethereum/eth/gasprice"
"github.com/ava-labs/go-ethereum/ethdb"
"github.com/ava-labs/go-ethereum/event"
"github.com/ava-labs/go-ethereum/log"
"github.com/ava-labs/go-ethereum/p2p"
"github.com/ava-labs/go-ethereum/p2p/enr"
"github.com/ava-labs/go-ethereum/params"
"github.com/ava-labs/go-ethereum/rlp"
"github.com/ava-labs/go-ethereum/rpc"
)
type LesServer interface {
Start(srvr *p2p.Server)
Stop()
APIs() []rpc.API
Protocols() []p2p.Protocol
SetBloomBitsIndexer(bbIndexer *core.ChainIndexer)
SetContractBackend(bind.ContractBackend)
}
// Ethereum implements the Ethereum full node service.
type Ethereum struct {
config *Config
// Channel for shutting down the service
shutdownChan chan bool
server *p2p.Server
// Handlers
txPool *core.TxPool
blockchain *core.BlockChain
protocolManager *ProtocolManager
lesServer LesServer
// DB interfaces
chainDb ethdb.Database // Block chain database
eventMux *event.TypeMux
engine consensus.Engine
accountManager *accounts.Manager
bloomRequests chan chan *bloombits.Retrieval // Channel receiving bloom data retrieval requests
bloomIndexer *core.ChainIndexer // Bloom indexer operating during block imports
APIBackend *EthAPIBackend
miner *miner.Miner
gasPrice *big.Int
etherbase common.Address
networkID uint64
netRPCService *ethapi.PublicNetAPI
lock sync.RWMutex // Protects the variadic fields (e.g. gas price and etherbase)
txSubmitChan chan struct{}
}
func (s *Ethereum) AddLesServer(ls LesServer) {
s.lesServer = ls
ls.SetBloomBitsIndexer(s.bloomIndexer)
}
// SetClient sets a rpc client which connecting to our local node.
func (s *Ethereum) SetContractBackend(backend bind.ContractBackend) {
// Pass the rpc client to les server if it is enabled.
if s.lesServer != nil {
s.lesServer.SetContractBackend(backend)
}
}
// New creates a new Ethereum object (including the
// initialisation of the common Ethereum object)
func New(ctx *node.ServiceContext, config *Config, cb *dummy.ConsensusCallbacks, mcb *miner.MinerCallbacks) (*Ethereum, error) {
// Ensure configuration values are compatible and sane
if config.SyncMode == downloader.LightSync {
return nil, errors.New("can't run eth.Ethereum in light sync mode, use les.LightEthereum")
}
if !config.SyncMode.IsValid() {
return nil, fmt.Errorf("invalid sync mode %d", config.SyncMode)
}
if config.Miner.GasPrice == nil || config.Miner.GasPrice.Cmp(common.Big0) <= 0 {
log.Warn("Sanitizing invalid miner gas price", "provided", config.Miner.GasPrice, "updated", DefaultConfig.Miner.GasPrice)
config.Miner.GasPrice = new(big.Int).Set(DefaultConfig.Miner.GasPrice)
}
if config.NoPruning && config.TrieDirtyCache > 0 {
config.TrieCleanCache += config.TrieDirtyCache
config.TrieDirtyCache = 0
}
log.Info("Allocated trie memory caches", "clean", common.StorageSize(config.TrieCleanCache)*1024*1024, "dirty", common.StorageSize(config.TrieDirtyCache)*1024*1024)
// Assemble the Ethereum object
chainDb, err := ctx.OpenDatabaseWithFreezer("chaindata", config.DatabaseCache, config.DatabaseHandles, config.DatabaseFreezer, "eth/db/chaindata/")
if err != nil {
return nil, err
}
chainConfig, genesisHash, genesisErr := mycore.SetupGenesisBlock(chainDb, config.Genesis)
if _, ok := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !ok {
return nil, genesisErr
}
log.Info("Initialised chain configuration", "config", chainConfig)
eth := &Ethereum{
config: config,
chainDb: chainDb,
eventMux: ctx.EventMux,
accountManager: ctx.AccountManager,
engine: CreateConsensusEngine(ctx, chainConfig, &config.Ethash, config.Miner.Notify, config.Miner.Noverify, chainDb, cb),
shutdownChan: make(chan bool),
networkID: config.NetworkId,
gasPrice: