@@ -24,6 +24,7 @@ import (
24
24
"math/big"
25
25
"math/rand"
26
26
"os"
27
+ "slices"
27
28
"sync"
28
29
"sync/atomic"
29
30
"testing"
@@ -174,6 +175,33 @@ func validatePoolInternals(pool *LegacyPool) error {
174
175
return fmt .Errorf ("totalcost went negative: %v" , txs .totalcost )
175
176
}
176
177
}
178
+ // Ensure all auths in pool are tracked
179
+ for _ , tx := range pool .all .locals {
180
+ for _ , addr := range tx .SetCodeAuthorities () {
181
+ list := pool .all .auths [addr ]
182
+ if i := slices .Index (list , tx .Hash ()); i < 0 {
183
+ return fmt .Errorf ("authority not tracked: addr %s, tx %s" , addr , tx .Hash ())
184
+ }
185
+ }
186
+ }
187
+ for _ , tx := range pool .all .remotes {
188
+ for _ , addr := range tx .SetCodeAuthorities () {
189
+ list := pool .all .auths [addr ]
190
+ if i := slices .Index (list , tx .Hash ()); i < 0 {
191
+ return fmt .Errorf ("authority not tracked: addr %s, tx %s" , addr , tx .Hash ())
192
+ }
193
+ }
194
+ }
195
+ // Ensure all auths in pool have an associated tx.
196
+ for addr , hashes := range pool .all .auths {
197
+ for _ , hash := range hashes {
198
+ _ , foundLocal := pool .all .locals [hash ]
199
+ _ , foundRemote := pool .all .remotes [hash ]
200
+ if ! foundLocal && ! foundRemote {
201
+ return fmt .Errorf ("dangling authority, missing originating tx: addr %s, hash %s" , addr , hash .Hex ())
202
+ }
203
+ }
204
+ }
177
205
return nil
178
206
}
179
207
@@ -2779,6 +2807,32 @@ func TestSetCodeTransactions(t *testing.T) {
2779
2807
}
2780
2808
},
2781
2809
},
2810
+ {
2811
+ name : "remove-hash-from-authority-tracker" ,
2812
+ pending : 10 ,
2813
+ run : func (name string ) {
2814
+ var keys []* ecdsa.PrivateKey
2815
+ for i := 0 ; i < 30 ; i ++ {
2816
+ key , _ := crypto .GenerateKey ()
2817
+ keys = append (keys , key )
2818
+ addr := crypto .PubkeyToAddress (key .PublicKey )
2819
+ testAddBalance (pool , addr , big .NewInt (params .Ether ))
2820
+ }
2821
+ // Create a transactions with 3 unique auths so the lookup's auth map is
2822
+ // filled with addresses.
2823
+ for i := 0 ; i < 30 ; i += 3 {
2824
+ 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 {
2825
+ t .Fatalf ("%s: failed to add with remote setcode transaction: %v" , name , err )
2826
+ }
2827
+ }
2828
+ // Replace one of the transactions with a normal transaction so that the
2829
+ // original hash is removed from the tracker. The hash should be
2830
+ // associated with 3 different authorities.
2831
+ if err := pool .addRemoteSync (pricedTransaction (0 , 100000 , big .NewInt (1000 ), keys [0 ])); err != nil {
2832
+ t .Fatalf ("%s: failed to replace with remote transaction: %v" , name , err )
2833
+ }
2834
+ },
2835
+ },
2782
2836
} {
2783
2837
tt .run (tt .name )
2784
2838
pending , queued := pool .Stats ()
0 commit comments