mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-23 13:16:42 +00:00
txpool: activate the new max blobs per transaction post Osaka
This commit is contained in:
parent
5035064421
commit
62d7220631
3 changed files with 110 additions and 10 deletions
|
|
@ -66,7 +66,7 @@ const (
|
|||
// carry. We choose a smaller limit than the protocol-permitted MaxBlobsPerBlock
|
||||
// in order to ensure network and txpool stability.
|
||||
// Note: if you increase this, validation will fail on txMaxSize.
|
||||
maxBlobsPerTx = params.BlobTxMaxBlobs
|
||||
maxBlobsPerTx = 7
|
||||
|
||||
// maxTxsPerAccount is the maximum number of blob transactions admitted from
|
||||
// a single account. The limit is enforced to minimize the DoS potential of
|
||||
|
|
@ -1102,6 +1102,11 @@ func (p *BlobPool) ValidateTxBasics(tx *types.Transaction) error {
|
|||
MinTip: p.gasTip.ToBig(),
|
||||
MaxBlobCount: maxBlobsPerTx,
|
||||
}
|
||||
|
||||
if p.chain.Config().IsOsaka(p.head.Number, p.head.Time) {
|
||||
opts.MaxBlobCount = params.BlobTxMaxBlobs
|
||||
}
|
||||
|
||||
return txpool.ValidateTransaction(tx, p.head, p.signer, opts)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2036,3 +2036,91 @@ func benchmarkPoolPending(b *testing.B, datacap uint64) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestOsakaMaxBlobsPerTx verifies that the maxBlobsPerTx parameter is dynamic
|
||||
// and changes according to the Osaka hardfork activation.
|
||||
func TestOsakaMaxBlobsPerTx(t *testing.T) {
|
||||
var (
|
||||
key, _ = crypto.GenerateKey()
|
||||
addr = crypto.PubkeyToAddress(key.PublicKey)
|
||||
)
|
||||
|
||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
||||
statedb.AddBalance(addr, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||
statedb.Commit(0, true, false)
|
||||
|
||||
osakaTime := uint64(1)
|
||||
pragueTime := uint64(0)
|
||||
cancunTime := uint64(0)
|
||||
config := ¶ms.ChainConfig{
|
||||
ChainID: big.NewInt(1),
|
||||
LondonBlock: big.NewInt(0),
|
||||
BerlinBlock: big.NewInt(0),
|
||||
CancunTime: &cancunTime,
|
||||
PragueTime: &pragueTime,
|
||||
OsakaTime: &osakaTime,
|
||||
BlobScheduleConfig: ¶ms.BlobScheduleConfig{
|
||||
Cancun: params.DefaultCancunBlobConfig,
|
||||
Prague: params.DefaultPragueBlobConfig,
|
||||
Osaka: params.DefaultOsakaBlobConfig,
|
||||
},
|
||||
}
|
||||
|
||||
chain := &testBlockChain{
|
||||
config: config,
|
||||
basefee: uint256.NewInt(params.InitialBaseFee),
|
||||
blobfee: uint256.NewInt(params.BlobTxMinBlobGasprice),
|
||||
statedb: statedb,
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
header *types.Header
|
||||
numBlobs int
|
||||
sidecarVer uint8
|
||||
expectErr error
|
||||
}{
|
||||
{
|
||||
name: "before Osaka, maxBlobsPerTx blobs",
|
||||
header: &types.Header{Number: big.NewInt(0), Time: 0, Difficulty: common.Big0, GasLimit: 30_000_000, BaseFee: big.NewInt(int64(params.InitialBaseFee))},
|
||||
numBlobs: maxBlobsPerTx,
|
||||
sidecarVer: types.BlobSidecarVersion0,
|
||||
expectErr: nil,
|
||||
},
|
||||
{
|
||||
name: "after Osaka, maxBlobsPerTx blobs",
|
||||
header: &types.Header{Number: big.NewInt(1), Time: 1, Difficulty: common.Big0, GasLimit: 30_000_000, BaseFee: big.NewInt(int64(params.InitialBaseFee))},
|
||||
numBlobs: maxBlobsPerTx,
|
||||
sidecarVer: types.BlobSidecarVersion1,
|
||||
expectErr: txpool.ErrTxBlobLimitExceeded,
|
||||
},
|
||||
{
|
||||
name: "after Osaka, BlobTxMaxBlobs blobs",
|
||||
header: &types.Header{Number: big.NewInt(1), Time: 1, Difficulty: common.Big0, GasLimit: 30_000_000, BaseFee: big.NewInt(int64(params.InitialBaseFee))},
|
||||
numBlobs: params.BlobTxMaxBlobs,
|
||||
sidecarVer: types.BlobSidecarVersion1,
|
||||
expectErr: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
pool := New(Config{Datadir: t.TempDir()}, chain, nil)
|
||||
if err := pool.Init(1, tt.header, newReserver()); err != nil {
|
||||
t.Fatalf("failed to create blob pool: %v", err)
|
||||
}
|
||||
tx := makeMultiBlobTx(0, 1, 1, 1, tt.numBlobs, 0, key, tt.sidecarVer)
|
||||
err := pool.add(tx)
|
||||
if tt.expectErr != nil {
|
||||
if !errors.Is(err, tt.expectErr) {
|
||||
t.Errorf("expected error %v, got: %v", tt.expectErr, err)
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Errorf("expected success, got: %v", err)
|
||||
}
|
||||
}
|
||||
pool.Close()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import (
|
|||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/consensus/misc/eip4844"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
|
|
@ -30,11 +31,9 @@ import (
|
|||
"github.com/ethereum/go-ethereum/params"
|
||||
)
|
||||
|
||||
var (
|
||||
// blobTxMinBlobGasPrice is the big.Int version of the configured protocol
|
||||
// parameter to avoid constructing a new big integer for every transaction.
|
||||
blobTxMinBlobGasPrice = big.NewInt(params.BlobTxMinBlobGasprice)
|
||||
)
|
||||
// blobTxMinBlobGasPrice is the big.Int version of the configured protocol
|
||||
// parameter to avoid constructing a new big integer for every transaction.
|
||||
var blobTxMinBlobGasPrice = big.NewInt(params.BlobTxMinBlobGasprice)
|
||||
|
||||
// ValidationOptions define certain differences between transaction validation
|
||||
// across the different pools without having to duplicate those checks.
|
||||
|
|
@ -166,19 +165,27 @@ func validateBlobTx(tx *types.Transaction, head *types.Header, opts *ValidationO
|
|||
if len(hashes) == 0 {
|
||||
return errors.New("blobless blob transaction")
|
||||
}
|
||||
if len(hashes) > params.BlobTxMaxBlobs {
|
||||
return fmt.Errorf("too many blobs in transaction: have %d, permitted %d", len(hashes), params.BlobTxMaxBlobs)
|
||||
}
|
||||
|
||||
if len(sidecar.Blobs) != len(hashes) {
|
||||
return fmt.Errorf("invalid number of %d blobs compared to %d blob hashes", len(sidecar.Blobs), len(hashes))
|
||||
}
|
||||
if err := sidecar.ValidateBlobCommitmentHashes(hashes); err != nil {
|
||||
return err
|
||||
}
|
||||
// Fork-specific sidecar checks, including proof verification.
|
||||
// Post-Osaka checks, Fork-specific sidecar checks, including proof verification.
|
||||
if opts.Config.IsOsaka(head.Number, head.Time) {
|
||||
if len(hashes) > params.BlobTxMaxBlobs {
|
||||
return fmt.Errorf("too many blobs in transaction: have %d, permitted %d", len(hashes), params.BlobTxMaxBlobs)
|
||||
}
|
||||
|
||||
return validateBlobSidecarOsaka(sidecar, hashes)
|
||||
}
|
||||
|
||||
maxBlobs := eip4844.MaxBlobsPerBlock(opts.Config, head.Time)
|
||||
if len(hashes) > maxBlobs {
|
||||
return fmt.Errorf("too many blobs in transaction: have %d, permitted %d", len(hashes), maxBlobs)
|
||||
}
|
||||
|
||||
return validateBlobSidecarLegacy(sidecar, hashes)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue