Ejemplo n.º 1
0
        /// <summary>
        /// Given a trie node directly or by reference, obtains the direct node to operate on.
        /// </summary>
        /// <param name="nodeOrReference">The trie node or trie node reference used to obtain the actual trie node.</param>
        /// <returns>Returns the representing trie node for this value.</returns>
        private RLPList DecodeNode(RLPItem nodeOrReference)
        {
            // If it's an RLP list, it's a direct representation of the node.
            if (nodeOrReference.IsList)
            {
                return((RLPList)nodeOrReference);
            }
            else
            {
                // If it's a RLP byte array/32 byte hash, it's the key used to look up the node (a reference)
                byte[] nodeHash = nodeOrReference;

                // If this matches our blank node hash, return our blank node.
                if (IsBlankNodeHash(nodeHash))
                {
                    return(null);
                }

                // Otherwise we decode our node from RLP after fetching it from our database.
                if (!Database.TryGet(nodeHash, out var nodeData))
                {
                    throw new Exception($"Could not fetch node from database with node hash: {nodeHash.ToHexString(hexPrefix: true)}");
                }

                return((RLPList)RLP.Decode(nodeData));
            }
        }
        /// <inheritdoc/>
        public Transaction CreateTransaction(byte[] rlpEncodedTrasaction)
        {
            Transaction transaction = new Transaction();

            RLPCollection decodedList = (RLPCollection)RLP.Decode(rlpEncodedTrasaction)[0];

            bool isSigned    = (decodedList.Count == 4);
            int  inputIdx    = isSigned ? 1 : 0;
            int  outputIdx   = isSigned ? 2 : 1;
            int  metadataIdx = isSigned ? 3 : 2;

            RLPCollection inputData = (RLPCollection)decodedList[inputIdx];

            foreach (RLPCollection input in inputData)
            {
                if (input.Count == 3)
                {
                    transaction.AddInput(Transaction.ToUInt64FromRLPDecoded(input[0].RLPData),
                                         Transaction.ToUInt16FromRLPDecoded(input[1].RLPData),
                                         Transaction.ToUInt16FromRLPDecoded(input[2].RLPData));
                }
            }

            RLPCollection outputData = (RLPCollection)decodedList[outputIdx];

            foreach (RLPCollection output in outputData)
            {
                if (output.Count == 3)
                {
                    transaction.AddOutput(output[0].RLPData.ToHex().PadLeft(32, '0').EnsureHexPrefix(),
                                          output[1].RLPData.ToHex().PadLeft(32, '0').EnsureHexPrefix(),
                                          output[2].RLPData.ToBigIntegerFromRLPDecoded());
                }
            }

            if (metadataIdx < decodedList.Count)
            {
                RLPItem metadata = (RLPItem)decodedList[metadataIdx];
                transaction.SetMetadata(metadata.RLPData.ToHex().HexToByteArray());
            }

            if (isSigned)
            {
                RLPCollection signatureData = (RLPCollection)decodedList[0];
                for (Int32 i = 0; i < signatureData.Count; ++i)
                {
                    transaction.SetSignature(i, signatureData[i].RLPData);
                }
            }

            return(transaction);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Deserializes the given RLP serialized receipt and sets all values accordingly.
        /// </summary>
        /// <param name="item">The RLP item to deserialize and obtain values from.</param>
        public void Deserialize(RLPItem item)
        {
            // Verify this is a list
            if (!item.IsList)
            {
                throw new ArgumentException();
            }

            // Verify it has 4 items.
            RLPList rlpReceipt = (RLPList)item;

            if (rlpReceipt.Items.Count != 4)
            {
                throw new ArgumentException();
            }

            // Verify the types of all items
            if (!rlpReceipt.Items[0].IsByteArray ||
                !rlpReceipt.Items[1].IsByteArray ||
                !rlpReceipt.Items[2].IsByteArray ||
                !rlpReceipt.Items[3].IsList)
            {
                throw new ArgumentException();
            }

            // Set our state root
            RLPByteArray rlpStateRoot = (RLPByteArray)rlpReceipt.Items[0];

            StateRoot = rlpStateRoot.Data.ToArray();

            // Set our gas used
            RLPByteArray rlpGasUsed = (RLPByteArray)rlpReceipt.Items[1];

            GasUsed = RLP.ToInteger(rlpGasUsed, EVMDefinitions.WORD_SIZE);

            // Set our bloom
            RLPByteArray rlpBloom = (RLPByteArray)rlpReceipt.Items[2];

            Bloom = RLP.ToInteger(rlpBloom, EVMDefinitions.BLOOM_FILTER_SIZE);

            // Obtain our logs
            RLPList rlpLogs = (RLPList)rlpReceipt.Items[3];

            Logs = new List <Log>();
            foreach (RLPItem rlpLog in rlpLogs.Items)
            {
                // Add our log
                Logs.Add(new Log(rlpLog));
            }
        }
Ejemplo n.º 4
0
Archivo: Log.cs Proyecto: zutobg/Meadow
        /// <summary>
        /// Deserializes the given RLP serialized log and sets all values accordingly.
        /// </summary>
        /// <param name="item">The RLP item to deserialize and obtain values from.</param>
        public void Deserialize(RLPItem item)
        {
            // Verify this is a list
            if (!item.IsList)
            {
                throw new ArgumentException();
            }

            // Verify it has 3 items.
            RLPList rlpLog = (RLPList)item;

            if (rlpLog.Items.Count != 3)
            {
                throw new ArgumentException();
            }

            // Verify the types of all items
            if (!rlpLog.Items[0].IsByteArray ||
                !rlpLog.Items[1].IsList ||
                !rlpLog.Items[2].IsByteArray)
            {
                throw new ArgumentException();
            }

            // Set our address
            RLPByteArray rlpAddress = (RLPByteArray)rlpLog.Items[0];

            Address = new Address(rlpAddress.Data.Span);

            // Obtain our topics
            RLPList rlpTopicsList = (RLPList)rlpLog.Items[1];

            Topics = new List <BigInteger>();
            foreach (RLPItem rlpTopic in rlpTopicsList.Items)
            {
                // Verify all of our items are data
                if (rlpTopic.GetType() != typeof(RLPByteArray))
                {
                    throw new ArgumentException();
                }

                // Add our topic.
                Topics.Add(RLP.ToInteger((RLPByteArray)rlpTopic, EVMDefinitions.WORD_SIZE));
            }

            // Obtain our data
            RLPByteArray rlpData = (RLPByteArray)rlpLog.Items[2];

            Data = rlpData.Data.ToArray();
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Deserializes the given RLP serialized block and sets all values accordingly.
        /// </summary>
        /// <param name="item">The RLP item to deserialize and obtain values from.</param>
        public void Deserialize(RLPItem item)
        {
            // Verify this is a list
            if (!item.IsList)
            {
                throw new ArgumentException();
            }

            // Verify it has 3 items.
            RLPList rlpBlock = (RLPList)item;

            if (rlpBlock.Items.Count != 3)
            {
                throw new ArgumentException();
            }

            // Verify the types of all items (should all be lists)
            for (int i = 0; i < rlpBlock.Items.Count; i++)
            {
                if (!rlpBlock.Items[i].IsList)
                {
                    throw new ArgumentException();
                }
            }

            // Obtain the block header
            Header = new BlockHeader(rlpBlock.Items[0]);

            // Obtain the list of transactions
            RLPList rlpTransactions = (RLPList)rlpBlock.Items[1];

            Transactions = new Transaction[rlpTransactions.Items.Count];
            for (int i = 0; i < rlpTransactions.Items.Count; i++)
            {
                Transactions[i] = new Transaction(rlpTransactions.Items[i]);
            }

            // Obtain the list of uncles.
            RLPList rlpUncles = (RLPList)rlpBlock.Items[2];

            Uncles = new BlockHeader[rlpUncles.Items.Count];
            for (int i = 0; i < rlpUncles.Items.Count; i++)
            {
                Uncles[i] = new BlockHeader(rlpUncles.Items[i]);
            }
        }
Ejemplo n.º 6
0
        private void RLPStringEncodeDecodeTest(string s)
        {
            RLPItem s1 = s;

            byte[]  encoded = RLP.Encode(s);
            RLPItem s2      = RLP.Decode(encoded);
            string  ss1     = s1;
            string  ss2     = s2;

            if (s.Length == 0)
            {
                Assert.Null((string)s2);
            }
            else
            {
                Assert.Equal((string)s1, (string)s2);
            }
        }
Ejemplo n.º 7
0
        public void RLPLogTest()
        {
            Meadow.EVM.Data_Types.Transactions.Log log = new Meadow.EVM.Data_Types.Transactions.Log((BigInteger)0x11223344, new List <BigInteger>()
            {
                3, 2, 1
            }, new byte[] { 00, 77, 00, 77 });
            RLPItem item = log.Serialize();

            byte[] data = RLP.Encode(item);
            item = RLP.Decode(data);
            log.Deserialize(item);
            item = log.Serialize();
            byte[] data2 = RLP.Encode(item);
            Assert.True(data.ValuesEqual(data2));
            Assert.Equal(0x11223344, (BigInteger)log.Address);
            Assert.True(log.Topics.Count == 3 && log.Topics[0] == 3 && log.Topics[1] == 2 && log.Topics[2] == 1);
            Assert.True(log.Data.ValuesEqual(new byte[] { 00, 77, 00, 77 }));
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Deserializes the given RLP serialized account and sets all values accordingly.
        /// </summary>
        /// <param name="item">The RLP item to deserialize and obtain values from.</param>
        public void Deserialize(RLPItem item)
        {
            // Verify this is a list
            if (!item.IsList)
            {
                throw new ArgumentException();
            }

            // Verify it has 4 items.
            RLPList rlpAccount = (RLPList)item;

            if (rlpAccount.Items.Count != 4)
            {
                throw new ArgumentException();
            }

            // Verify the types of all items
            if (!rlpAccount.Items[0].IsByteArray ||
                !rlpAccount.Items[1].IsByteArray ||
                !rlpAccount.Items[2].IsByteArray ||
                !rlpAccount.Items[3].IsByteArray)
            {
                throw new ArgumentException();
            }

            // Set our nonce, balance, storage, and code hash.
            Nonce       = RLP.ToInteger((RLPByteArray)rlpAccount.Items[0]);
            Balance     = RLP.ToInteger((RLPByteArray)rlpAccount.Items[1]);
            StorageRoot = rlpAccount.Items[2];
            CodeHash    = rlpAccount.Items[3];

            // Verify the length of our storage root and code hash.
            if (StorageRoot.Length != KeccakHash.HASH_SIZE || CodeHash.Length != KeccakHash.HASH_SIZE)
            {
                throw new ArgumentException();
            }

            // Initialize our storage change cache
            StorageCache = new Dictionary <Memory <byte>, byte[]>(new MemoryComparer <byte>());

            // Load our trie given our storage root
            StorageTrie = new Trie(Configuration.Database, StorageRoot);
        }
Ejemplo n.º 9
0
 public Block(RLPItem rlpBlockHeader)
 {
     Deserialize(rlpBlockHeader);
 }
Ejemplo n.º 10
0
 /// <summary>
 /// Creates a receipt instance given an RLP serialized Receipt we can decode to obtain values for.
 /// </summary>
 /// <param name="rlpReceipt">The RLP serialized receipt to decode and set values from.</param>
 public Receipt(RLPItem rlpReceipt)
 {
     Deserialize(rlpReceipt);
 }
Ejemplo n.º 11
0
        /// <summary>
        /// Deserializes the given RLP serialized block header and sets all values accordingly.
        /// </summary>
        /// <param name="item">The RLP item to block header and obtain values from.</param>
        public void Deserialize(RLPItem item)
        {
            // Verify this is a list
            if (!item.IsList)
            {
                throw new ArgumentException();
            }

            // Verify it has 15 items.
            RLPList rlpBlockHeader = (RLPList)item;

            if (rlpBlockHeader.Items.Count != 15)
            {
                throw new ArgumentException();
            }

            // Verify the types of all items
            for (int i = 0; i < rlpBlockHeader.Items.Count; i++)
            {
                if (!rlpBlockHeader.Items[i].IsByteArray)
                {
                    throw new ArgumentException();
                }
            }

            // Verify our items are the correct length
            if (((RLPByteArray)rlpBlockHeader.Items[0]).Data.Length != KeccakHash.HASH_SIZE)
            {
                throw new ArgumentException();
            }

            if (((RLPByteArray)rlpBlockHeader.Items[1]).Data.Length != KeccakHash.HASH_SIZE)
            {
                throw new ArgumentException();
            }

            if (((RLPByteArray)rlpBlockHeader.Items[2]).Data.Length != Address.ADDRESS_SIZE)
            {
                throw new ArgumentException();
            }

            if (((RLPByteArray)rlpBlockHeader.Items[3]).Data.Length != KeccakHash.HASH_SIZE)
            {
                throw new ArgumentException();
            }

            if (((RLPByteArray)rlpBlockHeader.Items[4]).Data.Length != KeccakHash.HASH_SIZE)
            {
                throw new ArgumentException();
            }

            if (((RLPByteArray)rlpBlockHeader.Items[5]).Data.Length != KeccakHash.HASH_SIZE)
            {
                throw new ArgumentException();
            }

            if (((RLPByteArray)rlpBlockHeader.Items[6]).Data.Length != EVMDefinitions.BLOOM_FILTER_SIZE)
            {
                throw new ArgumentException();
            }


            // Obtain our items
            PreviousHash         = rlpBlockHeader.Items[0];
            UnclesHash           = rlpBlockHeader.Items[1];
            Coinbase             = RLP.ToInteger((RLPByteArray)rlpBlockHeader.Items[2], Address.ADDRESS_SIZE);
            StateRootHash        = rlpBlockHeader.Items[3];
            TransactionsRootHash = rlpBlockHeader.Items[4];
            ReceiptsRootHash     = rlpBlockHeader.Items[5];
            Bloom       = RLP.ToInteger((RLPByteArray)rlpBlockHeader.Items[6], EVMDefinitions.BLOOM_FILTER_SIZE);
            Difficulty  = RLP.ToInteger((RLPByteArray)rlpBlockHeader.Items[7]);
            BlockNumber = RLP.ToInteger((RLPByteArray)rlpBlockHeader.Items[8]);
            GasLimit    = RLP.ToInteger((RLPByteArray)rlpBlockHeader.Items[9]);
            GasUsed     = RLP.ToInteger((RLPByteArray)rlpBlockHeader.Items[10]);
            Timestamp   = RLP.ToInteger((RLPByteArray)rlpBlockHeader.Items[11]);
            ExtraData   = rlpBlockHeader.Items[12];
            MixHash     = rlpBlockHeader.Items[13];
            Nonce       = rlpBlockHeader.Items[14];
        }
Ejemplo n.º 12
0
Archivo: Log.cs Proyecto: zutobg/Meadow
 /// <summary>
 /// Creates a log instance given an RLP serialized Log we can decode to obtain values for.
 /// </summary>
 /// <param name="rlpList">The RLP serialized log to decode and set values from.</param>
 public Log(RLPItem rlpList)
 {
     Deserialize(rlpList);
 }