mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 10:22:23 +00:00
feat: add BlockTxCount limit and BlockPayloadSize limit (#584)
* update consensus/errors.go * update core/error.go * update core/types/block.go * update rollup/rcfg/config.go * update params/config.go * update core/block_validator.go * fix * update miner/worker.go * fix
This commit is contained in:
parent
c70a901ed3
commit
b639349788
7 changed files with 73 additions and 0 deletions
|
|
@ -38,4 +38,7 @@ var (
|
|||
// ErrInvalidTerminalBlock is returned if a block is invalid wrt. the terminal
|
||||
// total difficulty.
|
||||
ErrInvalidTerminalBlock = errors.New("invalid terminal block")
|
||||
|
||||
// ErrInvalidTxCount is returned if a block contains too many transactions.
|
||||
ErrInvalidTxCount = errors.New("invalid transaction count")
|
||||
)
|
||||
|
|
|
|||
|
|
@ -55,6 +55,14 @@ func (v *BlockValidator) ValidateBody(block *types.Block) error {
|
|||
if v.bc.HasBlockAndState(block.Hash(), block.NumberU64()) {
|
||||
return ErrKnownBlock
|
||||
}
|
||||
// Check if block tx count is is smaller than the max count
|
||||
if !v.config.Scroll.IsValidTxCount(len(block.Transactions())) {
|
||||
return consensus.ErrInvalidTxCount
|
||||
}
|
||||
// Check if block payload size is smaller than the max size
|
||||
if !v.config.Scroll.IsValidBlockSize(block.PayloadSize()) {
|
||||
return ErrInvalidBlockPayloadSize
|
||||
}
|
||||
|
||||
// Header validity is known at this point. Here we verify that uncles, transactions
|
||||
// and withdrawals given in the block body match the header.
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@ var (
|
|||
// ErrKnownBlock is returned when a block to import is already known locally.
|
||||
ErrKnownBlock = errors.New("block already known")
|
||||
|
||||
// ErrInvalidBlockPayloadSize is returned when a block to import has an oversized payload.
|
||||
ErrInvalidBlockPayloadSize = errors.New("invalid block payload size")
|
||||
|
||||
// ErrBannedHash is returned if a block to import is on the banned list.
|
||||
ErrBannedHash = errors.New("banned hash")
|
||||
|
||||
|
|
|
|||
|
|
@ -415,6 +415,18 @@ func (b *Block) Size() uint64 {
|
|||
return uint64(c)
|
||||
}
|
||||
|
||||
// PayloadSize returns the encoded storage size sum of all transactions in a block.
|
||||
func (b *Block) PayloadSize() uint64 {
|
||||
// add up all txs sizes
|
||||
var totalSize uint64
|
||||
for _, tx := range b.transactions {
|
||||
if !tx.IsL1MessageTx() {
|
||||
totalSize += tx.Size()
|
||||
}
|
||||
}
|
||||
return totalSize
|
||||
}
|
||||
|
||||
// SanityCheck can be used to prevent that unbounded fields are
|
||||
// stuffed with junk data to add processing overhead
|
||||
func (b *Block) SanityCheck() error {
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ type environment struct {
|
|||
signer types.Signer
|
||||
state *state.StateDB // apply state changes here
|
||||
tcount int // tx count in cycle
|
||||
blockSize uint64 // approximate size of tx payload in bytes
|
||||
gasPool *core.GasPool // available gas used to pack transactions
|
||||
coinbase common.Address
|
||||
|
||||
|
|
@ -722,6 +723,7 @@ func (w *worker) makeEnv(parent *types.Header, header *types.Header, coinbase co
|
|||
}
|
||||
// Keep track of transactions which return errors so they can be removed
|
||||
env.tcount = 0
|
||||
env.blockSize = 0
|
||||
return env, nil
|
||||
}
|
||||
|
||||
|
|
@ -834,6 +836,18 @@ func (w *worker) commitTransactions(env *environment, txs *transactionsByPriceAn
|
|||
txs.Pop()
|
||||
continue
|
||||
}
|
||||
// If we have collected enough transactions then we're done
|
||||
// Originally we only limit l2txs count, but now strictly limit total txs number.
|
||||
// log.Info("w.chainConfig", "w.chainConfig.Scroll", w.chainConfig.Scroll)
|
||||
if !w.chainConfig.Scroll.IsValidTxCount(env.tcount + 1) {
|
||||
log.Trace("Transaction count limit reached", "have", env.tcount, "want", w.chainConfig.Scroll.MaxTxPerBlock)
|
||||
break
|
||||
}
|
||||
if !tx.IsL1MessageTx() && !w.chainConfig.Scroll.IsValidBlockSize(env.blockSize+tx.Size()) {
|
||||
log.Trace("Block size limit reached", "have", env.blockSize, "want", w.chainConfig.Scroll.MaxTxPayloadBytesPerBlock, "tx", tx.Size())
|
||||
txs.Pop() // skip transactions from this account
|
||||
continue
|
||||
}
|
||||
// Error may be ignored here. The error has already been checked
|
||||
// during transaction acceptance is the transaction pool.
|
||||
from, _ := types.Sender(env.signer, tx)
|
||||
|
|
@ -861,6 +875,12 @@ func (w *worker) commitTransactions(env *environment, txs *transactionsByPriceAn
|
|||
env.tcount++
|
||||
txs.Shift()
|
||||
|
||||
if tx.IsL1MessageTx() {
|
||||
} else {
|
||||
// only consider block size limit for L2 transactions
|
||||
env.blockSize += tx.Size()
|
||||
}
|
||||
|
||||
default:
|
||||
// Transaction is regarded as invalid, drop all consecutive transactions from
|
||||
// the same sender because of `nonce-too-high` clause.
|
||||
|
|
|
|||
|
|
@ -333,6 +333,28 @@ type ChainConfig struct {
|
|||
Ethash *EthashConfig `json:"ethash,omitempty"`
|
||||
Clique *CliqueConfig `json:"clique,omitempty"`
|
||||
IsDevMode bool `json:"isDev,omitempty"`
|
||||
|
||||
// Scroll genesis extension: enable scroll rollup-related traces & state transition
|
||||
Scroll ScrollConfig `json:"scroll,omitempty"`
|
||||
}
|
||||
|
||||
type ScrollConfig struct {
|
||||
// Maximum number of transactions per block [optional]
|
||||
MaxTxPerBlock *int `json:"maxTxPerBlock,omitempty"`
|
||||
|
||||
// Maximum tx payload size of blocks that we produce [optional]
|
||||
MaxTxPayloadBytesPerBlock *int `json:"maxTxPayloadBytesPerBlock,omitempty"`
|
||||
}
|
||||
|
||||
// IsValidTxCount returns whether the given block's transaction count is below the limit.
|
||||
// This limit corresponds to the number of ECDSA signature checks that we can fit into the zkEVM.
|
||||
func (s ScrollConfig) IsValidTxCount(count int) bool {
|
||||
return s.MaxTxPerBlock == nil || count <= *s.MaxTxPerBlock
|
||||
}
|
||||
|
||||
// IsValidBlockSize returns whether the given block's transaction payload size is below the limit.
|
||||
func (s ScrollConfig) IsValidBlockSize(size uint64) bool {
|
||||
return s.MaxTxPayloadBytesPerBlock == nil || size <= uint64(*s.MaxTxPayloadBytesPerBlock)
|
||||
}
|
||||
|
||||
// EthashConfig is the consensus engine configs for proof-of-work based sealing.
|
||||
|
|
|
|||
|
|
@ -9,6 +9,11 @@ import (
|
|||
// TODO:
|
||||
// verify in consensus layer when decentralizing sequencer
|
||||
|
||||
var (
|
||||
ScrollMaxTxPerBlock = 100
|
||||
ScrollMaxTxPayloadBytesPerBlock = 120 * 1024
|
||||
)
|
||||
|
||||
var (
|
||||
// L2MessageQueueAddress is the address of the L2MessageQueue
|
||||
// predeploy
|
||||
|
|
|
|||
Loading…
Reference in a new issue