I assumed the coinbase could be altered from Prepare, so that transaction fees could be paid out to a custom coinbase. But, it seems like worker.go simply ignores the header.Coinbase after calling engine.Prepare, and instead sets coinbase using genParams.coinbase. I wanted to ask, is there any way to set a custom coinbase, or if not, what is the rationale for not allowing it? (as simply using header.Coinbase instead of genParams.coinbase would allow it... ) This question applies to Geth traditional codebase and may not apply to the changes made in the past few months (I'm not entirely up to date but I assume lots may be changing for "ethereum 2.0". )
1 Answer
Traditionally, the consensus engine interface does not allow changing coinbase during block production, as far as I can see. This may have changed recently ("post-merge"). Traditionally, block validation could use a custom coinbase via the Author
method in consensus engine interface. It does not have to be set via header.Coinbase
, and this allows Clique to use coinbase field for other things (perhaps rationale for why Author
method was added. ) But during block production, the coinbase is set via the minerAPI SetEtherbase
and this cannot be overridden from consensus engine interface (it can be set manually by the validator, but not from Go code within consensus engine interface. )
The custom coinbase during block validation, relevant code below should be beneficiary, _ = chain.Engine().Author(header)
, and NewEVMBlockContext
is called from Process
method in state_processor.go.
func NewEVMBlockContext(header *types.Header, chain ChainContext, author *common.Address, params *params.ChainConfig) vm.BlockContext {
var (
beneficiary common.Address
baseFee *big.Int
blobBaseFee *big.Int
random *common.Hash
)
// If we don't have an explicit author (i.e. not mining), extract from the header
if author == nil {
beneficiary, _ = chain.Engine().Author(header) // Ignore error, we're past header validation
} else {
beneficiary = *author
}
[...]
Coinbase: beneficiary