core, consensus: pluggable consensus engines (#3817)
This commit adds pluggable consensus engines to go-ethereum. In short, it introduces a generic consensus interface, and refactors the entire codebase to use this interface.
This commit is contained in:
committed by
Felix Lange
parent
e50a5b7771
commit
09777952ee
93
eth/api.go
93
eth/api.go
@ -26,7 +26,6 @@ import (
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@ -37,6 +36,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/miner"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
@ -56,18 +56,18 @@ func NewPublicEthereumAPI(e *Ethereum) *PublicEthereumAPI {
|
||||
}
|
||||
|
||||
// Etherbase is the address that mining rewards will be send to
|
||||
func (s *PublicEthereumAPI) Etherbase() (common.Address, error) {
|
||||
return s.e.Etherbase()
|
||||
func (api *PublicEthereumAPI) Etherbase() (common.Address, error) {
|
||||
return api.e.Etherbase()
|
||||
}
|
||||
|
||||
// Coinbase is the address that mining rewards will be send to (alias for Etherbase)
|
||||
func (s *PublicEthereumAPI) Coinbase() (common.Address, error) {
|
||||
return s.Etherbase()
|
||||
func (api *PublicEthereumAPI) Coinbase() (common.Address, error) {
|
||||
return api.Etherbase()
|
||||
}
|
||||
|
||||
// Hashrate returns the POW hashrate
|
||||
func (s *PublicEthereumAPI) Hashrate() hexutil.Uint64 {
|
||||
return hexutil.Uint64(s.e.Miner().HashRate())
|
||||
func (api *PublicEthereumAPI) Hashrate() hexutil.Uint64 {
|
||||
return hexutil.Uint64(api.e.Miner().HashRate())
|
||||
}
|
||||
|
||||
// PublicMinerAPI provides an API to control the miner.
|
||||
@ -79,34 +79,34 @@ type PublicMinerAPI struct {
|
||||
|
||||
// NewPublicMinerAPI create a new PublicMinerAPI instance.
|
||||
func NewPublicMinerAPI(e *Ethereum) *PublicMinerAPI {
|
||||
agent := miner.NewRemoteAgent(e.Pow())
|
||||
agent := miner.NewRemoteAgent(e.BlockChain(), e.Engine())
|
||||
e.Miner().Register(agent)
|
||||
|
||||
return &PublicMinerAPI{e, agent}
|
||||
}
|
||||
|
||||
// Mining returns an indication if this node is currently mining.
|
||||
func (s *PublicMinerAPI) Mining() bool {
|
||||
return s.e.IsMining()
|
||||
func (api *PublicMinerAPI) Mining() bool {
|
||||
return api.e.IsMining()
|
||||
}
|
||||
|
||||
// SubmitWork can be used by external miner to submit their POW solution. It returns an indication if the work was
|
||||
// accepted. Note, this is not an indication if the provided work was valid!
|
||||
func (s *PublicMinerAPI) SubmitWork(nonce types.BlockNonce, solution, digest common.Hash) bool {
|
||||
return s.agent.SubmitWork(nonce, digest, solution)
|
||||
func (api *PublicMinerAPI) SubmitWork(nonce types.BlockNonce, solution, digest common.Hash) bool {
|
||||
return api.agent.SubmitWork(nonce, digest, solution)
|
||||
}
|
||||
|
||||
// GetWork returns a work package for external miner. The work package consists of 3 strings
|
||||
// result[0], 32 bytes hex encoded current block header pow-hash
|
||||
// result[1], 32 bytes hex encoded seed hash used for DAG
|
||||
// result[2], 32 bytes hex encoded boundary condition ("target"), 2^256/difficulty
|
||||
func (s *PublicMinerAPI) GetWork() ([3]string, error) {
|
||||
if !s.e.IsMining() {
|
||||
if err := s.e.StartMining(0); err != nil {
|
||||
func (api *PublicMinerAPI) GetWork() ([3]string, error) {
|
||||
if !api.e.IsMining() {
|
||||
if err := api.e.StartMining(); err != nil {
|
||||
return [3]string{}, err
|
||||
}
|
||||
}
|
||||
work, err := s.agent.GetWork()
|
||||
work, err := api.agent.GetWork()
|
||||
if err != nil {
|
||||
return work, fmt.Errorf("mining not ready: %v", err)
|
||||
}
|
||||
@ -116,8 +116,8 @@ func (s *PublicMinerAPI) GetWork() ([3]string, error) {
|
||||
// SubmitHashrate can be used for remote miners to submit their hash rate. This enables the node to report the combined
|
||||
// hash rate of all miners which submit work through this node. It accepts the miner hash rate and an identifier which
|
||||
// must be unique between nodes.
|
||||
func (s *PublicMinerAPI) SubmitHashrate(hashrate hexutil.Uint64, id common.Hash) bool {
|
||||
s.agent.SubmitHashrate(id, uint64(hashrate))
|
||||
func (api *PublicMinerAPI) SubmitHashrate(hashrate hexutil.Uint64, id common.Hash) bool {
|
||||
api.agent.SubmitHashrate(id, uint64(hashrate))
|
||||
return true
|
||||
}
|
||||
|
||||
@ -132,47 +132,59 @@ func NewPrivateMinerAPI(e *Ethereum) *PrivateMinerAPI {
|
||||
return &PrivateMinerAPI{e: e}
|
||||
}
|
||||
|
||||
// Start the miner with the given number of threads. If threads is nil the number of
|
||||
// workers started is equal to the number of logical CPU's that are usable by this process.
|
||||
func (s *PrivateMinerAPI) Start(threads *int) (bool, error) {
|
||||
var err error
|
||||
if threads == nil {
|
||||
err = s.e.StartMining(runtime.NumCPU())
|
||||
} else {
|
||||
err = s.e.StartMining(*threads)
|
||||
// Start the miner with the given number of threads. If threads is nil the number
|
||||
// of workers started is equal to the number of logical CPUs that are usable by
|
||||
// this process. If mining is already running, this method adjust the number of
|
||||
// threads allowed to use.
|
||||
func (api *PrivateMinerAPI) Start(threads *int) error {
|
||||
// Set the number of threads if the seal engine supports it
|
||||
if threads != nil {
|
||||
type threaded interface {
|
||||
SetThreads(threads int)
|
||||
}
|
||||
if th, ok := api.e.engine.(threaded); ok {
|
||||
log.Info("Updated mining threads", "threads", *threads)
|
||||
th.SetThreads(*threads)
|
||||
} else {
|
||||
log.Warn("Current seal engine isn't threaded")
|
||||
}
|
||||
}
|
||||
return err == nil, err
|
||||
// Start the miner and return
|
||||
if !api.e.IsMining() {
|
||||
return api.e.StartMining()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Stop the miner
|
||||
func (s *PrivateMinerAPI) Stop() bool {
|
||||
s.e.StopMining()
|
||||
func (api *PrivateMinerAPI) Stop() bool {
|
||||
api.e.StopMining()
|
||||
return true
|
||||
}
|
||||
|
||||
// SetExtra sets the extra data string that is included when this miner mines a block.
|
||||
func (s *PrivateMinerAPI) SetExtra(extra string) (bool, error) {
|
||||
if err := s.e.Miner().SetExtra([]byte(extra)); err != nil {
|
||||
func (api *PrivateMinerAPI) SetExtra(extra string) (bool, error) {
|
||||
if err := api.e.Miner().SetExtra([]byte(extra)); err != nil {
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// SetGasPrice sets the minimum accepted gas price for the miner.
|
||||
func (s *PrivateMinerAPI) SetGasPrice(gasPrice hexutil.Big) bool {
|
||||
s.e.Miner().SetGasPrice((*big.Int)(&gasPrice))
|
||||
func (api *PrivateMinerAPI) SetGasPrice(gasPrice hexutil.Big) bool {
|
||||
api.e.Miner().SetGasPrice((*big.Int)(&gasPrice))
|
||||
return true
|
||||
}
|
||||
|
||||
// SetEtherbase sets the etherbase of the miner
|
||||
func (s *PrivateMinerAPI) SetEtherbase(etherbase common.Address) bool {
|
||||
s.e.SetEtherbase(etherbase)
|
||||
func (api *PrivateMinerAPI) SetEtherbase(etherbase common.Address) bool {
|
||||
api.e.SetEtherbase(etherbase)
|
||||
return true
|
||||
}
|
||||
|
||||
// GetHashrate returns the current hashrate of the miner.
|
||||
func (s *PrivateMinerAPI) GetHashrate() uint64 {
|
||||
return uint64(s.e.miner.HashRate())
|
||||
func (api *PrivateMinerAPI) GetHashrate() uint64 {
|
||||
return uint64(api.e.miner.HashRate())
|
||||
}
|
||||
|
||||
// PrivateAdminAPI is the collection of Etheruem full node-related APIs
|
||||
@ -321,7 +333,7 @@ type TraceArgs struct {
|
||||
Timeout *string
|
||||
}
|
||||
|
||||
// TraceBlock processes the given block's RLP but does not import the block in to
|
||||
// TraceBlock processes the given block'api RLP but does not import the block in to
|
||||
// the chain.
|
||||
func (api *PrivateDebugAPI) TraceBlock(blockRlp []byte, config *vm.LogConfig) BlockTraceResult {
|
||||
var block types.Block
|
||||
@ -338,7 +350,7 @@ func (api *PrivateDebugAPI) TraceBlock(blockRlp []byte, config *vm.LogConfig) Bl
|
||||
}
|
||||
}
|
||||
|
||||
// TraceBlockFromFile loads the block's RLP from the given file name and attempts to
|
||||
// TraceBlockFromFile loads the block'api RLP from the given file name and attempts to
|
||||
// process it but does not import the block in to the chain.
|
||||
func (api *PrivateDebugAPI) TraceBlockFromFile(file string, config *vm.LogConfig) BlockTraceResult {
|
||||
blockRlp, err := ioutil.ReadFile(file)
|
||||
@ -395,8 +407,7 @@ func (api *PrivateDebugAPI) traceBlock(block *types.Block, logConfig *vm.LogConf
|
||||
Debug: true,
|
||||
Tracer: structLogger,
|
||||
}
|
||||
|
||||
if err := core.ValidateHeader(api.config, blockchain.AuxValidator(), block.Header(), blockchain.GetHeader(block.ParentHash(), block.NumberU64()-1), true, false); err != nil {
|
||||
if err := api.eth.engine.VerifyHeader(blockchain, block.Header(), true); err != nil {
|
||||
return false, structLogger.StructLogs(), err
|
||||
}
|
||||
statedb, err := blockchain.StateAt(blockchain.GetBlock(block.ParentHash(), block.NumberU64()-1).Root())
|
||||
|
Reference in New Issue
Block a user