public ChainLevelInfo Decode(Rlp.DecoderContext context, RlpBehaviors rlpBehaviors = RlpBehaviors.None)
        {
            if (context.IsNextItemNull())
            {
                return(null);
            }

            int  lastCheck         = context.ReadSequenceLength() + context.Position;
            bool hasMainChainBlock = context.DecodeBool();

            List <BlockInfo> blockInfos = new List <BlockInfo>();

            context.ReadSequenceLength();
            while (context.Position < lastCheck)
            {
                blockInfos.Add(Rlp.Decode <BlockInfo>(context, RlpBehaviors.AllowExtraData));
            }

            if (!rlpBehaviors.HasFlag(RlpBehaviors.AllowExtraData))
            {
                context.Check(lastCheck);
            }

            ChainLevelInfo info = new ChainLevelInfo(hasMainChainBlock, blockInfos.ToArray());

            return(info);
        }
示例#2
0
        public TransactionReceipt Decode(Rlp.DecoderContext context, RlpBehaviors rlpBehaviors = RlpBehaviors.None)
        {
            TransactionReceipt receipt = new TransactionReceipt();

            context.ReadSequenceLength();
            byte[] firstItem = context.DecodeByteArray();
            if (firstItem.Length == 1)
            {
                receipt.StatusCode = firstItem[0];
            }
            else
            {
                receipt.PostTransactionState = firstItem.Length == 0 ? null : new Keccak(firstItem);
            }

            receipt.GasUsed = (long)context.DecodeUBigInt(); // TODO: review
            receipt.Bloom   = context.DecodeBloom();

            int             lastCheck  = context.ReadSequenceLength() + context.Position;
            List <LogEntry> logEntries = new List <LogEntry>();

            while (context.Position < lastCheck)
            {
                logEntries.Add(Rlp.Decode <LogEntry>(context, RlpBehaviors.AllowExtraData));
            }

            if (!rlpBehaviors.HasFlag(RlpBehaviors.AllowExtraData))
            {
                context.Check(lastCheck);
            }

            receipt.Logs = logEntries.ToArray();
            return(receipt);
        }
示例#3
0
        public Transaction Decode(Rlp.DecoderContext context, RlpBehaviors rlpBehaviors = RlpBehaviors.None)
        {
            var transactionSequence = context.PeekNextItem();

            int         transactionLength = context.ReadSequenceLength();
            int         lastCheck         = context.Position + transactionLength;
            Transaction transaction       = new Transaction();

            transaction.Nonce    = context.DecodeUInt256();
            transaction.GasPrice = context.DecodeUInt256();
            transaction.GasLimit = context.DecodeUInt256();
            transaction.To       = context.DecodeAddress();
            transaction.Value    = context.DecodeUInt256();
            if (transaction.To == null)
            {
                transaction.Init = context.DecodeByteArray();
            }
            else
            {
                transaction.Data = context.DecodeByteArray();
            }

            if (context.Position < lastCheck)
            {
                byte[] vBytes = context.DecodeByteArray();
                byte[] rBytes = context.DecodeByteArray();
                byte[] sBytes = context.DecodeByteArray();

                if (vBytes[0] == 0 || rBytes[0] == 0 || sBytes[0] == 0)
                {
                    throw new RlpException("VRS starting with 0");
                }

                if (rBytes.Length > 32 || sBytes.Length > 32)
                {
                    throw new RlpException("R and S lengths expected to be less or equal 32");
                }

                int        v = vBytes.ToInt32();
                BigInteger r = rBytes.ToUnsignedBigInteger();
                BigInteger s = sBytes.ToUnsignedBigInteger();

                if (s.IsZero && r.IsZero)
                {
                    throw new RlpException("Both 'r' and 's' are zero when decoding a transaction.");
                }

                Signature signature = new Signature(r, s, v);
                transaction.Signature = signature;
                transaction.Hash      = Keccak.Compute(transactionSequence);
            }

            if (!rlpBehaviors.HasFlag(RlpBehaviors.AllowExtraData))
            {
                context.Check(lastCheck);
            }

            return(transaction);
        }
示例#4
0
        public Block Decode(Rlp.DecoderContext context, RlpBehaviors rlpBehaviors = RlpBehaviors.None)
        {
            int sequenceLength = context.ReadSequenceLength();

            if (sequenceLength == 0)
            {
                return(null);
            }

            int blockCheck = context.Position + sequenceLength;

            BlockHeader header = Rlp.Decode <BlockHeader>(context);

            int transactionsSequenceLength  = context.ReadSequenceLength();
            int transactionsCheck           = context.Position + transactionsSequenceLength;
            List <Transaction> transactions = new List <Transaction>();

            while (context.Position < transactionsCheck)
            {
                transactions.Add(Rlp.Decode <Transaction>(context));
            }

            context.Check(transactionsCheck);

            int ommersSequenceLength        = context.ReadSequenceLength();
            int ommersCheck                 = context.Position + ommersSequenceLength;
            List <BlockHeader> ommerHeaders = new List <BlockHeader>();

            while (context.Position < ommersCheck)
            {
                ommerHeaders.Add(Rlp.Decode <BlockHeader>(context, rlpBehaviors));
            }

            context.Check(ommersCheck);

            if (!rlpBehaviors.HasFlag(RlpBehaviors.AllowExtraData))
            {
                context.Check(blockCheck);
            }

            return(new Block(header, transactions, ommerHeaders));
        }
示例#5
0
        public BlockHeader Decode(Rlp.DecoderContext context, RlpBehaviors rlpBehaviors = RlpBehaviors.None)
        {
            if (context.Length == 1 && context.Data[0] == 192)
            {
                return(null);
            }

            var headerRlp = context.PeekNextItem();

            int headerSequenceLength = context.ReadSequenceLength();
            int headerCheck          = context.Position + headerSequenceLength;

            Keccak  parentHash       = context.DecodeKeccak();
            Keccak  ommersHash       = context.DecodeKeccak();
            Address beneficiary      = context.DecodeAddress();
            Keccak  stateRoot        = context.DecodeKeccak();
            Keccak  transactionsRoot = context.DecodeKeccak();
            Keccak  receiptsRoot     = context.DecodeKeccak();
            Bloom   bloom            = context.DecodeBloom();
            UInt256 difficulty       = context.DecodeUInt256();
            UInt256 number           = context.DecodeUInt256();
            UInt256 gasLimit         = context.DecodeUInt256();
            UInt256 gasUsed          = context.DecodeUInt256();
            UInt256 timestamp        = context.DecodeUInt256();

            byte[]     extraData = context.DecodeByteArray();
            Keccak     mixHash   = context.DecodeKeccak();
            BigInteger nonce     = context.DecodeUBigInt();

            if (!rlpBehaviors.HasFlag(RlpBehaviors.AllowExtraData))
            {
                context.Check(headerCheck);
            }

            BlockHeader blockHeader = new BlockHeader(
                parentHash,
                ommersHash,
                beneficiary,
                difficulty,
                number,
                (long)gasLimit,
                timestamp,
                extraData);

            blockHeader.StateRoot        = stateRoot;
            blockHeader.TransactionsRoot = transactionsRoot;
            blockHeader.ReceiptsRoot     = receiptsRoot;
            blockHeader.Bloom            = bloom;
            blockHeader.GasUsed          = (long)gasUsed;
            blockHeader.MixHash          = mixHash;
            blockHeader.Nonce            = (ulong)nonce;
            blockHeader.Hash             = Keccak.Compute(headerRlp);
            return(blockHeader);
        }
示例#6
0
        public BlockInfo Decode(Rlp.DecoderContext context, RlpBehaviors rlpBehaviors = RlpBehaviors.None)
        {
            int lastCheck = context.ReadSequenceLength() + context.Position;

            BlockInfo blockInfo = new BlockInfo();

            blockInfo.BlockHash         = context.DecodeKeccak();
            blockInfo.WasProcessed      = context.DecodeBool();
            blockInfo.TotalDifficulty   = context.DecodeUInt256();
            blockInfo.TotalTransactions = context.DecodeUInt256();

            if (!rlpBehaviors.HasFlag(RlpBehaviors.AllowExtraData))
            {
                context.Check(lastCheck);
            }

            return(blockInfo);
        }
        public TxReceipt Decode(Rlp.DecoderContext context, RlpBehaviors rlpBehaviors = RlpBehaviors.None)
        {
            bool      isStorage = (rlpBehaviors & RlpBehaviors.Storage) != 0;
            TxReceipt txReceipt = new TxReceipt();

            context.ReadSequenceLength();
            byte[] firstItem = context.DecodeByteArray();
            if (firstItem.Length == 1)
            {
                txReceipt.StatusCode = firstItem[0];
            }
            else
            {
                txReceipt.PostTransactionState = firstItem.Length == 0 ? null : new Keccak(firstItem);
            }

            if (isStorage)
            {
                txReceipt.BlockHash = context.DecodeKeccak();
            }
            if (isStorage)
            {
                txReceipt.BlockNumber = (long)context.DecodeUInt256();
            }
            if (isStorage)
            {
                txReceipt.Index = context.DecodeInt();
            }
            if (isStorage)
            {
                txReceipt.Sender = context.DecodeAddress();
            }
            if (isStorage)
            {
                txReceipt.Recipient = context.DecodeAddress();
            }
            if (isStorage)
            {
                txReceipt.ContractAddress = context.DecodeAddress();
            }
            if (isStorage)
            {
                txReceipt.GasUsed = (long)context.DecodeUBigInt();
            }
            txReceipt.GasUsedTotal = (long)context.DecodeUBigInt();
            txReceipt.Bloom        = context.DecodeBloom();

            int             lastCheck  = context.ReadSequenceLength() + context.Position;
            List <LogEntry> logEntries = new List <LogEntry>();

            while (context.Position < lastCheck)
            {
                logEntries.Add(Rlp.Decode <LogEntry>(context, RlpBehaviors.AllowExtraData));
            }

            bool allowExtraData = (rlpBehaviors & RlpBehaviors.AllowExtraData) != 0;

            if (!allowExtraData)
            {
                context.Check(lastCheck);
            }

            // since error was added later we can only rely on it in cases where we read receipt only and no data follows
            if (isStorage && !allowExtraData && context.Position != context.Length)
            {
                txReceipt.Error = context.DecodeString();
            }

            txReceipt.Logs = logEntries.ToArray();
            return(txReceipt);
        }