Example #1
0
        public void When_two_branches_with_two_same_children_change_one_and_change_back_next_block()
        {
            MemDb        memDb        = new();
            TrieStore    trieStore    = new(memDb, Prune.WhenCacheReaches(1.MB()), Persist.EveryBlock, _logManager);
            PatriciaTree patriciaTree = new(trieStore, _logManager);

            patriciaTree.Set(_keyA, _longLeaf1);
            patriciaTree.Set(_keyB, _longLeaf1);
            patriciaTree.Set(_keyC, _longLeaf1);
            patriciaTree.Set(_keyD, _longLeaf1);
            patriciaTree.UpdateRootHash();
            patriciaTree.Commit(0);
            patriciaTree.Set(_keyA, _longLeaf3);
            patriciaTree.Set(_keyA, _longLeaf1);
            patriciaTree.UpdateRootHash();
            patriciaTree.Commit(1);

            memDb.Keys.Should().HaveCount(5);
            PatriciaTree checkTree = CreateCheckTree(memDb, patriciaTree);

            checkTree.Get(_keyA).Should().BeEquivalentTo(_longLeaf1);
            checkTree.Get(_keyB).Should().BeEquivalentTo(_longLeaf1);
            checkTree.Get(_keyC).Should().BeEquivalentTo(_longLeaf1);
            checkTree.Get(_keyD).Should().BeEquivalentTo(_longLeaf1);
        }
Example #2
0
        public void Test_update_many(int i)
        {
            MemDb        memDb        = new();
            TrieStore    trieStore    = new(memDb, new MemoryLimit(128.MB()), Persist.EveryBlock, _logManager);
            PatriciaTree patriciaTree = new(trieStore, _logManager);

            for (int j = 0; j < i; j++)
            {
                Keccak key   = TestItem.Keccaks[j];
                byte[] value = GenerateIndexedAccountRlp(j);
                patriciaTree.Set(key.Bytes, value);
            }

            for (int j = 0; j < i; j++)
            {
                Keccak key   = TestItem.Keccaks[j];
                byte[] value = GenerateIndexedAccountRlp(j + 1);
                patriciaTree.Set(key.Bytes, value);
            }

            patriciaTree.Commit(0);
            patriciaTree.UpdateRootHash();

            PatriciaTree checkTree = CreateCheckTree(memDb, patriciaTree);

            for (int j = 0; j < i; j++)
            {
                Keccak key   = TestItem.Keccaks[j];
                byte[] value = GenerateIndexedAccountRlp(j + 1);
                checkTree.Get(key.Bytes).Should().BeEquivalentTo(value, $@"{i} {j}");
            }
        }
Example #3
0
        public int Find(string Name)
        {
            if (Name == null)
            {
                return(-1);
            }

            if (TreeNeedsRebuild)
            {
                RebuildTree();
            }

            int Output = 0;

            if (Nodes != null && Nodes.Count > 0)
            {
                H3DPatriciaTreeNode Root;

                Output = PatriciaTree.Traverse(Name, Nodes, out Root);

                if (Nodes[Output].Name != Name)
                {
                    Output = 0;
                }
            }

            return(Output - 1);
        }
Example #4
0
        public void Test_add_and_delete_many_next_block(int i)
        {
            MemDb        memDb        = new();
            TrieStore    trieStore    = new(memDb, new MemoryLimit(128.MB()), Persist.EveryBlock, _logManager);
            PatriciaTree patriciaTree = new(trieStore, _logManager);

            for (int j = 0; j < i; j++)
            {
                Keccak key   = TestItem.Keccaks[j];
                byte[] value = GenerateIndexedAccountRlp(j);
                patriciaTree.Set(key.Bytes, value);
            }

            patriciaTree.Commit(0);

            for (int j = 0; j < i; j++)
            {
                Keccak key = TestItem.Keccaks[j];
                patriciaTree.Set(key.Bytes, Array.Empty <byte>());
            }

            patriciaTree.Commit(1);
            patriciaTree.UpdateRootHash();

            PatriciaTree checkTree = CreateCheckTree(memDb, patriciaTree);

            for (int j = 0; j < i; j++)
            {
                Keccak key = TestItem.Keccaks[j];
                checkTree.Get(key.Bytes).Should().BeNull($@"{i} {j}");
            }
        }
