Ejemplo n.º 1
0
 private void Encode()
 {
     if (this.root != null)
     {
         root.Encode();
     }
 }
Ejemplo n.º 2
0
        private byte[] Encode(int depth, bool forceHash)
        {
            if (!dirty)
            {
                return(hash != null?RLP.EncodeElement(hash) : rlp);
            }
            else
            {
                TrieNodeType type = this.node_type;
                byte[]       ret;
                if (type == TrieNodeType.BranchNode)
                {
                    if (depth == 1 && this.reference.Async)
                    {
                        // parallelize encode() on the first trie level only and if there are at least
                        // MIN_BRANCHES_CONCURRENTLY branches are modified
                        object[] encoded      = new object[17];
                        int      encode_count = 0;
                        for (int i = 0; i < 16; i++)
                        {
                            TrieNode child = BranchNodeGetChild(i);
                            if (child == null)
                            {
                                encoded[i] = RLP.EMPTY_ELEMENT_RLP;
                            }
                            else if (!child.dirty)
                            {
                                encoded[i] = child.Encode(depth + 1, false);
                            }
                            else
                            {
                                encode_count++;
                            }
                        }
                        for (int i = 0; i < 16; i++)
                        {
                            if (encoded[i] == null)
                            {
                                TrieNode child = BranchNodeGetChild(i);
                                if (child == null)
                                {
                                    continue;
                                }
                                if (encode_count >= MIN_BRANCHES_CONCURRENTLY)
                                {
                                    encoded[i] = Task.Run <byte[]>(() =>
                                    {
                                        return(child.Encode(depth + 1, false));
                                    });
                                }
                                else
                                {
                                    encoded[i] = child.Encode(depth + 1, false);
                                }
                            }
                        }
                        byte[] value = BranchNodeGetValue();
                        encoded[16] = RLP.EncodeElement(value);
                        try
                        {
                            ret = EncodeRlpListTaskResult(encoded);
                        }
                        catch (System.Exception e)
                        {
                            throw new System.Exception(e.Message);
                        }
                    }
                    else
                    {
                        byte[][] encoded = new byte[17][];
                        for (int i = 0; i < 16; i++)
                        {
                            TrieNode child = BranchNodeGetChild(i);
                            encoded[i] = child == null ? RLP.EMPTY_ELEMENT_RLP : child.Encode(depth + 1, false);
                        }
                        byte[] value = BranchNodeGetValue();
                        encoded[16] = RLP.EncodeElement(value);
                        ret         = RLP.EncodeList(encoded);
                    }
                }
                else if (type == TrieNodeType.KVNodeNode)
                {
                    ret = RLP.EncodeList(RLP.EncodeElement(KVNodeGetKey().ToPacked()),
                                         KVNodeGetChildNode().Encode(depth + 1, false));
                }
                else
                {
                    byte[] value = KVNodeGetValue();
                    ret = RLP.EncodeList(RLP.EncodeElement(KVNodeGetKey().ToPacked()),
                                         RLP.EncodeElement(value == null ? new byte[0] : value));
                }
                if (this.hash != null)
                {
                    this.reference.DeleteHash(this.hash);
                }

                this.dirty = false;
                if (ret.Length < 32 && !forceHash)
                {
                    this.rlp = ret;
                    return(ret);
                }
                else
                {
                    this.hash = ret.SHA3();
                    this.reference.AddHash(this.hash, ret);
                    return(RLP.EncodeElement(hash));
                }
            }
        }