-
Notifications
You must be signed in to change notification settings - Fork 464
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor/extract block store from blocktree (#5704)
- Loading branch information
Showing
6 changed files
with
166 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
63 changes: 63 additions & 0 deletions
63
src/Nethermind/Nethermind.Blockchain.Test/Blocks/BlockStoreTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited | ||
// SPDX-License-Identifier: LGPL-3.0-only | ||
|
||
using FluentAssertions; | ||
using Nethermind.Blockchain.Blocks; | ||
using Nethermind.Core; | ||
using Nethermind.Core.Test; | ||
using Nethermind.Core.Test.Builders; | ||
using NUnit.Framework; | ||
|
||
namespace Nethermind.Blockchain.Test.Blocks; | ||
|
||
public class BlockStoreTests | ||
{ | ||
[TestCase(true)] | ||
[TestCase(false)] | ||
public void Test_can_insert_get_and_remove_blocks(bool cached) | ||
{ | ||
TestMemDb db = new TestMemDb(); | ||
BlockStore store = new BlockStore(db); | ||
|
||
Block block = Build.A.Block.WithNumber(1).TestObject; | ||
store.Insert(block); | ||
|
||
Block? retrieved = store.Get(block.Hash, cached); | ||
retrieved.Should().BeEquivalentTo(block); | ||
|
||
store.Delete(block.Hash); | ||
|
||
store.Get(block.Hash, cached).Should().BeNull(); | ||
} | ||
|
||
[Test] | ||
public void Test_can_set_and_get_metadata() | ||
{ | ||
TestMemDb db = new TestMemDb(); | ||
BlockStore store = new BlockStore(db); | ||
|
||
byte[] key = new byte[] { 1, 2, 3 }; | ||
byte[] value = new byte[] { 4, 5, 6 }; | ||
|
||
store.SetMetadata(key, value); | ||
store.GetMetadata(key).Should().BeEquivalentTo(value); | ||
} | ||
|
||
[Test] | ||
public void Test_when_cached_does_not_touch_db_on_next_get() | ||
{ | ||
TestMemDb db = new TestMemDb(); | ||
BlockStore store = new BlockStore(db); | ||
|
||
Block block = Build.A.Block.WithNumber(1).TestObject; | ||
store.Insert(block); | ||
|
||
Block? retrieved = store.Get(block.Hash, true); | ||
retrieved.Should().BeEquivalentTo(block); | ||
|
||
db.Clear(); | ||
|
||
retrieved = store.Get(block.Hash, true); | ||
retrieved.Should().BeEquivalentTo(block); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited | ||
// SPDX-License-Identifier: LGPL-3.0-only | ||
|
||
using System; | ||
using Nethermind.Core; | ||
using Nethermind.Core.Caching; | ||
using Nethermind.Core.Crypto; | ||
using Nethermind.Db; | ||
using Nethermind.Serialization.Rlp; | ||
|
||
namespace Nethermind.Blockchain.Blocks; | ||
|
||
public class BlockStore : IBlockStore | ||
{ | ||
private readonly IDb _blockDb; | ||
private readonly BlockDecoder _blockDecoder = new(); | ||
private const int CacheSize = 64; | ||
|
||
private readonly LruCache<KeccakKey, Block> | ||
_blockCache = new(CacheSize, CacheSize, "blocks"); | ||
|
||
public BlockStore(IDb blockDb) | ||
{ | ||
_blockDb = blockDb; | ||
} | ||
|
||
public void SetMetadata(byte[] key, byte[] value) | ||
{ | ||
_blockDb.Set(key, value); | ||
} | ||
|
||
public byte[]? GetMetadata(byte[] key) | ||
{ | ||
return _blockDb.Get(key); | ||
} | ||
|
||
public void Insert(Block block) | ||
{ | ||
if (block.Hash is null) | ||
{ | ||
throw new InvalidOperationException("An attempt to store a block with a null hash."); | ||
} | ||
|
||
// if we carry Rlp from the network message all the way here then we could solve 4GB of allocations and some processing | ||
// by avoiding encoding back to RLP here (allocations measured on a sample 3M blocks Goerli fast sync | ||
using NettyRlpStream newRlp = _blockDecoder.EncodeToNewNettyStream(block); | ||
_blockDb.Set(block.Hash, newRlp.AsSpan()); | ||
} | ||
|
||
public void Delete(Keccak blockHash) | ||
{ | ||
_blockDb.Delete(blockHash); | ||
_blockCache.Delete(blockHash); | ||
} | ||
|
||
public Block? Get(Keccak blockHash, bool shouldCache) | ||
{ | ||
return _blockDb.Get(blockHash, _blockDecoder, _blockCache, shouldCache); | ||
} | ||
|
||
public void Cache(Block block) | ||
{ | ||
_blockCache.Set(block.Hash, block); | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
src/Nethermind/Nethermind.Blockchain/Blocks/IBlockStore.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited | ||
// SPDX-License-Identifier: LGPL-3.0-only | ||
|
||
using Nethermind.Core; | ||
using Nethermind.Core.Crypto; | ||
|
||
namespace Nethermind.Blockchain.Blocks; | ||
|
||
/// <summary> | ||
/// Raw block store. Does not know or care about blockchain or blocktree, only encoding/decoding to kv store. | ||
/// Generally you probably need IBlockTree instead of this. | ||
/// </summary> | ||
public interface IBlockStore | ||
{ | ||
void Insert(Block block); | ||
void Delete(Keccak blockHash); | ||
Block Get(Keccak blockHash, bool shouldCache = true); | ||
void Cache(Block block); | ||
|
||
|
||
// These two are used by blocktree. Try not to use them... | ||
void SetMetadata(byte[] key, byte[] value); | ||
byte[]? GetMetadata(byte[] key); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters