public TxReceipt Decode(RlpStream rlpStream, RlpBehaviors rlpBehaviors = RlpBehaviors.None) { if (rlpStream.IsNextItemNull()) { rlpStream.ReadByte(); return(null); } TxReceipt txReceipt = new(); if (!rlpStream.IsSequenceNext()) { rlpStream.SkipLength(); txReceipt.TxType = (TxType)rlpStream.ReadByte(); } _ = rlpStream.ReadSequenceLength(); byte[] firstItem = rlpStream.DecodeByteArray(); if (firstItem.Length == 1 && (firstItem[0] == 0 || firstItem[0] == 1)) { txReceipt.StatusCode = firstItem[0]; txReceipt.GasUsedTotal = (long)rlpStream.DecodeUBigInt(); } else if (firstItem.Length >= 1 && firstItem.Length <= 4) { txReceipt.GasUsedTotal = (long)firstItem.ToUnsignedBigInteger(); txReceipt.SkipStateAndStatusInRlp = true; } else { txReceipt.PostTransactionState = firstItem.Length == 0 ? null : new Keccak(firstItem); txReceipt.GasUsedTotal = (long)rlpStream.DecodeUBigInt(); } txReceipt.Bloom = rlpStream.DecodeBloom(); int lastCheck = rlpStream.ReadSequenceLength() + rlpStream.Position; int numberOfReceipts = rlpStream.ReadNumberOfItemsRemaining(lastCheck); LogEntry[] entries = new LogEntry[numberOfReceipts]; for (int i = 0; i < numberOfReceipts; i++) { entries[i] = Rlp.Decode <LogEntry>(rlpStream, RlpBehaviors.AllowExtraData); } txReceipt.Logs = entries; return(txReceipt); }
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 & RlpBehaviors.AllowExtraData) != RlpBehaviors.AllowExtraData) { rlpStream.Check(blockCheck); } return(new Block(header, transactions, ommerHeaders)); }
public Block Decode(ref Rlp.ValueDecoderContext decoderContext, RlpBehaviors rlpBehaviors = RlpBehaviors.None) { if (decoderContext.IsNextItemNull()) { decoderContext.ReadByte(); return(null); } int sequenceLength = decoderContext.ReadSequenceLength(); int blockCheck = decoderContext.Position + sequenceLength; BlockHeader header = Rlp.Decode <BlockHeader>(ref decoderContext); int transactionsSequenceLength = decoderContext.ReadSequenceLength(); int transactionsCheck = decoderContext.Position + transactionsSequenceLength; List <Transaction> transactions = new List <Transaction>(); while (decoderContext.Position < transactionsCheck) { transactions.Add(Rlp.Decode <Transaction>(ref decoderContext)); } decoderContext.Check(transactionsCheck); int ommersSequenceLength = decoderContext.ReadSequenceLength(); int ommersCheck = decoderContext.Position + ommersSequenceLength; List <BlockHeader> ommerHeaders = new List <BlockHeader>(); while (decoderContext.Position < ommersCheck) { ommerHeaders.Add(Rlp.Decode <BlockHeader>(ref decoderContext, rlpBehaviors)); } decoderContext.Check(ommersCheck); if ((rlpBehaviors & RlpBehaviors.AllowExtraData) != RlpBehaviors.AllowExtraData) { decoderContext.Check(blockCheck); } return(new Block(header, transactions, ommerHeaders)); }
public TxReceipt Decode(RlpStream rlpStream, RlpBehaviors rlpBehaviors = RlpBehaviors.None) { if (rlpStream.IsNextItemNull()) { rlpStream.ReadByte(); return(null); } TxReceipt txReceipt = new TxReceipt(); var lenght = rlpStream.ReadSequenceLength(); byte[] firstItem = rlpStream.DecodeByteArray(); if (firstItem.Length == 1 && (firstItem[0] == 0 || firstItem[0] == 1)) { txReceipt.StatusCode = firstItem[0]; txReceipt.GasUsedTotal = (long)rlpStream.DecodeUBigInt(); } else if (firstItem.Length >= 1 && firstItem.Length <= 4) { txReceipt.GasUsedTotal = (long)firstItem.ToUnsignedBigInteger(); txReceipt.SkipStateAndStatusInRlp = true; } else { txReceipt.PostTransactionState = firstItem.Length == 0 ? null : new Keccak(firstItem); txReceipt.GasUsedTotal = (long)rlpStream.DecodeUBigInt(); } txReceipt.Bloom = rlpStream.DecodeBloom(); int lastCheck = rlpStream.ReadSequenceLength() + rlpStream.Position; List <LogEntry> logEntries = new List <LogEntry>(); while (rlpStream.Position < lastCheck) { logEntries.Add(Rlp.Decode <LogEntry>(rlpStream, RlpBehaviors.AllowExtraData)); } txReceipt.Logs = logEntries.ToArray(); return(txReceipt); }
public ChainLevelInfo?Decode(RlpStream rlpStream, RlpBehaviors rlpBehaviors = RlpBehaviors.None) { if (rlpStream.Length == 0) { throw new RlpException($"Received a 0 length stream when decoding a {nameof(ChainLevelInfo)}"); } if (rlpStream.IsNextItemNull()) { return(null); } int lastCheck = rlpStream.ReadSequenceLength() + rlpStream.Position; bool hasMainChainBlock = rlpStream.DecodeBool(); List <BlockInfo> blockInfos = new(); rlpStream.ReadSequenceLength(); while (rlpStream.Position < lastCheck) { // block info can be null for corrupted states (also cases where block hash is null from the old DBs) BlockInfo?blockInfo = Rlp.Decode <BlockInfo?>(rlpStream, RlpBehaviors.AllowExtraData); if (blockInfo is not null) { blockInfos.Add(blockInfo); } } if ((rlpBehaviors & RlpBehaviors.AllowExtraData) != RlpBehaviors.AllowExtraData) { rlpStream.Check(lastCheck); } ChainLevelInfo info = new(hasMainChainBlock, blockInfos.ToArray()); return(info); }
public TxReceipt Decode(RlpStream rlpStream, RlpBehaviors rlpBehaviors = RlpBehaviors.None) { if (rlpStream.IsNextItemNull()) { rlpStream.ReadByte(); return(null); } bool isStorage = (rlpBehaviors & RlpBehaviors.Storage) != 0; TxReceipt txReceipt = new TxReceipt(); rlpStream.ReadSequenceLength(); byte[] firstItem = rlpStream.DecodeByteArray(); if (firstItem.Length == 1) { txReceipt.StatusCode = firstItem[0]; } else { txReceipt.PostTransactionState = firstItem.Length == 0 ? null : new Keccak(firstItem); } if (isStorage) { txReceipt.BlockHash = rlpStream.DecodeKeccak(); } if (isStorage) { txReceipt.BlockNumber = (long)rlpStream.DecodeUInt256(); } if (isStorage) { txReceipt.Index = rlpStream.DecodeInt(); } if (isStorage) { txReceipt.Sender = rlpStream.DecodeAddress(); } if (isStorage) { txReceipt.Recipient = rlpStream.DecodeAddress(); } if (isStorage) { txReceipt.ContractAddress = rlpStream.DecodeAddress(); } if (isStorage) { txReceipt.GasUsed = (long)rlpStream.DecodeUBigInt(); } txReceipt.GasUsedTotal = (long)rlpStream.DecodeUBigInt(); txReceipt.Bloom = rlpStream.DecodeBloom(); int lastCheck = rlpStream.ReadSequenceLength() + rlpStream.Position; List <LogEntry> logEntries = new List <LogEntry>(); while (rlpStream.Position < lastCheck) { logEntries.Add(Rlp.Decode <LogEntry>(rlpStream, RlpBehaviors.AllowExtraData)); } bool allowExtraData = (rlpBehaviors & RlpBehaviors.AllowExtraData) != 0; if (!allowExtraData) { rlpStream.Check(lastCheck); } if (!allowExtraData) { if (isStorage && _supportTxHash) { // since txHash was added later and may not be in rlp, we provide special mark byte that it will be next if (rlpStream.PeekByte() == MarkTxHashByte) { rlpStream.ReadByte(); txReceipt.TxHash = rlpStream.DecodeKeccak(); } } // since error was added later we can only rely on it in cases where we read receipt only and no data follows, empty errors might not be serialized if (rlpStream.Position != rlpStream.Length) { txReceipt.Error = rlpStream.DecodeString(); } } txReceipt.Logs = logEntries.ToArray(); return(txReceipt); }