mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-23 05:06:43 +00:00
core/txpool/blobpool: add test for migration of existing txs at osaka boundary
This commit is contained in:
parent
ffc9d69cb2
commit
e194ef6393
1 changed files with 109 additions and 26 deletions
|
|
@ -2101,25 +2101,43 @@ func TestGetBlobs(t *testing.T) {
|
||||||
// TestSidecarConversion will verify that after the Osaka fork, all legacy
|
// TestSidecarConversion will verify that after the Osaka fork, all legacy
|
||||||
// sidecars in the pool are successfully convert to v1 sidecars.
|
// sidecars in the pool are successfully convert to v1 sidecars.
|
||||||
func TestSidecarConversion(t *testing.T) {
|
func TestSidecarConversion(t *testing.T) {
|
||||||
// log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelDebug, true)))
|
// log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelTrace, true)))
|
||||||
|
|
||||||
// Create a temporary folder for the persistent backend
|
// Create a temporary folder for the persistent backend
|
||||||
storage := t.TempDir()
|
storage := t.TempDir()
|
||||||
os.MkdirAll(filepath.Join(storage, pendingTransactionStore), 0700)
|
os.MkdirAll(filepath.Join(storage, pendingTransactionStore), 0700)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
count = 10
|
preOsakaTxs = make(types.Transactions, 10)
|
||||||
keys = make([]*ecdsa.PrivateKey, count)
|
postOsakaTxs = make(types.Transactions, 3)
|
||||||
addrs = make([]common.Address, count)
|
keys = make([]*ecdsa.PrivateKey, len(preOsakaTxs)+len(postOsakaTxs))
|
||||||
|
addrs = make([]common.Address, len(preOsakaTxs)+len(postOsakaTxs))
|
||||||
statedb, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
||||||
)
|
)
|
||||||
for i := 0; i < count; i++ {
|
for i := range keys {
|
||||||
keys[i], _ = crypto.GenerateKey()
|
keys[i], _ = crypto.GenerateKey()
|
||||||
addrs[i] = crypto.PubkeyToAddress(keys[i].PublicKey)
|
addrs[i] = crypto.PubkeyToAddress(keys[i].PublicKey)
|
||||||
statedb.AddBalance(addrs[i], uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
statedb.AddBalance(addrs[i], uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||||
}
|
}
|
||||||
|
for i := range preOsakaTxs {
|
||||||
|
preOsakaTxs[i] = makeMultiBlobTx(0, 1, 1000, 100, 2, 0, keys[i], types.BlobSidecarVersion0)
|
||||||
|
}
|
||||||
|
for i := range postOsakaTxs {
|
||||||
|
if i == 0 {
|
||||||
|
// First has a v0 sidecar.
|
||||||
|
postOsakaTxs[i] = makeMultiBlobTx(0, 1, 1000, 100, 1, 0, keys[len(preOsakaTxs)+i], types.BlobSidecarVersion0)
|
||||||
|
}
|
||||||
|
postOsakaTxs[i] = makeMultiBlobTx(0, 1, 1000, 100, 1, 0, keys[len(preOsakaTxs)+i], types.BlobSidecarVersion1)
|
||||||
|
}
|
||||||
statedb.Commit(0, true, false)
|
statedb.Commit(0, true, false)
|
||||||
|
|
||||||
|
// Test plan:
|
||||||
|
// 1) Create a bunch v0 sidecar txs and add to pool before Osaka.
|
||||||
|
// 2) Pass in new Osaka header to activate the conversion thread.
|
||||||
|
// 3) Continue adding both v0 and v1 transactions to the pool.
|
||||||
|
// 4) Verify that as additional blocks come in, transactions involved in the
|
||||||
|
// migration are correctly discarded.
|
||||||
|
|
||||||
config := ¶ms.ChainConfig{
|
config := ¶ms.ChainConfig{
|
||||||
ChainID: big.NewInt(1),
|
ChainID: big.NewInt(1),
|
||||||
LondonBlock: big.NewInt(0),
|
LondonBlock: big.NewInt(0),
|
||||||
|
|
@ -2134,35 +2152,106 @@ func TestSidecarConversion(t *testing.T) {
|
||||||
basefee: uint256.NewInt(1050),
|
basefee: uint256.NewInt(1050),
|
||||||
blobfee: uint256.NewInt(105),
|
blobfee: uint256.NewInt(105),
|
||||||
statedb: statedb,
|
statedb: statedb,
|
||||||
|
blocks: make(map[uint64]*types.Block),
|
||||||
}
|
}
|
||||||
|
|
||||||
before := chain.CurrentBlock()
|
// Create 3 blocks:
|
||||||
before.Time = 0
|
// - the current block, before Osaka
|
||||||
after := chain.CurrentBlock()
|
// - the first block after Osaka
|
||||||
after.Time = 1
|
// - another post-Osaka block with several transactions in it
|
||||||
|
header0 := chain.CurrentBlock()
|
||||||
|
header0.Time = 0
|
||||||
|
chain.blocks[0] = types.NewBlockWithHeader(header0)
|
||||||
|
|
||||||
|
header1 := chain.CurrentBlock()
|
||||||
|
header1.Number = big.NewInt(1)
|
||||||
|
header1.Time = 1
|
||||||
|
chain.blocks[1] = types.NewBlockWithHeader(header1)
|
||||||
|
|
||||||
|
header2 := chain.CurrentBlock()
|
||||||
|
header2.Time = 2
|
||||||
|
header2.Number = big.NewInt(2)
|
||||||
|
|
||||||
|
// Make a copy of one of the pre-Osaka transactions and convert it to v1 here
|
||||||
|
// so that we can add it to the pool later and ensure a duplicate is not added
|
||||||
|
// by the conversion queue.
|
||||||
|
tx := preOsakaTxs[len(preOsakaTxs)-1]
|
||||||
|
sc := *tx.BlobTxSidecar() // copy sidecar
|
||||||
|
sc.ToV1()
|
||||||
|
tx.WithBlobTxSidecar(&sc)
|
||||||
|
|
||||||
|
block2 := types.NewBlockWithHeader(header2).WithBody(types.Body{Transactions: append(postOsakaTxs, tx)})
|
||||||
|
chain.blocks[2] = block2
|
||||||
|
|
||||||
pool := New(Config{Datadir: storage}, chain, nil)
|
pool := New(Config{Datadir: storage}, chain, nil)
|
||||||
if err := pool.Init(1, before, newReserver()); err != nil {
|
if err := pool.Init(1, header0, newReserver()); err != nil {
|
||||||
t.Fatalf("failed to create blob pool: %v", err)
|
t.Fatalf("failed to create blob pool: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, key := range keys {
|
errs := pool.Add(preOsakaTxs, true)
|
||||||
tx := makeMultiBlobTx(0, 1, 1000, 100, 2, 0, key, types.BlobSidecarVersion0)
|
for i, err := range errs {
|
||||||
if errs := pool.Add([]*types.Transaction{tx}, true); errs[0] != nil {
|
if err != nil {
|
||||||
t.Errorf("failed to insert blob tx from %s: %s", addrs[i], errs[0])
|
t.Errorf("failed to insert blob tx from %s: %s", addrs[i], errs[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should kick off migration.
|
// Kick off migration.
|
||||||
pool.sidecarMigrationDoneCh = make(chan struct{})
|
pool.sidecarMigrationDoneCh = make(chan struct{})
|
||||||
pool.Reset(before, after)
|
pool.Reset(header0, header1)
|
||||||
|
|
||||||
|
// Add the v0 sidecar tx, but don't block so we can keep doing other stuff
|
||||||
|
// while it converts the sidecar.
|
||||||
|
addDone := make(chan struct{})
|
||||||
|
go func() {
|
||||||
|
pool.Add(types.Transactions{postOsakaTxs[0]}, false)
|
||||||
|
close(addDone)
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Add the post-Osaka v1 sidecar txs.
|
||||||
|
errs = pool.Add(postOsakaTxs[1:], false)
|
||||||
|
for _, err := range errs {
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expected tx add to succeed: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for the first tx's conversion to complete, then check that all
|
||||||
|
// transactions added after Osaka can be accounted for in the pool.
|
||||||
|
<-addDone
|
||||||
|
pending := pool.Pending(txpool.PendingFilter{BlobTxs: true, BlobVersion: types.BlobSidecarVersion1})
|
||||||
|
for _, tx := range postOsakaTxs {
|
||||||
|
from, _ := pool.signer.Sender(tx)
|
||||||
|
if len(pending[from]) != 1 || pending[from][0].Hash != tx.Hash() {
|
||||||
|
t.Fatalf("expected post-Osaka txs to be pending")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now update the pool with the next block. This should cause the pool to
|
||||||
|
// clear out the post-Osaka txs since they were included in block 2. Since the
|
||||||
|
// test blockchain doesn't manage nonces, we'll just do that manually before
|
||||||
|
// the reset is called. Don't forget about the pre-Osaka transaction we also
|
||||||
|
// added to block 2!
|
||||||
|
for i := range postOsakaTxs {
|
||||||
|
statedb.SetNonce(addrs[len(preOsakaTxs)+i], 1, tracing.NonceChangeEoACall)
|
||||||
|
}
|
||||||
|
statedb.SetNonce(addrs[len(preOsakaTxs)-1], 1, tracing.NonceChangeEoACall)
|
||||||
|
pool.Reset(header1, block2.Header())
|
||||||
|
|
||||||
|
// Now verify no post-Osaka transadctions are tracked by the pool.
|
||||||
|
for i, tx := range postOsakaTxs {
|
||||||
|
if pool.Get(tx.Hash()) != nil {
|
||||||
|
t.Fatalf("expected txs added post-osaka to have been placed in limbo due to inclusion in a block: index %d, hash %s", i, tx.Hash())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for the pool migration to complete.
|
||||||
<-pool.sidecarMigrationDoneCh
|
<-pool.sidecarMigrationDoneCh
|
||||||
|
|
||||||
// Verify all transactions in the pool were converted and verify the
|
// Verify all transactions in the pool were converted and verify the
|
||||||
// subsequent cell proofs.
|
// subsequent cell proofs.
|
||||||
pending, _ := pool.Stats()
|
count, _ := pool.Stats()
|
||||||
if pending != count {
|
if count != len(preOsakaTxs)-1 {
|
||||||
t.Errorf("expected pending count to match initial tx count: pending=%d, expected=%d", pending, count)
|
t.Errorf("expected pending count to match initial tx count: pending=%d, expected=%d", count, len(preOsakaTxs)-1)
|
||||||
}
|
}
|
||||||
for addr, acc := range pool.index {
|
for addr, acc := range pool.index {
|
||||||
for _, m := range acc {
|
for _, m := range acc {
|
||||||
|
|
@ -2180,13 +2269,7 @@ func TestSidecarConversion(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify all the calculated pool internals. Interestingly, this is **not**
|
|
||||||
// a duplication of the above checks, this actually validates the verifier
|
|
||||||
// using the above already hard coded checks.
|
|
||||||
//
|
|
||||||
// Do not remove this, nor alter the above to be generic.
|
|
||||||
verifyPoolInternals(t, pool)
|
verifyPoolInternals(t, pool)
|
||||||
|
|
||||||
pool.Close()
|
pool.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue