From 9293eba4caf3e00427b213c4fc99289c39129342 Mon Sep 17 00:00:00 2001 From: Amirul Ashraf Date: Wed, 25 Oct 2023 16:50:47 +0800 Subject: [PATCH 1/9] Pass write flags --- src/Nethermind/Nethermind.Blockchain/BlockTree.cs | 4 ++-- src/Nethermind/Nethermind.Blockchain/Blocks/BlockStore.cs | 2 +- src/Nethermind/Nethermind.Blockchain/Blocks/IBlockStore.cs | 2 +- src/Nethermind/Nethermind.Blockchain/IBlockTree.cs | 2 +- src/Nethermind/Nethermind.Blockchain/ReadOnlyBlockTree.cs | 2 +- src/Nethermind/Nethermind.Db/DbExtensions.cs | 6 +++--- src/Nethermind/Nethermind.Db/IDbWithSpan.cs | 3 ++- src/Nethermind/Nethermind.Db/MemDb.cs | 4 ++-- src/Nethermind/Nethermind.Db/ReadOnlyDb.cs | 4 ++-- 9 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/Nethermind/Nethermind.Blockchain/BlockTree.cs b/src/Nethermind/Nethermind.Blockchain/BlockTree.cs index b1b36a5fcf3..8eadd958fcd 100644 --- a/src/Nethermind/Nethermind.Blockchain/BlockTree.cs +++ b/src/Nethermind/Nethermind.Blockchain/BlockTree.cs @@ -275,7 +275,7 @@ public AddBlockResult Insert(BlockHeader header, BlockTreeInsertHeaderOptions he } public AddBlockResult Insert(Block block, BlockTreeInsertBlockOptions insertBlockOptions = BlockTreeInsertBlockOptions.None, - BlockTreeInsertHeaderOptions insertHeaderOptions = BlockTreeInsertHeaderOptions.None) + BlockTreeInsertHeaderOptions insertHeaderOptions = BlockTreeInsertHeaderOptions.None, WriteFlags blockWriteFlags = WriteFlags.None) { bool skipCanAcceptNewBlocks = (insertBlockOptions & BlockTreeInsertBlockOptions.SkipCanAcceptNewBlocks) != 0; if (!CanAcceptNewBlocks) @@ -293,7 +293,7 @@ public AddBlockResult Insert(Block block, BlockTreeInsertBlockOptions insertBloc throw new InvalidOperationException("Genesis block should not be inserted."); } - _blockStore.Insert(block); + _blockStore.Insert(block, writeFlags: blockWriteFlags); _headerStore.InsertBlockNumber(block.Hash, block.Number); bool saveHeader = (insertBlockOptions & BlockTreeInsertBlockOptions.SaveHeader) != 0; diff --git a/src/Nethermind/Nethermind.Blockchain/Blocks/BlockStore.cs b/src/Nethermind/Nethermind.Blockchain/Blocks/BlockStore.cs index 067fcfe00c7..c12862510b1 100644 --- a/src/Nethermind/Nethermind.Blockchain/Blocks/BlockStore.cs +++ b/src/Nethermind/Nethermind.Blockchain/Blocks/BlockStore.cs @@ -42,7 +42,7 @@ public void SetMetadata(byte[] key, byte[] value) return _blockDb.Get(key); } - public void Insert(Block block) + public void Insert(Block block, WriteFlags writeFlags = WriteFlags.None) { if (block.Hash is null) { diff --git a/src/Nethermind/Nethermind.Blockchain/Blocks/IBlockStore.cs b/src/Nethermind/Nethermind.Blockchain/Blocks/IBlockStore.cs index 8a38db46706..a84f2c5fe4a 100644 --- a/src/Nethermind/Nethermind.Blockchain/Blocks/IBlockStore.cs +++ b/src/Nethermind/Nethermind.Blockchain/Blocks/IBlockStore.cs @@ -13,7 +13,7 @@ namespace Nethermind.Blockchain.Blocks; /// public interface IBlockStore { - void Insert(Block block); + void Insert(Block block, WriteFlags writeFlags = WriteFlags.None); void Delete(long blockNumber, Hash256 blockHash); Block? Get(long blockNumber, Hash256 blockHash, bool shouldCache = true); ReceiptRecoveryBlock? GetReceiptRecoveryBlock(long blockNumber, Hash256 blockHash); diff --git a/src/Nethermind/Nethermind.Blockchain/IBlockTree.cs b/src/Nethermind/Nethermind.Blockchain/IBlockTree.cs index 4b9b325d148..5fd0bf9111c 100644 --- a/src/Nethermind/Nethermind.Blockchain/IBlockTree.cs +++ b/src/Nethermind/Nethermind.Blockchain/IBlockTree.cs @@ -77,7 +77,7 @@ public interface IBlockTree : IBlockFinder /// Block to add /// Result of the operation, eg. Added, AlreadyKnown, etc. AddBlockResult Insert(Block block, BlockTreeInsertBlockOptions insertBlockOptions = BlockTreeInsertBlockOptions.None, - BlockTreeInsertHeaderOptions insertHeaderOptions = BlockTreeInsertHeaderOptions.None); + BlockTreeInsertHeaderOptions insertHeaderOptions = BlockTreeInsertHeaderOptions.None, WriteFlags bodiesWriteFlags = WriteFlags.None); void UpdateHeadBlock(Hash256 blockHash); diff --git a/src/Nethermind/Nethermind.Blockchain/ReadOnlyBlockTree.cs b/src/Nethermind/Nethermind.Blockchain/ReadOnlyBlockTree.cs index 05f45d70746..1c401dc10c4 100644 --- a/src/Nethermind/Nethermind.Blockchain/ReadOnlyBlockTree.cs +++ b/src/Nethermind/Nethermind.Blockchain/ReadOnlyBlockTree.cs @@ -68,7 +68,7 @@ public async Task Accept(IBlockTreeVisitor blockTreeVisitor, CancellationToken c public ChainLevelInfo FindLevel(long number) => _wrapped.FindLevel(number); public BlockInfo FindCanonicalBlockInfo(long blockNumber) => _wrapped.FindCanonicalBlockInfo(blockNumber); - public AddBlockResult Insert(Block block, BlockTreeInsertBlockOptions insertBlockOptions = BlockTreeInsertBlockOptions.None, BlockTreeInsertHeaderOptions insertHeaderOptions = BlockTreeInsertHeaderOptions.None) => + public AddBlockResult Insert(Block block, BlockTreeInsertBlockOptions insertBlockOptions = BlockTreeInsertBlockOptions.None, BlockTreeInsertHeaderOptions insertHeaderOptions = BlockTreeInsertHeaderOptions.None, WriteFlags blockWriteFlags = WriteFlags.None) => throw new InvalidOperationException($"{nameof(ReadOnlyBlockTree)} does not expect {nameof(Insert)} calls"); public void Insert(IEnumerable blocks) => throw new InvalidOperationException($"{nameof(ReadOnlyBlockTree)} does not expect {nameof(Insert)} calls"); diff --git a/src/Nethermind/Nethermind.Db/DbExtensions.cs b/src/Nethermind/Nethermind.Db/DbExtensions.cs index 7f6f15bebdc..9c3da443c05 100644 --- a/src/Nethermind/Nethermind.Db/DbExtensions.cs +++ b/src/Nethermind/Nethermind.Db/DbExtensions.cs @@ -74,15 +74,15 @@ public static void Set(this IDb db, in ValueHash256 key, Span value) } } - public static void Set(this IDb db, ReadOnlySpan key, ReadOnlySpan value) + public static void Set(this IDb db, ReadOnlySpan key, ReadOnlySpan value, WriteFlags writeFlags = WriteFlags.None) { if (db is IDbWithSpan dbWithSpan) { - dbWithSpan.PutSpan(key, value); + dbWithSpan.PutSpan(key, value, flags: writeFlags); } else { - db[key] = value.ToArray(); + db.Set(key, value.ToArray(), flags: writeFlags); } } diff --git a/src/Nethermind/Nethermind.Db/IDbWithSpan.cs b/src/Nethermind/Nethermind.Db/IDbWithSpan.cs index 6d819cca910..0977595a917 100644 --- a/src/Nethermind/Nethermind.Db/IDbWithSpan.cs +++ b/src/Nethermind/Nethermind.Db/IDbWithSpan.cs @@ -3,6 +3,7 @@ using System; using System.Buffers; +using Nethermind.Core; using Nethermind.Core.Buffers; using Nethermind.Core.Extensions; @@ -16,7 +17,7 @@ public interface IDbWithSpan : IDb /// /// Can return null or empty Span on missing key Span GetSpan(ReadOnlySpan key); - void PutSpan(ReadOnlySpan key, ReadOnlySpan value); + void PutSpan(ReadOnlySpan key, ReadOnlySpan value, WriteFlags flags = WriteFlags.None); void DangerousReleaseMemory(in Span span); MemoryManager? GetOwnedMemory(ReadOnlySpan key) { diff --git a/src/Nethermind/Nethermind.Db/MemDb.cs b/src/Nethermind/Nethermind.Db/MemDb.cs index 3ea97044e27..180f2a9208d 100644 --- a/src/Nethermind/Nethermind.Db/MemDb.cs +++ b/src/Nethermind/Nethermind.Db/MemDb.cs @@ -114,9 +114,9 @@ public virtual Span GetSpan(ReadOnlySpan key) return Get(key).AsSpan(); } - public void PutSpan(ReadOnlySpan key, ReadOnlySpan value) + public void PutSpan(ReadOnlySpan key, ReadOnlySpan value, WriteFlags writeFlags) { - Set(key, value.ToArray()); + Set(key, value.ToArray(), writeFlags); } public void DangerousReleaseMemory(in Span span) diff --git a/src/Nethermind/Nethermind.Db/ReadOnlyDb.cs b/src/Nethermind/Nethermind.Db/ReadOnlyDb.cs index 317b63cf65f..cfddcff9d9e 100644 --- a/src/Nethermind/Nethermind.Db/ReadOnlyDb.cs +++ b/src/Nethermind/Nethermind.Db/ReadOnlyDb.cs @@ -96,14 +96,14 @@ public virtual void ClearTempChanges() } public Span GetSpan(ReadOnlySpan key) => _memDb.Get(key).AsSpan(); - public void PutSpan(ReadOnlySpan keyBytes, ReadOnlySpan value) + public void PutSpan(ReadOnlySpan keyBytes, ReadOnlySpan value, WriteFlags writeFlags = WriteFlags.None) { if (!_createInMemWriteStore) { throw new InvalidOperationException($"This {nameof(ReadOnlyDb)} did not expect any writes."); } - _memDb.Set(keyBytes, value.ToArray()); + _memDb.Set(keyBytes, value.ToArray(), writeFlags); } public void DangerousReleaseMemory(in Span span) { } From 00dcdb41a0e2490c2c1385ecc5ad83d5ddcd1299 Mon Sep 17 00:00:00 2001 From: Amirul Ashraf Date: Wed, 25 Oct 2023 17:00:58 +0800 Subject: [PATCH 2/9] Disable wal on old bodies --- .../FastBlocks/BodiesSyncFeed.cs | 23 ++++++++++++++----- .../Synchronizer.cs | 2 +- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs index 8e22cf58930..033be323bd1 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs @@ -8,7 +8,7 @@ using Nethermind.Blockchain.Synchronization; using Nethermind.Core; using Nethermind.Core.Crypto; -using Nethermind.Core.Specs; +using Nethermind.Db; using Nethermind.Logging; using Nethermind.State.Proofs; using Nethermind.Stats.Model; @@ -22,13 +22,14 @@ namespace Nethermind.Synchronization.FastBlocks public class BodiesSyncFeed : ActivatedSyncFeed { private int _requestSize = GethSyncLimits.MaxBodyFetch; + private const long FlushDbInterval = 100000; // About every 10GB on mainnet private readonly ILogger _logger; private readonly IBlockTree _blockTree; private readonly ISyncConfig _syncConfig; private readonly ISyncReport _syncReport; - private readonly ISpecProvider _specProvider; private readonly ISyncPeerPool _syncPeerPool; + private readonly IDbMeta _blocksDb; private long _pivotNumber; private long _barrier; @@ -41,7 +42,7 @@ public BodiesSyncFeed( ISyncPeerPool syncPeerPool, ISyncConfig syncConfig, ISyncReport syncReport, - ISpecProvider specProvider, + IDbMeta blocksDb, ILogManager logManager) : base(syncModeSelector) { _logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager)); @@ -49,7 +50,7 @@ public BodiesSyncFeed( _syncPeerPool = syncPeerPool ?? throw new ArgumentNullException(nameof(syncPeerPool)); _syncConfig = syncConfig ?? throw new ArgumentNullException(nameof(syncConfig)); _syncReport = syncReport ?? throw new ArgumentNullException(nameof(syncReport)); - _specProvider = specProvider ?? throw new ArgumentNullException(nameof(specProvider)); + _blocksDb = blocksDb ?? throw new ArgumentNullException(nameof(blocksDb)); if (!_syncConfig.FastBlocks) { @@ -115,6 +116,7 @@ private void PostFinishCleanUp() _syncReport.FastBlocksBodies.MarkEnd(); _syncReport.BodiesInQueue.Update(0); _syncReport.BodiesInQueue.MarkEnd(); + Flush(); } public override Task PrepareRequest(CancellationToken token = default) @@ -132,11 +134,20 @@ private void PostFinishCleanUp() } } - _blockTree.LowestInsertedBodyNumber = _syncStatusList.LowestInsertWithoutGaps; + if ((_blockTree.LowestInsertedBodyNumber ?? long.MaxValue) - _syncStatusList.LowestInsertWithoutGaps > FlushDbInterval) + { + Flush(); + } return Task.FromResult(batch); } + private void Flush() + { + _blocksDb.Flush(); + _blockTree.LowestInsertedBodyNumber = _syncStatusList.LowestInsertWithoutGaps; + } + public override SyncResponseHandlingResult HandleResponse(BodiesSyncBatch? batch, PeerInfo peer = null) { batch?.MarkHandlingStart(); @@ -234,7 +245,7 @@ private int InsertBodies(BodiesSyncBatch batch) private void InsertOneBlock(Block block) { - _blockTree.Insert(block, BlockTreeInsertBlockOptions.SkipCanAcceptNewBlocks); + _blockTree.Insert(block, BlockTreeInsertBlockOptions.SkipCanAcceptNewBlocks, bodiesWriteFlags: WriteFlags.DisableWAL); _syncStatusList.MarkInserted(block.Number); } diff --git a/src/Nethermind/Nethermind.Synchronization/Synchronizer.cs b/src/Nethermind/Nethermind.Synchronization/Synchronizer.cs index d7829ad815b..1158566083b 100644 --- a/src/Nethermind/Nethermind.Synchronization/Synchronizer.cs +++ b/src/Nethermind/Nethermind.Synchronization/Synchronizer.cs @@ -267,7 +267,7 @@ private void StartFastBlocksComponents() { if (_syncConfig.DownloadBodiesInFastSync) { - _bodiesFeed = new BodiesSyncFeed(_syncMode, _blockTree, _syncPeerPool, _syncConfig, _syncReport, _specProvider, _logManager); + _bodiesFeed = new BodiesSyncFeed(_syncMode, _blockTree, _syncPeerPool, _syncConfig, _syncReport, _dbProvider.BlocksDb, _logManager); SyncDispatcher bodiesDispatcher = CreateDispatcher( _bodiesFeed, From 1d5694e3c6c1f2b89f6fb654e334f032d0c51b60 Mon Sep 17 00:00:00 2001 From: Amirul Ashraf Date: Wed, 25 Oct 2023 17:09:40 +0800 Subject: [PATCH 3/9] Fix build --- .../Nethermind.Db.Rocks/ColumnDb.cs | 5 ++-- .../Nethermind.Db.Rocks/DbOnTheRocks.cs | 23 ++++--------------- src/Nethermind/Nethermind.Db.Rpc/RpcDb.cs | 4 ++-- 3 files changed, 8 insertions(+), 24 deletions(-) diff --git a/src/Nethermind/Nethermind.Db.Rocks/ColumnDb.cs b/src/Nethermind/Nethermind.Db.Rocks/ColumnDb.cs index 5d1f974637e..f8e5cc4ec16 100644 --- a/src/Nethermind/Nethermind.Db.Rocks/ColumnDb.cs +++ b/src/Nethermind/Nethermind.Db.Rocks/ColumnDb.cs @@ -128,10 +128,9 @@ public Span GetSpan(ReadOnlySpan key) return _rocksDb.GetSpan(key, _columnFamily); } - public void PutSpan(ReadOnlySpan key, ReadOnlySpan value) + public void PutSpan(ReadOnlySpan key, ReadOnlySpan value, WriteFlags writeFlags = WriteFlags.None) { - _mainDb.UpdateWriteMetrics(); - _rocksDb.Put(key, value, _columnFamily, _mainDb.WriteOptions); + _mainDb.SetWithColumnFamily(key, _columnFamily, value, writeFlags); } public void DangerousReleaseMemory(in Span span) => _rocksDb.DangerousReleaseMemory(span); diff --git a/src/Nethermind/Nethermind.Db.Rocks/DbOnTheRocks.cs b/src/Nethermind/Nethermind.Db.Rocks/DbOnTheRocks.cs index d590884baa6..30fdc75ff22 100644 --- a/src/Nethermind/Nethermind.Db.Rocks/DbOnTheRocks.cs +++ b/src/Nethermind/Nethermind.Db.Rocks/DbOnTheRocks.cs @@ -509,7 +509,7 @@ public void Set(ReadOnlySpan key, byte[]? value, WriteFlags flags = WriteF SetWithColumnFamily(key, null, value, flags); } - internal void SetWithColumnFamily(ReadOnlySpan key, ColumnFamilyHandle? cf, byte[]? value, WriteFlags flags = WriteFlags.None) + internal void SetWithColumnFamily(ReadOnlySpan key, ColumnFamilyHandle? cf, ReadOnlySpan value, WriteFlags flags = WriteFlags.None) { if (_isDisposing) { @@ -520,7 +520,7 @@ internal void SetWithColumnFamily(ReadOnlySpan key, ColumnFamilyHandle? cf try { - if (value is null) + if (value.IsNull()) { _db.Remove(key, cf, WriteFlagsToWriteOptions(flags)); } @@ -596,24 +596,9 @@ public Span GetSpan(ReadOnlySpan key) } } - public void PutSpan(ReadOnlySpan key, ReadOnlySpan value) + public void PutSpan(ReadOnlySpan key, ReadOnlySpan value, WriteFlags writeFlags) { - if (_isDisposing) - { - throw new ObjectDisposedException($"Attempted to write form a disposed database {Name}"); - } - - UpdateWriteMetrics(); - - try - { - _db.Put(key, value, null, WriteOptions); - } - catch (RocksDbSharpException e) - { - CreateMarkerIfCorrupt(e); - throw; - } + SetWithColumnFamily(key, null, value, writeFlags); } public void DangerousReleaseMemory(in Span span) diff --git a/src/Nethermind/Nethermind.Db.Rpc/RpcDb.cs b/src/Nethermind/Nethermind.Db.Rpc/RpcDb.cs index a91a3c8b236..903f51ff982 100644 --- a/src/Nethermind/Nethermind.Db.Rpc/RpcDb.cs +++ b/src/Nethermind/Nethermind.Db.Rpc/RpcDb.cs @@ -107,9 +107,9 @@ public Span GetSpan(ReadOnlySpan key) return Get(key); } - public void PutSpan(ReadOnlySpan key, ReadOnlySpan value) + public void PutSpan(ReadOnlySpan key, ReadOnlySpan value, WriteFlags writeFlags) { - Set(key, value.ToArray()); + Set(key, value.ToArray(), writeFlags); } public void DangerousReleaseMemory(in Span span) From 7be0695b063669a5dc611694ded7da900983a4d3 Mon Sep 17 00:00:00 2001 From: Amirul Ashraf Date: Sat, 28 Oct 2023 11:16:28 +0800 Subject: [PATCH 4/9] Fix flag not forwarded --- src/Nethermind/Nethermind.Blockchain/Blocks/BlockStore.cs | 2 +- src/Nethermind/Nethermind.Db/DbExtensions.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Nethermind/Nethermind.Blockchain/Blocks/BlockStore.cs b/src/Nethermind/Nethermind.Blockchain/Blocks/BlockStore.cs index c12862510b1..dda0a4eb282 100644 --- a/src/Nethermind/Nethermind.Blockchain/Blocks/BlockStore.cs +++ b/src/Nethermind/Nethermind.Blockchain/Blocks/BlockStore.cs @@ -53,7 +53,7 @@ public void Insert(Block block, WriteFlags writeFlags = WriteFlags.None) // 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.Number, block.Hash, newRlp.AsSpan()); + _blockDb.Set(block.Number, block.Hash, newRlp.AsSpan(), writeFlags); } private static void GetBlockNumPrefixedKey(long blockNumber, Hash256 blockHash, Span output) diff --git a/src/Nethermind/Nethermind.Db/DbExtensions.cs b/src/Nethermind/Nethermind.Db/DbExtensions.cs index 9c3da443c05..9c10b076173 100644 --- a/src/Nethermind/Nethermind.Db/DbExtensions.cs +++ b/src/Nethermind/Nethermind.Db/DbExtensions.cs @@ -49,11 +49,11 @@ public static void Set(this IDb db, Hash256 key, Span value) } } - public static void Set(this IDb db, long blockNumber, Hash256 key, Span value) + public static void Set(this IDb db, long blockNumber, Hash256 key, Span value, WriteFlags writeFlags = WriteFlags.None) { Span blockNumberPrefixedKey = stackalloc byte[40]; GetBlockNumPrefixedKey(blockNumber, key, blockNumberPrefixedKey); - db.Set(blockNumberPrefixedKey, value); + db.Set(blockNumberPrefixedKey, value, writeFlags); } private static void GetBlockNumPrefixedKey(long blockNumber, ValueHash256 blockHash, Span output) From a9fb2441fae50d990d6477c9186117f2e2104ca9 Mon Sep 17 00:00:00 2001 From: Amirul Ashraf Date: Wed, 25 Oct 2023 17:52:10 +0800 Subject: [PATCH 5/9] Added some tests --- .../Blocks/BlockStoreTests.cs | 14 ++++++++++++++ src/Nethermind/Nethermind.Core.Test/TestMemDb.cs | 5 +++-- .../FastBlocks/BodiesSyncFeed.cs | 9 ++++++--- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/Nethermind/Nethermind.Blockchain.Test/Blocks/BlockStoreTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/Blocks/BlockStoreTests.cs index 309abca4cc6..8b7d9b94491 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/Blocks/BlockStoreTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/Blocks/BlockStoreTests.cs @@ -5,6 +5,7 @@ using FluentAssertions; using Nethermind.Blockchain.Blocks; using Nethermind.Core; +using Nethermind.Core.Extensions; using Nethermind.Core.Test; using Nethermind.Core.Test.Builders; using Nethermind.Serialization.Rlp; @@ -33,6 +34,19 @@ public void Test_can_insert_get_and_remove_blocks(bool cached) store.Get(block.Number, block.Hash!, cached).Should().BeNull(); } + [Test] + public void Test_insert_would_pass_in_writeflag() + { + TestMemDb db = new TestMemDb(); + BlockStore store = new BlockStore(db); + + Block block = Build.A.Block.WithNumber(1).TestObject; + store.Insert(block, WriteFlags.DisableWAL); + + byte[] key = Bytes.Concat(block.Number.ToBigEndianByteArray(), block.Hash!.BytesToArray()); + db.KeyWasWrittenWithFlags(key, WriteFlags.DisableWAL); + } + [TestCase(true)] [TestCase(false)] public void Test_can_get_block_that_was_stored_with_hash(bool cached) diff --git a/src/Nethermind/Nethermind.Core.Test/TestMemDb.cs b/src/Nethermind/Nethermind.Core.Test/TestMemDb.cs index d531930340a..c76d7823574 100644 --- a/src/Nethermind/Nethermind.Core.Test/TestMemDb.cs +++ b/src/Nethermind/Nethermind.Core.Test/TestMemDb.cs @@ -24,7 +24,8 @@ public class TestMemDb : MemDb, ITunableDb public Func? ReadFunc { get; set; } public Action? RemoveFunc { get; set; } - public bool WasFlushed { get; set; } + public bool WasFlushed => FlushCount > 0; + public int FlushCount { get; set; } = 0; [MethodImpl(MethodImplOptions.Synchronized)] public override byte[]? Get(ReadOnlySpan key, ReadFlags flags = ReadFlags.None) @@ -107,6 +108,6 @@ public override IWriteBatch StartWriteBatch() public override void Flush() { - WasFlushed = true; + FlushCount++; } } diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs index 033be323bd1..3f45844da15 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs @@ -22,7 +22,8 @@ namespace Nethermind.Synchronization.FastBlocks public class BodiesSyncFeed : ActivatedSyncFeed { private int _requestSize = GethSyncLimits.MaxBodyFetch; - private const long FlushDbInterval = 100000; // About every 10GB on mainnet + private const long DefaultFlushDbInterval = 100000; // About every 10GB on mainnet + private readonly long _flushDbInterval; // About every 10GB on mainnet private readonly ILogger _logger; private readonly IBlockTree _blockTree; @@ -43,7 +44,8 @@ public BodiesSyncFeed( ISyncConfig syncConfig, ISyncReport syncReport, IDbMeta blocksDb, - ILogManager logManager) : base(syncModeSelector) + ILogManager logManager, + long flushDbInterval = DefaultFlushDbInterval) : base(syncModeSelector) { _logger = logManager?.GetClassLogger() ?? throw new ArgumentNullException(nameof(logManager)); _blockTree = blockTree ?? throw new ArgumentNullException(nameof(blockTree)); @@ -51,6 +53,7 @@ public BodiesSyncFeed( _syncConfig = syncConfig ?? throw new ArgumentNullException(nameof(syncConfig)); _syncReport = syncReport ?? throw new ArgumentNullException(nameof(syncReport)); _blocksDb = blocksDb ?? throw new ArgumentNullException(nameof(blocksDb)); + _flushDbInterval = flushDbInterval; if (!_syncConfig.FastBlocks) { @@ -134,7 +137,7 @@ private void PostFinishCleanUp() } } - if ((_blockTree.LowestInsertedBodyNumber ?? long.MaxValue) - _syncStatusList.LowestInsertWithoutGaps > FlushDbInterval) + if ((_blockTree.LowestInsertedBodyNumber ?? long.MaxValue) - _syncStatusList.LowestInsertWithoutGaps > _flushDbInterval) { Flush(); } From 57aeea2ef6177720659c1d698f52d6b04601e354 Mon Sep 17 00:00:00 2001 From: Amirul Ashraf Date: Wed, 25 Oct 2023 18:33:50 +0800 Subject: [PATCH 6/9] Fix sync can't finish --- .../Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs index 3f45844da15..431ab91bc3e 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs @@ -137,8 +137,10 @@ private void PostFinishCleanUp() } } - if ((_blockTree.LowestInsertedBodyNumber ?? long.MaxValue) - _syncStatusList.LowestInsertWithoutGaps > _flushDbInterval) - { + if ( + (_blockTree.LowestInsertedBodyNumber ?? long.MaxValue) - _syncStatusList.LowestInsertWithoutGaps > _flushDbInterval || + _syncStatusList.LowestInsertWithoutGaps <= _barrier // Other state depends on LowestInsertedBodyNumber, so this need to flush or it wont finish + ) { Flush(); } From 1de5a41a34866925ebb3d2e32702c3850116a499 Mon Sep 17 00:00:00 2001 From: Amirul Ashraf Date: Wed, 25 Oct 2023 18:34:00 +0800 Subject: [PATCH 7/9] Missed a file --- .../FastBlocks/BodiesSyncFeedTests.cs | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/BodiesSyncFeedTests.cs diff --git a/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/BodiesSyncFeedTests.cs b/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/BodiesSyncFeedTests.cs new file mode 100644 index 00000000000..9dea6c7b178 --- /dev/null +++ b/src/Nethermind/Nethermind.Synchronization.Test/FastBlocks/BodiesSyncFeedTests.cs @@ -0,0 +1,90 @@ +// SPDX-FileCopyrightText: 2023 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System.Linq; +using System.Threading.Tasks; +using FluentAssertions; +using Nethermind.Blockchain; +using Nethermind.Blockchain.Synchronization; +using Nethermind.Core; +using Nethermind.Core.Test; +using Nethermind.Core.Test.Builders; +using Nethermind.Logging; +using Nethermind.Synchronization.FastBlocks; +using Nethermind.Synchronization.ParallelSync; +using Nethermind.Synchronization.Peers; +using Nethermind.Synchronization.Reporting; +using NSubstitute; +using NUnit.Framework; + +namespace Nethermind.Synchronization.Test.FastBlocks; + +public class BodiesSyncFeedTests +{ + [Test] + public async Task ShouldCallFlushPeriodically() + { + BlockTree syncingFromBlockTree = Build.A.BlockTree() + .OfChainLength(100) + .TestObject; + + TestMemDb blocksDb = new TestMemDb(); + BlockTree syncingTooBlockTree = Build.A.BlockTree() + .WithBlocksDb(blocksDb) + .TestObject; + + for (int i = 1; i < 100; i++) + { + Block block = syncingFromBlockTree.FindBlock(i, BlockTreeLookupOptions.None)!; + syncingTooBlockTree.Insert(block.Header); + } + + Block pivot = syncingFromBlockTree.FindBlock(99, BlockTreeLookupOptions.None)!; + + SyncConfig syncConfig = new SyncConfig() + { + FastSync = true, + PivotHash = pivot.Hash!.ToString(), + PivotNumber = pivot.Number.ToString(), + AncientBodiesBarrier = 0, + FastBlocks = true, + DownloadBodiesInFastSync = true, + }; + + BodiesSyncFeed syncFeed = new BodiesSyncFeed( + Substitute.For(), + syncingTooBlockTree, + Substitute.For(), + syncConfig, + new NullSyncReport(), + blocksDb, + LimboLogs.Instance, + flushDbInterval: 10 + ); + + syncFeed.InitializeFeed(); + BodiesSyncBatch req = (await syncFeed.PrepareRequest())!; + blocksDb.FlushCount.Should().Be(1); + + async Task HandleAndPrepareNextRequest() + { + req.Response = new OwnedBlockBodies(req.Infos.Take(8).Select((info) => + syncingFromBlockTree.FindBlock(info!.BlockNumber, BlockTreeLookupOptions.None)!.Body).ToArray()); + + syncFeed.HandleResponse(req); + req = (await syncFeed.PrepareRequest())!; + } + + await HandleAndPrepareNextRequest(); + blocksDb.FlushCount.Should().Be(1); + + await HandleAndPrepareNextRequest(); + blocksDb.FlushCount.Should().Be(2); + + await HandleAndPrepareNextRequest(); + blocksDb.FlushCount.Should().Be(2); + + await HandleAndPrepareNextRequest(); + blocksDb.FlushCount.Should().Be(3); + } +} From adfae40412a45046da7ac9a56919a03b6a39d695 Mon Sep 17 00:00:00 2001 From: Amirul Ashraf Date: Thu, 26 Oct 2023 14:02:43 +0800 Subject: [PATCH 8/9] Make sure flush pointer is correct --- .../Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs index 431ab91bc3e..b4d5795ba1b 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs @@ -149,8 +149,9 @@ private void PostFinishCleanUp() private void Flush() { + long lowestInsertedAtPoint = _syncStatusList.LowestInsertWithoutGaps; _blocksDb.Flush(); - _blockTree.LowestInsertedBodyNumber = _syncStatusList.LowestInsertWithoutGaps; + _blockTree.LowestInsertedBodyNumber = lowestInsertedAtPoint; } public override SyncResponseHandlingResult HandleResponse(BodiesSyncBatch? batch, PeerInfo peer = null) From bb8b8947b8de7185cad3ab64ebddb1f507271fbf Mon Sep 17 00:00:00 2001 From: Amirul Ashraf Date: Thu, 26 Oct 2023 14:22:06 +0800 Subject: [PATCH 9/9] Whitespace --- .../Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs b/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs index b4d5795ba1b..3de32f7b366 100644 --- a/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs +++ b/src/Nethermind/Nethermind.Synchronization/FastBlocks/BodiesSyncFeed.cs @@ -140,7 +140,8 @@ private void PostFinishCleanUp() if ( (_blockTree.LowestInsertedBodyNumber ?? long.MaxValue) - _syncStatusList.LowestInsertWithoutGaps > _flushDbInterval || _syncStatusList.LowestInsertWithoutGaps <= _barrier // Other state depends on LowestInsertedBodyNumber, so this need to flush or it wont finish - ) { + ) + { Flush(); }