Skip to content

Commit 57030ea

Browse files
authored
Merge pull request #549 from NethermindEth/lazytree
Lazytree
2 parents 59b7cb6 + 65d3a5a commit 57030ea

File tree

47 files changed

+366
-297
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+366
-297
lines changed

.travis.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ jobs:
2626
- stage: run tests
2727
script: dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:Exclude="[Nethermind.HashLib]*" src/Nethermind/Ethereum.Basic.Test
2828
name: "Ethereum.Basic.Test"
29+
- script: dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:Exclude="[Nethermind.HashLib]*" src/Nethermind.DataMarketplace.Consumers.Test
30+
name: "Nethermind.DataMarketplace.Consumers.Test"
31+
- script: dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:Exclude="[Nethermind.HashLib]*" src/Nethermind.DataMarketplace.Integration.Test
32+
name: "Nethermind.DataMarketplace.Integration.Test"
33+
- script: dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:Exclude="[Nethermind.HashLib]*" src/Nethermind.DataMarketplace.Test
34+
name: "Nethermind.DataMarketplace.Test"
2935
- script: dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:Exclude="[Nethermind.HashLib]*" src/Nethermind/Ethereum.Blockchain.Block.Test
3036
name: "Ethereum.Blockchain.Block.Test"
3137
- script: dotnet test src/Nethermind/Ethereum.Blockchain.Test

src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ private static Block Convert(TestBlockJson testBlockJson)
571571
BlockHeader header = Convert(testBlockJson.BlockHeader);
572572
BlockHeader[] ommers = testBlockJson.UncleHeaders?.Select(Convert).ToArray() ?? new BlockHeader[0];
573573
Block block = new Block(header, ommers);
574-
block.Transactions = testBlockJson.Transactions?.Select(Convert).ToArray();
574+
block.Body.Transactions = testBlockJson.Transactions?.Select(Convert).ToArray();
575575
return block;
576576
}
577577

src/Nethermind/Nethermind.Blockchain.Test/BlockTreeTests.cs

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ public void Add_and_find_branch()
167167
BlockTree blockTree = BuildBlockTree();
168168
Block block = Build.A.Block.TestObject;
169169
blockTree.SuggestBlock(block);
170-
Block found = blockTree.FindBlock(block.Hash, false);
170+
Block found = blockTree.FindBlock(block.Hash, BlockTreeLookupOptions.None);
171171
Assert.AreEqual(block.Hash, BlockHeader.CalculateHash(found.Header));
172172
}
173173

@@ -177,7 +177,7 @@ public void Add_on_branch_move_find()
177177
BlockTree blockTree = BuildBlockTree();
178178
Block block = Build.A.Block.TestObject;
179179
AddToMain(blockTree, block);
180-
Block found = blockTree.FindBlock(block.Hash, true);
180+
Block found = blockTree.FindBlock(block.Hash, BlockTreeLookupOptions.RequireCanonical);
181181
Assert.AreEqual(block.Hash, BlockHeader.CalculateHash(found.Header));
182182
}
183183

@@ -187,7 +187,7 @@ public void Add_on_branch_and_not_find_on_main()
187187
BlockTree blockTree = BuildBlockTree();
188188
Block block = Build.A.Block.TestObject;
189189
blockTree.SuggestBlock(block);
190-
Block found = blockTree.FindBlock(block.Hash, true);
190+
Block found = blockTree.FindBlock(block.Hash, BlockTreeLookupOptions.RequireCanonical);
191191
Assert.IsNull(found);
192192
}
193193

@@ -473,7 +473,7 @@ public void Stores_multiple_blocks_per_level()
473473
AddToMain(blockTree, block1);
474474
blockTree.SuggestBlock(block1B);
475475

476-
Block found = blockTree.FindBlock(block1B.Hash, false);
476+
Block found = blockTree.FindBlock(block1B.Hash, BlockTreeLookupOptions.None);
477477

478478
Assert.AreEqual(block1B.Hash, BlockHeader.CalculateHash(found.Header));
479479
}
@@ -1147,6 +1147,34 @@ public void Can_batch_insert_blocks()
11471147

11481148
tree.Insert(blocks);
11491149
}
1150+
1151+
[Test]
1152+
public void Block_loading_is_lazy()
1153+
{
1154+
MemDb blocksDb = new MemDb();
1155+
MemDb blockInfosDb = new MemDb();
1156+
MemDb headersDb = new MemDb();
1157+
1158+
SyncConfig syncConfig = new SyncConfig();
1159+
syncConfig.PivotNumber = 0L.ToString();
1160+
1161+
Block genesis = Build.A.Block.Genesis.TestObject;
1162+
BlockTree tree = new BlockTree(blocksDb, headersDb, blockInfosDb, MainNetSpecProvider.Instance, NullTxPool.Instance, syncConfig, LimboLogs.Instance);
1163+
tree.SuggestBlock(genesis);
1164+
1165+
Block previousBlock = genesis;
1166+
for (int i = 1; i < 10; i++)
1167+
{
1168+
Block block = Build.A.Block.WithNumber(i).WithParent(previousBlock).TestObject;
1169+
tree.SuggestBlock(block);
1170+
previousBlock = block;
1171+
}
1172+
1173+
Block lastBlock = previousBlock;
1174+
1175+
BlockTree loadedTree = new BlockTree(blocksDb, headersDb, blockInfosDb, MainNetSpecProvider.Instance, NullTxPool.Instance, syncConfig, LimboLogs.Instance);
1176+
loadedTree.FindHeader(lastBlock.Hash, BlockTreeLookupOptions.None);
1177+
}
11501178

11511179
static object[] SourceOfBSearchTestCases =
11521180
{

src/Nethermind/Nethermind.Blockchain.Test/BlockchainProcessorTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ public ProcessingTestContext IsDeletedAsInvalid()
348348
_processingTestContext._resetEvent.WaitOne(IgnoreWait);
349349
Assert.AreEqual(_processingTestContext._headBefore, _processingTestContext._blockTree.Head.Hash, "head");
350350
_logger.Info($"Finished waiting for {_block.ToString(Block.Format.Short)} to be deleted");
351-
Assert.Null(_processingTestContext._blockTree.FindBlock(_block.Hash, false));
351+
Assert.Null(_processingTestContext._blockTree.FindBlock(_block.Hash, BlockTreeLookupOptions.None));
352352
return _processingTestContext;
353353
}
354354
}

src/Nethermind/Nethermind.Blockchain.Test/Synchronization/BlockDownloaderTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public async Task<BlockHeader[]> BuildHeaderResponse(long startNumber, int numbe
7474
throw new TimeoutException();
7575
}
7676

77-
BlockHeader startBlock = _blockTree.FindHeader(_testHeaderMapping[startNumber], false);
77+
BlockHeader startBlock = _blockTree.FindHeader(_testHeaderMapping[startNumber], BlockTreeLookupOptions.None);
7878
BlockHeader[] headers = new BlockHeader[number];
7979
headers[0] = startBlock;
8080
if (!justFirst)
@@ -116,7 +116,7 @@ public async Task<BlockBody[]> BuildBlocksResponse(Keccak[] blockHashes, Respons
116116
throw new TimeoutException();
117117
}
118118

119-
BlockHeader startHeader = _blockTree.FindHeader(blockHashes[0], false);
119+
BlockHeader startHeader = _blockTree.FindHeader(blockHashes[0], BlockTreeLookupOptions.None);
120120
if (startHeader == null) startHeader = Build.A.BlockHeader.WithHash(blockHashes[0]).TestObject;
121121

122122
BlockHeader[] blockHeaders = new BlockHeader[blockHashes.Length];

src/Nethermind/Nethermind.Blockchain.Test/Synchronization/FastBlocks/FastBlocksFeedTests.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -655,15 +655,15 @@ private void AssertTreeSynced(IBlockTree tree, bool bodiesSync = false, bool rec
655655
Keccak nextHash = tree.Head.Hash;
656656
for (int i = 0; i < tree.Head.Number; i++)
657657
{
658-
BlockHeader header = _localBlockTree.FindHeader(nextHash);
658+
BlockHeader header = _localBlockTree.FindHeader(nextHash, BlockTreeLookupOptions.None);
659659
Assert.NotNull(header, $"header {tree.Head.Number - i}");
660660
if (bodiesSync)
661661
{
662-
Block expectedBlock = _localBlockTree.FindBlock(nextHash, false);
662+
Block expectedBlock = _localBlockTree.FindBlock(nextHash, BlockTreeLookupOptions.None);
663663
Assert.AreEqual(nextHash, expectedBlock?.Hash, $"hash difference {tree.Head.Number - i}");
664664
if (expectedBlock != null)
665665
{
666-
Block actualBlock = tree.FindBlock(expectedBlock.Hash, false);
666+
Block actualBlock = tree.FindBlock(expectedBlock.Hash, BlockTreeLookupOptions.None);
667667
Rlp saved = Rlp.Encode(actualBlock);
668668
Rlp expected = Rlp.Encode(expectedBlock);
669669
Assert.AreEqual(expected, saved, $"body {tree.Head.Number - i}");
@@ -832,7 +832,7 @@ private void PrepareReceiptsResponse(ReceiptsSyncBatch receiptSyncBatch, Latency
832832
receiptSyncBatch.Response = new TxReceipt[receiptSyncBatch.Request.Length][];
833833
for (int i = 0; i < receiptSyncBatch.Request.Length; i++)
834834
{
835-
Block block = tree.FindBlock(receiptSyncBatch.Request[i], false);
835+
Block block = tree.FindBlock(receiptSyncBatch.Request[i], BlockTreeLookupOptions.None);
836836
receiptSyncBatch.Response[i] = new TxReceipt[block.Transactions.Length];
837837
for (int j = 0; j < block.Transactions.Length; j++)
838838
{
@@ -861,7 +861,7 @@ private void PrepareBodiesResponse(BodiesSyncBatch bodiesSyncBatch, LatencySyncP
861861

862862
for (int i = 0; i < Math.Min(maxResponseSize, requestSize); i++)
863863
{
864-
Block block = tree.FindBlock(bodiesSyncBatch.Request[i], false);
864+
Block block = tree.FindBlock(bodiesSyncBatch.Request[i], BlockTreeLookupOptions.None);
865865
bodiesSyncBatch.Response[i] = new BlockBody(block.Transactions, block.Ommers);
866866
}
867867

src/Nethermind/Nethermind.Blockchain.Test/Synchronization/OldStyleFullSynchronizerTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ public void Can_sync_on_split_of_length_1()
199199

200200
Assert.AreEqual(miner1Tree.BestSuggestedHeader.Hash, _blockTree.BestSuggestedHeader.Hash, "client agrees with miner before split");
201201

202-
Block splitBlock = Build.A.Block.WithParent(miner1Tree.FindParent(miner1Tree.Head)).WithDifficulty(miner1Tree.Head.Difficulty - 1).TestObject;
202+
Block splitBlock = Build.A.Block.WithParent(miner1Tree.FindParent(miner1Tree.Head, BlockTreeLookupOptions.TotalDifficultyNotNeeded)).WithDifficulty(miner1Tree.Head.Difficulty - 1).TestObject;
203203
Block splitBlockChild = Build.A.Block.WithParent(splitBlock).TestObject;
204204

205205
miner1Tree.SuggestBlock(splitBlock);

src/Nethermind/Nethermind.Blockchain.Test/Synchronization/SyncPeerMock.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public Task<BlockBody[]> GetBlocks(Keccak[] blockHashes, CancellationToken token
8585
BlockBody[] result = new BlockBody[blockHashes.Length];
8686
for (int i = 0; i < blockHashes.Length; i++)
8787
{
88-
Block block = _remoteTree.FindBlock(blockHashes[i], true);
88+
Block block = _remoteTree.FindBlock(blockHashes[i], BlockTreeLookupOptions.RequireCanonical);
8989
result[i] = new BlockBody(block.Transactions, block.Ommers);
9090
}
9191

@@ -95,7 +95,7 @@ public Task<BlockBody[]> GetBlocks(Keccak[] blockHashes, CancellationToken token
9595
public Task<BlockHeader[]> GetBlockHeaders(Keccak blockHash, int maxBlocks, int skip, CancellationToken token)
9696
{
9797
BlockHeader[] result = new BlockHeader[maxBlocks];
98-
long? firstNumber = _remoteTree.FindHeader(blockHash, true)?.Number;
98+
long? firstNumber = _remoteTree.FindHeader(blockHash, BlockTreeLookupOptions.RequireCanonical)?.Number;
9999
if (!firstNumber.HasValue)
100100
{
101101
return Task.FromResult(result);

src/Nethermind/Nethermind.Blockchain/BlockExtensions.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,20 @@ public static class BlockExtensions
2828
{
2929
public static Keccak CalculateReceiptRoot(this Block block, ISpecProvider specProvider, TxReceipt[] txReceipts)
3030
{
31-
PatriciaTree receiptTree = txReceipts.Length > 0 ? new PatriciaTree(NullDb.Instance, Keccak.EmptyTreeHash, false) : null;
31+
if (txReceipts.Length == 0)
32+
{
33+
return PatriciaTree.EmptyTreeHash;
34+
}
35+
36+
PatriciaTree receiptTree = new PatriciaTree();
3237
for (int i = 0; i < txReceipts.Length; i++)
3338
{
3439
Rlp receiptRlp = Rlp.Encode(txReceipts[i], specProvider.GetSpec(block.Number).IsEip658Enabled ? RlpBehaviors.Eip658Receipts : RlpBehaviors.None);
35-
receiptTree?.Set(Rlp.Encode(i).Bytes, receiptRlp);
40+
receiptTree.Set(Rlp.Encode(i).Bytes, receiptRlp);
3641
}
3742

38-
receiptTree?.UpdateRootHash();
39-
Keccak receiptRoot = receiptTree?.RootHash ?? PatriciaTree.EmptyTreeHash;
40-
return receiptRoot;
43+
receiptTree.UpdateRootHash();
44+
return receiptTree.RootHash;
4145
}
4246

4347
public static Keccak CalculateTxRoot(this Block block)
@@ -60,7 +64,9 @@ public static Keccak CalculateTxRoot(this Block block)
6064

6165
public static Keccak CalculateOmmersHash(this Block block)
6266
{
63-
return Keccak.Compute(Rlp.Encode(block.Ommers));
67+
return block.Ommers.Length == 0
68+
? Keccak.OfAnEmptySequenceRlp
69+
: Keccak.Compute(Rlp.Encode(block.Ommers));
6470
}
6571
}
6672
}

0 commit comments

Comments
 (0)