Example #5
0
        private void RunTest(TrieTest test, bool secure)
        {
            string permutationDescription =
                string.Join(Environment.NewLine, test.Input.Select(p => $"{p.Key} -> {p.Value}"));

            TestContext.WriteLine(Surrounded(permutationDescription));

            PatriciaTree patriciaTree = secure ? new SecurePatriciaTree(_db) : new PatriciaTree(_db, Keccak.EmptyTreeHash, false);

            foreach (KeyValuePair <string, string> keyValuePair in test.Input)
            {
                string keyString   = keyValuePair.Key;
                string valueString = keyValuePair.Value;

                Nibble[] key = keyString.StartsWith("0x")
                    ? Hex.ToNibbles(keyString)
                    : Nibbles.FromBytes(Encoding.ASCII.GetBytes(keyString));

                byte[] value = valueString.StartsWith("0x")
                    ? Hex.ToBytes(valueString)
                    : Encoding.ASCII.GetBytes(valueString);

                TestContext.WriteLine();
                TestContext.WriteLine($"Setting {keyString} -> {valueString}");
                patriciaTree.Set(key, value);
            }

            patriciaTree.UpdateRootHash();
            Assert.AreEqual(test.ExpectedRoot, patriciaTree.RootHash.ToString());
        }
Example #6
0
        private static PatriciaTree CreateCheckTree(MemDb memDb, PatriciaTree patriciaTree)
        {
            PatriciaTree checkTree = new(memDb);

            checkTree.RootHash = patriciaTree.RootHash;
            return(checkTree);
        }
Example #7
0
        public void Single_leaf_and_keep_for_multiple_dispatches_then_delete()
        {
            MemDb        memDb        = new();
            TrieStore    trieStore    = new(memDb, Prune.WhenCacheReaches(1.MB()), new ConstantInterval(4), LimboLogs.Instance);
            PatriciaTree patriciaTree = new(trieStore, _logManager);

            patriciaTree.Commit(0);
            patriciaTree.Commit(1);
            patriciaTree.Commit(2);
            patriciaTree.Set(_keyA, _longLeaf1);
            patriciaTree.Commit(3);
            patriciaTree.Commit(4);
            patriciaTree.Set(_keyA, Array.Empty <byte>());
            patriciaTree.Commit(5);
            patriciaTree.Set(_keyB, _longLeaf2);
            patriciaTree.Commit(6);
            patriciaTree.Commit(7);
            patriciaTree.Commit(8);
            patriciaTree.Commit(9);
            patriciaTree.Commit(10);
            patriciaTree.Commit(11);
            patriciaTree.Set(_keyB, Array.Empty <byte>());
            patriciaTree.Commit(12);
            patriciaTree.Commit(13);
            patriciaTree.UpdateRootHash();

            // leaf (root)
            memDb.Keys.Should().HaveCount(2);

            PatriciaTree checkTree = CreateCheckTree(memDb, patriciaTree);

            checkTree.Get(_keyA).Should().BeNull();
            checkTree.Get(_keyB).Should().BeNull();
        }
Example #8
0
        public void Two_branches_exactly_same_leaf_then_one_removed()
        {
            MemDb     memDb     = new();
            TrieStore trieStore = new(
                memDb,
                Prune.WhenCacheReaches(1.MB()),
                Persist.EveryBlock,
                LimboLogs.Instance);
            PatriciaTree patriciaTree = new(trieStore, _logManager);

            patriciaTree.Set(_keyA, _longLeaf1);
            patriciaTree.Set(_keyB, _longLeaf1);
            patriciaTree.Set(_keyC, _longLeaf1);
            patriciaTree.Set(_keyD, _longLeaf1);
            patriciaTree.Set(_keyA, Array.Empty <byte>());
            patriciaTree.Commit(0);

            // leaf (root)
            memDb.Keys.Should().HaveCount(6);
            PatriciaTree checkTree = CreateCheckTree(memDb, patriciaTree);

            checkTree.Get(_keyA).Should().BeNull();
            checkTree.Get(_keyB).Should().BeEquivalentTo(_longLeaf1);
            checkTree.Get(_keyC).Should().BeEquivalentTo(_longLeaf1);
            checkTree.Get(_keyD).Should().BeEquivalentTo(_longLeaf1);
        }
