Tests that more expensive transactions push out cheap ones from the pool, but without producing instability by creating gaps that start jumping transactions back and forth between queued/pending.
(t *testing.T)
| 1428 | // without producing instability by creating gaps that start jumping transactions |
| 1429 | // back and forth between queued/pending. |
| 1430 | func TestTransactionPoolStableUnderpricing(t *testing.T) { |
| 1431 | t.Parallel() |
| 1432 | |
| 1433 | // Create the pool to test the pricing enforcement with |
| 1434 | statedb, _ := state.New(common.Hash{}, state.NewDatabase(database.NewMemDatabase())) |
| 1435 | blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} |
| 1436 | |
| 1437 | config := testTxPoolConfig |
| 1438 | config.GlobalSlots = 128 |
| 1439 | config.GlobalQueue = 0 |
| 1440 | |
| 1441 | pool := NewTxPool(config, configs.TestChainConfig, blockchain) |
| 1442 | defer pool.Stop() |
| 1443 | |
| 1444 | // Keep track of transaction events to ensure all executables get announced |
| 1445 | events := make(chan NewTxsEvent, 32) |
| 1446 | sub := pool.txFeed.Subscribe(events) |
| 1447 | defer sub.Unsubscribe() |
| 1448 | |
| 1449 | // Create a number of test accounts and fund them |
| 1450 | keys := make([]*ecdsa.PrivateKey, 2) |
| 1451 | for i := 0; i < len(keys); i++ { |
| 1452 | keys[i], _ = crypto.GenerateKey() |
| 1453 | pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000)) |
| 1454 | } |
| 1455 | // Fill up the entire queue with the same transaction price points |
| 1456 | txs := types.Transactions{} |
| 1457 | for i := uint64(0); i < config.GlobalSlots; i++ { |
| 1458 | txs = append(txs, pricedTransaction(i, 100000, big.NewInt(1), keys[0])) |
| 1459 | } |
| 1460 | pool.AddRemotes(txs) |
| 1461 | |
| 1462 | pending, queued := pool.Stats() |
| 1463 | if pending != int(config.GlobalSlots) { |
| 1464 | t.Fatalf("pending transactions mismatched: have %d, want %d", pending, config.GlobalSlots) |
| 1465 | } |
| 1466 | if queued != 0 { |
| 1467 | t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) |
| 1468 | } |
| 1469 | if err := validateEvents(events, int(config.GlobalSlots)); err != nil { |
| 1470 | t.Fatalf("original event firing failed: %v", err) |
| 1471 | } |
| 1472 | if err := validateTxPoolInternals(pool); err != nil { |
| 1473 | t.Fatalf("pool internal state corrupted: %v", err) |
| 1474 | } |
| 1475 | // Ensure that adding high priced transactions drops a cheap, but doesn't produce a gap |
| 1476 | if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(3), keys[1])); err != nil { |
| 1477 | t.Fatalf("failed to add well priced transaction: %v", err) |
| 1478 | } |
| 1479 | pending, queued = pool.Stats() |
| 1480 | if pending != int(config.GlobalSlots) { |
| 1481 | t.Fatalf("pending transactions mismatched: have %d, want %d", pending, config.GlobalSlots) |
| 1482 | } |
| 1483 | if queued != 0 { |
| 1484 | t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) |
| 1485 | } |
| 1486 | if err := validateEvents(events, 1); err != nil { |
| 1487 | t.Fatalf("additional event firing failed: %v", err) |
nothing calls this directly
no test coverage detected