private static void EncodeAction(List <Rlp> calls, ParityTraceAction action) { Rlp[] actionElements; if (action.RewardType != null) { actionElements = new Rlp[3]; actionElements[0] = Rlp.Encode(action.RewardType); actionElements[1] = Rlp.Encode(action.Author); actionElements[2] = Rlp.Encode(action.Value); } else { actionElements = new Rlp[10]; actionElements[0] = Rlp.Encode(action.CallType); actionElements[1] = Rlp.Encode(action.From); actionElements[2] = Rlp.Encode(action.To); actionElements[3] = Rlp.Encode(action.Value); actionElements[4] = Rlp.Encode(action.Gas); actionElements[5] = Rlp.Encode(action.Input); actionElements[6] = Rlp.Encode(action.Result?.Output ?? Bytes.Empty); actionElements[7] = Rlp.Encode(action.Result?.GasUsed ?? 0L); actionElements[8] = Rlp.Encode(action.TraceAddress); actionElements[9] = Rlp.Encode(action.Subtraces.Count); } calls.Add(Rlp.Encode(actionElements)); foreach (ParityTraceAction subtrace in action.Subtraces) { EncodeAction(calls, subtrace); } }
private static ParityTraceAction DecodeAction(RlpStream rlpStream) { ParityTraceAction action = new ParityTraceAction(); int sequenceLength = rlpStream.ReadSequenceLength(); if (rlpStream.ReadNumberOfItemsRemaining(rlpStream.Position + sequenceLength) == 3) { action.CallType = "reward"; action.RewardType = rlpStream.DecodeString(); action.Author = rlpStream.DecodeAddress(); action.Value = rlpStream.DecodeUInt256(); action.TraceAddress = Array.Empty <int>(); } else { action.CallType = rlpStream.DecodeString(); action.From = rlpStream.DecodeAddress(); action.To = rlpStream.DecodeAddress(); action.Value = rlpStream.DecodeUInt256(); action.Gas = rlpStream.DecodeLong(); action.Input = rlpStream.DecodeByteArray(); action.Result = new ParityTraceResult(); action.Result.Output = rlpStream.DecodeByteArray(); action.Result.GasUsed = rlpStream.DecodeLong(); action.TraceAddress = rlpStream.DecodeArray(c => c.DecodeInt()); int subtracesCount = rlpStream.DecodeInt(); action.Subtraces = new List <ParityTraceAction>(subtracesCount); for (int i = 0; i < subtracesCount; i++) { action.Subtraces.Add(DecodeAction(rlpStream)); } } return(action); }
public void ReportCall(long gas, UInt256 value, Address @from, Address to, byte[] input, ExecutionType callType) { ParityTraceAction action = new ParityTraceAction(); action.From = @from; action.To = to; action.Value = value; action.Input = input; action.Gas = gas; action.CallType = GetCallType(callType); PushCall(action); }
public Rlp Encode(ParityLikeTxTrace item, RlpBehaviors rlpBehaviors = RlpBehaviors.None) { Rlp[] traceElements = new Rlp[7]; traceElements[0] = Rlp.Encode(item.BlockHash); traceElements[1] = Rlp.Encode(item.BlockNumber); traceElements[2] = Rlp.Encode(item.TransactionHash); traceElements[3] = item.TransactionPosition == null ? Rlp.OfEmptyByteArray : Rlp.Encode(item.TransactionPosition.Value); ParityTraceAction action = item.Action; List <Rlp> calls = new List <Rlp>(); EncodeAction(calls, action); // trace traceElements[4] = Rlp.Encode(calls.ToArray()); traceElements[5] = EncodeChange(item.StateChanges); // stateDiff traceElements[6] = Rlp.OfEmptySequence; // vmTrace placeholder return(Rlp.Encode(traceElements)); }
private void PushCall(ParityTraceAction call) { if (_currentCall != null) { call.TraceAddress = new int[_currentCall.TraceAddress.Length + 1]; for (int i = 0; i < _currentCall.TraceAddress.Length; i++) { call.TraceAddress[i] = _currentCall.TraceAddress[i]; } call.TraceAddress[_currentCall.TraceAddress.Length] = _currentCall.Subtraces.Count; _currentCall.Subtraces.Add(call); } else { _trace.Action = call; call.TraceAddress = Array.Empty <int>(); } _callStack.Push(call); _currentCall = call; }
private void PopCall() { _callStack.Pop(); _currentCall = _callStack.Count == 0 ? null : _callStack.Peek(); }