public void Insert_without_recalculating_hashes_with_starting_index(uint nodesCount, uint startCalculatingHashes) { BaselineTree withHashesTree = BuildATree(); BaselineTree withoutHashesTree = BuildATree(); for (int i = 0; i < nodesCount; i++) { withHashesTree.Insert(_testLeaves[i]); if (i < startCalculatingHashes) { withoutHashesTree.Insert(_testLeaves[i]); Assert.AreEqual(withHashesTree.Root, withoutHashesTree.Root); } else { withoutHashesTree.Insert(_testLeaves[i], false); Assert.AreNotEqual(withHashesTree.Root, withoutHashesTree.Root); } Assert.AreEqual(withHashesTree.Count, withoutHashesTree.Count); } withoutHashesTree.CalculateHashes(startCalculatingHashes); Assert.AreEqual(withHashesTree.Root, withoutHashesTree.Root); Assert.AreEqual(withHashesTree.Count, withoutHashesTree.Count); }
public async Task Can_safely_insert_concurrently() { BaselineTree baselineTree = BuildATree(); uint iterations = 1000; uint concurrentTasksCount = 8; Action keepAdding = () => { for (int i = 0; i < iterations; i++) { baselineTree.Insert(_testLeaves[0]); } }; Task[] tasks = new Task[concurrentTasksCount]; for (int i = 0; i < tasks.Length; i++) { tasks[i] = new Task(keepAdding); } for (int i = 0; i < tasks.Length; i++) { tasks[i].Start(); } await Task.WhenAll(tasks); baselineTree.Count.Should().Be(concurrentTasksCount * iterations); }
public void On_adding_one_leaf_count_goes_up_to_1() { BaselineTree baselineTree = BuildATree(); baselineTree.Insert(_testLeaves[0]); baselineTree.Count.Should().Be(1); }
public async Task Tree_tracker_insert_leaves([ValueSource(nameof(InsertLeavesTestCases))] InsertLeavesTest test) { var address = TestItem.Addresses[0]; var result = await InitializeTestRpc(address); var testRpc = result.TestRpc; BaselineTree baselineTree = BuildATree(); var fromContractAdress = ContractAddress.From(address, 0); var baselineTreeHelper = new BaselineTreeHelper(testRpc.LogFinder, _baselineDb, _metadataBaselineDb, LimboNoErrorLogger.Instance); new BaselineTreeTracker(fromContractAdress, baselineTree, testRpc.BlockProcessor, baselineTreeHelper, testRpc.BlockFinder, LimboNoErrorLogger.Instance); var contract = new MerkleTreeSHAContract(_abiEncoder, fromContractAdress); UInt256 nonce = 1L; for (int i = 0; i < test.ExpectedTreeCounts.Length; i++) { nonce = await InsertLeavesFromArray(test.LeavesInTransactionsAndBlocks[i], nonce, testRpc, contract, address); await testRpc.AddBlock(); Assert.AreEqual(test.ExpectedTreeCounts[i], baselineTree.Count); } }
public void On_inserting_one_leaf_and_deleting_last_element() { BaselineTree baselineTree = BuildATree(); baselineTree.Insert(_testLeaves[0]); baselineTree.Count.Should().Be(1); baselineTree.DeleteLast(); baselineTree.Count.Should().Be(0); }
public void When_inserting_more_leaves_count_keeps_growing(int numberOfLeaves) { BaselineTree baselineTree = BuildATree(); for (uint i = 0; i < numberOfLeaves; i++) { baselineTree.Insert(_testLeaves[i]); baselineTree.Count.Should().Be(i + 1); } }
public void Can_calculate_parent_index(ulong nodeIndex, uint?parentIndex) { if (parentIndex == null) { Assert.Throws <ArgumentOutOfRangeException>(() => BaselineTree.GetParentIndex(nodeIndex)); } else { BaselineTree.GetParentIndex(nodeIndex).Should().Be(parentIndex.Value); } }
public void Can_calculate_index_at_row_from_node_index(uint row, ulong nodeIndex, uint?indexAtRow) { if (indexAtRow == null) { Assert.Throws <ArgumentOutOfRangeException>(() => BaselineTree.GetIndexAtRow(row, nodeIndex)); } else { BaselineTree.GetIndexAtRow(row, nodeIndex).Should().Be(indexAtRow.Value); } }
public void Can_calculate_leaf_index_from_node_index(ulong nodeIndex, uint?leafIndex) { if (leafIndex == null) { Assert.Throws <ArgumentOutOfRangeException>(() => BaselineTree.GetLeafIndex(nodeIndex)); } else { BaselineTree.GetLeafIndex(nodeIndex).Should().Be(leafIndex.Value); } }
public void Can_calculate_node_row(ulong nodeIndex, uint?expectedRow) { if (expectedRow == null) { Assert.Throws <ArgumentOutOfRangeException>(() => BaselineTree.GetRow(nodeIndex)); } else { BaselineTree.GetRow(nodeIndex).Should().Be(expectedRow.Value); } }
public void On_deleting_last_element() { BaselineTree baselineTree = BuildATree(); baselineTree.Insert(_testLeaves[0]); baselineTree.Insert(_testLeaves[1]); baselineTree.Insert(_testLeaves[2]); baselineTree.Count.Should().Be(3); baselineTree.DeleteLast(); baselineTree.Count.Should().Be(2); }
public void Can_calculate_node_index_from_row_and_index_at_row(uint row, uint indexAtRow, ulong?nodeIndex) { if (nodeIndex == null) { Assert.Throws <ArgumentOutOfRangeException>(() => BaselineTree.GetNodeIndex(row, indexAtRow)); } else { BaselineTree.GetNodeIndex(row, indexAtRow).Should().Be(nodeIndex.Value); } }
public void Can_calculate_sibling_index(uint row, uint indexAtRow, uint?expectedSiblingIndex) { if (expectedSiblingIndex == null) { Assert.Throws <ArgumentOutOfRangeException>(() => BaselineTree.GetSiblingIndexAtRow(row, indexAtRow)); } else { BaselineTree.GetSiblingIndexAtRow(row, indexAtRow).Should().Be(expectedSiblingIndex.Value); BaselineTree.GetSiblingIndexAtRow(row, expectedSiblingIndex.Value).Should().Be(indexAtRow); } }
public void Can_restore_count_from_the_database(uint leafCount) { MemDb memDb = new MemDb(); BaselineTree baselineTree = BuildATree(memDb); for (int i = 0; i < leafCount; i++) { baselineTree.Insert(_testLeaves[0]); } BaselineTree baselineTreeRestored = BuildATree(memDb); baselineTreeRestored.Count.Should().Be(leafCount); }
public void Can_get_leaf(uint nodesCount) { BaselineTree baselineTree = BuildATree(); for (int i = 0; i < nodesCount; i++) { baselineTree.Insert(_testLeaves[0]); } for (int i = 0; i < nodesCount; i++) { baselineTree.GetLeaf((uint)i).Hash.Should().NotBe(Keccak.Zero); } }
public void Can_get_root(uint nodesCount) { BaselineTree baselineTree = BuildATree(); Keccak root = baselineTree.Root; Console.WriteLine(root); for (int i = 0; i < nodesCount; i++) { baselineTree.Insert(_testLeaves[0]); Keccak newRoot = baselineTree.Root; Console.WriteLine(newRoot); newRoot.Should().NotBeEquivalentTo(root); root = newRoot; } }
public void Can_get_leaves(uint nodesCount) { BaselineTree baselineTree = BuildATree(); for (int i = 0; i < nodesCount; i++) { baselineTree.Insert(_testLeaves[0]); } var leafIndexes = Enumerable.Range(0, (int)nodesCount).Select(l => (uint)l).ToArray(); var result = baselineTree.GetLeaves(leafIndexes); for (int i = 0; i < result.Length; i++) { result[i].Hash.Should().NotBe(Keccak.Zero); } }
public async Task Tree_tracker_reorganization([ValueSource(nameof(ReorganizationTestCases))] ReorganizedInsertLeafTest test) { Address address = TestItem.Addresses[0]; (TestRpcBlockchain TestRpc, BaselineModule BaselineModule)result = await InitializeTestRpc(address); TestRpcBlockchain testRpc = result.TestRpc; BaselineTree baselineTree = BuildATree(); Address contractAddress = ContractAddress.From(address, 0L); BaselineTreeHelper baselineTreeHelper = new (testRpc.LogFinder, _baselineDb, _metadataBaselineDb, LimboNoErrorLogger.Instance); _ = new BaselineTreeTracker(contractAddress, baselineTree, testRpc.BlockProcessor, baselineTreeHelper, testRpc.BlockFinder, LimboNoErrorLogger.Instance); MerkleTreeSHAContract contract = new (_abiEncoder, contractAddress); for (int i = 0; i < test.LeavesInBlocksCounts.Length; i++) { InsertLeafFromArray(test.LeavesInTransactionsAndBlocks[i], testRpc, contract, address); await testRpc.AddBlock(); Assert.AreEqual(test.LeavesInBlocksCounts[i], baselineTree.Count); } int initBlocksCount = 4; int allBlocksCount = initBlocksCount + test.LeavesInBlocksCounts.Length; TestBlockProducer testRpcBlockProducer = (TestBlockProducer)testRpc.BlockProducer; Block lastProducedBlock = null; testRpcBlockProducer.BlockProduced += (o, e) => lastProducedBlock = e.Block; testRpcBlockProducer.BlockParent = testRpc.BlockTree.FindHeader(allBlocksCount); InsertLeafFromArray(test.LeavesInMiddleOfReorganization, testRpc, contract, address); await testRpc.AddBlock(false); testRpcBlockProducer.BlockParent = lastProducedBlock.Header; InsertLeafFromArray(test.LeavesInAfterReorganization, testRpc, contract, address); await testRpc.AddBlock(); Assert.AreEqual(test.FinalLeavesCount, baselineTree.Count); }
public void Insert_without_recalculating_hashes(uint nodesCount) { BaselineTree withHashesTree = BuildATree(); BaselineTree withoutHashesTree = BuildATree(); for (int i = 0; i < nodesCount; i++) { withHashesTree.Insert(_testLeaves[i]); withoutHashesTree.Insert(_testLeaves[i], false); Assert.AreNotEqual(withHashesTree.Root, withoutHashesTree.Root); Assert.AreEqual(withHashesTree.Count, withoutHashesTree.Count); } withoutHashesTree.CalculateHashes(); Assert.AreEqual(withHashesTree.Root, withoutHashesTree.Root); Assert.AreEqual(withHashesTree.Count, withoutHashesTree.Count); }
public async Task Tree_tracker_reorganization([ValueSource(nameof(ReorganizationTestCases))] ReorganizedInsertLeafTest test) { var address = TestItem.Addresses[0]; var result = await InitializeTestRpc(address); var testRpc = result.TestRpc; BaselineTree baselineTree = BuildATree(); var fromContractAdress = ContractAddress.From(address, 0L); var baselineTreeHelper = new BaselineTreeHelper(testRpc.LogFinder, _baselineDb, _metadataBaselineDb, LimboNoErrorLogger.Instance); new BaselineTreeTracker(fromContractAdress, baselineTree, testRpc.BlockProcessor, baselineTreeHelper, testRpc.BlockFinder, LimboNoErrorLogger.Instance); var contract = new MerkleTreeSHAContract(_abiEncoder, fromContractAdress); UInt256 nonce = 1L; for (int i = 0; i < test.LeavesInBlocksCounts.Length; i++) { nonce = await InsertLeafFromArray(test.LeavesInTransactionsAndBlocks[i], nonce, testRpc, contract, address); await testRpc.AddBlock(); Assert.AreEqual(test.LeavesInBlocksCounts[i], baselineTree.Count); } var initBlocksCount = 4; var allBlocksCount = initBlocksCount + test.LeavesInBlocksCounts.Length; testRpc.BlockProducer.BlockParent = testRpc.BlockTree.FindHeader(allBlocksCount); nonce = 1L; nonce = await InsertLeafFromArray(test.LeavesInMiddleOfReorganization, nonce, testRpc, contract, address); await testRpc.AddBlock(false); testRpc.BlockProducer.BlockParent = testRpc.BlockProducer.LastProducedBlock.Header; await InsertLeafFromArray(test.LeavesInAfterReorganization, nonce, testRpc, contract, address); await testRpc.AddBlock(); Assert.AreEqual(test.FinalLeavesCount, baselineTree.Count); }
public void Can_verify_zero_and_one_elements(uint nodesCount) { BaselineTree baselineTree = BuildATree(); Keccak root = baselineTree.Root; Console.WriteLine(root); for (int i = 0; i < nodesCount; i++) { baselineTree.Insert(_testLeaves[i]); Keccak newRoot = baselineTree.Root; Console.WriteLine(newRoot); newRoot.Should().NotBeEquivalentTo(root); root = newRoot; var proof0 = baselineTree.GetProof(0); var proof1 = baselineTree.GetProof(1); baselineTree.Verify(root, _testLeaves[0], proof0).Should().BeTrue("left in " + i); if (i > 0) { baselineTree.Verify(root, _testLeaves[1], proof1).Should().BeTrue("right in " + i); } } }
public async Task Tree_tracker_start_stop_tracking([ValueSource(nameof(InsertLeafTestCases))] InsertLeafTest test) { Address address = TestItem.Addresses[0]; (TestRpcBlockchain TestRpc, BaselineModule BaselineModule)result = await InitializeTestRpc(address); TestRpcBlockchain testRpc = result.TestRpc; BaselineTree baselineTree = BuildATree(); Address fromContractAdress = ContractAddress.From(address, 0L); BaselineTreeHelper baselineTreeHelper = new (testRpc.LogFinder, _baselineDb, _metadataBaselineDb, LimboNoErrorLogger.Instance); MerkleTreeSHAContract contract = new (_abiEncoder, fromContractAdress); for (int i = 0; i < test.ExpectedTreeCounts.Length; i++) { InsertLeafFromArray(test.LeavesInTransactionsAndBlocks[i], testRpc, contract, address); await testRpc.AddBlock(); } BaselineTreeTracker tracker = new (fromContractAdress, baselineTree, testRpc.BlockProcessor, baselineTreeHelper, testRpc.BlockFinder, LimboNoErrorLogger.Instance); Assert.AreEqual(test.ExpectedTreeCounts[^ 1], baselineTree.Count);
public void Can_get_proof_on_a_populated_trie_on_an_index(uint nodesCount) { BaselineTree baselineTree = BuildATree(); for (int i = 0; i < nodesCount; i++) { baselineTree.Insert(_testLeaves[0]); } BaselineTreeNode[] proof = baselineTree.GetProof(0); proof.Should().HaveCount(BaselineTree.TreeHeight); for (int proofRow = 0; proofRow < BaselineTree.TreeHeight; proofRow++) { if (nodesCount > 1 >> proofRow) { proof[proofRow].Should().NotBe(Keccak.Zero, proofRow.ToString()); } else { proof[proofRow].Hash.Should().Be(Keccak.Zero, proofRow.ToString()); } } }
public void Keccak_a_b_verify() { BaselineTree baselineTree = BuildATree(); Keccak root0 = baselineTree.Root; Console.WriteLine("root0 " + root0); Console.WriteLine("KeccakA " + TestItem.KeccakA); baselineTree.Insert(TestItem.KeccakA); var proof0_0 = baselineTree.GetProof(0); Keccak root1 = baselineTree.Root; Console.WriteLine("root1 " + root1); Console.WriteLine("KeccakB " + TestItem.KeccakB); baselineTree.Insert(TestItem.KeccakB); Keccak root2 = baselineTree.Root; Console.WriteLine("root2 " + root2); var proof1_0 = baselineTree.GetProof(0); var proof1_1 = baselineTree.GetProof(1); baselineTree.Verify(root1, TestItem.KeccakA, proof0_0).Should().BeTrue(); baselineTree.Verify(root2, TestItem.KeccakA, proof1_0).Should().BeTrue(); baselineTree.Verify(root2, TestItem.KeccakB, proof1_1).Should().BeTrue(); }
public void Initially_count_is_0() { BaselineTree baselineTree = BuildATree(); baselineTree.Count.Should().Be(0); }
private static void WriteHistory(Dictionary <long, uint> historicalCountChecks, BaselineTree baselineTree) { foreach (KeyValuePair <long, uint> check in historicalCountChecks) { TestContext.WriteLine($" History is {check.Key}=>{check.Value} {baselineTree.Metadata.LoadBlockNumberCount(check.Key)})"); } TestContext.WriteLine($" Last with leaves {baselineTree.LastBlockWithLeaves}"); TestContext.WriteLine($" Last with leaves in DB {baselineTree.Metadata.LoadCurrentBlockInDb().LastBlockWithLeaves}"); TestContext.WriteLine($" Count {baselineTree.Count}"); }