Skip to content

Commit 62d7220

Browse files
committed
txpool: activate the new max blobs per transaction post Osaka
1 parent 5035064 commit 62d7220

File tree

3 files changed

+110
-10
lines changed

3 files changed

+110
-10
lines changed

core/txpool/blobpool/blobpool.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ const (
6666
// carry. We choose a smaller limit than the protocol-permitted MaxBlobsPerBlock
6767
// in order to ensure network and txpool stability.
6868
// Note: if you increase this, validation will fail on txMaxSize.
69-
maxBlobsPerTx = params.BlobTxMaxBlobs
69+
maxBlobsPerTx = 7
7070

7171
// maxTxsPerAccount is the maximum number of blob transactions admitted from
7272
// 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 {
11021102
MinTip: p.gasTip.ToBig(),
11031103
MaxBlobCount: maxBlobsPerTx,
11041104
}
1105+
1106+
if p.chain.Config().IsOsaka(p.head.Number, p.head.Time) {
1107+
opts.MaxBlobCount = params.BlobTxMaxBlobs
1108+
}
1109+
11051110
return txpool.ValidateTransaction(tx, p.head, p.signer, opts)
11061111
}
11071112

core/txpool/blobpool/blobpool_test.go

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2036,3 +2036,91 @@ func benchmarkPoolPending(b *testing.B, datacap uint64) {
20362036
}
20372037
}
20382038
}
2039+
2040+
// TestOsakaMaxBlobsPerTx verifies that the maxBlobsPerTx parameter is dynamic
2041+
// and changes according to the Osaka hardfork activation.
2042+
func TestOsakaMaxBlobsPerTx(t *testing.T) {
2043+
var (
2044+
key, _ = crypto.GenerateKey()
2045+
addr = crypto.PubkeyToAddress(key.PublicKey)
2046+
)
2047+
2048+
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
2049+
statedb.AddBalance(addr, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
2050+
statedb.Commit(0, true, false)
2051+
2052+
osakaTime := uint64(1)
2053+
pragueTime := uint64(0)
2054+
cancunTime := uint64(0)
2055+
config := &params.ChainConfig{
2056+
ChainID: big.NewInt(1),
2057+
LondonBlock: big.NewInt(0),
2058+
BerlinBlock: big.NewInt(0),
2059+
CancunTime: &cancunTime,
2060+
PragueTime: &pragueTime,
2061+
OsakaTime: &osakaTime,
2062+
BlobScheduleConfig: &params.BlobScheduleConfig{
2063+
Cancun: params.DefaultCancunBlobConfig,
2064+
Prague: params.DefaultPragueBlobConfig,
2065+
Osaka: params.DefaultOsakaBlobConfig,
2066+
},
2067+
}
2068+
2069+
chain := &testBlockChain{
2070+
config: config,
2071+
basefee: uint256.NewInt(params.InitialBaseFee),
2072+
blobfee: uint256.NewInt(params.BlobTxMinBlobGasprice),
2073+
statedb: statedb,
2074+
}
2075+
2076+
tests := []struct {
2077+
name string
2078+
header *types.Header
2079+
numBlobs int
2080+
sidecarVer uint8
2081+
expectErr error
2082+
}{
2083+
{
2084+
name: "before Osaka, maxBlobsPerTx blobs",
2085+
header: &types.Header{Number: big.NewInt(0), Time: 0, Difficulty: common.Big0, GasLimit: 30_000_000, BaseFee: big.NewInt(int64(params.InitialBaseFee))},
2086+
numBlobs: maxBlobsPerTx,
2087+
sidecarVer: types.BlobSidecarVersion0,
2088+
expectErr: nil,
2089+
},
2090+
{
2091+
name: "after Osaka, maxBlobsPerTx blobs",
2092+
header: &types.Header{Number: big.NewInt(1), Time: 1, Difficulty: common.Big0, GasLimit: 30_000_000, BaseFee: big.NewInt(int64(params.InitialBaseFee))},
2093+
numBlobs: maxBlobsPerTx,
2094+
sidecarVer: types.BlobSidecarVersion1,
2095+
expectErr: txpool.ErrTxBlobLimitExceeded,
2096+
},
2097+
{
2098+
name: "after Osaka, BlobTxMaxBlobs blobs",
2099+
header: &types.Header{Number: big.NewInt(1), Time: 1, Difficulty: common.Big0, GasLimit: 30_000_000, BaseFee: big.NewInt(int64(params.InitialBaseFee))},
2100+
numBlobs: params.BlobTxMaxBlobs,
2101+
sidecarVer: types.BlobSidecarVersion1,
2102+
expectErr: nil,
2103+
},
2104+
}
2105+
2106+
for _, tt := range tests {
2107+
t.Run(tt.name, func(t *testing.T) {
2108+
pool := New(Config{Datadir: t.TempDir()}, chain, nil)
2109+
if err := pool.Init(1, tt.header, newReserver()); err != nil {
2110+
t.Fatalf("failed to create blob pool: %v", err)
2111+
}
2112+
tx := makeMultiBlobTx(0, 1, 1, 1, tt.numBlobs, 0, key, tt.sidecarVer)
2113+
err := pool.add(tx)
2114+
if tt.expectErr != nil {
2115+
if !errors.Is(err, tt.expectErr) {
2116+
t.Errorf("expected error %v, got: %v", tt.expectErr, err)
2117+
}
2118+
} else {
2119+
if err != nil {
2120+
t.Errorf("expected success, got: %v", err)
2121+
}
2122+
}
2123+
pool.Close()
2124+
})
2125+
}
2126+
}

core/txpool/validation.go

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"math/big"
2323

2424
"github.com/ethereum/go-ethereum/common"
25+
"github.com/ethereum/go-ethereum/consensus/misc/eip4844"
2526
"github.com/ethereum/go-ethereum/core"
2627
"github.com/ethereum/go-ethereum/core/state"
2728
"github.com/ethereum/go-ethereum/core/types"
@@ -30,11 +31,9 @@ import (
3031
"github.com/ethereum/go-ethereum/params"
3132
)
3233

33-
var (
34-
// blobTxMinBlobGasPrice is the big.Int version of the configured protocol
35-
// parameter to avoid constructing a new big integer for every transaction.
36-
blobTxMinBlobGasPrice = big.NewInt(params.BlobTxMinBlobGasprice)
37-
)
34+
// blobTxMinBlobGasPrice is the big.Int version of the configured protocol
35+
// parameter to avoid constructing a new big integer for every transaction.
36+
var blobTxMinBlobGasPrice = big.NewInt(params.BlobTxMinBlobGasprice)
3837

3938
// ValidationOptions define certain differences between transaction validation
4039
// across the different pools without having to duplicate those checks.
@@ -166,19 +165,27 @@ func validateBlobTx(tx *types.Transaction, head *types.Header, opts *ValidationO
166165
if len(hashes) == 0 {
167166
return errors.New("blobless blob transaction")
168167
}
169-
if len(hashes) > params.BlobTxMaxBlobs {
170-
return fmt.Errorf("too many blobs in transaction: have %d, permitted %d", len(hashes), params.BlobTxMaxBlobs)
171-
}
168+
172169
if len(sidecar.Blobs) != len(hashes) {
173170
return fmt.Errorf("invalid number of %d blobs compared to %d blob hashes", len(sidecar.Blobs), len(hashes))
174171
}
175172
if err := sidecar.ValidateBlobCommitmentHashes(hashes); err != nil {
176173
return err
177174
}
178-
// Fork-specific sidecar checks, including proof verification.
175+
// Post-Osaka checks, Fork-specific sidecar checks, including proof verification.
179176
if opts.Config.IsOsaka(head.Number, head.Time) {
177+
if len(hashes) > params.BlobTxMaxBlobs {
178+
return fmt.Errorf("too many blobs in transaction: have %d, permitted %d", len(hashes), params.BlobTxMaxBlobs)
179+
}
180+
180181
return validateBlobSidecarOsaka(sidecar, hashes)
181182
}
183+
184+
maxBlobs := eip4844.MaxBlobsPerBlock(opts.Config, head.Time)
185+
if len(hashes) > maxBlobs {
186+
return fmt.Errorf("too many blobs in transaction: have %d, permitted %d", len(hashes), maxBlobs)
187+
}
188+
182189
return validateBlobSidecarLegacy(sidecar, hashes)
183190
}
184191

0 commit comments

Comments
 (0)