Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor payload building #3592

Merged
merged 16 commits into from
Feb 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion cmd/rpcdaemon/commands/engine_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,9 @@ func (e *EngineImpl) GetPayloadV1(ctx context.Context, payloadID hexutil.Bytes)
}, nil
}

// Gets a transistionConfiguration and pings the execution layer and checks if the execution layer has the correct configurations
// Receives consensus layer's transition configuration and checks if the execution layer has the correct configuration.
// Can also be used to ping the execution layer (heartbeats).
// See https://github.com/ethereum/execution-apis/blob/v1.0.0-alpha.7/src/engine/specification.md#engine_exchangetransitionconfigurationv1
func (e *EngineImpl) ExchangeTransitionConfigurationV1(ctx context.Context, beaconConfig TransitionConfiguration) (TransitionConfiguration, error) {
tx, err := e.db.BeginRo(ctx)

Expand Down
11 changes: 11 additions & 0 deletions core/block_proposer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package core

import "github.com/ledgerwatch/erigon/common"

// See https://github.com/ethereum/execution-apis/blob/main/src/engine/specification.md#payloadattributesv1
type BlockProposerParametersPOS struct {
ParentHash common.Hash
Timestamp uint64
PrevRandao common.Hash
SuggestedFeeRecipient common.Address
}
62 changes: 37 additions & 25 deletions core/chain_makers.go
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,33 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
return &ChainPack{Length: n, Headers: headers, Blocks: blocks, Receipts: receipts, TopBlock: blocks[n-1]}, nil
}

func MakeEmptyHeader(parent *types.Header, chainConfig *params.ChainConfig, timestamp uint64, targetGasLimit *uint64) *types.Header {
header := &types.Header{
Root: parent.Root,
ParentHash: parent.Hash(),
Number: new(big.Int).Add(parent.Number, common.Big1),
Difficulty: common.Big0,
Time: timestamp,
}

parentGasLimit := parent.GasLimit
// Set baseFee and GasLimit if we are on an EIP-1559 chain
if chainConfig.IsLondon(header.Number.Uint64()) {
header.Eip1559 = true
header.BaseFee = misc.CalcBaseFee(chainConfig, parent)
if !chainConfig.IsLondon(parent.Number.Uint64()) {
parentGasLimit = parent.GasLimit * params.ElasticityMultiplier
}
}
if targetGasLimit != nil {
header.GasLimit = CalcGasLimit(parentGasLimit, *targetGasLimit)
} else {
header.GasLimit = parentGasLimit
}

return header
}