Example #9
0
        public void Extension_branch_extension_and_leaf_then_branch_leaf_leaf()
        {
            /* R
             * E - - - - - - - - - - - - - - -
             * B B B B B B B B B B B B B B B B
             * E L - - - - - - - - - - - - - -
             * E - - - - - - - - - - - - - - -
             * B B B B B B B B B B B B B B B B
             * L L - - - - - - - - - - - - - - */

            byte[] key1 = Bytes.FromHexString("000000100000000aa");
            byte[] key2 = Bytes.FromHexString("000000100000000bb");
            byte[] key3 = Bytes.FromHexString("000000200000000cc");

            MemDb        memDb        = new();
            TrieStore    trieStore    = new(memDb, Prune.WhenCacheReaches(1.MB()), Persist.EveryBlock, _logManager);
            PatriciaTree patriciaTree = new(trieStore, _logManager);

            patriciaTree.Set(key1, _longLeaf1);
            patriciaTree.Set(key2, _longLeaf1);
            patriciaTree.Set(key3, _longLeaf1);
            patriciaTree.UpdateRootHash();
            patriciaTree.Commit(0);

            memDb.Keys.Should().HaveCount(7);
            PatriciaTree checkTree = CreateCheckTree(memDb, patriciaTree);

            checkTree.Get(key1).Should().BeEquivalentTo(_longLeaf1);
            checkTree.Get(key2).Should().BeEquivalentTo(_longLeaf1);
            checkTree.Get(key3).Should().BeEquivalentTo(_longLeaf1);
        }
Example #10
0
        private void RebuildTree()
        {
            var Nodes = new List <DICTEntry>();

            // Adapted from SPICA's code

            if (Entries.Count > 0)
            {
                Nodes.Add(new DICTEntry {
                    ReferenceBit = uint.MaxValue
                });
            }
            else
            {
                Nodes.Add(new DICTEntry());
            }

            int MaxLength = 0;

            foreach (var Value in Entries)
            {
                if (MaxLength < Value.Name.Length)
                {
                    MaxLength = Value.Name.Length;
                }
            }

            foreach (var Value in Entries)
            {
                var Node = new DICTEntry
                {
                    Name = Value.Name,
                    //EntryObject = Value
                };

                PatriciaTree.Insert(Nodes, Node, MaxLength);
            }


            // TODO: Bit of a hacky implementation here, but this "should work"
            // and at least I thankfully get this functionality, courtesy of SPICA

            // Nodes index 0 will be the root node, the others should line up with
            // the subsequent entries...
            RootEntry = Nodes[0];
            for (var entryIndex = 0; entryIndex < Entries.Count; entryIndex++)
            {
                var node  = Nodes[entryIndex + 1];  // +1 because index zero is the root
                var entry = Entries[entryIndex];
                if (node.Name != entry.Name)
                {
                    throw new InvalidOperationException("RebuildTree: Name mismatch in node");
                }

                entry.ReferenceBit   = node.ReferenceBit;
                entry.LeftNodeIndex  = node.LeftNodeIndex;
                entry.RightNodeIndex = node.RightNodeIndex;
            }
        }
Example #11
0
        public void Lookup_in_empty_tree()
        {
            PatriciaTree tree = new PatriciaTree(new MemDb(), Keccak.EmptyTreeHash, false, true);

            Assert.AreEqual(tree.RootRef, null);
            tree.Get(new byte[] { 1 });
            Assert.AreEqual(tree.RootRef, null);
        }
Example #12
0
        public void Delete_on_empty()
        {
            PatriciaTree patriciaTree = new PatriciaTree(_db, Keccak.EmptyTreeHash, false, true);

            patriciaTree.Set(Keccak.Compute("1").Bytes, new byte[0]);
            patriciaTree.Commit();
            Assert.AreEqual(PatriciaTree.EmptyTreeHash, patriciaTree.RootHash);
        }
Example #13
0
        private static IPruningContext CopyDb(IPruningContext pruningContext, MemDb trieDb, MemDb clonedDb)
        {
            LimboLogs    logManager  = LimboLogs.Instance;
            PatriciaTree trie        = Build.A.Trie(trieDb).WithAccountsByIndex(0, 100).TestObject;
            IStateReader stateReader = new StateReader(new TrieStore(trieDb, logManager), new MemDb(), logManager);

            using CopyTreeVisitor copyTreeVisitor = new(pruningContext, logManager);
            stateReader.RunTreeVisitor(copyTreeVisitor, trie.RootHash);
            return(pruningContext);
        }
