mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
create separate functions for IL verification for NewInclusionList engine API
This commit is contained in:
parent
5f4dd02074
commit
068ce5c6d6
6 changed files with 118 additions and 26 deletions
|
|
@ -64,7 +64,7 @@ type ExecutableData struct {
|
|||
BlobGasUsed *uint64 `json:"blobGasUsed"`
|
||||
ExcessBlobGas *uint64 `json:"excessBlobGas"`
|
||||
|
||||
Summary []*InclusionListEntry `json:"summary"`
|
||||
Summary []*types.InclusionListEntry `json:"summary"`
|
||||
}
|
||||
|
||||
// JSON type overrides for executableData.
|
||||
|
|
@ -280,14 +280,7 @@ type ExecutionPayloadBodyV1 struct {
|
|||
Withdrawals []*types.Withdrawal `json:"withdrawals"`
|
||||
}
|
||||
|
||||
// InclusionListV1 is used in the response to GetInclusionListV1 and request to NewInclusionListV1
|
||||
type InclusionListV1 struct {
|
||||
Summary []*InclusionListEntry `json:"summary"`
|
||||
Transactions []*types.Transaction `json:"transactions"`
|
||||
}
|
||||
|
||||
// InclusionListEntry denotes a summary entry of (address, gasLimit)
|
||||
type InclusionListEntry struct {
|
||||
address common.Address `json:"address"`
|
||||
gasLimit uint32 `json:"gasLimit"` // TODO(manav): change to uint8
|
||||
type VerifiableInclusionList struct {
|
||||
ParentHash common.Hash `json:"parentHash"`
|
||||
InclusionList types.InclusionList `json:"inclusionList"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2587,3 +2587,7 @@ func (bc *BlockChain) SetTrieFlushInterval(interval time.Duration) {
|
|||
func (bc *BlockChain) GetTrieFlushInterval() time.Duration {
|
||||
return time.Duration(bc.flushInterval.Load())
|
||||
}
|
||||
|
||||
func (bc *BlockChain) VerifyInclusionList(list types.InclusionList, parent *types.Header, state *state.StateDB) bool {
|
||||
return verifyInclusionList(list, parent, state, bc.Config())
|
||||
}
|
||||
|
|
|
|||
70
core/inclusion_list.go
Normal file
70
core/inclusion_list.go
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
package core
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/consensus/misc/eip1559"
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
)
|
||||
|
||||
// IL constants taken from specs here: https://github.com/potuz/consensus-specs/blob/a6c55576de059a1b2cae69848dee827f6e26e72d/specs/_features/epbs/beacon-chain.md#execution
|
||||
const (
|
||||
MAX_TRANSACTIONS_PER_INCLUSION_LIST = 16
|
||||
MAX_GAS_PER_INCLUSION_LIST = 2_097_152 // 2^21
|
||||
)
|
||||
|
||||
// VerifyInclusionList verifies the properties of the inclusion list and the
|
||||
// transactions in it against the given `state` object.
|
||||
//
|
||||
// The verification involves actual execution of the transactions so
|
||||
// it's the caller's responsibility to send a copy of the state object.
|
||||
func verifyInclusionList(list types.InclusionList, parent *types.Header, state *state.StateDB, config *params.ChainConfig) bool {
|
||||
// Validate few basic things first in the inclusion list.
|
||||
if len(list.Summary) != len(list.Transactions) {
|
||||
log.Debug("Inclusion list summary and transactions length mismatch")
|
||||
return false
|
||||
}
|
||||
|
||||
if len(list.Summary) > MAX_TRANSACTIONS_PER_INCLUSION_LIST {
|
||||
log.Debug("Inclusion list exceeds maximum number of transactions")
|
||||
return false
|
||||
}
|
||||
|
||||
// As IL will be included in the next block, calculate the current block's base fee.
|
||||
// As the current block's payload isn't revealed yet (due to ePBS), calculate
|
||||
// it from parent block.
|
||||
currentBaseFee := eip1559.CalcBaseFee(config, parent)
|
||||
|
||||
// 1.125 * currentBaseFee
|
||||
gasFeeThreshold := new(big.Float).Mul(new(big.Float).SetFloat64(0.125), new(big.Float).SetInt(currentBaseFee))
|
||||
|
||||
// Prepare the signer object
|
||||
signer := types.LatestSigner(config)
|
||||
|
||||
// Verify if the summary and transactions match. Also check if the txs
|
||||
// have at least 12.5% higher `maxFeePerGas` than parent block's base fee.
|
||||
for i, summary := range list.Summary {
|
||||
tx := list.Transactions[i]
|
||||
from, err := types.Sender(signer, tx)
|
||||
if err != nil {
|
||||
log.Debug("Failed to get sender from transaction", "err", err)
|
||||
return false
|
||||
}
|
||||
if summary.Address != from {
|
||||
log.Debug("Inclusion list summary and transaction address mismatch")
|
||||
return false
|
||||
}
|
||||
|
||||
// tx.GasFeeCap > 1.125 * parent.BaseFee
|
||||
if new(big.Float).SetInt(tx.GasFeeCap()).Cmp(gasFeeThreshold) < 1 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Execute txs. Mostly all required params are available except evm context.
|
||||
|
||||
return false
|
||||
}
|
||||
|
|
@ -173,18 +173,6 @@ type Body struct {
|
|||
Withdrawals []*Withdrawal `rlp:"optional"`
|
||||
}
|
||||
|
||||
// InclusionList represents pairs of transaction summary and the transaction data itself
|
||||
type InclusionList struct {
|
||||
Summary []*InclusionListEntry `json:"summary"`
|
||||
Transactions []*Transaction `json:"transactions"`
|
||||
}
|
||||
|
||||
// InclusionListEntry denotes a summary entry of (address, gasLimit)
|
||||
type InclusionListEntry struct {
|
||||
Address common.Address `json:"address"`
|
||||
GasLimit uint32 `json:"gasLimit"` // TODO(manav): change to uint8
|
||||
}
|
||||
|
||||
// Block represents an Ethereum block.
|
||||
//
|
||||
// Note the Block type tries to be 'immutable', and contains certain caches that rely
|
||||
|
|
|
|||
15
core/types/inclusion_list.go
Normal file
15
core/types/inclusion_list.go
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
package types
|
||||
|
||||
import "github.com/ethereum/go-ethereum/common"
|
||||
|
||||
// InclusionList represents pairs of transaction summary and the transaction data itself
|
||||
type InclusionList struct {
|
||||
Summary []*InclusionListEntry `json:"summary"`
|
||||
Transactions []*Transaction `json:"transactions"`
|
||||
}
|
||||
|
||||
// InclusionListEntry denotes a summary entry of (address, gasLimit)
|
||||
type InclusionListEntry struct {
|
||||
Address common.Address `json:"address"`
|
||||
GasLimit uint32 `json:"gasLimit"` // TODO(manav): change to uint8
|
||||
}
|
||||
|
|
@ -161,7 +161,7 @@ func newConsensusAPIWithoutHeartbeat(eth *eth.Ethereum) *ConsensusAPI {
|
|||
|
||||
// GetInclusionListV1 returns an inclusion list which contains summary + list of transactions
|
||||
// which are valid for the current slot.
|
||||
func (api *ConsensusAPI) GetInclusionListV1() (*engine.InclusionListV1, error) {
|
||||
func (api *ConsensusAPI) GetInclusionListV1() (*types.InclusionList, error) {
|
||||
// TODO(manav): Do we check here if we're on correct fork or are fully synced? If not
|
||||
// we might end up delivering wrong IL. Other will reject it though but do we want to
|
||||
// risk it?
|
||||
|
|
@ -171,8 +171,30 @@ func (api *ConsensusAPI) GetInclusionListV1() (*engine.InclusionListV1, error) {
|
|||
|
||||
// NewInclusionListV1 validates whether an inclusion list (summary + txs) is
|
||||
// correct for the current state or not.
|
||||
func (api *ConsensusAPI) NewInclusionListV1() bool {
|
||||
return false
|
||||
func (api *ConsensusAPI) NewInclusionListV1(params engine.VerifiableInclusionList) bool {
|
||||
log.Trace("Engine API request received", "method", "NewInclusionListV1")
|
||||
if params.ParentHash == (common.Hash{}) {
|
||||
log.Warn("Inclusion list verification requested with zero parent hash")
|
||||
return false
|
||||
}
|
||||
|
||||
// Check if we have parent block available or not. If not, reject the
|
||||
// inclusion list.
|
||||
// (TODO): Do we need to trigger a sync here? I believe not.
|
||||
parent := api.eth.BlockChain().GetBlockByHash(params.ParentHash)
|
||||
if parent == nil {
|
||||
log.Warn("Inclusion list verification requested with unknown parent", "hash", params.ParentHash)
|
||||
return false
|
||||
}
|
||||
|
||||
// Fetch the parent state to verify the inclusion list.
|
||||
state, err := api.eth.BlockChain().StateAt(parent.Root())
|
||||
if err != nil {
|
||||
log.Warn("Unable to fetch parent block state, skipping verification", "err", err)
|
||||
return false
|
||||
}
|
||||
|
||||
return api.eth.BlockChain().VerifyInclusionList(params.InclusionList, parent.Header(), state.Copy())
|
||||
}
|
||||
|
||||
// TODO: update/define executable params
|
||||
|
|
|
|||
Loading…
Reference in a new issue