Skip to content

Commit

Permalink
Fix eviction, work in progress.
Browse files Browse the repository at this point in the history
  • Loading branch information
andreibancioiu committed Nov 1, 2024
1 parent a6faf2e commit 1920a2f
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 22 deletions.
5 changes: 5 additions & 0 deletions txcache/eviction.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,11 @@ func (cache *TxCache) evictLeastLikelyToSelectTransactions() *evictionJournal {
}
}

if len(transactionsToEvict) == 0 {
// No more transactions to evict.
break
}

// For each sender, find the "lowest" (in nonce) transaction to evict.
lowestToEvictBySender := make(map[string]uint64)

Expand Down
68 changes: 46 additions & 22 deletions txcache/eviction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,28 @@ import (

func TestTxCache_DoEviction_BecauseOfCount(t *testing.T) {
config := ConfigSourceMe{
Name: "untitled",
NumChunks: 16,
NumBytesThreshold: maxNumBytesUpperBound,
NumBytesPerSenderThreshold: maxNumBytesPerSenderUpperBound,
CountThreshold: 2,
CountPerSenderThreshold: math.MaxUint32,
Name: "untitled",
NumChunks: 16,
NumBytesThreshold: maxNumBytesUpperBound,
NumBytesPerSenderThreshold: maxNumBytesPerSenderUpperBound,
CountThreshold: 4,
CountPerSenderThreshold: math.MaxUint32,
EvictionEnabled: true,
NumItemsToPreemptivelyEvict: 1,
}
txGasHandler := txcachemocks.NewTxGasHandlerMock()
cache, err := NewTxCache(config, txGasHandler)
require.Nil(t, err)
require.NotNil(t, cache)

cache.AddTx(createTx([]byte("hash-alice"), "alice", 1).withGasPrice(1 * oneBillion))
cache.AddTx(createTx([]byte("hash-bob"), "bob", 1).withGasPrice(1 * oneBillion))
cache.AddTx(createTx([]byte("hash-bob"), "bob", 1).withGasPrice(2 * oneBillion))
cache.AddTx(createTx([]byte("hash-carol"), "carol", 1).withGasPrice(3 * oneBillion))
cache.AddTx(createTx([]byte("hash-eve"), "eve", 1).withGasPrice(4 * oneBillion))
cache.AddTx(createTx([]byte("hash-dan"), "dan", 1).withGasPrice(5 * oneBillion))

journal := cache.doEviction()
require.Equal(t, uint32(2), journal.numTxs)
require.Equal(t, uint32(1), journal.numEvicted)

// Alice and Bob evicted. Carol still there (better score).
_, ok := cache.GetByTxHash([]byte("hash-carol"))
Expand All @@ -38,12 +42,14 @@ func TestTxCache_DoEviction_BecauseOfCount(t *testing.T) {

func TestTxCache_DoEviction_BecauseOfSize(t *testing.T) {
config := ConfigSourceMe{
Name: "untitled",
NumChunks: 16,
NumBytesThreshold: 1000,
NumBytesPerSenderThreshold: maxNumBytesPerSenderUpperBound,
CountThreshold: math.MaxUint32,
CountPerSenderThreshold: math.MaxUint32,
Name: "untitled",
NumChunks: 16,
NumBytesThreshold: 1000,
NumBytesPerSenderThreshold: maxNumBytesPerSenderUpperBound,
CountThreshold: math.MaxUint32,
CountPerSenderThreshold: math.MaxUint32,
EvictionEnabled: true,
NumItemsToPreemptivelyEvict: 1,
}

txGasHandler := txcachemocks.NewTxGasHandlerMock()
Expand All @@ -57,7 +63,7 @@ func TestTxCache_DoEviction_BecauseOfSize(t *testing.T) {
cache.AddTx(createTx([]byte("hash-eve"), "eve", 1).withSize(256).withGasLimit(500000).withGasPrice(3 * oneBillion))

journal := cache.doEviction()
require.Equal(t, uint32(2), journal.numTxs)
require.Equal(t, 2, journal.numEvicted)

// Alice and Bob evicted (lower score). Carol and Eve still there.
_, ok := cache.GetByTxHash([]byte("hash-carol"))
Expand All @@ -70,23 +76,41 @@ func TestTxCache_DoEviction_BecauseOfSize(t *testing.T) {

func TestTxCache_DoEviction_DoesNothingWhenAlreadyInProgress(t *testing.T) {
config := ConfigSourceMe{
Name: "untitled",
NumChunks: 1,
NumBytesPerSenderThreshold: maxNumBytesPerSenderUpperBound,
CountThreshold: 0,
CountPerSenderThreshold: math.MaxUint32,
Name: "untitled",
NumChunks: 1,
NumBytesThreshold: maxNumBytesUpperBound,
NumBytesPerSenderThreshold: maxNumBytesPerSenderUpperBound,
CountThreshold: 4,
CountPerSenderThreshold: math.MaxUint32,
EvictionEnabled: true,
NumItemsToPreemptivelyEvict: 1,
}

txGasHandler := txcachemocks.NewTxGasHandlerMock()
cache, err := NewTxCache(config, txGasHandler)
require.Nil(t, err)
require.NotNil(t, cache)

cache.AddTx(createTx([]byte("hash-alice"), "alice", uint64(1)))

_ = cache.isEvictionInProgress.SetReturningPrevious()

cache.AddTx(createTx([]byte("hash-alice-1"), "alice", uint64(1)))
cache.AddTx(createTx([]byte("hash-alice-2"), "alice", uint64(2)))
cache.AddTx(createTx([]byte("hash-alice-3"), "alice", uint64(3)))
cache.AddTx(createTx([]byte("hash-alice-4"), "alice", uint64(4)))
cache.AddTx(createTx([]byte("hash-alice-5"), "alice", uint64(5)))

// Nothing is evicted because eviction is already in progress.
journal := cache.doEviction()
require.Nil(t, journal)
require.Equal(t, uint64(5), cache.CountTx())

cache.isEvictionInProgress.Reset()

// Now eviction can happen.
journal = cache.doEviction()
require.NotNil(t, journal)
require.Equal(t, 1, journal.numEvicted)
require.Equal(t, 4, int(cache.CountTx()))
}

// This seems to be the most reasonable "bad-enough" (not worst) scenario to benchmark:
Expand Down

0 comments on commit 1920a2f

Please sign in to comment.