Example #14
0
        public void Delete_missing_resolved_on_branch()
        {
            PatriciaTree patriciaTree = new PatriciaTree(_db, Keccak.EmptyTreeHash, false, true);

            patriciaTree.Set(Keccak.Compute("1123").Bytes, new byte[] { 1 });
            patriciaTree.Set(Keccak.Compute("1124").Bytes, new byte[] { 2 });
            Keccak rootBefore = patriciaTree.RootHash;

            patriciaTree.Set(Keccak.Compute("1125").Bytes, new byte[0]);
            Assert.AreEqual(rootBefore, patriciaTree.RootHash);
        }
Example #15
0
        public void Child_and_value_store_encode()
        {
            TrieNode node = new TrieNode(NodeType.Branch);

            node.SetChild(0, new TrieNode(NodeType.Leaf, TestItem.KeccakA));
            PatriciaTree tree    = BuildATreeFromNode(node);
            TrieNode     decoded = new TrieNode(NodeType.Unknown, node.Keccak);

            decoded.ResolveNode(tree);
            decoded.RlpEncode();
        }
Example #16
0
        public void Connect_extension_with_extension()
        {
            /* to test this case we need something like this initially */

            /* R
             * E - - - - - - - - - - - - - - -
             * B B B B B B B B B B B B B B B B
             * E L - - - - - - - - - - - - - -
             * E - - - - - - - - - - - - - - -
             * B B B B B B B B B B B B B B B B
             * L L - - - - - - - - - - - - - - */

            /* then we delete the leaf (marked as X) */

            /* R
             * B B B B B B B B B B B B B B B B
             * E X - - - - - - - - - - - - - -
             * E - - - - - - - - - - - - - - -
             * B B B B B B B B B B B B B B B B
             * L L - - - - - - - - - - - - - - */

            /* and we end up with an extended extension replacing what was previously a top-level branch*/

            /* R
             * E
             * E
             * E - - - - - - - - - - - - - - -
             * B B B B B B B B B B B B B B B B
             * L L - - - - - - - - - - - - - - */

            byte[] key1 = Bytes.FromHexString("000000100000000aa");
            byte[] key2 = Bytes.FromHexString("000000100000000bb");
            byte[] key3 = Bytes.FromHexString("000000200000000cc");

            MemDb        memDb        = new();
            TrieStore    trieStore    = new(memDb, Prune.WhenCacheReaches(1.MB()), Persist.EveryBlock, _logManager);
            PatriciaTree patriciaTree = new(trieStore, _logManager);

            patriciaTree.Set(key1, _longLeaf1);
            patriciaTree.Set(key2, _longLeaf1);
            patriciaTree.Set(key3, _longLeaf1);
            patriciaTree.UpdateRootHash();
            patriciaTree.Commit(0);
            patriciaTree.Set(key3, Array.Empty <byte>());
            patriciaTree.UpdateRootHash();
            patriciaTree.Commit(1);

            memDb.Keys.Should().HaveCount(8);
            PatriciaTree checkTree = CreateCheckTree(memDb, patriciaTree);

            checkTree.Get(key1).Should().BeEquivalentTo(_longLeaf1);
            checkTree.Get(key2).Should().BeEquivalentTo(_longLeaf1);
            checkTree.Get(key3).Should().BeNull();
        }
Example #17
0
        public void Unknown_node_with_missing_data_can_accept_visitor()
        {
            ITreeVisitor     visitor = Substitute.For <ITreeVisitor>();
            TrieVisitContext context = new TrieVisitContext();
            PatriciaTree     tree    = new PatriciaTree();
            TrieNode         node    = new TrieNode(NodeType.Unknown);

            node.Accept(visitor, tree, context);

            visitor.Received().VisitMissingNode(node.Keccak, context);
        }
Example #18
0
        public void Two_children_store_resolve_encode()
        {
            TrieNode node = new TrieNode(NodeType.Branch);

            node.SetChild(0, new TrieNode(NodeType.Leaf, TestObject.KeccakA));
            node.SetChild(1, new TrieNode(NodeType.Leaf, TestObject.KeccakB));
            PatriciaTree tree    = BuildATreeFromNode(node);
            TrieNode     decoded = new TrieNode(NodeType.Unknown, node.Keccak);

            decoded.ResolveNode(tree);
            decoded.RlpEncode();
        }
Example #19
0
        public void Single_leaf()
        {
            MemDb        memDb        = new MemDb();
            TrieStore    trieStore    = new TrieStore(memDb, Prune.WhenCacheReaches(1.MB()), Persist.EveryBlock, _logManager);
            PatriciaTree patriciaTree = new PatriciaTree(trieStore, _logManager);

            patriciaTree.Set(_keyA, _longLeaf1);
            patriciaTree.Commit(0);

            // leaf (root)
            memDb.Keys.Should().HaveCount(1);
        }
Example #20
0
        public void Delete_missing_resolved_on_extension()
        {
            PatriciaTree patriciaTree = new PatriciaTree(_db, Keccak.EmptyTreeHash, false, true);

            patriciaTree.Set(new Nibble[] { 1, 2, 3, 4 }.ToPackedByteArray(), new byte[] { 1 });
            patriciaTree.Set(new Nibble[] { 1, 2, 3, 4, 5 }.ToPackedByteArray(), new byte[] { 2 });
            patriciaTree.UpdateRootHash();
            Keccak rootBefore = patriciaTree.RootHash;

            patriciaTree.Set(new Nibble[] { 1, 2, 3 }.ToPackedByteArray(), new byte[] { });
            patriciaTree.UpdateRootHash();
            Assert.AreEqual(rootBefore, patriciaTree.RootHash);
        }
Example #21
0
        public void Delete_missing_resolved_on_leaf()
        {
            PatriciaTree patriciaTree = new PatriciaTree(_db, Keccak.EmptyTreeHash, false, true);

            patriciaTree.Set(Keccak.Compute("1234567").Bytes, new byte[] { 1 });
            patriciaTree.Set(Keccak.Compute("1234501").Bytes, new byte[] { 2 });
            patriciaTree.UpdateRootHash();
            Keccak rootBefore = patriciaTree.RootHash;

            patriciaTree.Set(Keccak.Compute("1234502").Bytes, new byte[0]);
            patriciaTree.UpdateRootHash();
            Assert.AreEqual(rootBefore, patriciaTree.RootHash);
        }
Example #22
0
        private static PatriciaTree BuildATreeFromNode(TrieNode node)
        {
            TrieNode.AllowBranchValues = true;
            byte[] rlp = node.RlpEncode();
            node.ResolveKey(true);

            MemDb memDb = new MemDb();

            memDb[node.Keccak.Bytes] = rlp;

            PatriciaTree tree = new PatriciaTree(memDb, node.Keccak, false, true);

            return(tree);
        }
Example #23
0
        private static PatriciaTree BuildATreeFromNode(TrieNode node)
        {
            Rlp rlp = node.RlpEncode();

            node.ResolveKey(true);

            MemDb memDb = new MemDb();

            memDb[node.Keccak.Bytes] = rlp.Bytes;

            PatriciaTree tree = new PatriciaTree(memDb, node.Keccak, false);

            return(tree);
        }
Example #24
0
        public void Extension_can_accept_visitors()
        {
            ITreeVisitor     visitor = Substitute.For <ITreeVisitor>();
            TrieVisitContext context = new TrieVisitContext();
            PatriciaTree     tree    = new PatriciaTree();
            TrieNode         ignore  = new TrieNode(NodeType.Unknown);
            TrieNode         node    = new TrieNode(NodeType.Extension);

            node.SetChild(0, ignore);

            node.Accept(visitor, tree, context);

            visitor.Received().VisitExtension(node, context);
        }
        public static Keccak CalculateReceiptRoot(this Block block, ISpecProvider specProvider, TxReceipt[] txReceipts)
        {
            PatriciaTree receiptTree = txReceipts.Length > 0 ? new PatriciaTree(NullDb.Instance, Keccak.EmptyTreeHash, false) : null;

            for (int i = 0; i < txReceipts.Length; i++)
            {
                Rlp receiptRlp = Rlp.Encode(txReceipts[i], specProvider.GetSpec(block.Number).IsEip658Enabled ? RlpBehaviors.Eip658Receipts : RlpBehaviors.None);
                receiptTree?.Set(Rlp.Encode(i).Bytes, receiptRlp);
            }

            receiptTree?.UpdateRootHash();
            Keccak receiptRoot = receiptTree?.RootHash ?? PatriciaTree.EmptyTreeHash;

            return(receiptRoot);
        }
