mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-12 06:53:46 +00:00
core/txpool/legacypool: add integrity checks to avoid dangling auths in tracker
This commit is contained in:
parent
bcb983693e
commit
1212781c9a
1 changed files with 44 additions and 0 deletions
|
|
@ -23,6 +23,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"slices"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
@ -238,6 +239,23 @@ func validatePoolInternals(pool *LegacyPool) error {
|
||||||
return fmt.Errorf("pending nonce mismatch: have %v, want %v", nonce, last+1)
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2381,6 +2399,32 @@ 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)
|
tt.run(tt.name)
|
||||||
pending, queued := pool.Stats()
|
pending, queued := pool.Stats()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue