@@ -27,7 +27,6 @@ import (
2727 "path/filepath"
2828 "sync"
2929 "testing"
30- "time"
3130
3231 "github.com/ethereum/go-ethereum/common"
3332 "github.com/ethereum/go-ethereum/consensus/misc/eip1559"
@@ -53,33 +52,22 @@ var (
5352 emptyBlobVHash = kzg4844 .CalcBlobHashV1 (sha256 .New (), & emptyBlobCommit )
5453)
5554
56- // Chain configuration with Cancun enabled.
57- //
58- // TODO(karalabe): replace with params.MainnetChainConfig after Cancun.
59- var testChainConfig * params.ChainConfig
60-
61- func init () {
62- testChainConfig = new (params.ChainConfig )
63- * testChainConfig = * params .MainnetChainConfig
64-
65- testChainConfig .CancunTime = new (uint64 )
66- * testChainConfig .CancunTime = uint64 (time .Now ().Unix ())
67- }
68-
6955// testBlockChain is a mock of the live chain for testing the pool.
7056type testBlockChain struct {
7157 config * params.ChainConfig
7258 basefee * uint256.Int
7359 blobfee * uint256.Int
7460 statedb * state.StateDB
61+
62+ blocks map [uint64 ]* types.Block
7563}
7664
7765func (bc * testBlockChain ) Config () * params.ChainConfig {
7866 return bc .config
7967}
8068
8169func (bc * testBlockChain ) CurrentBlock () * types.Header {
82- // Yolo, life is too short to invert mist .CalcBaseFee and misc.CalcBlobFee,
70+ // Yolo, life is too short to invert misc .CalcBaseFee and misc.CalcBlobFee,
8371 // just binary search it them.
8472
8573 // The base fee at 5714 ETH translates into the 21000 base gas higher than
@@ -142,7 +130,14 @@ func (bc *testBlockChain) CurrentFinalBlock() *types.Header {
142130}
143131
144132func (bc * testBlockChain ) GetBlock (hash common.Hash , number uint64 ) * types.Block {
145- return nil
133+ // This is very yolo for the tests. If the number is the origin block we use
134+ // to init the pool, return an empty block with the correct starting header.
135+ //
136+ // If it is something else, return some baked in mock data.
137+ if number == bc .config .LondonBlock .Uint64 ()+ 1 {
138+ return types .NewBlockWithHeader (bc .CurrentBlock ())
139+ }
140+ return bc .blocks [number ]
146141}
147142
148143func (bc * testBlockChain ) StateAt (common.Hash ) (* state.StateDB , error ) {
@@ -181,14 +176,14 @@ func makeAddressReserver() txpool.AddressReserver {
181176// the blob pool.
182177func makeTx (nonce uint64 , gasTipCap uint64 , gasFeeCap uint64 , blobFeeCap uint64 , key * ecdsa.PrivateKey ) * types.Transaction {
183178 blobtx := makeUnsignedTx (nonce , gasTipCap , gasFeeCap , blobFeeCap )
184- return types .MustSignNewTx (key , types .LatestSigner (testChainConfig ), blobtx )
179+ return types .MustSignNewTx (key , types .LatestSigner (params . MainnetChainConfig ), blobtx )
185180}
186181
187182// makeUnsignedTx is a utility method to construct a random blob transaction
188183// without signing it.
189184func makeUnsignedTx (nonce uint64 , gasTipCap uint64 , gasFeeCap uint64 , blobFeeCap uint64 ) * types.BlobTx {
190185 return & types.BlobTx {
191- ChainID : uint256 .MustFromBig (testChainConfig .ChainID ),
186+ ChainID : uint256 .MustFromBig (params . MainnetChainConfig .ChainID ),
192187 Nonce : nonce ,
193188 GasTipCap : uint256 .NewInt (gasTipCap ),
194189 GasFeeCap : uint256 .NewInt (gasFeeCap ),
@@ -229,13 +224,17 @@ func verifyPoolInternals(t *testing.T, pool *BlobPool) {
229224 for hash := range seen {
230225 t .Errorf ("indexed transaction hash #%x missing from lookup table" , hash )
231226 }
232- // Verify that transactions are sorted per account and contain no nonce gaps
227+ // Verify that transactions are sorted per account and contain no nonce gaps,
228+ // and that the first nonce is the next expected one based on the state.
233229 for addr , txs := range pool .index {
234230 for i := 1 ; i < len (txs ); i ++ {
235231 if txs [i ].nonce != txs [i - 1 ].nonce + 1 {
236232 t .Errorf ("addr %v, tx %d nonce mismatch: have %d, want %d" , addr , i , txs [i ].nonce , txs [i - 1 ].nonce + 1 )
237233 }
238234 }
235+ if txs [0 ].nonce != pool .state .GetNonce (addr ) {
236+ t .Errorf ("addr %v, first tx nonce mismatch: have %d, want %d" , addr , txs [0 ].nonce , pool .state .GetNonce (addr ))
237+ }
239238 }
240239 // Verify that calculated evacuation thresholds are correct
241240 for addr , txs := range pool .index {
@@ -331,7 +330,7 @@ func TestOpenDrops(t *testing.T) {
331330 // Insert a transaction with a bad signature to verify that stale junk after
332331 // potential hard-forks can get evicted (case 2)
333332 tx := types .NewTx (& types.BlobTx {
334- ChainID : uint256 .MustFromBig (testChainConfig .ChainID ),
333+ ChainID : uint256 .MustFromBig (params . MainnetChainConfig .ChainID ),
335334 GasTipCap : new (uint256.Int ),
336335 GasFeeCap : new (uint256.Int ),
337336 Gas : 0 ,
@@ -560,7 +559,7 @@ func TestOpenDrops(t *testing.T) {
560559 statedb .Commit (0 , true )
561560
562561 chain := & testBlockChain {
563- config : testChainConfig ,
562+ config : params . MainnetChainConfig ,
564563 basefee : uint256 .NewInt (params .InitialBaseFee ),
565564 blobfee : uint256 .NewInt (params .BlobTxMinBlobGasprice ),
566565 statedb : statedb ,
@@ -679,7 +678,7 @@ func TestOpenIndex(t *testing.T) {
679678 statedb .Commit (0 , true )
680679
681680 chain := & testBlockChain {
682- config : testChainConfig ,
681+ config : params . MainnetChainConfig ,
683682 basefee : uint256 .NewInt (params .InitialBaseFee ),
684683 blobfee : uint256 .NewInt (params .BlobTxMinBlobGasprice ),
685684 statedb : statedb ,
@@ -781,7 +780,7 @@ func TestOpenHeap(t *testing.T) {
781780 statedb .Commit (0 , true )
782781
783782 chain := & testBlockChain {
784- config : testChainConfig ,
783+ config : params . MainnetChainConfig ,
785784 basefee : uint256 .NewInt (1050 ),
786785 blobfee : uint256 .NewInt (105 ),
787786 statedb : statedb ,
@@ -861,7 +860,7 @@ func TestOpenCap(t *testing.T) {
861860 statedb .Commit (0 , true )
862861
863862 chain := & testBlockChain {
864- config : testChainConfig ,
863+ config : params . MainnetChainConfig ,
865864 basefee : uint256 .NewInt (1050 ),
866865 blobfee : uint256 .NewInt (105 ),
867866 statedb : statedb ,
@@ -908,13 +907,12 @@ func TestOpenCap(t *testing.T) {
908907func TestAdd (t * testing.T ) {
909908 log .SetDefault (log .NewLogger (log .NewTerminalHandlerWithLevel (os .Stderr , log .LevelTrace , true )))
910909
911- // seed is a helper tumpe to seed an initial state db and pool
910+ // seed is a helper tuple to seed an initial state db and pool
912911 type seed struct {
913912 balance uint64
914913 nonce uint64
915914 txs []* types.BlobTx
916915 }
917-
918916 // addtx is a helper sender/tx tuple to represent a new tx addition
919917 type addtx struct {
920918 from string
@@ -925,6 +923,7 @@ func TestAdd(t *testing.T) {
925923 tests := []struct {
926924 seeds map [string ]seed
927925 adds []addtx
926+ block []addtx
928927 }{
929928 // Transactions from new accounts should be accepted if their initial
930929 // nonce matches the expected one from the statedb. Higher or lower must
@@ -1250,6 +1249,25 @@ func TestAdd(t *testing.T) {
12501249 },
12511250 },
12521251 },
1252+ // Tests issue #30518 where a refactor broke internal state invariants,
1253+ // causing included transactions not to be properly accounted and thus
1254+ // account states going our of sync with the chain.
1255+ {
1256+ seeds : map [string ]seed {
1257+ "alice" : {
1258+ balance : 1000000 ,
1259+ txs : []* types.BlobTx {
1260+ makeUnsignedTx (0 , 1 , 1 , 1 ),
1261+ },
1262+ },
1263+ },
1264+ block : []addtx {
1265+ {
1266+ from : "alice" ,
1267+ tx : makeUnsignedTx (0 , 1 , 1 , 1 ),
1268+ },
1269+ },
1270+ },
12531271 }
12541272 for i , tt := range tests {
12551273 // Create a temporary folder for the persistent backend
@@ -1276,7 +1294,7 @@ func TestAdd(t *testing.T) {
12761294
12771295 // Sign the seed transactions and store them in the data store
12781296 for _ , tx := range seed .txs {
1279- signed := types .MustSignNewTx (keys [acc ], types .LatestSigner (testChainConfig ), tx )
1297+ signed := types .MustSignNewTx (keys [acc ], types .LatestSigner (params . MainnetChainConfig ), tx )
12801298 blob , _ := rlp .EncodeToBytes (signed )
12811299 store .Put (blob )
12821300 }
@@ -1286,7 +1304,7 @@ func TestAdd(t *testing.T) {
12861304
12871305 // Create a blob pool out of the pre-seeded dats
12881306 chain := & testBlockChain {
1289- config : testChainConfig ,
1307+ config : params . MainnetChainConfig ,
12901308 basefee : uint256 .NewInt (1050 ),
12911309 blobfee : uint256 .NewInt (105 ),
12921310 statedb : statedb ,
@@ -1299,14 +1317,40 @@ func TestAdd(t *testing.T) {
12991317
13001318 // Add each transaction one by one, verifying the pool internals in between
13011319 for j , add := range tt .adds {
1302- signed , _ := types .SignNewTx (keys [add .from ], types .LatestSigner (testChainConfig ), add .tx )
1320+ signed , _ := types .SignNewTx (keys [add .from ], types .LatestSigner (params . MainnetChainConfig ), add .tx )
13031321 if err := pool .add (signed ); ! errors .Is (err , add .err ) {
13041322 t .Errorf ("test %d, tx %d: adding transaction error mismatch: have %v, want %v" , i , j , err , add .err )
13051323 }
13061324 verifyPoolInternals (t , pool )
13071325 }
1308- // Verify the pool internals and close down the test
13091326 verifyPoolInternals (t , pool )
1327+
1328+ // If the test contains a chain head event, run that and gain verify the internals
1329+ if tt .block != nil {
1330+ // Fake a header for the new set of transactions
1331+ header := & types.Header {
1332+ Number : big .NewInt (int64 (chain .CurrentBlock ().Number .Uint64 () + 1 )),
1333+ BaseFee : chain .CurrentBlock ().BaseFee , // invalid, but nothing checks it, yolo
1334+ }
1335+ // Inject the fake block into the chain
1336+ txs := make ([]* types.Transaction , len (tt .block ))
1337+ for j , inc := range tt .block {
1338+ txs [j ] = types .MustSignNewTx (keys [inc .from ], types .LatestSigner (params .MainnetChainConfig ), inc .tx )
1339+ }
1340+ chain .blocks = map [uint64 ]* types.Block {
1341+ header .Number .Uint64 (): types .NewBlockWithHeader (header ).WithBody (types.Body {
1342+ Transactions : txs ,
1343+ }),
1344+ }
1345+ // Apply the nonce updates to the state db
1346+ for _ , tx := range txs {
1347+ sender , _ := types .Sender (types .LatestSigner (params .MainnetChainConfig ), tx )
1348+ chain .statedb .SetNonce (sender , tx .Nonce ()+ 1 )
1349+ }
1350+ pool .Reset (chain .CurrentBlock (), header )
1351+ verifyPoolInternals (t , pool )
1352+ }
1353+ // Close down the test
13101354 pool .Close ()
13111355 }
13121356}
@@ -1325,10 +1369,10 @@ func benchmarkPoolPending(b *testing.B, datacap uint64) {
13251369 var (
13261370 basefee = uint64 (1050 )
13271371 blobfee = uint64 (105 )
1328- signer = types .LatestSigner (testChainConfig )
1372+ signer = types .LatestSigner (params . MainnetChainConfig )
13291373 statedb , _ = state .New (types .EmptyRootHash , state .NewDatabaseForTesting ())
13301374 chain = & testBlockChain {
1331- config : testChainConfig ,
1375+ config : params . MainnetChainConfig ,
13321376 basefee : uint256 .NewInt (basefee ),
13331377 blobfee : uint256 .NewInt (blobfee ),
13341378 statedb : statedb ,
0 commit comments