Skip to content

Commit a7b9e48

Browse files
authored
consensus, core, ethstats: use engine specific block beneficiary (ethereum#14318)
* consensus, core, ethstats: use engine specific block beneficiary * core, eth, les, miner: use explicit beneficiary during mining
1 parent 6b7ae4e commit a7b9e48

File tree

18 files changed

+76
-26
lines changed

18 files changed

+76
-26
lines changed

accounts/abi/bind/backends/simulated.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM
248248
// Execute the call.
249249
msg := callmsg{call}
250250

251-
evmContext := core.NewEVMContext(msg, block.Header(), b.blockchain)
251+
evmContext := core.NewEVMContext(msg, block.Header(), b.blockchain, nil)
252252
// Create a new environment which holds all relevant information
253253
// about the transaction and calling mechanisms.
254254
vmenv := vm.NewEVM(evmContext, statedb, b.config, vm.Config{})

consensus/clique/clique.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,12 @@ func New(config *params.CliqueConfig, db ethdb.Database) *Clique {
220220
}
221221
}
222222

223+
// Author implements consensus.Engine, returning the Ethereum address recovered
224+
// from the signature in the header's extra-data section.
225+
func (c *Clique) Author(header *types.Header) (common.Address, error) {
226+
return ecrecover(header)
227+
}
228+
223229
// VerifyHeader checks whether a header conforms to the consensus rules.
224230
func (c *Clique) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error {
225231
return c.verifyHeader(chain, header, nil)

consensus/consensus.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ type ChainReader interface {
4949

5050
// Engine is an algorithm agnostic consensus engine.
5151
type Engine interface {
52+
// Author retrieves the Ethereum address of the account that minted the given
53+
// block, which may be different from the header's coinbase if a consensus
54+
// engine is based on signatures.
55+
Author(header *types.Header) (common.Address, error)
56+
5257
// VerifyHeader checks whether a header conforms to the consensus rules of a
5358
// given engine. Verifying the seal may be done optionally here, or explicitly
5459
// via the VerifySeal method.

consensus/ethash/consensus.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ var (
5959
errInvalidPoW = errors.New("invalid proof-of-work")
6060
)
6161

62+
// Author implements consensus.Engine, returning the header's coinbase as the
63+
// proof-of-work verified author of the block.
64+
func (ethash *Ethash) Author(header *types.Header) (common.Address, error) {
65+
return header.Coinbase, nil
66+
}
67+
6268
// VerifyHeader checks whether a header conforms to the consensus rules of the
6369
// stock Ethereum ethash engine.
6470
func (ethash *Ethash) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error {

core/blockchain.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1398,3 +1398,6 @@ func (self *BlockChain) GetHeaderByNumber(number uint64) *types.Header {
13981398

13991399
// Config retrieves the blockchain's chain configuration.
14001400
func (self *BlockChain) Config() *params.ChainConfig { return self.config }
1401+
1402+
// Engine retrieves the blockchain's consensus engine.
1403+
func (self *BlockChain) Engine() consensus.Engine { return self.engine }

core/chain_makers.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ func (b *BlockGen) AddTx(tx *types.Transaction) {
8585
b.SetCoinbase(common.Address{})
8686
}
8787
b.statedb.StartRecord(tx.Hash(), common.Hash{}, len(b.txs))
88-
receipt, _, err := ApplyTransaction(b.config, nil, b.gasPool, b.statedb, b.header, tx, b.header.GasUsed, vm.Config{})
88+
receipt, _, err := ApplyTransaction(b.config, nil, &b.header.Coinbase, b.gasPool, b.statedb, b.header, tx, b.header.GasUsed, vm.Config{})
8989
if err != nil {
9090
panic(err)
9191
}

core/evm.go

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,25 +20,36 @@ import (
2020
"math/big"
2121

2222
"github.com/ethereum/go-ethereum/common"
23+
"github.com/ethereum/go-ethereum/consensus"
2324
"github.com/ethereum/go-ethereum/core/types"
2425
"github.com/ethereum/go-ethereum/core/vm"
2526
)
2627

27-
// BlockFetcher retrieves headers by their hash
28-
type HeaderFetcher interface {
29-
// GetHeader returns the hash corresponding to their hash
28+
// ChainContext supports retrieving headers and consensus parameters from the
29+
// current blockchain to be used during transaction processing.
30+
type ChainContext interface {
31+
// Engine retrieves the chain's consensus engine.
32+
Engine() consensus.Engine
33+
34+
// GetHeader returns the hash corresponding to their hash.
3035
GetHeader(common.Hash, uint64) *types.Header
3136
}
3237

3338
// NewEVMContext creates a new context for use in the EVM.
34-
func NewEVMContext(msg Message, header *types.Header, chain HeaderFetcher) vm.Context {
39+
func NewEVMContext(msg Message, header *types.Header, chain ChainContext, author *common.Address) vm.Context {
40+
// If we don't have an explicit author (i.e. not mining), extract from the header
41+
var beneficiary common.Address
42+
if author == nil {
43+
beneficiary, _ = chain.Engine().Author(header) // Ignore error, we're past header validation
44+
} else {
45+
beneficiary = *author
46+
}
3547
return vm.Context{
3648
CanTransfer: CanTransfer,
3749
Transfer: Transfer,
3850
GetHash: GetHashFn(header, chain),
39-
4051
Origin: msg.From(),
41-
Coinbase: header.Coinbase,
52+
Coinbase: beneficiary,
4253
BlockNumber: new(big.Int).Set(header.Number),
4354
Time: new(big.Int).Set(header.Time),
4455
Difficulty: new(big.Int).Set(header.Difficulty),
@@ -48,7 +59,7 @@ func NewEVMContext(msg Message, header *types.Header, chain HeaderFetcher) vm.Co
4859
}
4960

5061
// GetHashFn returns a GetHashFunc which retrieves header hashes by number
51-
func GetHashFn(ref *types.Header, chain HeaderFetcher) func(n uint64) common.Hash {
62+
func GetHashFn(ref *types.Header, chain ChainContext) func(n uint64) common.Hash {
5263
return func(n uint64) common.Hash {
5364
for header := chain.GetHeader(ref.ParentHash, ref.Number.Uint64()-1); header != nil; header = chain.GetHeader(header.ParentHash, header.Number.Uint64()-1) {
5465
if header.Number.Uint64() == n {

core/headerchain.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,9 @@ func (hc *HeaderChain) SetGenesis(head *types.Header) {
442442
// Config retrieves the header chain's chain configuration.
443443
func (hc *HeaderChain) Config() *params.ChainConfig { return hc.config }
444444

445+
// Engine retrieves the header chain's consensus engine.
446+
func (hc *HeaderChain) Engine() consensus.Engine { return hc.engine }
447+
445448
// GetBlock implements consensus.ChainReader, and returns nil for every input as
446449
// a header chain does not have blocks available for retrieval.
447450
func (hc *HeaderChain) GetBlock(hash common.Hash, number uint64) *types.Block {

core/state_processor.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package core
1919
import (
2020
"math/big"
2121

22+
"github.com/ethereum/go-ethereum/common"
2223
"github.com/ethereum/go-ethereum/consensus"
2324
"github.com/ethereum/go-ethereum/consensus/misc"
2425
"github.com/ethereum/go-ethereum/core/state"
@@ -69,7 +70,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
6970
// Iterate over and process the individual transactions
7071
for i, tx := range block.Transactions() {
7172
statedb.StartRecord(tx.Hash(), block.Hash(), i)
72-
receipt, _, err := ApplyTransaction(p.config, p.bc, gp, statedb, header, tx, totalUsedGas, cfg)
73+
receipt, _, err := ApplyTransaction(p.config, p.bc, nil, gp, statedb, header, tx, totalUsedGas, cfg)
7374
if err != nil {
7475
return nil, nil, nil, err
7576
}
@@ -86,13 +87,13 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
8687
// and uses the input parameters for its environment. It returns the receipt
8788
// for the transaction, gas used and an error if the transaction failed,
8889
// indicating the block was invalid.
89-
func ApplyTransaction(config *params.ChainConfig, bc *BlockChain, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *big.Int, cfg vm.Config) (*types.Receipt, *big.Int, error) {
90+
func ApplyTransaction(config *params.ChainConfig, bc *BlockChain, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *big.Int, cfg vm.Config) (*types.Receipt, *big.Int, error) {
9091
msg, err := tx.AsMessage(types.MakeSigner(config, header.Number))
9192
if err != nil {
9293
return nil, nil, err
9394
}
9495
// Create a new context to be used in the EVM environment
95-
context := NewEVMContext(msg, header, bc)
96+
context := NewEVMContext(msg, header, bc, author)
9697
// Create a new environment which holds all relevant information
9798
// about the transaction and calling mechanisms.
9899
vmenv := vm.NewEVM(context, statedb, config, cfg)

eth/api.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,7 @@ func (api *PrivateDebugAPI) TraceTransaction(ctx context.Context, txHash common.
548548
if err != nil {
549549
return nil, fmt.Errorf("sender retrieval failed: %v", err)
550550
}
551-
context := core.NewEVMContext(msg, block.Header(), api.eth.BlockChain())
551+
context := core.NewEVMContext(msg, block.Header(), api.eth.BlockChain(), nil)
552552

553553
// Mutate the state if we haven't reached the tracing transaction yet
554554
if uint64(idx) < txIndex {

0 commit comments

Comments
 (0)