示例#1
0
        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);
        }
示例#2
0
        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);
        }
示例#3
0
        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);
            }
        }
示例#5
0
        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);
        }
示例#6
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);
            }
        }
示例#7
0
 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);
     }
 }
示例#11
0
        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);
     }
 }
示例#14
0
        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);
        }
示例#15
0
        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);
            }
        }
示例#16
0
        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;
            }
        }
示例#17
0
        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);
            }
        }
示例#18
0
        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);
        }
示例#19
0
        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);
        }
示例#20
0
        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);
        }
示例#21
0
        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);
示例#23
0
        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());
                }
            }
        }
示例#24
0
        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();
        }
示例#25
0
        public void Initially_count_is_0()
        {
            BaselineTree baselineTree = BuildATree();

            baselineTree.Count.Should().Be(0);
        }
示例#26
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}");
        }