Skip to content

Commit 7041829

Browse files
core: added unit test for LRU witness cache
1 parent c60bb98 commit 7041829

File tree

1 file changed

+95
-0
lines changed

1 file changed

+95
-0
lines changed

core/blockchain_test.go

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5892,3 +5892,98 @@ func TestSplitReceiptsAndDeriveFields(t *testing.T) {
58925892
require.Equal(t, rlp.RawValue(stateSyncEncoded), stateSync, fmt.Sprintf("case: %s, state-sync receipts mismatch, got: %v, expected: %v", test.name, stateSync, stateSyncEncoded))
58935893
}
58945894
}
5895+
5896+
// TestWitnessCache tests the witness caching functionality to ensure witnesses
5897+
// are properly cached during writes and retrieved from cache during reads.
5898+
func TestWitnessCache(t *testing.T) {
5899+
// Setup: Create a test blockchain
5900+
engine := ethash.NewFaker()
5901+
gspec := &Genesis{
5902+
Config: params.TestChainConfig,
5903+
}
5904+
cfg := DefaultConfig()
5905+
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, engine, cfg)
5906+
if err != nil {
5907+
t.Fatalf("failed to create blockchain: %v", err)
5908+
}
5909+
defer chain.Stop()
5910+
5911+
// Create test witness data
5912+
testHash := common.HexToHash("0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef")
5913+
testWitness1 := []byte("test witness data 1")
5914+
testWitness2 := []byte("test witness data 2 - different")
5915+
5916+
// Test 1: Write witness and verify it's cached
5917+
rawdb.WriteWitness(chain.db, testHash, testWitness1)
5918+
// Manually add to cache to simulate what happens during block import
5919+
chain.witnessCache.Add(testHash, testWitness1)
5920+
5921+
// Verify witness can be retrieved from cache
5922+
retrieved := chain.GetWitness(testHash)
5923+
require.NotNil(t, retrieved, "witness should be retrieved")
5924+
require.Equal(t, testWitness1, retrieved, "retrieved witness should match written witness")
5925+
5926+
// Test 2: Verify cache hit (witness should be in cache, not read from DB)
5927+
// We can verify this by checking the cache directly
5928+
cached, ok := chain.witnessCache.Get(testHash)
5929+
require.True(t, ok, "witness should be in cache")
5930+
require.Equal(t, testWitness1, cached, "cached witness should match")
5931+
5932+
// Test 3: Update witness in cache and verify GetWitness returns cached version
5933+
chain.witnessCache.Add(testHash, testWitness2)
5934+
retrieved = chain.GetWitness(testHash)
5935+
require.Equal(t, testWitness2, retrieved, "GetWitness should return cached version")
5936+
5937+
// Test 4: Test cache miss - witness not in cache but in DB
5938+
testHash2 := common.HexToHash("0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890")
5939+
testWitness3 := []byte("test witness data 3")
5940+
rawdb.WriteWitness(chain.db, testHash2, testWitness3)
5941+
// Don't add to cache - simulate cache miss
5942+
5943+
// GetWitness should read from DB and cache it
5944+
retrieved = chain.GetWitness(testHash2)
5945+
require.NotNil(t, retrieved, "witness should be retrieved from DB")
5946+
require.Equal(t, testWitness3, retrieved, "retrieved witness should match DB witness")
5947+
5948+
// Verify it's now in cache
5949+
cached, ok = chain.witnessCache.Get(testHash2)
5950+
require.True(t, ok, "witness should be cached after GetWitness")
5951+
require.Equal(t, testWitness3, cached, "cached witness should match")
5952+
5953+
// Test 5: Test non-existent witness
5954+
nonExistentHash := common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000")
5955+
retrieved = chain.GetWitness(nonExistentHash)
5956+
require.Nil(t, retrieved, "non-existent witness should return nil")
5957+
5958+
// Test 6: Test cache purge
5959+
chain.witnessCache.Purge()
5960+
_, ok = chain.witnessCache.Get(testHash)
5961+
require.False(t, ok, "witness should not be in cache after purge")
5962+
_, ok = chain.witnessCache.Get(testHash2)
5963+
require.False(t, ok, "witness should not be in cache after purge")
5964+
5965+
// After purge, GetWitness should still work by reading from DB
5966+
retrieved = chain.GetWitness(testHash2)
5967+
require.NotNil(t, retrieved, "witness should still be retrievable from DB after cache purge")
5968+
require.Equal(t, testWitness3, retrieved, "retrieved witness should match DB witness")
5969+
5970+
// Test 7: Test that witness is cached during block import
5971+
// Create a block and witness, then import it
5972+
testChain, testBlock, testWitness := createTestBlockAndWitness(t)
5973+
defer testChain.Stop()
5974+
5975+
// Import the block with witness - this should cache the witness
5976+
blockHash := testBlock.Hash()
5977+
_, err = testChain.InsertChainStateless(types.Blocks{testBlock}, []*stateless.Witness{testWitness})
5978+
require.NoError(t, err, "block import should succeed")
5979+
5980+
// Verify witness is in cache after import
5981+
cached, ok = testChain.witnessCache.Get(blockHash)
5982+
require.True(t, ok, "witness should be cached after block import")
5983+
require.NotNil(t, cached, "cached witness should not be nil")
5984+
5985+
// Verify GetWitness retrieves from cache
5986+
retrieved = testChain.GetWitness(blockHash)
5987+
require.NotNil(t, retrieved, "witness should be retrievable after import")
5988+
require.Equal(t, cached, retrieved, "GetWitness should return cached witness")
5989+
}

0 commit comments

Comments
 (0)