mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-07 23:48:36 +00:00
Merge 94f55e5575 into e1047b9c84
This commit is contained in:
commit
2d32d542d2
6 changed files with 89 additions and 19 deletions
|
|
@ -339,7 +339,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
|||
for _, receipt := range receipts {
|
||||
allLogs = append(allLogs, receipt.Logs...)
|
||||
}
|
||||
if err := core.ParseDepositLogs(&requests, allLogs, chainConfig); err != nil {
|
||||
if err := core.ParseDepositLogs(&requests, allLogs, chainConfig, vmContext.BlockNumber, vmContext.Time); err != nil {
|
||||
return nil, nil, nil, NewError(ErrorEVM, fmt.Errorf("could not parse requests logs: %v", err))
|
||||
}
|
||||
// EIP-7002
|
||||
|
|
|
|||
|
|
@ -322,7 +322,7 @@ func (b *BlockGen) collectRequests(readonly bool) (requests [][]byte) {
|
|||
for _, r := range b.receipts {
|
||||
blockLogs = append(blockLogs, r.Logs...)
|
||||
}
|
||||
if err := ParseDepositLogs(&requests, blockLogs, b.cm.config); err != nil {
|
||||
if err := ParseDepositLogs(&requests, blockLogs, b.cm.config, b.header.Number, b.header.Time); err != nil {
|
||||
panic(fmt.Sprintf("failed to parse deposit log: %v", err))
|
||||
}
|
||||
// create EVM for system calls
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ func postExecution(ctx context.Context, config *params.ChainConfig, block *types
|
|||
if config.IsPrague(block.Number(), block.Time()) {
|
||||
requests = [][]byte{}
|
||||
// EIP-6110
|
||||
if err := ParseDepositLogs(&requests, allLogs, config); err != nil {
|
||||
if err := ParseDepositLogs(&requests, allLogs, config, block.Number(), block.Time()); err != nil {
|
||||
return requests, fmt.Errorf("failed to parse deposit logs: %w", err)
|
||||
}
|
||||
// EIP-7002
|
||||
|
|
@ -348,21 +348,47 @@ func processRequestsSystemCall(requests *[][]byte, evm *vm.EVM, requestType byte
|
|||
return nil
|
||||
}
|
||||
|
||||
var depositTopic = common.HexToHash("0x649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5")
|
||||
// DepositTopic is the topic hash of the EIP-6110 DepositEvent.
|
||||
var DepositTopic = common.HexToHash("0x649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5")
|
||||
|
||||
// IsDepositLog reports whether the log is an EIP-6110 deposit event emitted
|
||||
// by the given deposit contract address.
|
||||
func IsDepositLog(log *types.Log, depositContract common.Address) bool {
|
||||
return log.Address == depositContract && len(log.Topics) > 0 && log.Topics[0] == DepositTopic
|
||||
}
|
||||
|
||||
// CountDepositLogs returns the number of EIP-6110 deposit events present in
|
||||
// the given logs.
|
||||
func CountDepositLogs(logs []*types.Log, depositContract common.Address) int {
|
||||
count := 0
|
||||
for _, log := range logs {
|
||||
if IsDepositLog(log, depositContract) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
// ParseDepositLogs extracts the EIP-6110 deposit values from logs emitted by
|
||||
// BeaconDepositContract.
|
||||
func ParseDepositLogs(requests *[][]byte, logs []*types.Log, config *params.ChainConfig) error {
|
||||
// BeaconDepositContract. From the Amsterdam fork onwards the number of
|
||||
// deposits per block is capped to params.MaxDepositRequestsPerBlock by
|
||||
// EIP-8254.
|
||||
func ParseDepositLogs(requests *[][]byte, logs []*types.Log, config *params.ChainConfig, blockNumber *big.Int, blockTime uint64) error {
|
||||
deposits := make([]byte, 1) // note: first byte is 0x00 (== deposit request type)
|
||||
count := 0
|
||||
for _, log := range logs {
|
||||
if log.Address == config.DepositContractAddress && len(log.Topics) > 0 && log.Topics[0] == depositTopic {
|
||||
if IsDepositLog(log, config.DepositContractAddress) {
|
||||
request, err := types.DepositLogToRequest(log.Data)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to parse deposit data: %v", err)
|
||||
}
|
||||
deposits = append(deposits, request...)
|
||||
count++
|
||||
}
|
||||
}
|
||||
if config.IsAmsterdam(blockNumber, blockTime) && count > params.MaxDepositRequestsPerBlock {
|
||||
return fmt.Errorf("too many deposit requests in block: have %d, max %d", count, params.MaxDepositRequestsPerBlock)
|
||||
}
|
||||
if len(deposits) > 1 {
|
||||
*requests = append(*requests, deposits)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -398,7 +398,7 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header,
|
|||
if sim.chainConfig.IsPrague(header.Number, header.Time) {
|
||||
requests = [][]byte{}
|
||||
// EIP-6110
|
||||
if err := core.ParseDepositLogs(&requests, allLogs, sim.chainConfig); err != nil {
|
||||
if err := core.ParseDepositLogs(&requests, allLogs, sim.chainConfig, header.Number, header.Time); err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
// EIP-7002
|
||||
|
|
|
|||
|
|
@ -43,6 +43,10 @@ var (
|
|||
errBlockInterruptedByNewHead = errors.New("new head arrived while building block")
|
||||
errBlockInterruptedByRecommit = errors.New("recommit interrupt while building block")
|
||||
errBlockInterruptedByTimeout = errors.New("timeout while building block")
|
||||
|
||||
// errDepositCapExceeded is returned when including a transaction would
|
||||
// push the block over the EIP-8254 deposit-request cap.
|
||||
errDepositCapExceeded = errors.New("deposit request cap exceeded")
|
||||
)
|
||||
|
||||
// maxBlobsPerBlock returns the maximum number of blobs per block.
|
||||
|
|
@ -66,11 +70,12 @@ type environment struct {
|
|||
coinbase common.Address
|
||||
evm *vm.EVM
|
||||
|
||||
header *types.Header
|
||||
txs []*types.Transaction
|
||||
receipts []*types.Receipt
|
||||
sidecars []*types.BlobTxSidecar
|
||||
blobs int
|
||||
header *types.Header
|
||||
txs []*types.Transaction
|
||||
receipts []*types.Receipt
|
||||
sidecars []*types.BlobTxSidecar
|
||||
blobs int
|
||||
depositRequests int // running count of EIP-6110 deposit requests, capped by EIP-8254
|
||||
|
||||
witness *stateless.Witness
|
||||
}
|
||||
|
|
@ -212,7 +217,7 @@ func (miner *Miner) generateWork(ctx context.Context, genParam *generateParams,
|
|||
if miner.chainConfig.IsPrague(work.header.Number, work.header.Time) {
|
||||
requests = [][]byte{}
|
||||
// EIP-6110 deposits
|
||||
if err := core.ParseDepositLogs(&requests, allLogs, miner.chainConfig); err != nil {
|
||||
if err := core.ParseDepositLogs(&requests, allLogs, miner.chainConfig, work.header.Number, work.header.Time); err != nil {
|
||||
return &newPayloadResult{err: err}
|
||||
}
|
||||
// EIP-7002
|
||||
|
|
@ -372,10 +377,13 @@ func (miner *Miner) commitTransaction(ctx context.Context, env *environment, tx
|
|||
if tx.Type() == types.BlobTxType {
|
||||
return miner.commitBlobTransaction(env, tx)
|
||||
}
|
||||
receipt, err := miner.applyTransaction(env, tx)
|
||||
receipt, snap, gp, err := miner.applyTransaction(env, tx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := miner.checkDepositCap(env, receipt, snap, gp); err != nil {
|
||||
return err
|
||||
}
|
||||
env.txs = append(env.txs, tx)
|
||||
env.receipts = append(env.receipts, receipt)
|
||||
env.size += tx.Size()
|
||||
|
|
@ -396,10 +404,13 @@ func (miner *Miner) commitBlobTransaction(env *environment, tx *types.Transactio
|
|||
if env.blobs+len(sc.Blobs) > maxBlobs {
|
||||
return errors.New("max data blobs reached")
|
||||
}
|
||||
receipt, err := miner.applyTransaction(env, tx)
|
||||
receipt, snap, gp, err := miner.applyTransaction(env, tx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := miner.checkDepositCap(env, receipt, snap, gp); err != nil {
|
||||
return err
|
||||
}
|
||||
txNoBlob := tx.WithoutBlobTxSidecar()
|
||||
env.txs = append(env.txs, txNoBlob)
|
||||
env.receipts = append(env.receipts, receipt)
|
||||
|
|
@ -412,7 +423,9 @@ func (miner *Miner) commitBlobTransaction(env *environment, tx *types.Transactio
|
|||
}
|
||||
|
||||
// applyTransaction runs the transaction. If execution fails, state and gas pool are reverted.
|
||||
func (miner *Miner) applyTransaction(env *environment, tx *types.Transaction) (*types.Receipt, error) {
|
||||
// On success the pre-execution snapshot/gas-pool checkpoint are returned so the
|
||||
// caller can revert if a post-execution constraint (e.g. EIP-8254 deposit cap) fails.
|
||||
func (miner *Miner) applyTransaction(env *environment, tx *types.Transaction) (*types.Receipt, int, *core.GasPool, error) {
|
||||
var (
|
||||
snap = env.state.Snapshot()
|
||||
gp = env.gasPool.Snapshot()
|
||||
|
|
@ -421,10 +434,32 @@ func (miner *Miner) applyTransaction(env *environment, tx *types.Transaction) (*
|
|||
if err != nil {
|
||||
env.state.RevertToSnapshot(snap)
|
||||
env.gasPool.Set(gp)
|
||||
return nil, err
|
||||
return nil, 0, nil, err
|
||||
}
|
||||
env.header.GasUsed = env.gasPool.Used()
|
||||
return receipt, nil
|
||||
return receipt, snap, gp, nil
|
||||
}
|
||||
|
||||
// checkDepositCap enforces the EIP-8254 cap on deposit requests per block.
|
||||
// If including the receipt would push the running deposit count over
|
||||
// params.MaxDepositRequestsPerBlock, the state and gas pool are reverted to
|
||||
// the pre-execution checkpoint and errDepositCapExceeded is returned.
|
||||
func (miner *Miner) checkDepositCap(env *environment, receipt *types.Receipt, snap int, gp *core.GasPool) error {
|
||||
if !miner.chainConfig.IsAmsterdam(env.header.Number, env.header.Time) {
|
||||
return nil
|
||||
}
|
||||
added := core.CountDepositLogs(receipt.Logs, miner.chainConfig.DepositContractAddress)
|
||||
if added == 0 {
|
||||
return nil
|
||||
}
|
||||
if env.depositRequests+added > params.MaxDepositRequestsPerBlock {
|
||||
env.state.RevertToSnapshot(snap)
|
||||
env.gasPool.Set(gp)
|
||||
env.header.GasUsed = env.gasPool.Used()
|
||||
return errDepositCapExceeded
|
||||
}
|
||||
env.depositRequests += added
|
||||
return nil
|
||||
}
|
||||
|
||||
func (miner *Miner) commitTransactions(ctx context.Context, env *environment, plainTxs, blobTxs *transactionsByPriceAndNonce, interrupt *atomic.Int32) error {
|
||||
|
|
@ -522,6 +557,13 @@ func (miner *Miner) commitTransactions(ctx context.Context, env *environment, pl
|
|||
|
||||
err := miner.commitTransaction(ctx, env, tx)
|
||||
switch {
|
||||
case errors.Is(err, errDepositCapExceeded):
|
||||
// EIP-8254: including this tx would push the block past the
|
||||
// deposit-request cap. Skip this sender; subsequent senders may
|
||||
// still produce non-deposit-bearing transactions that fit.
|
||||
log.Trace("Skipping tx that would exceed deposit-request cap", "hash", ltx.Hash, "sender", from)
|
||||
txs.Pop()
|
||||
|
||||
case errors.Is(err, core.ErrNonceTooLow):
|
||||
// New head notification data race between the transaction pool and miner, shift
|
||||
log.Trace("Skipping transaction with low nonce", "hash", ltx.Hash, "sender", from, "nonce", tx.Nonce())
|
||||
|
|
|
|||
|
|
@ -186,6 +186,8 @@ const (
|
|||
HistoryServeWindow = 8191 // Number of blocks to serve historical block hashes for, EIP-2935.
|
||||
|
||||
MaxBlockSize = 8_388_608 // maximum size of an RLP-encoded block
|
||||
|
||||
MaxDepositRequestsPerBlock = 8192 // Maximum number of EIP-6110 deposit requests per block, EIP-8254.
|
||||
)
|
||||
|
||||
// Bls12381G1MultiExpDiscountTable is the gas discount table for BLS12-381 G1 multi exponentiation operation
|
||||
|
|
|
|||
Loading…
Reference in a new issue