Skip to content

Commit 08aaa7c

Browse files
authored
eth: add debug_clearTxpool api (#33347)
Implement a similar RPC as what reth offers paradigmxyz/reth#18539, to clear the tx pool.
1 parent 10614fc commit 08aaa7c

3 files changed

Lines changed: 88 additions & 0 deletions

File tree

eth/api_debug.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,3 +517,15 @@ func (api *DebugAPI) ExecutionWitness(bn rpc.BlockNumberOrHash) (*stateless.ExtW
517517
}
518518
return result.Witness().ToExtWitness(), nil
519519
}
520+
521+
// ClearTxpool clears all transactions from the transaction pool.
522+
// This method removes all pending and queued transactions from both the
523+
// legacy transaction pool and the blob transaction pool.
524+
//
525+
// Note: This operation invokes Sync() internally and should be used with
526+
// caution as it can be susceptible to DoS vectors. It's primarily intended
527+
// for testing and debugging purposes.
528+
func (api *DebugAPI) ClearTxpool() error {
529+
api.eth.TxPool().Clear()
530+
return nil
531+
}

eth/api_debug_test.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,15 @@ import (
2929

3030
"github.com/davecgh/go-spew/spew"
3131
"github.com/ethereum/go-ethereum/common"
32+
"github.com/ethereum/go-ethereum/consensus/beacon"
3233
"github.com/ethereum/go-ethereum/consensus/ethash"
3334
"github.com/ethereum/go-ethereum/core"
3435
"github.com/ethereum/go-ethereum/core/rawdb"
3536
"github.com/ethereum/go-ethereum/core/state"
3637
"github.com/ethereum/go-ethereum/core/tracing"
38+
"github.com/ethereum/go-ethereum/core/txpool"
39+
"github.com/ethereum/go-ethereum/core/txpool/blobpool"
40+
"github.com/ethereum/go-ethereum/core/txpool/legacypool"
3741
"github.com/ethereum/go-ethereum/core/types"
3842
"github.com/ethereum/go-ethereum/crypto"
3943
"github.com/ethereum/go-ethereum/params"
@@ -335,3 +339,70 @@ func TestGetModifiedAccounts(t *testing.T) {
335339
}
336340
})
337341
}
342+
343+
func TestDebugAPI_ClearTxpool(t *testing.T) {
344+
// Create test key and genesis
345+
testKey, _ := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
346+
testAddress := crypto.PubkeyToAddress(testKey.PublicKey)
347+
testFunds := big.NewInt(1000_000_000_000_000)
348+
testGspec := &core.Genesis{
349+
Config: params.MergedTestChainConfig,
350+
Alloc: types.GenesisAlloc{
351+
testAddress: {Balance: testFunds},
352+
},
353+
Difficulty: common.Big0,
354+
BaseFee: big.NewInt(params.InitialBaseFee),
355+
}
356+
testSigner := types.LatestSignerForChainID(testGspec.Config.ChainID)
357+
358+
// Initialize backend
359+
db := rawdb.NewMemoryDatabase()
360+
engine := beacon.New(ethash.NewFaker())
361+
chain, _ := core.NewBlockChain(db, testGspec, engine, nil)
362+
363+
txconfig := legacypool.DefaultConfig
364+
txconfig.Journal = "" // Don't litter the disk with test journals
365+
366+
blobPool := blobpool.New(blobpool.Config{Datadir: ""}, chain, nil)
367+
legacyPool := legacypool.New(txconfig, chain)
368+
pool, _ := txpool.New(txconfig.PriceLimit, chain, []txpool.SubPool{legacyPool, blobPool})
369+
370+
eth := &Ethereum{
371+
blockchain: chain,
372+
txPool: pool,
373+
}
374+
375+
// Create debug API
376+
api := NewDebugAPI(eth)
377+
378+
// Create and add a test transaction
379+
tx := types.NewTransaction(0, common.Address{1}, big.NewInt(1000), params.TxGas, big.NewInt(params.InitialBaseFee), nil)
380+
signedTx, err := types.SignTx(tx, testSigner, testKey)
381+
if err != nil {
382+
t.Fatalf("Failed to sign transaction: %v", err)
383+
}
384+
385+
// Add transaction to pool
386+
errs := pool.Add([]*types.Transaction{signedTx}, true)
387+
if errs[0] != nil {
388+
t.Logf("Note: Transaction addition returned: %v (this may be expected)", errs[0])
389+
}
390+
391+
// Verify we tried to add a transaction
392+
t.Logf("Transaction added to pool from: %s", testAddress.Hex())
393+
394+
// Clear the transaction pool
395+
err = api.ClearTxpool()
396+
if err != nil {
397+
t.Fatalf("ClearTxpool failed: %v", err)
398+
}
399+
400+
// Verify the pool is empty after clear
401+
pool.Sync()
402+
pending := pool.Pending(txpool.PendingFilter{})
403+
if len(pending) > 0 {
404+
t.Errorf("Expected empty pool after clear, but found %d accounts with pending transactions", len(pending))
405+
}
406+
407+
t.Log("Successfully cleared transaction pool")
408+
}

internal/web3ext/web3ext.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,11 @@ web3._extend({
158158
name: 'stopWS',
159159
call: 'admin_stopWS'
160160
}),
161+
new web3._extend.Method({
162+
name: 'clearTxpool',
163+
call: 'debug_clearTxpool',
164+
params: 0
165+
}),
161166
],
162167
properties: [
163168
new web3._extend.Property({

0 commit comments

Comments
 (0)