Skip to content

Commit

Permalink
Engine API and type changes for flat requests in Pectra (#12337)
Browse files Browse the repository at this point in the history
Summary of changes
- Remove `Requests` interface in favour of new `FlatRequest` struct
- Add changes for new `RequestHash` calculation that `sha256` digests
the set of flat requests
- Remove `Requests` from block and body related structs and methods
- Set of requests that gets pulled at the `Finalize` stage is now
returned from there, both for execution and block-building

Ref1: ethereum/execution-apis#591
Ref2: ethereum/EIPs#8854
Ref3: ethereum/EIPs#8924


Needs interface change -
erigontech/interfaces#239

(Tasks board - #12106)
  • Loading branch information
somnathb1 authored Oct 23, 2024
1 parent 3137718 commit 4837639
Show file tree
Hide file tree
Showing 35 changed files with 714 additions and 1,443 deletions.
2 changes: 1 addition & 1 deletion cmd/rpcdaemon/cli/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -1083,7 +1083,7 @@ func (e *remoteConsensusEngine) Prepare(_ consensus.ChainHeaderReader, _ *types.
panic("remoteConsensusEngine.Prepare not supported")
}

func (e *remoteConsensusEngine) Finalize(_ *chain.Config, _ *types.Header, _ *state.IntraBlockState, _ types.Transactions, _ []*types.Header, _ types.Receipts, _ []*types.Withdrawal, _ consensus.ChainReader, _ consensus.SystemCall, _ log.Logger) (types.Transactions, types.Receipts, types.Requests, error) {
func (e *remoteConsensusEngine) Finalize(_ *chain.Config, _ *types.Header, _ *state.IntraBlockState, _ types.Transactions, _ []*types.Header, _ types.Receipts, _ []*types.Withdrawal, _ consensus.ChainReader, _ consensus.SystemCall, _ log.Logger) (types.Transactions, types.Receipts, types.FlatRequests, error) {
panic("remoteConsensusEngine.Finalize not supported")
}

Expand Down
3 changes: 2 additions & 1 deletion cmd/state/commands/opcode_tracer.go
Original file line number Diff line number Diff line change
Expand Up @@ -740,7 +740,8 @@ func runBlock(engine consensus.Engine, ibs *state.IntraBlockState, txnWriter sta
if !vmConfig.ReadOnly {
// Finalize the block, applying any consensus engine specific extras (e.g. block rewards)
tx := block.Transactions()
if _, _, _, err := engine.FinalizeAndAssemble(chainConfig, header, ibs, tx, block.Uncles(), receipts, block.Withdrawals(), nil, nil, nil, nil, logger); err != nil {
if _, _, _, _, err := engine.FinalizeAndAssemble(chainConfig, header, ibs, tx, block.Uncles(), receipts, block.Withdrawals(), nil, nil, nil, nil, logger); err != nil {

return nil, fmt.Errorf("finalize of block %d failed: %w", block.NumberU64(), err)
}

Expand Down
4 changes: 2 additions & 2 deletions cmd/state/exec3/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,9 +233,9 @@ func (rw *Worker) RunTxTaskNoLock(txTask *state.TxTask, isMining bool) {
}

if isMining {
_, txTask.Txs, txTask.BlockReceipts, err = rw.engine.FinalizeAndAssemble(rw.chainConfig, types.CopyHeader(header), ibs, txTask.Txs, txTask.Uncles, txTask.BlockReceipts, txTask.Withdrawals, txTask.Requests, rw.chain, syscall, nil, rw.logger)
_, txTask.Txs, txTask.BlockReceipts, _, err = rw.engine.FinalizeAndAssemble(rw.chainConfig, types.CopyHeader(header), ibs, txTask.Txs, txTask.Uncles, txTask.BlockReceipts, txTask.Withdrawals, nil /*requests */, rw.chain, syscall, nil, rw.logger)
} else {
_, _, _, err = rw.engine.Finalize(rw.chainConfig, types.CopyHeader(header), ibs, txTask.Txs, txTask.Uncles, txTask.BlockReceipts, txTask.Withdrawals, txTask.Requests, rw.chain, syscall, rw.logger)
_, _, _, err = rw.engine.Finalize(rw.chainConfig, types.CopyHeader(header), ibs, txTask.Txs, txTask.Uncles, txTask.BlockReceipts, txTask.Withdrawals, nil /*requests*/, rw.chain, syscall, rw.logger)
}
if err != nil {
txTask.Error = err
Expand Down
10 changes: 5 additions & 5 deletions consensus/aura/aura.go
Original file line number Diff line number Diff line change
Expand Up @@ -706,9 +706,9 @@ func (c *AuRa) applyRewards(header *types.Header, state *state.IntraBlockState,

// word `signal epoch` == word `pending epoch`
func (c *AuRa) Finalize(config *chain.Config, header *types.Header, state *state.IntraBlockState, txs types.Transactions,
uncles []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, requests types.Requests,
uncles []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, requests types.FlatRequests,
chain consensus.ChainReader, syscall consensus.SystemCall, logger log.Logger,
) (types.Transactions, types.Receipts, types.Requests, error) {
) (types.Transactions, types.Receipts, types.FlatRequests, error) {
if err := c.applyRewards(header, state, syscall); err != nil {
return nil, nil, nil, err
}
Expand Down Expand Up @@ -845,14 +845,14 @@ func allHeadersUntil(chain consensus.ChainHeaderReader, from *types.Header, to l
//}

// FinalizeAndAssemble implements consensus.Engine
func (c *AuRa) FinalizeAndAssemble(config *chain.Config, header *types.Header, state *state.IntraBlockState, txs types.Transactions, uncles []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, requests types.Requests, chain consensus.ChainReader, syscall consensus.SystemCall, call consensus.Call, logger log.Logger) (*types.Block, types.Transactions, types.Receipts, error) {
func (c *AuRa) FinalizeAndAssemble(config *chain.Config, header *types.Header, state *state.IntraBlockState, txs types.Transactions, uncles []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, requests types.FlatRequests, chain consensus.ChainReader, syscall consensus.SystemCall, call consensus.Call, logger log.Logger) (*types.Block, types.Transactions, types.Receipts, types.FlatRequests, error) {
outTxs, outReceipts, _, err := c.Finalize(config, header, state, txs, uncles, receipts, withdrawals, requests, chain, syscall, logger)
if err != nil {
return nil, nil, nil, err
return nil, nil, nil, nil, err
}

// Assemble and return the final block for sealing
return types.NewBlockForAsembling(header, outTxs, uncles, outReceipts, withdrawals), outTxs, outReceipts, nil
return types.NewBlockForAsembling(header, outTxs, uncles, outReceipts, withdrawals), outTxs, outReceipts, nil, nil
}

// Authorize injects a private key into the consensus engine to mint new blocks
Expand Down
10 changes: 5 additions & 5 deletions consensus/clique/clique.go
Original file line number Diff line number Diff line change
Expand Up @@ -380,19 +380,19 @@ func (c *Clique) CalculateRewards(config *chain.Config, header *types.Header, un
// Finalize implements consensus.Engine, ensuring no uncles are set, nor block
// rewards given.
func (c *Clique) Finalize(config *chain.Config, header *types.Header, state *state.IntraBlockState,
txs types.Transactions, uncles []*types.Header, r types.Receipts, withdrawals []*types.Withdrawal, requests types.Requests,
txs types.Transactions, uncles []*types.Header, r types.Receipts, withdrawals []*types.Withdrawal, requests types.FlatRequests,
chain consensus.ChainReader, syscall consensus.SystemCall, logger log.Logger,
) (types.Transactions, types.Receipts, types.Requests, error) {
) (types.Transactions, types.Receipts, types.FlatRequests, error) {
return txs, r, nil, nil
}

// FinalizeAndAssemble implements consensus.Engine, ensuring no uncles are set,
// nor block rewards given, and returns the final block.
func (c *Clique) FinalizeAndAssemble(chainConfig *chain.Config, header *types.Header, state *state.IntraBlockState,
txs types.Transactions, uncles []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, requests types.Requests, chain consensus.ChainReader, syscall consensus.SystemCall, call consensus.Call, logger log.Logger,
) (*types.Block, types.Transactions, types.Receipts, error) {
txs types.Transactions, uncles []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, requests types.FlatRequests, chain consensus.ChainReader, syscall consensus.SystemCall, call consensus.Call, logger log.Logger,
) (*types.Block, types.Transactions, types.Receipts, types.FlatRequests, error) {
// Assemble and return the final block for sealing
return types.NewBlockForAsembling(header, txs, nil, receipts, withdrawals), txs, receipts, nil
return types.NewBlockForAsembling(header, txs, nil, receipts, withdrawals), txs, receipts, nil, nil
}

// Authorize injects a private key into the consensus engine to mint new blocks
Expand Down
8 changes: 4 additions & 4 deletions consensus/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,17 +168,17 @@ type EngineWriter interface {
// Finalize runs any post-transaction state modifications (e.g. block rewards)
// but does not assemble the block.
Finalize(config *chain.Config, header *types.Header, state *state.IntraBlockState,
txs types.Transactions, uncles []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, requests types.Requests, chain ChainReader, syscall SystemCall, logger log.Logger,
) (types.Transactions, types.Receipts, types.Requests, error)
txs types.Transactions, uncles []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, requests types.FlatRequests, chain ChainReader, syscall SystemCall, logger log.Logger,
) (types.Transactions, types.Receipts, types.FlatRequests, error)

// FinalizeAndAssemble runs any post-transaction state modifications (e.g. block
// rewards) and assembles the final block.
//
// Note: The block header and state database might be updated to reflect any
// consensus rules that happen at finalization (e.g. block rewards).
FinalizeAndAssemble(config *chain.Config, header *types.Header, state *state.IntraBlockState,
txs types.Transactions, uncles []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, requests types.Requests, chain ChainReader, syscall SystemCall, call Call, logger log.Logger,
) (*types.Block, types.Transactions, types.Receipts, error)
txs types.Transactions, uncles []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, requests types.FlatRequests, chain ChainReader, syscall SystemCall, call Call, logger log.Logger,
) (*types.Block, types.Transactions, types.Receipts, types.FlatRequests, error)

// Seal generates a new sealing request for the given input block and pushes
// the result into the given channel.
Expand Down
12 changes: 6 additions & 6 deletions consensus/ethash/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -567,9 +567,9 @@ func (ethash *Ethash) Initialize(config *chain.Config, chain consensus.ChainHead
// Finalize implements consensus.Engine, accumulating the block and uncle rewards,
// setting the final state on the header
func (ethash *Ethash) Finalize(config *chain.Config, header *types.Header, state *state.IntraBlockState,
txs types.Transactions, uncles []*types.Header, r types.Receipts, withdrawals []*types.Withdrawal, requests types.Requests,
txs types.Transactions, uncles []*types.Header, r types.Receipts, withdrawals []*types.Withdrawal, requests types.FlatRequests,
chain consensus.ChainReader, syscall consensus.SystemCall, logger log.Logger,
) (types.Transactions, types.Receipts, types.Requests, error) {
) (types.Transactions, types.Receipts, types.FlatRequests, error) {
// Accumulate any block and uncle rewards and commit the final state root
accumulateRewards(config, state, header, uncles)
return txs, r, nil, nil
Expand All @@ -578,17 +578,17 @@ func (ethash *Ethash) Finalize(config *chain.Config, header *types.Header, state
// FinalizeAndAssemble implements consensus.Engine, accumulating the block and
// uncle rewards, setting the final state and assembling the block.
func (ethash *Ethash) FinalizeAndAssemble(chainConfig *chain.Config, header *types.Header, state *state.IntraBlockState,
txs types.Transactions, uncles []*types.Header, r types.Receipts, withdrawals []*types.Withdrawal, requests types.Requests,
txs types.Transactions, uncles []*types.Header, r types.Receipts, withdrawals []*types.Withdrawal, requests types.FlatRequests,
chain consensus.ChainReader, syscall consensus.SystemCall, call consensus.Call, logger log.Logger,
) (*types.Block, types.Transactions, types.Receipts, error) {
) (*types.Block, types.Transactions, types.Receipts, types.FlatRequests, error) {

// Finalize block
outTxs, outR, _, err := ethash.Finalize(chainConfig, header, state, txs, uncles, r, withdrawals, requests, chain, syscall, logger)
if err != nil {
return nil, nil, nil, err
return nil, nil, nil, nil, err
}
// Header seems complete, assemble into a block and return
return types.NewBlock(header, outTxs, uncles, outR, withdrawals), outTxs, outR, nil
return types.NewBlock(header, outTxs, uncles, outR, withdrawals), outTxs, outR, nil, nil
}

// SealHash returns the hash of a block prior to it being sealed.
Expand Down
46 changes: 20 additions & 26 deletions consensus/merge/merge.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (
"errors"
"fmt"
"math/big"
"reflect"

"github.com/holiman/uint256"

Expand Down Expand Up @@ -151,9 +150,9 @@ func (s *Merge) CalculateRewards(config *chain.Config, header *types.Header, unc
}

func (s *Merge) Finalize(config *chain.Config, header *types.Header, state *state.IntraBlockState,
txs types.Transactions, uncles []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, requestsInBlock types.Requests,
txs types.Transactions, uncles []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, requestsInBlock types.FlatRequests,
chain consensus.ChainReader, syscall consensus.SystemCall, logger log.Logger,
) (types.Transactions, types.Receipts, types.Requests, error) {
) (types.Transactions, types.Receipts, types.FlatRequests, error) {
if !misc.IsPoSHeader(header) {
return s.eth1Engine.Finalize(config, header, state, txs, uncles, receipts, withdrawals, requestsInBlock, chain, syscall, logger)
}
Expand Down Expand Up @@ -186,9 +185,9 @@ func (s *Merge) Finalize(config *chain.Config, header *types.Header, state *stat
}
}

var rs types.Requests
var rs types.FlatRequests
if config.IsPrague(header.Time) {
rs = make(types.Requests, 0)
rs = make(types.FlatRequests, 0)
allLogs := types.Logs{}
for _, rec := range receipts {
allLogs = append(allLogs, rec.Logs...)
Expand All @@ -197,44 +196,39 @@ func (s *Merge) Finalize(config *chain.Config, header *types.Header, state *stat
if err != nil {
return nil, nil, nil, fmt.Errorf("error: could not parse requests logs: %v", err)
}
rs = append(rs, depositReqs...)
withdrawalReqs := misc.DequeueWithdrawalRequests7002(syscall)
rs = append(rs, withdrawalReqs...)
rs = append(rs, types.FlatRequest{Type: types.DepositRequestType, RequestData: depositReqs.Encode()})
withdrawalReq := misc.DequeueWithdrawalRequests7002(syscall)
rs = append(rs, *withdrawalReq)
consolidations := misc.DequeueConsolidationRequests7251(syscall)
rs = append(rs, consolidations...)
if requestsInBlock != nil || header.RequestsHash != nil {
rh := types.DeriveSha(rs)
if *header.RequestsHash != rh {
rs = append(rs, *consolidations)
if header.RequestsHash != nil {
rh := rs.Hash()
if *header.RequestsHash != *rh {
return nil, nil, nil, fmt.Errorf("error: invalid requests root hash in header, expected: %v, got :%v", header.RequestsHash, rh)
}
if !reflect.DeepEqual(requestsInBlock.Deposits(), depositReqs.Deposits()) {
return nil, nil, nil, errors.New("error: invalid EIP-6110 Deposit Requests in block")
}
if !reflect.DeepEqual(requestsInBlock.Withdrawals(), withdrawalReqs.Withdrawals()) {
return nil, nil, nil, errors.New("error: invalid EIP-7002 Withdrawal requests in block")
}
if !reflect.DeepEqual(requestsInBlock.Consolidations(), consolidations.Consolidations()) {
return nil, nil, nil, errors.New("error: invalid EIP-7251 Consolidation requests in block")
}
}

}

return txs, receipts, rs, nil
}

func (s *Merge) FinalizeAndAssemble(config *chain.Config, header *types.Header, state *state.IntraBlockState,
txs types.Transactions, uncles []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, requests types.Requests, chain consensus.ChainReader, syscall consensus.SystemCall, call consensus.Call, logger log.Logger,
) (*types.Block, types.Transactions, types.Receipts, error) {
txs types.Transactions, uncles []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, requests types.FlatRequests, chain consensus.ChainReader, syscall consensus.SystemCall, call consensus.Call, logger log.Logger,
) (*types.Block, types.Transactions, types.Receipts, types.FlatRequests, error) {
if !misc.IsPoSHeader(header) {
return s.eth1Engine.FinalizeAndAssemble(config, header, state, txs, uncles, receipts, withdrawals, requests, chain, syscall, call, logger)
}
header.RequestsHash = nil
outTxs, outReceipts, _, err := s.Finalize(config, header, state, txs, uncles, receipts, withdrawals, requests, chain, syscall, logger)
outTxs, outReceipts, rs, err := s.Finalize(config, header, state, txs, uncles, receipts, withdrawals, requests, chain, syscall, logger)

if err != nil {
return nil, nil, nil, err
return nil, nil, nil, nil, err
}
if config.IsPrague(header.Time) {
header.RequestsHash = rs.Hash()
}
return types.NewBlockForAsembling(header, outTxs, uncles, outReceipts, withdrawals), outTxs, outReceipts, nil
return types.NewBlockForAsembling(header, outTxs, uncles, outReceipts, withdrawals), outTxs, outReceipts, rs, nil
}

func (s *Merge) SealHash(header *types.Header) (hash libcommon.Hash) {
Expand Down
19 changes: 2 additions & 17 deletions consensus/misc/eip7002.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,27 +23,12 @@ import (
"github.com/erigontech/erigon/params"
)

// Configuration related to EIP-7002
// (May have to move it to config json later for cross-chain compatibility)
// TODO @somnathb1 Probably not needed outside of EVM
const (
WithdrawalRequestDataLen = 76 // addr + pubkey + amt
)

func DequeueWithdrawalRequests7002(syscall consensus.SystemCall) types.Requests {
func DequeueWithdrawalRequests7002(syscall consensus.SystemCall) *types.FlatRequest {
res, err := syscall(params.WithdrawalRequestAddress, nil)
if err != nil {
log.Warn("Err with syscall to WithdrawalRequestAddress", "err", err)
return nil
}
// Just append the contract outputs
var reqs types.Requests
for i := 0; i <= len(res)-WithdrawalRequestDataLen; i += WithdrawalRequestDataLen {

wr := &types.WithdrawalRequest{
RequestData: [WithdrawalRequestDataLen]byte(res[i : i+WithdrawalRequestDataLen]),
}
reqs = append(reqs, wr)
}
return reqs
return &types.FlatRequest{Type: types.WithdrawalRequestType, RequestData: res}
}
13 changes: 2 additions & 11 deletions consensus/misc/eip7251.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,12 @@ import (
"github.com/erigontech/erigon/params"
)

const ConsolidationRequestDataLen = 116

func DequeueConsolidationRequests7251(syscall consensus.SystemCall) types.Requests {
func DequeueConsolidationRequests7251(syscall consensus.SystemCall) *types.FlatRequest {
res, err := syscall(params.ConsolidationRequestAddress, nil)
if err != nil {
log.Warn("Err with syscall to ConsolidationRequestAddress", "err", err)
return nil
}
// Just append the contract outputs as the encoded request data
var reqs types.Requests
for i := 0; i <= len(res)-ConsolidationRequestDataLen; i += ConsolidationRequestDataLen {
wr := &types.ConsolidationRequest{
RequestData: [ConsolidationRequestDataLen]byte(res[i : i+ConsolidationRequestDataLen]),
}
reqs = append(reqs, wr)
}
return reqs
return &types.FlatRequest{Type: types.ConsolidationRequestType, RequestData: res}
}
Loading

0 comments on commit 4837639

Please sign in to comment.