mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
core: Test drop / reject in txpool tests
This extends the existing txpool tests to evaluate the number of dropped and rejected transactions throughout each test.
This commit is contained in:
parent
2791b22d83
commit
f7dc0f5b73
1 changed files with 118 additions and 0 deletions
|
|
@ -152,6 +152,55 @@ func validateEvents(events chan NewTxsEvent, count int) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// validateDroppedEvents checks that the correct number of transaction rejection
|
||||
// and drop events were fired.
|
||||
func validateDroppedEvents(reject chan RejectedTxEvent, rcount int, dropped chan DropTxsEvent, dcount int) error {
|
||||
count := 0
|
||||
for count < rcount {
|
||||
select {
|
||||
case <-reject:
|
||||
count++
|
||||
case <-time.After(time.Second):
|
||||
return fmt.Errorf("reject event #%d not fired", count)
|
||||
}
|
||||
}
|
||||
rloop:
|
||||
for {
|
||||
select {
|
||||
case <-reject:
|
||||
count++
|
||||
case <-time.After(50 * time.Millisecond):
|
||||
break rloop
|
||||
}
|
||||
}
|
||||
if count > rcount {
|
||||
return fmt.Errorf("more than %v reject events fired: %v", rcount, count)
|
||||
}
|
||||
count = 0
|
||||
for count < dcount {
|
||||
select {
|
||||
case <-dropped:
|
||||
count++
|
||||
case <-time.After(time.Second):
|
||||
return fmt.Errorf("drop event #%d not fired", count)
|
||||
}
|
||||
}
|
||||
dloop:
|
||||
for {
|
||||
select {
|
||||
case <-dropped:
|
||||
count++
|
||||
case <-time.After(50 * time.Millisecond):
|
||||
break dloop
|
||||
}
|
||||
}
|
||||
if count > dcount {
|
||||
return fmt.Errorf("more than %v drop events fired: %v", dcount, count)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func deriveSender(tx *types.Transaction) (common.Address, error) {
|
||||
return types.Sender(types.HomesteadSigner{}, tx)
|
||||
}
|
||||
|
|
@ -689,6 +738,12 @@ func TestTransactionGapFilling(t *testing.T) {
|
|||
events := make(chan NewTxsEvent, testTxPoolConfig.AccountQueue+5)
|
||||
sub := pool.txFeed.Subscribe(events)
|
||||
defer sub.Unsubscribe()
|
||||
revents := make(chan RejectedTxEvent, testTxPoolConfig.AccountQueue+5)
|
||||
rsub := pool.rejectTxFeed.Subscribe(revents)
|
||||
defer rsub.Unsubscribe()
|
||||
devents := make(chan DropTxsEvent, testTxPoolConfig.AccountQueue+5)
|
||||
dsub := pool.dropTxFeed.Subscribe(devents)
|
||||
defer dsub.Unsubscribe()
|
||||
|
||||
// Create a pending and a queued transaction with a nonce-gap in between
|
||||
pool.AddRemotesSync([]*types.Transaction{
|
||||
|
|
@ -722,6 +777,9 @@ func TestTransactionGapFilling(t *testing.T) {
|
|||
if err := validateEvents(events, 2); err != nil {
|
||||
t.Fatalf("gap-filling event firing failed: %v", err)
|
||||
}
|
||||
if err := validateDroppedEvents(revents, 0, devents, 6); err != nil {
|
||||
t.Errorf("gap-filling drop / reject event firing failed: %v", err)
|
||||
}
|
||||
if err := validateTxPoolInternals(pool); err != nil {
|
||||
t.Fatalf("pool internal state corrupted: %v", err)
|
||||
}
|
||||
|
|
@ -1201,6 +1259,12 @@ func TestTransactionPoolRepricing(t *testing.T) {
|
|||
if err := validateEvents(events, 7); err != nil {
|
||||
t.Fatalf("original event firing failed: %v", err)
|
||||
}
|
||||
revents := make(chan RejectedTxEvent, testTxPoolConfig.AccountQueue+5)
|
||||
rsub := pool.rejectTxFeed.Subscribe(revents)
|
||||
defer rsub.Unsubscribe()
|
||||
devents := make(chan DropTxsEvent, testTxPoolConfig.AccountQueue+5)
|
||||
dsub := pool.dropTxFeed.Subscribe(devents)
|
||||
defer dsub.Unsubscribe()
|
||||
if err := validateTxPoolInternals(pool); err != nil {
|
||||
t.Fatalf("pool internal state corrupted: %v", err)
|
||||
}
|
||||
|
|
@ -1217,6 +1281,9 @@ func TestTransactionPoolRepricing(t *testing.T) {
|
|||
if err := validateEvents(events, 0); err != nil {
|
||||
t.Fatalf("reprice event firing failed: %v", err)
|
||||
}
|
||||
if err := validateDroppedEvents(revents, 0, devents, 3); err != nil {
|
||||
t.Errorf("gap-filling drop / reject event firing failed: %v", err)
|
||||
}
|
||||
if err := validateTxPoolInternals(pool); err != nil {
|
||||
t.Fatalf("pool internal state corrupted: %v", err)
|
||||
}
|
||||
|
|
@ -1233,6 +1300,9 @@ func TestTransactionPoolRepricing(t *testing.T) {
|
|||
if err := validateEvents(events, 0); err != nil {
|
||||
t.Fatalf("post-reprice event firing failed: %v", err)
|
||||
}
|
||||
if err := validateDroppedEvents(revents, 3, devents, 0); err != nil {
|
||||
t.Errorf("gap-filling drop / reject event firing failed: %v", err)
|
||||
}
|
||||
if err := validateTxPoolInternals(pool); err != nil {
|
||||
t.Fatalf("pool internal state corrupted: %v", err)
|
||||
}
|
||||
|
|
@ -1247,6 +1317,9 @@ func TestTransactionPoolRepricing(t *testing.T) {
|
|||
if err := validateEvents(events, 1); err != nil {
|
||||
t.Fatalf("post-reprice local event firing failed: %v", err)
|
||||
}
|
||||
if err := validateDroppedEvents(revents, 0, devents, 2); err != nil {
|
||||
t.Errorf("gap-filling drop / reject event firing failed: %v", err)
|
||||
}
|
||||
if err := validateTxPoolInternals(pool); err != nil {
|
||||
t.Fatalf("pool internal state corrupted: %v", err)
|
||||
}
|
||||
|
|
@ -1263,6 +1336,9 @@ func TestTransactionPoolRepricing(t *testing.T) {
|
|||
if err := validateEvents(events, 5); err != nil {
|
||||
t.Fatalf("post-reprice event firing failed: %v", err)
|
||||
}
|
||||
if err := validateDroppedEvents(revents, 0, devents, 9); err != nil {
|
||||
t.Errorf("gap-filling drop / reject event firing failed: %v", err)
|
||||
}
|
||||
if err := validateTxPoolInternals(pool); err != nil {
|
||||
t.Fatalf("pool internal state corrupted: %v", err)
|
||||
}
|
||||
|
|
@ -1350,6 +1426,12 @@ func TestTransactionPoolUnderpricing(t *testing.T) {
|
|||
events := make(chan NewTxsEvent, 32)
|
||||
sub := pool.txFeed.Subscribe(events)
|
||||
defer sub.Unsubscribe()
|
||||
revents := make(chan RejectedTxEvent, testTxPoolConfig.AccountQueue+5)
|
||||
rsub := pool.rejectTxFeed.Subscribe(revents)
|
||||
defer rsub.Unsubscribe()
|
||||
devents := make(chan DropTxsEvent, testTxPoolConfig.AccountQueue+5)
|
||||
dsub := pool.dropTxFeed.Subscribe(devents)
|
||||
defer dsub.Unsubscribe()
|
||||
|
||||
// Create a number of test accounts and fund them
|
||||
keys := make([]*ecdsa.PrivateKey, 4)
|
||||
|
|
@ -1381,6 +1463,9 @@ func TestTransactionPoolUnderpricing(t *testing.T) {
|
|||
if err := validateEvents(events, 3); err != nil {
|
||||
t.Fatalf("original event firing failed: %v", err)
|
||||
}
|
||||
if err := validateDroppedEvents(revents, 0, devents, 8); err != nil {
|
||||
t.Errorf("gap-filling drop / reject event firing failed: %v", err)
|
||||
}
|
||||
if err := validateTxPoolInternals(pool); err != nil {
|
||||
t.Fatalf("pool internal state corrupted: %v", err)
|
||||
}
|
||||
|
|
@ -1408,6 +1493,9 @@ func TestTransactionPoolUnderpricing(t *testing.T) {
|
|||
if err := validateEvents(events, 1); err != nil {
|
||||
t.Fatalf("additional event firing failed: %v", err)
|
||||
}
|
||||
if err := validateDroppedEvents(revents, 1, devents, 13); err != nil {
|
||||
t.Errorf("gap-filling drop / reject event firing failed: %v", err)
|
||||
}
|
||||
if err := validateTxPoolInternals(pool); err != nil {
|
||||
t.Fatalf("pool internal state corrupted: %v", err)
|
||||
}
|
||||
|
|
@ -1430,6 +1518,9 @@ func TestTransactionPoolUnderpricing(t *testing.T) {
|
|||
if err := validateEvents(events, 2); err != nil {
|
||||
t.Fatalf("local event firing failed: %v", err)
|
||||
}
|
||||
if err := validateDroppedEvents(revents, 0, devents, 7); err != nil {
|
||||
t.Errorf("gap-filling drop / reject event firing failed: %v", err)
|
||||
}
|
||||
if err := validateTxPoolInternals(pool); err != nil {
|
||||
t.Fatalf("pool internal state corrupted: %v", err)
|
||||
}
|
||||
|
|
@ -1456,6 +1547,12 @@ func TestTransactionPoolStableUnderpricing(t *testing.T) {
|
|||
events := make(chan NewTxsEvent, 32)
|
||||
sub := pool.txFeed.Subscribe(events)
|
||||
defer sub.Unsubscribe()
|
||||
revents := make(chan RejectedTxEvent, testTxPoolConfig.AccountQueue+5)
|
||||
rsub := pool.rejectTxFeed.Subscribe(revents)
|
||||
defer rsub.Unsubscribe()
|
||||
devents := make(chan DropTxsEvent, testTxPoolConfig.AccountQueue+5)
|
||||
dsub := pool.dropTxFeed.Subscribe(devents)
|
||||
defer dsub.Unsubscribe()
|
||||
|
||||
// Create a number of test accounts and fund them
|
||||
keys := make([]*ecdsa.PrivateKey, 2)
|
||||
|
|
@ -1480,6 +1577,9 @@ func TestTransactionPoolStableUnderpricing(t *testing.T) {
|
|||
if err := validateEvents(events, int(config.GlobalSlots)); err != nil {
|
||||
t.Fatalf("original event firing failed: %v", err)
|
||||
}
|
||||
if err := validateDroppedEvents(revents, 0, devents, 3); err != nil {
|
||||
t.Errorf("gap-filling drop / reject event firing failed: %v", err)
|
||||
}
|
||||
if err := validateTxPoolInternals(pool); err != nil {
|
||||
t.Fatalf("pool internal state corrupted: %v", err)
|
||||
}
|
||||
|
|
@ -1497,6 +1597,9 @@ func TestTransactionPoolStableUnderpricing(t *testing.T) {
|
|||
if err := validateEvents(events, 1); err != nil {
|
||||
t.Fatalf("additional event firing failed: %v", err)
|
||||
}
|
||||
if err := validateDroppedEvents(revents, 0, devents, 4); err != nil {
|
||||
t.Errorf("gap-filling drop / reject event firing failed: %v", err)
|
||||
}
|
||||
if err := validateTxPoolInternals(pool); err != nil {
|
||||
t.Fatalf("pool internal state corrupted: %v", err)
|
||||
}
|
||||
|
|
@ -1583,6 +1686,12 @@ func TestTransactionReplacement(t *testing.T) {
|
|||
events := make(chan NewTxsEvent, 32)
|
||||
sub := pool.txFeed.Subscribe(events)
|
||||
defer sub.Unsubscribe()
|
||||
revents := make(chan RejectedTxEvent, testTxPoolConfig.AccountQueue+5)
|
||||
rsub := pool.rejectTxFeed.Subscribe(revents)
|
||||
defer rsub.Unsubscribe()
|
||||
devents := make(chan DropTxsEvent, testTxPoolConfig.AccountQueue+5)
|
||||
dsub := pool.dropTxFeed.Subscribe(devents)
|
||||
defer dsub.Unsubscribe()
|
||||
|
||||
// Create a test account to add transactions with
|
||||
key, _ := crypto.GenerateKey()
|
||||
|
|
@ -1604,6 +1713,9 @@ func TestTransactionReplacement(t *testing.T) {
|
|||
if err := validateEvents(events, 2); err != nil {
|
||||
t.Fatalf("cheap replacement event firing failed: %v", err)
|
||||
}
|
||||
if err := validateDroppedEvents(revents, 1, devents, 4); err != nil {
|
||||
t.Errorf("gap-filling drop / reject event firing failed: %v", err)
|
||||
}
|
||||
|
||||
if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(price), key)); err != nil {
|
||||
t.Fatalf("failed to add original proper pending transaction: %v", err)
|
||||
|
|
@ -1617,6 +1729,9 @@ func TestTransactionReplacement(t *testing.T) {
|
|||
if err := validateEvents(events, 2); err != nil {
|
||||
t.Fatalf("proper replacement event firing failed: %v", err)
|
||||
}
|
||||
if err := validateDroppedEvents(revents, 1, devents, 2); err != nil {
|
||||
t.Errorf("gap-filling drop / reject event firing failed: %v", err)
|
||||
}
|
||||
|
||||
// Add queued transactions, ensuring the minimum price bump is enforced for replacement (for ultra low prices too)
|
||||
if err := pool.AddRemote(pricedTransaction(2, 100000, big.NewInt(1), key)); err != nil {
|
||||
|
|
@ -1642,6 +1757,9 @@ func TestTransactionReplacement(t *testing.T) {
|
|||
if err := validateEvents(events, 0); err != nil {
|
||||
t.Fatalf("queued replacement event firing failed: %v", err)
|
||||
}
|
||||
if err := validateDroppedEvents(revents, 2, devents, 6); err != nil {
|
||||
t.Errorf("gap-filling drop / reject event firing failed: %v", err)
|
||||
}
|
||||
if err := validateTxPoolInternals(pool); err != nil {
|
||||
t.Fatalf("pool internal state corrupted: %v", err)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue