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
|
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) {
|
func deriveSender(tx *types.Transaction) (common.Address, error) {
|
||||||
return types.Sender(types.HomesteadSigner{}, tx)
|
return types.Sender(types.HomesteadSigner{}, tx)
|
||||||
}
|
}
|
||||||
|
|
@ -689,6 +738,12 @@ func TestTransactionGapFilling(t *testing.T) {
|
||||||
events := make(chan NewTxsEvent, testTxPoolConfig.AccountQueue+5)
|
events := make(chan NewTxsEvent, testTxPoolConfig.AccountQueue+5)
|
||||||
sub := pool.txFeed.Subscribe(events)
|
sub := pool.txFeed.Subscribe(events)
|
||||||
defer sub.Unsubscribe()
|
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
|
// Create a pending and a queued transaction with a nonce-gap in between
|
||||||
pool.AddRemotesSync([]*types.Transaction{
|
pool.AddRemotesSync([]*types.Transaction{
|
||||||
|
|
@ -722,6 +777,9 @@ func TestTransactionGapFilling(t *testing.T) {
|
||||||
if err := validateEvents(events, 2); err != nil {
|
if err := validateEvents(events, 2); err != nil {
|
||||||
t.Fatalf("gap-filling event firing failed: %v", err)
|
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 {
|
if err := validateTxPoolInternals(pool); err != nil {
|
||||||
t.Fatalf("pool internal state corrupted: %v", err)
|
t.Fatalf("pool internal state corrupted: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -1201,6 +1259,12 @@ func TestTransactionPoolRepricing(t *testing.T) {
|
||||||
if err := validateEvents(events, 7); err != nil {
|
if err := validateEvents(events, 7); err != nil {
|
||||||
t.Fatalf("original event firing failed: %v", err)
|
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 {
|
if err := validateTxPoolInternals(pool); err != nil {
|
||||||
t.Fatalf("pool internal state corrupted: %v", err)
|
t.Fatalf("pool internal state corrupted: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -1217,6 +1281,9 @@ func TestTransactionPoolRepricing(t *testing.T) {
|
||||||
if err := validateEvents(events, 0); err != nil {
|
if err := validateEvents(events, 0); err != nil {
|
||||||
t.Fatalf("reprice event firing failed: %v", err)
|
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 {
|
if err := validateTxPoolInternals(pool); err != nil {
|
||||||
t.Fatalf("pool internal state corrupted: %v", err)
|
t.Fatalf("pool internal state corrupted: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -1233,6 +1300,9 @@ func TestTransactionPoolRepricing(t *testing.T) {
|
||||||
if err := validateEvents(events, 0); err != nil {
|
if err := validateEvents(events, 0); err != nil {
|
||||||
t.Fatalf("post-reprice event firing failed: %v", err)
|
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 {
|
if err := validateTxPoolInternals(pool); err != nil {
|
||||||
t.Fatalf("pool internal state corrupted: %v", err)
|
t.Fatalf("pool internal state corrupted: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -1247,6 +1317,9 @@ func TestTransactionPoolRepricing(t *testing.T) {
|
||||||
if err := validateEvents(events, 1); err != nil {
|
if err := validateEvents(events, 1); err != nil {
|
||||||
t.Fatalf("post-reprice local event firing failed: %v", err)
|
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 {
|
if err := validateTxPoolInternals(pool); err != nil {
|
||||||
t.Fatalf("pool internal state corrupted: %v", err)
|
t.Fatalf("pool internal state corrupted: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -1263,6 +1336,9 @@ func TestTransactionPoolRepricing(t *testing.T) {
|
||||||
if err := validateEvents(events, 5); err != nil {
|
if err := validateEvents(events, 5); err != nil {
|
||||||
t.Fatalf("post-reprice event firing failed: %v", err)
|
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 {
|
if err := validateTxPoolInternals(pool); err != nil {
|
||||||
t.Fatalf("pool internal state corrupted: %v", err)
|
t.Fatalf("pool internal state corrupted: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -1350,6 +1426,12 @@ func TestTransactionPoolUnderpricing(t *testing.T) {
|
||||||
events := make(chan NewTxsEvent, 32)
|
events := make(chan NewTxsEvent, 32)
|
||||||
sub := pool.txFeed.Subscribe(events)
|
sub := pool.txFeed.Subscribe(events)
|
||||||
defer sub.Unsubscribe()
|
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
|
// Create a number of test accounts and fund them
|
||||||
keys := make([]*ecdsa.PrivateKey, 4)
|
keys := make([]*ecdsa.PrivateKey, 4)
|
||||||
|
|
@ -1381,6 +1463,9 @@ func TestTransactionPoolUnderpricing(t *testing.T) {
|
||||||
if err := validateEvents(events, 3); err != nil {
|
if err := validateEvents(events, 3); err != nil {
|
||||||
t.Fatalf("original event firing failed: %v", err)
|
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 {
|
if err := validateTxPoolInternals(pool); err != nil {
|
||||||
t.Fatalf("pool internal state corrupted: %v", err)
|
t.Fatalf("pool internal state corrupted: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -1408,6 +1493,9 @@ func TestTransactionPoolUnderpricing(t *testing.T) {
|
||||||
if err := validateEvents(events, 1); err != nil {
|
if err := validateEvents(events, 1); err != nil {
|
||||||
t.Fatalf("additional event firing failed: %v", err)
|
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 {
|
if err := validateTxPoolInternals(pool); err != nil {
|
||||||
t.Fatalf("pool internal state corrupted: %v", err)
|
t.Fatalf("pool internal state corrupted: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -1430,6 +1518,9 @@ func TestTransactionPoolUnderpricing(t *testing.T) {
|
||||||
if err := validateEvents(events, 2); err != nil {
|
if err := validateEvents(events, 2); err != nil {
|
||||||
t.Fatalf("local event firing failed: %v", err)
|
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 {
|
if err := validateTxPoolInternals(pool); err != nil {
|
||||||
t.Fatalf("pool internal state corrupted: %v", err)
|
t.Fatalf("pool internal state corrupted: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -1456,6 +1547,12 @@ func TestTransactionPoolStableUnderpricing(t *testing.T) {
|
||||||
events := make(chan NewTxsEvent, 32)
|
events := make(chan NewTxsEvent, 32)
|
||||||
sub := pool.txFeed.Subscribe(events)
|
sub := pool.txFeed.Subscribe(events)
|
||||||
defer sub.Unsubscribe()
|
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
|
// Create a number of test accounts and fund them
|
||||||
keys := make([]*ecdsa.PrivateKey, 2)
|
keys := make([]*ecdsa.PrivateKey, 2)
|
||||||
|
|
@ -1480,6 +1577,9 @@ func TestTransactionPoolStableUnderpricing(t *testing.T) {
|
||||||
if err := validateEvents(events, int(config.GlobalSlots)); err != nil {
|
if err := validateEvents(events, int(config.GlobalSlots)); err != nil {
|
||||||
t.Fatalf("original event firing failed: %v", err)
|
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 {
|
if err := validateTxPoolInternals(pool); err != nil {
|
||||||
t.Fatalf("pool internal state corrupted: %v", err)
|
t.Fatalf("pool internal state corrupted: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -1497,6 +1597,9 @@ func TestTransactionPoolStableUnderpricing(t *testing.T) {
|
||||||
if err := validateEvents(events, 1); err != nil {
|
if err := validateEvents(events, 1); err != nil {
|
||||||
t.Fatalf("additional event firing failed: %v", err)
|
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 {
|
if err := validateTxPoolInternals(pool); err != nil {
|
||||||
t.Fatalf("pool internal state corrupted: %v", err)
|
t.Fatalf("pool internal state corrupted: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -1583,6 +1686,12 @@ func TestTransactionReplacement(t *testing.T) {
|
||||||
events := make(chan NewTxsEvent, 32)
|
events := make(chan NewTxsEvent, 32)
|
||||||
sub := pool.txFeed.Subscribe(events)
|
sub := pool.txFeed.Subscribe(events)
|
||||||
defer sub.Unsubscribe()
|
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
|
// Create a test account to add transactions with
|
||||||
key, _ := crypto.GenerateKey()
|
key, _ := crypto.GenerateKey()
|
||||||
|
|
@ -1604,6 +1713,9 @@ func TestTransactionReplacement(t *testing.T) {
|
||||||
if err := validateEvents(events, 2); err != nil {
|
if err := validateEvents(events, 2); err != nil {
|
||||||
t.Fatalf("cheap replacement event firing failed: %v", err)
|
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 {
|
if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(price), key)); err != nil {
|
||||||
t.Fatalf("failed to add original proper pending transaction: %v", err)
|
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 {
|
if err := validateEvents(events, 2); err != nil {
|
||||||
t.Fatalf("proper replacement event firing failed: %v", err)
|
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)
|
// 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 {
|
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 {
|
if err := validateEvents(events, 0); err != nil {
|
||||||
t.Fatalf("queued replacement event firing failed: %v", err)
|
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 {
|
if err := validateTxPoolInternals(pool); err != nil {
|
||||||
t.Fatalf("pool internal state corrupted: %v", err)
|
t.Fatalf("pool internal state corrupted: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue