public Rlp Encode(TxReceipt item, RlpBehaviors rlpBehaviors = RlpBehaviors.None)
        {
            if (rlpBehaviors.HasFlag(RlpBehaviors.Storage))
            {
                return(Rlp.Encode(
                           rlpBehaviors.HasFlag(RlpBehaviors.Eip658Receipts) ? Rlp.Encode(item.StatusCode) : Rlp.Encode(item.PostTransactionState),
                           Rlp.Encode(item.BlockHash),
                           Rlp.Encode(item.BlockNumber),
                           Rlp.Encode(item.Index),
                           Rlp.Encode(item.Sender),
                           Rlp.Encode(item.Recipient),
                           Rlp.Encode(item.ContractAddress),
                           Rlp.Encode(item.GasUsed),
                           Rlp.Encode(item.GasUsedTotal),
                           Rlp.Encode(item.Bloom),
                           Rlp.Encode(item.Logs),
                           Rlp.Encode(item.Error)));
            }

            return(Rlp.Encode(
                       rlpBehaviors.HasFlag(RlpBehaviors.Eip658Receipts) ? Rlp.Encode(item.StatusCode) : Rlp.Encode(item.PostTransactionState),
                       Rlp.Encode(item.GasUsedTotal),
                       Rlp.Encode(item.Bloom),
                       Rlp.Encode(item.Logs)));
        }
        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);
        }
Esempio n. 3
0
        public BlockInfo Decode(RlpStream rlpStream, RlpBehaviors rlpBehaviors = RlpBehaviors.None)
        {
            if (rlpStream.IsNextItemNull())
            {
                rlpStream.ReadByte();
                return(null);
            }

            int lastCheck = rlpStream.ReadSequenceLength() + rlpStream.Position;

            BlockInfo blockInfo = new BlockInfo
            {
                BlockHash       = rlpStream.DecodeKeccak(),
                WasProcessed    = rlpStream.DecodeBool(),
                TotalDifficulty = rlpStream.DecodeUInt256()
            };

            if (_chainWithFinalization)
            {
                blockInfo.IsFinalized = rlpStream.DecodeBool();
            }

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

            return(blockInfo);
        }
Esempio n. 4
0
        public Rlp Encode(BlockHeader item, RlpBehaviors behaviors = RlpBehaviors.None)
        {
            bool withMixHashAndNonce = !behaviors.HasFlag(RlpBehaviors.ExcludeBlockMixHashAndNonce);
            int  numberOfElements    = withMixHashAndNonce ? 15 : 13;

            Rlp[] elements = new Rlp[numberOfElements];
            elements[0]  = Rlp.Encode(item.ParentHash);
            elements[1]  = Rlp.Encode(item.OmmersHash);
            elements[2]  = Rlp.Encode(item.Beneficiary);
            elements[3]  = Rlp.Encode(item.StateRoot);
            elements[4]  = Rlp.Encode(item.TransactionsRoot);
            elements[5]  = Rlp.Encode(item.ReceiptsRoot);
            elements[6]  = Rlp.Encode(item.Bloom);
            elements[7]  = Rlp.Encode(item.Difficulty);
            elements[8]  = Rlp.Encode(item.Number);
            elements[9]  = Rlp.Encode(item.GasLimit);
            elements[10] = Rlp.Encode(item.GasUsed);
            elements[11] = Rlp.Encode(item.Timestamp);
            elements[12] = Rlp.Encode(item.ExtraData);
            if (withMixHashAndNonce)
            {
                elements[13] = Rlp.Encode(item.MixHash);
                elements[14] = Rlp.Encode(item.Nonce);
            }

            return(Rlp.Encode(elements));
        }
Esempio n. 5
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);
        }
Esempio n. 6
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);
        }
Esempio n. 7
0
 public Rlp Encode(TransactionReceipt item, RlpBehaviors rlpBehaviors = RlpBehaviors.None)
 {
     return(Rlp.Encode(
                rlpBehaviors.HasFlag(RlpBehaviors.Eip658Receipts) ? Rlp.Encode(item.StatusCode) : Rlp.Encode(item.PostTransactionState),
                Rlp.Encode(item.GasUsed),
                Rlp.Encode(item.Bloom),
                Rlp.Encode(item.Logs)));
 }
Esempio n. 8
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);
        }
Esempio n. 9
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.DecodeUBigInt();
            blockInfo.TotalTransactions = context.DecodeUBigInt();

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

            return(blockInfo);
        }
Esempio n. 10
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));
        }
Esempio n. 11
0
        public Block Decode(RlpStream rlpStream, RlpBehaviors rlpBehaviors = RlpBehaviors.None)
        {
            if (rlpStream.IsNextItemNull())
            {
                rlpStream.ReadByte();
                return(null);
            }

            int sequenceLength = rlpStream.ReadSequenceLength();
            int blockCheck     = rlpStream.Position + sequenceLength;

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

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

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

            rlpStream.Check(transactionsCheck);

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

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

            rlpStream.Check(ommersCheck);

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

            return(new Block(header, transactions, ommerHeaders));
        }
Esempio n. 12
0
        public void Encode(MemoryStream stream, BlockHeader item, RlpBehaviors rlpBehaviors = RlpBehaviors.None)
        {
            if (item == null)
            {
                stream.Write(Rlp.OfEmptySequence.Bytes);
                return;
            }

            bool notForSealing = !rlpBehaviors.HasFlag(RlpBehaviors.ForSealing);

            Rlp.StartSequence(stream, GetContentLength(item, rlpBehaviors));
            Rlp.Encode(stream, item.ParentHash);
            Rlp.Encode(stream, item.OmmersHash);
            Rlp.Encode(stream, item.Beneficiary);
            Rlp.Encode(stream, item.StateRoot);
            Rlp.Encode(stream, item.TxRoot);
            Rlp.Encode(stream, item.ReceiptsRoot);
            Rlp.Encode(stream, item.Bloom);
            Rlp.Encode(stream, item.Difficulty);
            Rlp.Encode(stream, item.Number);
            Rlp.Encode(stream, item.GasLimit);
            Rlp.Encode(stream, item.GasUsed);
            Rlp.Encode(stream, item.Timestamp);
            Rlp.Encode(stream, item.ExtraData);

            if (notForSealing)
            {
                bool isAuRa = item.AuRaSignature != null;

                if (isAuRa)
                {
                    Rlp.Encode(stream, item.AuRaStep.Value);
                    Rlp.Encode(stream, item.AuRaSignature);
                }
                else
                {
                    Rlp.Encode(stream, item.MixHash);
                    Rlp.Encode(stream, item.Nonce);
                }
            }
        }
Esempio n. 13
0
        public Transaction Decode(RlpStream rlpStream, RlpBehaviors rlpBehaviors = RlpBehaviors.None)
        {
            if (rlpStream.IsNextItemNull())
            {
                rlpStream.ReadByte();
                return null;
            }
            
            var transactionSequence = rlpStream.PeekNextItem();

            int transactionLength = rlpStream.ReadSequenceLength();
            int lastCheck = rlpStream.Position + transactionLength;
            Transaction transaction = new Transaction();
            transaction.Nonce = rlpStream.DecodeUInt256();
            transaction.GasPrice = rlpStream.DecodeUInt256();
            transaction.GasLimit = rlpStream.DecodeLong();
            transaction.To = rlpStream.DecodeAddress();
            transaction.Value = rlpStream.DecodeUInt256();
            if (transaction.To == null)
            {
                transaction.Init = rlpStream.DecodeByteArray();
            }
            else
            {
                transaction.Data = rlpStream.DecodeByteArray();
            }

            if (rlpStream.Position < lastCheck)
            {
                Span<byte> vBytes = rlpStream.DecodeByteArraySpan();
                Span<byte> rBytes = rlpStream.DecodeByteArraySpan();
                Span<byte> sBytes = rlpStream.DecodeByteArraySpan();

                if (vBytes == null || rBytes == null || sBytes == null)
                {
                    throw new RlpException("VRS null when decoding Transaction");
                }
                
                if (vBytes.Length == 0 || rBytes.Length == 0 || sBytes.Length == 0)
                {
                    throw new RlpException("VRS is 0 length when decoding Transaction");
                }
                
                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.ReadEthInt32();

                if (rBytes.SequenceEqual(Bytes.Zero32) && sBytes.SequenceEqual(Bytes.Zero32))
                {
                    throw new RlpException("Both 'r' and 's' are zero when decoding a transaction.");
                }

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

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

            return transaction;
        }
Esempio n. 14
0
        public BlockHeader Decode(RlpStream rlpStream, RlpBehaviors rlpBehaviors = RlpBehaviors.None)
        {
            if (rlpStream.IsNextItemNull())
            {
                rlpStream.ReadByte();
                return(null);
            }

            var headerRlp            = rlpStream.PeekNextItem();
            int headerSequenceLength = rlpStream.ReadSequenceLength();
            int headerCheck          = rlpStream.Position + headerSequenceLength;

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

            byte[] extraData = rlpStream.DecodeByteArray();

            BlockHeader blockHeader = new BlockHeader(
                parentHash,
                ommersHash,
                beneficiary,
                difficulty,
                (long)number,
                (long)gasLimit,
                timestamp,
                extraData)
            {
                StateRoot    = stateRoot,
                TxRoot       = transactionsRoot,
                ReceiptsRoot = receiptsRoot,
                Bloom        = bloom,
                GasUsed      = (long)gasUsed,
                Hash         = Keccak.Compute(headerRlp)
            };

            if (rlpStream.PeekPrefixAndContentLength().ContentLength == Keccak.Size)
            {
                blockHeader.MixHash = rlpStream.DecodeKeccak();
                blockHeader.Nonce   = (ulong)rlpStream.DecodeUBigInt();
            }
            else
            {
                blockHeader.AuRaStep      = (long)rlpStream.DecodeUInt256();
                blockHeader.AuRaSignature = rlpStream.DecodeByteArray();
            }

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

            return(blockHeader);
        }