func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.IntraBlockState, engine consensus.Engine) *types.Header {
var time uint64
if parent.Time() == 0 {
Expand All @@ -404,32 +431,17 @@ func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.I
time = parent.Time() + 10 // block time is fixed at 10 seconds
}

header := &types.Header{
Root: common.Hash{},
ParentHash: parent.Hash(),
Coinbase: parent.Coinbase(),
Difficulty: engine.CalcDifficulty(chain, time,
time-10,
parent.Difficulty(),
parent.NumberU64(),
parent.Hash(),
parent.UncleHash(),
parent.Seal(),
),
GasLimit: CalcGasLimit(parent.GasLimit(), parent.GasLimit()),
Number: new(big.Int).Add(parent.Number(), common.Big1),
Time: time,
}
header := MakeEmptyHeader(parent.Header(), chain.Config(), time, nil)
header.Coinbase = parent.Coinbase()
header.Difficulty = engine.CalcDifficulty(chain, time,
time-10,
parent.Difficulty(),
parent.NumberU64(),
parent.Hash(),
parent.UncleHash(),
parent.Seal(),
)
header.Seal = engine.GenerateSeal(chain, header, parent.Header(), nil)

if chain.Config().IsLondon(header.Number.Uint64()) {
header.BaseFee = misc.CalcBaseFee(chain.Config(), parent.Header())
header.Eip1559 = true
if !chain.Config().IsLondon(parent.NumberU64()) {
parentGasLimit := parent.GasLimit() * params.ElasticityMultiplier
header.GasLimit = CalcGasLimit(parentGasLimit, parentGasLimit)
}
}
header.WithSeal = chain.Config().IsHeaderWithSeal()

return header
Expand Down
1 change: 1 addition & 0 deletions core/types/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -958,6 +958,7 @@ func NewBlock(header *Header, txs []Transaction, uncles []*Header, receipts []*R

if len(receipts) == 0 {
b.header.ReceiptHash = EmptyRootHash
b.header.Bloom = Bloom{}
} else {
b.header.ReceiptHash = DeriveSha(Receipts(receipts))
b.header.Bloom = CreateBloom(receipts)
Expand Down
10 changes: 3 additions & 7 deletions eth/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -395,16 +395,12 @@ func New(stack *node.Node, config *ethconfig.Config, txpoolCfg txpool2.Config, l
ethashApi = casted.APIs(nil)[1].Service.(*ethash.API)
}
// proof-of-stake mining
assembleBlockPOS := func(random common.Hash, suggestedFeeRecipient common.Address, timestamp uint64) (*types.Block, error) {
assembleBlockPOS := func(param *core.BlockProposerParametersPOS) (*types.Block, error) {
miningStatePos := stagedsync.NewMiningState(&config.Miner)
miningStatePos.MiningConfig.Etherbase = suggestedFeeRecipient
miningStatePos.MiningConfig.Etherbase = param.SuggestedFeeRecipient
proposingSync := stagedsync.New(
stagedsync.MiningStages(backend.sentryCtx,
stagedsync.StageMiningCreateBlockCfg(backend.chainDB, miningStatePos, *backend.chainConfig, backend.engine, backend.txPool2, backend.txPool2DB, &stagedsync.BlockProposerParametersPOS{
Random: random,
SuggestedFeeRecipient: suggestedFeeRecipient,
Timestamp: timestamp,
}, tmpdir),
stagedsync.StageMiningCreateBlockCfg(backend.chainDB, miningStatePos, *backend.chainConfig, backend.engine, backend.txPool2, backend.txPool2DB, param, tmpdir),
stagedsync.StageMiningExecCfg(backend.chainDB, miningStatePos, backend.notifications.Events, *backend.chainConfig, backend.engine, &vm.Config{}, tmpdir),
stagedsync.StageHashStateCfg(backend.chainDB, tmpdir),
stagedsync.StageTrieCfg(backend.chainDB, false, true, tmpdir, blockReader),
Expand Down
61 changes: 19 additions & 42 deletions eth/stagedsync/stage_mining_create_block.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,16 @@ import (
"math/big"
"time"

"github.com/ledgerwatch/erigon/core/state"

mapset "github.com/deckarep/golang-set"
libcommon "github.com/ledgerwatch/erigon-lib/common"
"github.com/ledgerwatch/erigon-lib/kv"
"github.com/ledgerwatch/erigon-lib/txpool"
"github.com/ledgerwatch/erigon/common"
"github.com/ledgerwatch/erigon/common/debug"
"github.com/ledgerwatch/erigon/consensus"
"github.com/ledgerwatch/erigon/consensus/misc"
"github.com/ledgerwatch/erigon/core"
"github.com/ledgerwatch/erigon/core/rawdb"
"github.com/ledgerwatch/erigon/core/state"
"github.com/ledgerwatch/erigon/core/types"
"github.com/ledgerwatch/erigon/eth/ethutils"
"github.com/ledgerwatch/erigon/params"
Expand Down Expand Up @@ -55,12 +53,6 @@ func NewMiningState(cfg *params.MiningConfig) MiningState {
}
}

type BlockProposerParametersPOS struct {
Random common.Hash
SuggestedFeeRecipient common.Address // For now, we apply a suggested recipient only if etherbase is unset
Timestamp uint64
}

type MiningCreateBlockCfg struct {
db kv.RwDB
miner MiningState
Expand All @@ -69,10 +61,10 @@ type MiningCreateBlockCfg struct {
txPool2 *txpool.TxPool
txPool2DB kv.RoDB
tmpdir string
blockProposerParameters *BlockProposerParametersPOS
blockProposerParameters *core.BlockProposerParametersPOS
}

func StageMiningCreateBlockCfg(db kv.RwDB, miner MiningState, chainConfig params.ChainConfig, engine consensus.Engine, txPool2 *txpool.TxPool, txPool2DB kv.RoDB, blockProposerParameters *BlockProposerParametersPOS, tmpdir string) MiningCreateBlockCfg {
func StageMiningCreateBlockCfg(db kv.RwDB, miner MiningState, chainConfig params.ChainConfig, engine consensus.Engine, txPool2 *txpool.TxPool, txPool2DB kv.RoDB, blockProposerParameters *core.BlockProposerParametersPOS, tmpdir string) MiningCreateBlockCfg {
return MiningCreateBlockCfg{
db: db,
miner: miner,
Expand Down Expand Up @@ -105,7 +97,11 @@ func SpawnMiningCreateBlockStage(s *StageState, tx kv.RwTx, cfg MiningCreateBloc
}
parent := rawdb.ReadHeaderByNumber(tx, executionAt)
if parent == nil { // todo: how to return error and don't stop Erigon?
return fmt.Errorf(fmt.Sprintf("[%s] Empty block", logPrefix), "blocknum", executionAt)
return fmt.Errorf("empty block %d", executionAt)
}

if cfg.blockProposerParameters != nil && cfg.blockProposerParameters.ParentHash != parent.Hash() {
return fmt.Errorf("wrong head block: %x (current) vs %x (requested)", parent.Hash(), cfg.blockProposerParameters.ParentHash)
}

isTrans, err := rawdb.Transitioned(tx, executionAt, cfg.chainConfig.TerminalTotalDifficulty)
Expand Down Expand Up @@ -187,40 +183,23 @@ func SpawnMiningCreateBlockStage(s *StageState, tx kv.RwTx, cfg MiningCreateBloc
}

// re-written miner/worker.go:commitNewWork
var timestamp int64
// If we are on proof-of-stake timestamp should be already set for us
var timestamp uint64
if !isTrans {
timestamp = time.Now().Unix()
if parent.Time >= uint64(timestamp) {
timestamp = int64(parent.Time + 1)
timestamp = uint64(time.Now().Unix())
if parent.Time >= timestamp {
timestamp = parent.Time + 1
}
} else {
// If we are on proof-of-stake timestamp should be already set for us
timestamp = cfg.blockProposerParameters.Timestamp
}

num := parent.Number
header := &types.Header{
ParentHash: parent.Hash(),
Number: num.Add(num, common.Big1),
GasLimit: core.CalcGasLimit(parent.GasLimit, cfg.miner.MiningConfig.GasLimit),
Extra: cfg.miner.MiningConfig.ExtraData,
Time: uint64(timestamp),
}
header := core.MakeEmptyHeader(parent, &cfg.chainConfig, timestamp, &cfg.miner.MiningConfig.GasLimit)
header.Coinbase = coinbase
header.Extra = cfg.miner.MiningConfig.ExtraData

// Set baseFee and GasLimit if we are on an EIP-1559 chain
if cfg.chainConfig.IsLondon(header.Number.Uint64()) {
header.Eip1559 = true
header.BaseFee = misc.CalcBaseFee(&cfg.chainConfig, parent)
if !cfg.chainConfig.IsLondon(parent.Number.Uint64()) {
parentGasLimit := parent.GasLimit * params.ElasticityMultiplier
header.GasLimit = core.CalcGasLimit(parentGasLimit, cfg.miner.MiningConfig.GasLimit)
}
}
log.Info(fmt.Sprintf("[%s] Start mine", logPrefix), "block", executionAt+1, "baseFee", header.BaseFee, "gasLimit", header.GasLimit)

// Only set the coinbase if our consensus engine is running (avoid spurious block rewards)
//if w.isRunning() {
header.Coinbase = coinbase
//}

stateReader := state.NewPlainStateReader(tx)
ibs := state.New(stateReader)

Expand All @@ -237,9 +216,7 @@ func SpawnMiningCreateBlockStage(s *StageState, tx kv.RwTx, cfg MiningCreateBloc
}

if isTrans {
// We apply pre-made fields
header.MixDigest = cfg.blockProposerParameters.Random
header.Time = cfg.blockProposerParameters.Timestamp
header.MixDigest = cfg.blockProposerParameters.PrevRandao

current.Header = header
current.Uncles = nil
Expand Down
Loading