Example #26
0
        private void SetReceiptsRootAndBloom(Block block, TransactionReceipt[] transactionReceipts)
        {
            PatriciaTree receiptTree = transactionReceipts.Length > 0 ? new PatriciaTree(NullDb.Instance, Keccak.EmptyTreeHash, false) : null;

            for (int i = 0; i < transactionReceipts.Length; i++)
            {
                Rlp receiptRlp = Rlp.Encode(transactionReceipts[i], _specProvider.GetSpec(block.Header.Number).IsEip658Enabled ? RlpBehaviors.Eip658Receipts : RlpBehaviors.None);
                receiptTree?.Set(Rlp.Encode(i).Bytes, receiptRlp);
            }

            receiptTree?.UpdateRootHash();

            block.Header.ReceiptsRoot = receiptTree?.RootHash ?? PatriciaTree.EmptyTreeHash;
            block.Header.Bloom        = transactionReceipts.Length > 0 ? BuildBloom(transactionReceipts) : Bloom.Empty;
        }
Example #27
0
        private void SetReceipts(Block block, TransactionReceipt[] receipts)
        {
            PatriciaTree receiptTree = receipts.Length > 0 ? new PatriciaTree(NullDb.Instance, Keccak.EmptyTreeHash, false) : null;

            for (int i = 0; i < receipts.Length; i++)
            {
                Rlp receiptRlp = Rlp.Encode(receipts[i], _specProvider.GetSpec(block.Header.Number).IsEip658Enabled ? RlpBehaviors.Eip658Receipts : RlpBehaviors.None);
                receiptTree?.Set(Rlp.Encode(i).Bytes, receiptRlp);
            }

            receiptTree?.UpdateRootHash();

            block.Header.ReceiptsRoot = receiptTree?.RootHash ?? PatriciaTree.EmptyTreeHash;
            block.Header.Bloom        = receipts.Length > 0 ? TransactionProcessor.BuildBloom(receipts.SelectMany(r => r.Logs).ToArray()) : Bloom.Empty; // TODO not tested anywhere at the time of writing
        }
Example #28
0
        public void Extension_with_branch_with_two_same_children()
        {
            MemDb        memDb        = new();
            TrieStore    trieStore    = new(memDb, Prune.WhenCacheReaches(1.MB()), Persist.EveryBlock, _logManager);
            PatriciaTree patriciaTree = new(trieStore, _logManager);

            patriciaTree.Set(_keyA, _longLeaf1);
            patriciaTree.Set(_keyB, _longLeaf1);
            patriciaTree.Commit(0);
            memDb.Keys.Should().HaveCount(4);
            PatriciaTree checkTree = CreateCheckTree(memDb, patriciaTree);

            checkTree.Get(_keyA).Should().BeEquivalentTo(_longLeaf1);
            checkTree.Get(_keyB).Should().BeEquivalentTo(_longLeaf1);
        }
Example #29
0
        public void Leaf_with_simple_account_can_accept_visitors()
        {
            ITreeVisitor     visitor = Substitute.For <ITreeVisitor>();
            TrieVisitContext context = new TrieVisitContext();
            PatriciaTree     tree    = new PatriciaTree();
            Account          account = new Account(100);
            AccountDecoder   decoder = new AccountDecoder();
            TrieNode         node    = new TrieNode(NodeType.Leaf);

            node.Value = decoder.Encode(account).Bytes;

            node.Accept(visitor, tree, context);

            visitor.Received().VisitLeaf(node, context, node.Value);
        }
Example #30
0
        public void Leaf_with_contract_without_storage_and_empty_code_can_accept_visitors()
        {
            ITreeVisitor     visitor = Substitute.For <ITreeVisitor>();
            TrieVisitContext context = new TrieVisitContext();
            PatriciaTree     tree    = new PatriciaTree();
            Account          account = new Account(1, 100, Keccak.EmptyTreeHash, Keccak.OfAnEmptyString);
            AccountDecoder   decoder = new AccountDecoder();
            TrieNode         node    = new TrieNode(NodeType.Leaf);

            node.Value = decoder.Encode(account).Bytes;

            node.Accept(visitor, tree, context);

            visitor.Received().VisitLeaf(node, context, node.Value);
        }
 protected static PatriciaTree Join (PatriciaTree t0, PatriciaTree t1)
 {
   int p0 = t0.KeyNumber, p1 = t1.KeyNumber;
   int m = BranchingBit(p0, p1);
   return ZeroBit(p0, m) ?
     new Branch(MaskBits(p0,m), m, t0, t1) :
     new Branch(MaskBits(p0,m), m, t1, t0);
 }
 public Branch (int prefix, int mask, PatriciaTree left, PatriciaTree right) 
 { 
   this.Prefix = prefix;
   this.Mask = mask; 
   this.Left = left; 
   this.Right = right; 
   this.count = left.Count + right.Count;
 }