mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 15:16:43 +00:00
consensus, core, ethstats: use engine specific block beneficiary
This commit is contained in:
parent
9de257505b
commit
4fca35e2eb
10 changed files with 55 additions and 8 deletions
|
|
@ -220,6 +220,12 @@ func New(config *params.CliqueConfig, db ethdb.Database) *Clique {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Author implements consensus.Engine, returning the Ethereum address recovered
|
||||||
|
// from the signature in the header's extra-data section.
|
||||||
|
func (c *Clique) Author(header *types.Header) (common.Address, error) {
|
||||||
|
return ecrecover(header)
|
||||||
|
}
|
||||||
|
|
||||||
// VerifyHeader checks whether a header conforms to the consensus rules.
|
// VerifyHeader checks whether a header conforms to the consensus rules.
|
||||||
func (c *Clique) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error {
|
func (c *Clique) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error {
|
||||||
return c.verifyHeader(chain, header, nil)
|
return c.verifyHeader(chain, header, nil)
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,11 @@ type ChainReader interface {
|
||||||
|
|
||||||
// Engine is an algorithm agnostic consensus engine.
|
// Engine is an algorithm agnostic consensus engine.
|
||||||
type Engine interface {
|
type Engine interface {
|
||||||
|
// Author retrieves the Ethereum address of the account that minted the given
|
||||||
|
// block, which may be different from the header's coinbase if a consensus
|
||||||
|
// engine is based on signatures.
|
||||||
|
Author(header *types.Header) (common.Address, error)
|
||||||
|
|
||||||
// VerifyHeader checks whether a header conforms to the consensus rules of a
|
// VerifyHeader checks whether a header conforms to the consensus rules of a
|
||||||
// given engine. Verifying the seal may be done optionally here, or explicitly
|
// given engine. Verifying the seal may be done optionally here, or explicitly
|
||||||
// via the VerifySeal method.
|
// via the VerifySeal method.
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,12 @@ var (
|
||||||
errInvalidPoW = errors.New("invalid proof-of-work")
|
errInvalidPoW = errors.New("invalid proof-of-work")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Author implements consensus.Engine, returning the header's coinbase as the
|
||||||
|
// proof-of-work verified author of the block.
|
||||||
|
func (ethash *Ethash) Author(header *types.Header) (common.Address, error) {
|
||||||
|
return header.Coinbase, nil
|
||||||
|
}
|
||||||
|
|
||||||
// VerifyHeader checks whether a header conforms to the consensus rules of the
|
// VerifyHeader checks whether a header conforms to the consensus rules of the
|
||||||
// stock Ethereum ethash engine.
|
// stock Ethereum ethash engine.
|
||||||
func (ethash *Ethash) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error {
|
func (ethash *Ethash) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error {
|
||||||
|
|
|
||||||
|
|
@ -1398,3 +1398,6 @@ func (self *BlockChain) GetHeaderByNumber(number uint64) *types.Header {
|
||||||
|
|
||||||
// Config retrieves the blockchain's chain configuration.
|
// Config retrieves the blockchain's chain configuration.
|
||||||
func (self *BlockChain) Config() *params.ChainConfig { return self.config }
|
func (self *BlockChain) Config() *params.ChainConfig { return self.config }
|
||||||
|
|
||||||
|
// Engine retrieves the blockchain's consensus engine.
|
||||||
|
func (self *BlockChain) Engine() consensus.Engine { return self.engine }
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ func (b *BlockGen) AddTx(tx *types.Transaction) {
|
||||||
b.SetCoinbase(common.Address{})
|
b.SetCoinbase(common.Address{})
|
||||||
}
|
}
|
||||||
b.statedb.StartRecord(tx.Hash(), common.Hash{}, len(b.txs))
|
b.statedb.StartRecord(tx.Hash(), common.Hash{}, len(b.txs))
|
||||||
receipt, _, err := ApplyTransaction(b.config, nil, b.gasPool, b.statedb, b.header, tx, b.header.GasUsed, vm.Config{})
|
receipt, _, err := ApplyTransaction(b.config, &BlockChain{engine: ethash.NewFaker()}, b.gasPool, b.statedb, b.header, tx, b.header.GasUsed, vm.Config{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
21
core/evm.go
21
core/evm.go
|
|
@ -20,25 +20,34 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/consensus"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
)
|
)
|
||||||
|
|
||||||
// BlockFetcher retrieves headers by their hash
|
// ChainContext supports retrieving headers and consensus parameters from the
|
||||||
type HeaderFetcher interface {
|
// current blockchain to be used during transaction processing.
|
||||||
// GetHeader returns the hash corresponding to their hash
|
type ChainContext interface {
|
||||||
|
// Engine retrieves the chain's consensus engine.
|
||||||
|
Engine() consensus.Engine
|
||||||
|
|
||||||
|
// GetHeader returns the hash corresponding to their hash.
|
||||||
GetHeader(common.Hash, uint64) *types.Header
|
GetHeader(common.Hash, uint64) *types.Header
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewEVMContext creates a new context for use in the EVM.
|
// NewEVMContext creates a new context for use in the EVM.
|
||||||
func NewEVMContext(msg Message, header *types.Header, chain HeaderFetcher) vm.Context {
|
func NewEVMContext(msg Message, header *types.Header, chain ChainContext) vm.Context {
|
||||||
|
author, err := chain.Engine().Author(header)
|
||||||
|
if err != nil {
|
||||||
|
// Explicitly ignore, don't crash. Header is invalid.
|
||||||
|
}
|
||||||
return vm.Context{
|
return vm.Context{
|
||||||
CanTransfer: CanTransfer,
|
CanTransfer: CanTransfer,
|
||||||
Transfer: Transfer,
|
Transfer: Transfer,
|
||||||
GetHash: GetHashFn(header, chain),
|
GetHash: GetHashFn(header, chain),
|
||||||
|
|
||||||
Origin: msg.From(),
|
Origin: msg.From(),
|
||||||
Coinbase: header.Coinbase,
|
Coinbase: author,
|
||||||
BlockNumber: new(big.Int).Set(header.Number),
|
BlockNumber: new(big.Int).Set(header.Number),
|
||||||
Time: new(big.Int).Set(header.Time),
|
Time: new(big.Int).Set(header.Time),
|
||||||
Difficulty: new(big.Int).Set(header.Difficulty),
|
Difficulty: new(big.Int).Set(header.Difficulty),
|
||||||
|
|
@ -48,7 +57,7 @@ func NewEVMContext(msg Message, header *types.Header, chain HeaderFetcher) vm.Co
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetHashFn returns a GetHashFunc which retrieves header hashes by number
|
// GetHashFn returns a GetHashFunc which retrieves header hashes by number
|
||||||
func GetHashFn(ref *types.Header, chain HeaderFetcher) func(n uint64) common.Hash {
|
func GetHashFn(ref *types.Header, chain ChainContext) func(n uint64) common.Hash {
|
||||||
return func(n uint64) common.Hash {
|
return func(n uint64) common.Hash {
|
||||||
for header := chain.GetHeader(ref.ParentHash, ref.Number.Uint64()-1); header != nil; header = chain.GetHeader(header.ParentHash, header.Number.Uint64()-1) {
|
for header := chain.GetHeader(ref.ParentHash, ref.Number.Uint64()-1); header != nil; header = chain.GetHeader(header.ParentHash, header.Number.Uint64()-1) {
|
||||||
if header.Number.Uint64() == n {
|
if header.Number.Uint64() == n {
|
||||||
|
|
|
||||||
|
|
@ -442,6 +442,9 @@ func (hc *HeaderChain) SetGenesis(head *types.Header) {
|
||||||
// Config retrieves the header chain's chain configuration.
|
// Config retrieves the header chain's chain configuration.
|
||||||
func (hc *HeaderChain) Config() *params.ChainConfig { return hc.config }
|
func (hc *HeaderChain) Config() *params.ChainConfig { return hc.config }
|
||||||
|
|
||||||
|
// Engine retrieves the header chain's consensus engine.
|
||||||
|
func (hc *HeaderChain) Engine() consensus.Engine { return hc.engine }
|
||||||
|
|
||||||
// GetBlock implements consensus.ChainReader, and returns nil for every input as
|
// GetBlock implements consensus.ChainReader, and returns nil for every input as
|
||||||
// a header chain does not have blocks available for retrieval.
|
// a header chain does not have blocks available for retrieval.
|
||||||
func (hc *HeaderChain) GetBlock(hash common.Hash, number uint64) *types.Block {
|
func (hc *HeaderChain) GetBlock(hash common.Hash, number uint64) *types.Block {
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/consensus"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/eth"
|
"github.com/ethereum/go-ethereum/eth"
|
||||||
|
|
@ -54,6 +55,7 @@ type Service struct {
|
||||||
server *p2p.Server // Peer-to-peer server to retrieve networking infos
|
server *p2p.Server // Peer-to-peer server to retrieve networking infos
|
||||||
eth *eth.Ethereum // Full Ethereum service if monitoring a full node
|
eth *eth.Ethereum // Full Ethereum service if monitoring a full node
|
||||||
les *les.LightEthereum // Light Ethereum service if monitoring a light node
|
les *les.LightEthereum // Light Ethereum service if monitoring a light node
|
||||||
|
engine consensus.Engine // Consensus engine to retrieve variadic block fields
|
||||||
|
|
||||||
node string // Name of the node to display on the monitoring page
|
node string // Name of the node to display on the monitoring page
|
||||||
pass string // Password to authorize access to the monitoring page
|
pass string // Password to authorize access to the monitoring page
|
||||||
|
|
@ -72,9 +74,16 @@ func New(url string, ethServ *eth.Ethereum, lesServ *les.LightEthereum) (*Servic
|
||||||
return nil, fmt.Errorf("invalid netstats url: \"%s\", should be nodename:secret@host:port", url)
|
return nil, fmt.Errorf("invalid netstats url: \"%s\", should be nodename:secret@host:port", url)
|
||||||
}
|
}
|
||||||
// Assemble and return the stats service
|
// Assemble and return the stats service
|
||||||
|
var engine consensus.Engine
|
||||||
|
if ethServ != nil {
|
||||||
|
engine = ethServ.Engine()
|
||||||
|
} else {
|
||||||
|
engine = lesServ.Engine()
|
||||||
|
}
|
||||||
return &Service{
|
return &Service{
|
||||||
eth: ethServ,
|
eth: ethServ,
|
||||||
les: lesServ,
|
les: lesServ,
|
||||||
|
engine: engine,
|
||||||
node: parts[1],
|
node: parts[1],
|
||||||
pass: parts[3],
|
pass: parts[3],
|
||||||
host: parts[4],
|
host: parts[4],
|
||||||
|
|
@ -493,12 +502,14 @@ func (s *Service) assembleBlockStats(block *types.Block) *blockStats {
|
||||||
td = s.les.BlockChain().GetTd(header.Hash(), header.Number.Uint64())
|
td = s.les.BlockChain().GetTd(header.Hash(), header.Number.Uint64())
|
||||||
}
|
}
|
||||||
// Assemble and return the block stats
|
// Assemble and return the block stats
|
||||||
|
author, _ := s.engine.Author(header)
|
||||||
|
|
||||||
return &blockStats{
|
return &blockStats{
|
||||||
Number: header.Number,
|
Number: header.Number,
|
||||||
Hash: header.Hash(),
|
Hash: header.Hash(),
|
||||||
ParentHash: header.ParentHash,
|
ParentHash: header.ParentHash,
|
||||||
Timestamp: header.Time,
|
Timestamp: header.Time,
|
||||||
Miner: header.Coinbase,
|
Miner: author,
|
||||||
GasUsed: new(big.Int).Set(header.GasUsed),
|
GasUsed: new(big.Int).Set(header.GasUsed),
|
||||||
GasLimit: new(big.Int).Set(header.GasLimit),
|
GasLimit: new(big.Int).Set(header.GasLimit),
|
||||||
Diff: header.Difficulty.String(),
|
Diff: header.Difficulty.String(),
|
||||||
|
|
|
||||||
|
|
@ -176,6 +176,7 @@ func (s *LightEthereum) ResetWithGenesisBlock(gb *types.Block) {
|
||||||
|
|
||||||
func (s *LightEthereum) BlockChain() *light.LightChain { return s.blockchain }
|
func (s *LightEthereum) BlockChain() *light.LightChain { return s.blockchain }
|
||||||
func (s *LightEthereum) TxPool() *light.TxPool { return s.txPool }
|
func (s *LightEthereum) TxPool() *light.TxPool { return s.txPool }
|
||||||
|
func (s *LightEthereum) Engine() consensus.Engine { return s.engine }
|
||||||
func (s *LightEthereum) LesVersion() int { return int(s.protocolManager.SubProtocols[0].Version) }
|
func (s *LightEthereum) LesVersion() int { return int(s.protocolManager.SubProtocols[0].Version) }
|
||||||
func (s *LightEthereum) Downloader() *downloader.Downloader { return s.protocolManager.downloader }
|
func (s *LightEthereum) Downloader() *downloader.Downloader { return s.protocolManager.downloader }
|
||||||
func (s *LightEthereum) EventMux() *event.TypeMux { return s.eventMux }
|
func (s *LightEthereum) EventMux() *event.TypeMux { return s.eventMux }
|
||||||
|
|
|
||||||
|
|
@ -213,6 +213,9 @@ func (bc *LightChain) ResetWithGenesisBlock(genesis *types.Block) {
|
||||||
|
|
||||||
// Accessors
|
// Accessors
|
||||||
|
|
||||||
|
// Engine retrieves the light chain's consensus engine.
|
||||||
|
func (bc *LightChain) Engine() consensus.Engine { return bc.engine }
|
||||||
|
|
||||||
// Genesis returns the genesis block
|
// Genesis returns the genesis block
|
||||||
func (bc *LightChain) Genesis() *types.Block {
|
func (bc *LightChain) Genesis() *types.Block {
|
||||||
return bc.genesisBlock
|
return bc.genesisBlock
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue