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)); }
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)); }
private (int Total, int Logs) GetContentLength(TxReceipt item, RlpBehaviors rlpBehaviors) { var contentLength = 0; var logsLength = 0; if (item == null) { return(contentLength, 0); } bool isStorage = (rlpBehaviors & RlpBehaviors.Storage) != 0; if (isStorage) { contentLength += Rlp.LengthOf(item.BlockHash); contentLength += Rlp.LengthOf(item.BlockNumber); contentLength += Rlp.LengthOf(item.Index); contentLength += Rlp.LengthOf(item.Sender); contentLength += Rlp.LengthOf(item.Recipient); contentLength += Rlp.LengthOf(item.ContractAddress); contentLength += Rlp.LengthOf(item.GasUsed); contentLength += Rlp.LengthOf(item.Error); } contentLength += Rlp.LengthOf(item.GasUsedTotal); contentLength += Rlp.LengthOf(item.Bloom); logsLength = GetLogsLength(item); contentLength += Rlp.GetSequenceRlpLength(logsLength); bool isEip658receipts = (rlpBehaviors & RlpBehaviors.Eip658Receipts) == RlpBehaviors.Eip658Receipts; if (isEip658receipts) { contentLength += Rlp.LengthOf(item.StatusCode); } else { contentLength += Rlp.LengthOf(item.PostTransactionState); } return(contentLength, logsLength); }
public static Rlp Encode( Transaction transaction, bool forSigning, bool isEip155Enabled = false, int chainId = 0) { Rlp[] sequence = new Rlp[forSigning && !(isEip155Enabled && chainId != 0) ? 6 : 9]; sequence[0] = Encode(transaction.Nonce); sequence[1] = Encode(transaction.GasPrice); sequence[2] = Encode(transaction.GasLimit); sequence[3] = Encode(transaction.To); sequence[4] = Encode(transaction.Value); sequence[5] = Encode(transaction.To == null ? transaction.Init : transaction.Data); if (forSigning) { if (isEip155Enabled && chainId != 0) { sequence[6] = Encode(chainId); sequence[7] = OfEmptyByteArray; sequence[8] = OfEmptyByteArray; } } else { // TODO: below obviously fails when Signature is null sequence[6] = transaction.Signature == null ? OfEmptyByteArray : Encode(transaction.Signature.V); sequence[7] = Encode(transaction.Signature == null ? null : transaction.Signature.R .WithoutLeadingZeros()); // TODO: consider storing R and S differently sequence[8] = Encode(transaction.Signature == null ? null : transaction.Signature.S .WithoutLeadingZeros()); // TODO: consider storing R and S differently } return(Encode(sequence)); }
public static Rlp Encode <T>(T[] items, RlpBehaviors behaviors = RlpBehaviors.None) { if (items == null) { return(OfEmptySequence); } if (Decoders.ContainsKey(typeof(T))) { IRlpDecoder <T> decoder = (IRlpDecoder <T>)Decoders[typeof(T)]; Rlp[] rlpSequence = new Rlp[items.Length]; for (int i = 0; i < items.Length; i++) { rlpSequence[i] = items[i] == null ? OfEmptySequence : decoder.Encode(items[i], behaviors); } return(Encode(rlpSequence)); } throw new RlpException($"{nameof(Rlp)} does not support encoding {typeof(T).Name}"); }
public Rlp Encode(ChainLevelInfo item, RlpBehaviors rlpBehaviors = RlpBehaviors.None) { if (item == null) { return(Rlp.OfEmptySequence); } Rlp[] elements = new Rlp[2]; elements[0] = Rlp.Encode(item.HasBlockOnMainChain); elements[1] = Rlp.Encode(item.BlockInfos); if (item.BlockInfos.Any(bi => bi == null)) { throw new InvalidOperationException($"{nameof(BlockInfo)} is null when encoding {nameof(ChainLevelInfo)}"); } Rlp rlp = Rlp.Encode(elements); return(rlp); }
public Rlp Encode(ChainLevelInfo item, RlpBehaviors rlpBehaviors = RlpBehaviors.None) { if (item == null) { return(Rlp.OfEmptySequence); } Rlp[] elements = new Rlp[2]; elements[0] = Rlp.Encode(item.HasBlockOnMainChain); elements[1] = Rlp.Encode(item.BlockInfos); if (item.BlockInfos.Any(bi => bi == null)) { throw new Exception(); } Rlp rlp = Rlp.Encode(elements); return(rlp); }
public ChainLevelInfo Decode(Rlp.DecoderContext context, RlpBehaviors rlpBehaviors = RlpBehaviors.None) { 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); }
public void Encode(MemoryStream stream, Block item, RlpBehaviors rlpBehaviors = RlpBehaviors.None) { if (item == null) { stream.Write(Rlp.OfEmptySequence.Bytes); return; } (int contentLength, int txsLength, int ommersLength) = GetContentLength(item, rlpBehaviors); Rlp.StartSequence(stream, contentLength); _headerDecoder.Encode(stream, item.Header); Rlp.StartSequence(stream, txsLength); for (int i = 0; i < item.Transactions.Length; i++) { _txDecoder.Encode(stream, item.Transactions[i]); } Rlp.StartSequence(stream, ommersLength); for (int i = 0; i < item.Ommers.Length; i++) { _headerDecoder.Encode(stream, item.Ommers[i]); } }
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 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); }
public int GetLength(Transaction item, RlpBehaviors rlpBehaviors) { return(Rlp.GetSequenceRlpLength(GetContentLength(item, false))); }
public int GetLength(TxReceipt item, RlpBehaviors rlpBehaviors) { return(Rlp.LengthOfSequence(GetContentLength(item, rlpBehaviors).Total)); }
public int GetLength(BlockHeader item, RlpBehaviors rlpBehaviors) { return(Rlp.LengthOfSequence(GetContentLength(item, rlpBehaviors))); }
public int GetHashCode(Rlp obj) { return(obj.Bytes.GetXxHashCode()); }
public Rlp Encode(Transaction item, RlpBehaviors rlpBehaviors = RlpBehaviors.None) { return(Rlp.Encode(item, false)); }
public static T Decode <T>(Rlp oldRlp, RlpBehaviors rlpBehaviors = RlpBehaviors.None) { return(Decode <T>(oldRlp.Bytes.AsRlpContext(), rlpBehaviors)); }
public bool Equals(Rlp other) { return(null != other && Extensions.Bytes.AreEqual(Bytes, other.Bytes)); }
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))); }
public static Rlp[] ExtractRlpList(Rlp rlp) { return(ExtractRlpList(new DecoderContext(rlp.Bytes))); }