From 03f4a1bb1203a78ca6f7b42e00b380069c66c008 Mon Sep 17 00:00:00 2001 From: lightclient Date: Tue, 25 Feb 2025 21:55:08 -0700 Subject: [PATCH] core/txpool/legacypool: fix incorrect error in authority tracker when removing tx --- core/txpool/legacypool/legacypool.go | 2 -- core/txpool/legacypool/legacypool_test.go | 43 +++++++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go index 4250283b03..e959bdb55f 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -1814,8 +1814,6 @@ func (t *lookup) removeAuthorities(hash common.Hash) { // Remove tx from tracker. if i := slices.Index(list, hash); i >= 0 { list = append(list[:i], list[i+1:]...) - } else { - log.Error("Authority with untracked tx", "addr", addr, "hash", hash) } if len(list) == 0 { // If list is newly empty, delete it entirely. diff --git a/core/txpool/legacypool/legacypool_test.go b/core/txpool/legacypool/legacypool_test.go index b2a068467f..5cc00785a4 100644 --- a/core/txpool/legacypool/legacypool_test.go +++ b/core/txpool/legacypool/legacypool_test.go @@ -23,6 +23,7 @@ import ( "fmt" "math/big" "math/rand" + "slices" "sync" "sync/atomic" "testing" @@ -238,6 +239,23 @@ func validatePoolInternals(pool *LegacyPool) error { return fmt.Errorf("pending nonce mismatch: have %v, want %v", nonce, last+1) } } + // Ensure all auths in pool are tracked + for _, tx := range pool.all.txs { + for _, addr := range tx.SetCodeAuthorities() { + list := pool.all.auths[addr] + if i := slices.Index(list, tx.Hash()); i < 0 { + return fmt.Errorf("authority not tracked: addr %s, tx %s", addr, tx.Hash()) + } + } + } + // Ensure all auths in pool have an associated tx. + for addr, hashes := range pool.all.auths { + for _, hash := range hashes { + if _, ok := pool.all.txs[hash]; !ok { + return fmt.Errorf("dangling authority, missing originating tx: addr %s, hash %s", addr, hash.Hex()) + } + } + } return nil } @@ -2381,6 +2399,31 @@ func TestSetCodeTransactions(t *testing.T) { } }, }, + { + name: "remove-hash-from-authority-tracker", + pending: 10, + run: func(name string) { + var keys []*ecdsa.PrivateKey + for i := 0; i < 30; i++ { + key, _ := crypto.GenerateKey() + keys = append(keys, key) + addr := crypto.PubkeyToAddress(key.PublicKey) + testAddBalance(pool, addr, big.NewInt(params.Ether)) + } + // Create a transactions with 3 unique auths so the lookup's auth map is + // filled with addresses. + for i := 0; i < 30; i += 3 { + if err := pool.addRemoteSync(pricedSetCodeTx(0, 250000, uint256.NewInt(10), uint256.NewInt(3), keys[i], []unsignedAuth{{0, keys[i]}, {0, keys[i+1]}, {0, keys[i+2]}})); err != nil { + t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err) + } + } + // Replace one of the transactions with a normal transaction so that the + // original hash is removed from the tracker. The hash should be associated with 3 different authorities. + if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1000), keys[0])); err != nil { + t.Fatalf("%s: failed to replace with remote transaction: %v", name, err) + } + }, + }, } { tt.run(tt.name) pending, queued := pool.Stats()