mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-01-30 09:38:24 -05:00
feat(rpc-types): implement serialization for LocalizedTransactionTrace (#5446)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
committed by
GitHub
parent
8100a88f9a
commit
1e1cdceb0c
@@ -4,7 +4,7 @@
|
||||
//! See <https://openethereum.github.io/JSONRPC-trace-module>
|
||||
|
||||
use alloy_primitives::{Address, Bytes, B256, U256, U64};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer};
|
||||
use std::{
|
||||
collections::BTreeMap,
|
||||
ops::{Deref, DerefMut},
|
||||
@@ -171,6 +171,16 @@ impl Action {
|
||||
pub fn is_reward(&self) -> bool {
|
||||
matches!(self, Action::Reward(_))
|
||||
}
|
||||
|
||||
/// Returns what kind of action this is
|
||||
pub fn kind(&self) -> ActionType {
|
||||
match self {
|
||||
Action::Call(_) => ActionType::Call,
|
||||
Action::Create(_) => ActionType::Create,
|
||||
Action::Selfdestruct(_) => ActionType::Selfdestruct,
|
||||
Action::Reward(_) => ActionType::Reward,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An external action type.
|
||||
@@ -231,12 +241,12 @@ pub struct CallAction {
|
||||
pub struct CreateAction {
|
||||
/// The address of the creator.
|
||||
pub from: Address,
|
||||
/// The value with which the new account is endowed.
|
||||
pub value: U256,
|
||||
/// The gas available for the creation init code.
|
||||
pub gas: U64,
|
||||
/// The init code.
|
||||
pub init: Bytes,
|
||||
/// The value with which the new account is endowed.
|
||||
pub value: U256,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
|
||||
@@ -251,10 +261,10 @@ pub enum RewardType {
|
||||
pub struct RewardAction {
|
||||
/// Author's address.
|
||||
pub author: Address,
|
||||
/// Reward amount.
|
||||
pub value: U256,
|
||||
/// Reward type.
|
||||
pub reward_type: RewardType,
|
||||
/// Reward amount.
|
||||
pub value: U256,
|
||||
}
|
||||
|
||||
/// Represents a _selfdestruct_ action fka `suicide`.
|
||||
@@ -263,10 +273,10 @@ pub struct RewardAction {
|
||||
pub struct SelfdestructAction {
|
||||
/// destroyed/suicided address.
|
||||
pub address: Address,
|
||||
/// destroyed contract heir.
|
||||
pub refund_address: Address,
|
||||
/// Balance of the contract just before it was destroyed.
|
||||
pub balance: U256,
|
||||
/// destroyed contract heir.
|
||||
pub refund_address: Address,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
|
||||
@@ -279,9 +289,9 @@ pub struct CallOutput {
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CreateOutput {
|
||||
pub gas_used: U64,
|
||||
pub code: Bytes,
|
||||
pub address: Address,
|
||||
pub code: Bytes,
|
||||
pub gas_used: U64,
|
||||
}
|
||||
|
||||
/// Represents the output of a trace.
|
||||
@@ -327,29 +337,88 @@ pub struct TransactionTrace {
|
||||
pub trace_address: Vec<usize>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct LocalizedTransactionTrace {
|
||||
/// Trace of the transaction and its result.
|
||||
#[serde(flatten)]
|
||||
pub trace: TransactionTrace,
|
||||
/// Hash of the block, if not pending
|
||||
/// Hash of the block, if not pending.
|
||||
///
|
||||
/// Note: this deviates from <https://openethereum.github.io/JSONRPC-trace-module#trace_transaction> which always returns a block number
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub block_hash: Option<B256>,
|
||||
/// Block number the transaction is included in, None if pending.
|
||||
///
|
||||
/// Note: this deviates from <https://openethereum.github.io/JSONRPC-trace-module#trace_transaction> which always returns a block number
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub block_number: Option<u64>,
|
||||
/// Hash of the transaction
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub transaction_hash: Option<B256>,
|
||||
/// Transaction index within the block, None if pending.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub transaction_position: Option<u64>,
|
||||
}
|
||||
|
||||
// Implement Serialize manually to ensure consistent ordering of fields to match other client's
|
||||
// format
|
||||
impl Serialize for LocalizedTransactionTrace {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let mut s = serializer.serialize_struct("LocalizedTransactionTrace", 9)?;
|
||||
|
||||
let TransactionTrace { action, error, result, subtraces, trace_address } = &self.trace;
|
||||
|
||||
match action {
|
||||
Action::Call(call_action) => {
|
||||
s.serialize_field("action", call_action)?;
|
||||
}
|
||||
Action::Create(create_action) => {
|
||||
s.serialize_field("action", create_action)?;
|
||||
}
|
||||
Action::Selfdestruct(selfdestruct_action) => {
|
||||
s.serialize_field("action", selfdestruct_action)?;
|
||||
}
|
||||
Action::Reward(reward_action) => {
|
||||
s.serialize_field("action", reward_action)?;
|
||||
}
|
||||
}
|
||||
if let Some(block_hash) = self.block_hash {
|
||||
s.serialize_field("blockHash", &block_hash)?;
|
||||
}
|
||||
if let Some(block_number) = self.block_number {
|
||||
s.serialize_field("blockNumber", &block_number)?;
|
||||
}
|
||||
|
||||
if let Some(error) = error {
|
||||
s.serialize_field("error", error)?;
|
||||
}
|
||||
|
||||
match result {
|
||||
Some(TraceOutput::Call(call)) => {
|
||||
s.serialize_field("result", call)?;
|
||||
}
|
||||
Some(TraceOutput::Create(create)) => {
|
||||
s.serialize_field("result", create)?;
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
|
||||
s.serialize_field("subtraces", &subtraces)?;
|
||||
s.serialize_field("traceAddress", &trace_address)?;
|
||||
|
||||
if let Some(transaction_hash) = &self.transaction_hash {
|
||||
s.serialize_field("transactionHash", transaction_hash)?;
|
||||
}
|
||||
if let Some(transaction_position) = &self.transaction_position {
|
||||
s.serialize_field("transactionPosition", transaction_position)?;
|
||||
}
|
||||
|
||||
s.serialize_field("type", &action.kind())?;
|
||||
|
||||
s.end()
|
||||
}
|
||||
}
|
||||
|
||||
/// A record of a full VM trace for a CALL/CREATE.
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
@@ -413,6 +482,8 @@ pub struct StorageDelta {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use serde_json::{json, Value};
|
||||
use std::str::FromStr;
|
||||
|
||||
#[test]
|
||||
fn test_transaction_trace() {
|
||||
@@ -469,4 +540,176 @@ mod tests {
|
||||
let val = serde_json::from_str::<TransactionTrace>(&input).unwrap();
|
||||
assert!(val.action.is_selfdestruct());
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct TraceTestCase {
|
||||
trace: LocalizedTransactionTrace,
|
||||
expected_json: Value,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_serialization_order() {
|
||||
let test_cases = vec![
|
||||
TraceTestCase {
|
||||
trace: LocalizedTransactionTrace {
|
||||
trace: TransactionTrace {
|
||||
action: Action::Call(CallAction {
|
||||
from: "0x4f4495243837681061c4743b74b3eedf548d56a5".parse::<Address>().unwrap(),
|
||||
call_type: CallType::DelegateCall,
|
||||
gas: U64::from(3148955),
|
||||
input: Bytes::from_str("0x585a9fd40000000000000000000000000000000000000000000000000000000000000040a47c5ad9a4af285720eae6cc174a9c75c5bbaf973b00f1a0c191327445b6581000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000ce16f69375520ab01377ce7b88f5ba8c48f8d666f61490331372e432315cd97447e3bc452d6c73a6e0536260a88ddab46f85c88d00000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000aab8cf0fbfb038751339cb61161fa11789b41a78f1b7b0e12cf8e467d403590b7a5f26f0000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000646616e746f6d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a3078636531364636393337353532306162303133373763653742383866354241384334384638443636360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045553444300000000000000000000000000000000000000000000000000000000").unwrap(),
|
||||
to: "0x99b5fa03a5ea4315725c43346e55a6a6fbd94098".parse::<Address>().unwrap(),
|
||||
value: U256::from(0),
|
||||
}),
|
||||
error: None,
|
||||
result: Some(TraceOutput::Call(CallOutput { gas_used: U64::from(32364), output: Bytes::new() })),
|
||||
subtraces: 0,
|
||||
trace_address: vec![0, 10, 0],
|
||||
},
|
||||
block_hash: Some(B256::ZERO),
|
||||
block_number: Some(18557272),
|
||||
transaction_hash: Some(B256::from_str("0x54160ddcdbfaf98a43a43c328ebd44aa99faa765e0daa93e61145b06815a4071").unwrap()),
|
||||
transaction_position: Some(102),
|
||||
},
|
||||
expected_json: json!({
|
||||
"action": {
|
||||
"from": "0x4f4495243837681061c4743b74b3eedf548d56a5",
|
||||
"callType": "delegatecall",
|
||||
"gas": "0x300c9b",
|
||||
"input": "0x585a9fd40000000000000000000000000000000000000000000000000000000000000040a47c5ad9a4af285720eae6cc174a9c75c5bbaf973b00f1a0c191327445b6581000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000ce16f69375520ab01377ce7b88f5ba8c48f8d666f61490331372e432315cd97447e3bc452d6c73a6e0536260a88ddab46f85c88d00000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000aab8cf0fbfb038751339cb61161fa11789b41a78f1b7b0e12cf8e467d403590b7a5f26f0000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000646616e746f6d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a3078636531364636393337353532306162303133373763653742383866354241384334384638443636360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045553444300000000000000000000000000000000000000000000000000000000",
|
||||
"to": "0x99b5fa03a5ea4315725c43346e55a6a6fbd94098",
|
||||
"value": "0x0"
|
||||
},
|
||||
"blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"blockNumber": 18557272,
|
||||
"result": {
|
||||
"gasUsed": "0x7e6c",
|
||||
"output": "0x"
|
||||
},
|
||||
"subtraces": 0,
|
||||
"traceAddress": [
|
||||
0,
|
||||
10,
|
||||
0
|
||||
],
|
||||
"transactionHash": "0x54160ddcdbfaf98a43a43c328ebd44aa99faa765e0daa93e61145b06815a4071",
|
||||
"transactionPosition": 102,
|
||||
"type": "call"
|
||||
}),
|
||||
},
|
||||
TraceTestCase {
|
||||
trace: LocalizedTransactionTrace {
|
||||
trace: TransactionTrace {
|
||||
action: Action::Create(CreateAction{
|
||||
from: "0x4f4495243837681061c4743b74b3eedf548d56a5".parse::<Address>().unwrap(),
|
||||
gas: U64::from(3438907),
|
||||
init: Bytes::from_str("0x6080604052600160005534801561001557600080fd5b50610324806100256000396000f3fe608060405234801561001057600080fd5b50600436106100355760003560e01c8062f55d9d1461003a5780631cff79cd1461004f575b600080fd5b61004d6100483660046101da565b610079565b005b61006261005d3660046101fc565b6100bb565b60405161007092919061027f565b60405180910390f35b6002600054141561009d5760405163caa30f5560e01b815260040160405180910390fd5b600260005573ffffffffffffffffffffffffffffffffffffffff8116ff5b60006060600260005414156100e35760405163caa30f5560e01b815260040160405180910390fd5b600260005573ffffffffffffffffffffffffffffffffffffffff85163b610136576040517f6f7c43f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8473ffffffffffffffffffffffffffffffffffffffff16848460405161015d9291906102de565b6000604051808303816000865af19150503d806000811461019a576040519150601f19603f3d011682016040523d82523d6000602084013e61019f565b606091505b50600160005590969095509350505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101d557600080fd5b919050565b6000602082840312156101ec57600080fd5b6101f5826101b1565b9392505050565b60008060006040848603121561021157600080fd5b61021a846101b1565b9250602084013567ffffffffffffffff8082111561023757600080fd5b818601915086601f83011261024b57600080fd5b81358181111561025a57600080fd5b87602082850101111561026c57600080fd5b6020830194508093505050509250925092565b821515815260006020604081840152835180604085015260005b818110156102b557858101830151858201606001528201610299565b818111156102c7576000606083870101525b50601f01601f191692909201606001949350505050565b818382376000910190815291905056fea264697066735822122032cb5e746816b7fac95205c068b30da37bd40119a57265be331c162cae74712464736f6c63430008090033").unwrap(),
|
||||
value: U256::from(0),
|
||||
}),
|
||||
error: None,
|
||||
result: Some(TraceOutput::Create(CreateOutput { gas_used: U64::from(183114), address: "0x7eb6c6c1db08c0b9459a68cfdcedab64f319c138".parse::<Address>().unwrap(), code: Bytes::from_str("0x608060405234801561001057600080fd5b50600436106100355760003560e01c8062f55d9d1461003a5780631cff79cd1461004f575b600080fd5b61004d6100483660046101da565b610079565b005b61006261005d3660046101fc565b6100bb565b60405161007092919061027f565b60405180910390f35b6002600054141561009d5760405163caa30f5560e01b815260040160405180910390fd5b600260005573ffffffffffffffffffffffffffffffffffffffff8116ff5b60006060600260005414156100e35760405163caa30f5560e01b815260040160405180910390fd5b600260005573ffffffffffffffffffffffffffffffffffffffff85163b610136576040517f6f7c43f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8473ffffffffffffffffffffffffffffffffffffffff16848460405161015d9291906102de565b6000604051808303816000865af19150503d806000811461019a576040519150601f19603f3d011682016040523d82523d6000602084013e61019f565b606091505b50600160005590969095509350505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101d557600080fd5b919050565b6000602082840312156101ec57600080fd5b6101f5826101b1565b9392505050565b60008060006040848603121561021157600080fd5b61021a846101b1565b9250602084013567ffffffffffffffff8082111561023757600080fd5b818601915086601f83011261024b57600080fd5b81358181111561025a57600080fd5b87602082850101111561026c57600080fd5b6020830194508093505050509250925092565b821515815260006020604081840152835180604085015260005b818110156102b557858101830151858201606001528201610299565b818111156102c7576000606083870101525b50601f01601f191692909201606001949350505050565b818382376000910190815291905056fea264697066735822122032cb5e746816b7fac95205c068b30da37bd40119a57265be331c162cae74712464736f6c63430008090033").unwrap() })),
|
||||
subtraces: 0,
|
||||
trace_address: vec![0, 7, 0, 0],
|
||||
},
|
||||
block_hash: Some(B256::from_str("0xd5ac5043011d4f16dba7841fa760c4659644b78f663b901af4673b679605ed0d").unwrap()),
|
||||
block_number: Some(18557272),
|
||||
transaction_hash: Some(B256::from_str("0x54160ddcdbfaf98a43a43c328ebd44aa99faa765e0daa93e61145b06815a4071").unwrap()),
|
||||
transaction_position: Some(102),
|
||||
},
|
||||
expected_json: json!({
|
||||
"action": {
|
||||
"from": "0x4f4495243837681061c4743b74b3eedf548d56a5",
|
||||
"gas": "0x34793b",
|
||||
"init": "0x6080604052600160005534801561001557600080fd5b50610324806100256000396000f3fe608060405234801561001057600080fd5b50600436106100355760003560e01c8062f55d9d1461003a5780631cff79cd1461004f575b600080fd5b61004d6100483660046101da565b610079565b005b61006261005d3660046101fc565b6100bb565b60405161007092919061027f565b60405180910390f35b6002600054141561009d5760405163caa30f5560e01b815260040160405180910390fd5b600260005573ffffffffffffffffffffffffffffffffffffffff8116ff5b60006060600260005414156100e35760405163caa30f5560e01b815260040160405180910390fd5b600260005573ffffffffffffffffffffffffffffffffffffffff85163b610136576040517f6f7c43f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8473ffffffffffffffffffffffffffffffffffffffff16848460405161015d9291906102de565b6000604051808303816000865af19150503d806000811461019a576040519150601f19603f3d011682016040523d82523d6000602084013e61019f565b606091505b50600160005590969095509350505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101d557600080fd5b919050565b6000602082840312156101ec57600080fd5b6101f5826101b1565b9392505050565b60008060006040848603121561021157600080fd5b61021a846101b1565b9250602084013567ffffffffffffffff8082111561023757600080fd5b818601915086601f83011261024b57600080fd5b81358181111561025a57600080fd5b87602082850101111561026c57600080fd5b6020830194508093505050509250925092565b821515815260006020604081840152835180604085015260005b818110156102b557858101830151858201606001528201610299565b818111156102c7576000606083870101525b50601f01601f191692909201606001949350505050565b818382376000910190815291905056fea264697066735822122032cb5e746816b7fac95205c068b30da37bd40119a57265be331c162cae74712464736f6c63430008090033",
|
||||
"value": "0x0"
|
||||
},
|
||||
"blockHash": "0xd5ac5043011d4f16dba7841fa760c4659644b78f663b901af4673b679605ed0d",
|
||||
"blockNumber": 18557272,
|
||||
"result": {
|
||||
"address": "0x7eb6c6c1db08c0b9459a68cfdcedab64f319c138",
|
||||
"code": "0x608060405234801561001057600080fd5b50600436106100355760003560e01c8062f55d9d1461003a5780631cff79cd1461004f575b600080fd5b61004d6100483660046101da565b610079565b005b61006261005d3660046101fc565b6100bb565b60405161007092919061027f565b60405180910390f35b6002600054141561009d5760405163caa30f5560e01b815260040160405180910390fd5b600260005573ffffffffffffffffffffffffffffffffffffffff8116ff5b60006060600260005414156100e35760405163caa30f5560e01b815260040160405180910390fd5b600260005573ffffffffffffffffffffffffffffffffffffffff85163b610136576040517f6f7c43f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8473ffffffffffffffffffffffffffffffffffffffff16848460405161015d9291906102de565b6000604051808303816000865af19150503d806000811461019a576040519150601f19603f3d011682016040523d82523d6000602084013e61019f565b606091505b50600160005590969095509350505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101d557600080fd5b919050565b6000602082840312156101ec57600080fd5b6101f5826101b1565b9392505050565b60008060006040848603121561021157600080fd5b61021a846101b1565b9250602084013567ffffffffffffffff8082111561023757600080fd5b818601915086601f83011261024b57600080fd5b81358181111561025a57600080fd5b87602082850101111561026c57600080fd5b6020830194508093505050509250925092565b821515815260006020604081840152835180604085015260005b818110156102b557858101830151858201606001528201610299565b818111156102c7576000606083870101525b50601f01601f191692909201606001949350505050565b818382376000910190815291905056fea264697066735822122032cb5e746816b7fac95205c068b30da37bd40119a57265be331c162cae74712464736f6c63430008090033",
|
||||
"gasUsed": "0x2cb4a"
|
||||
},
|
||||
"subtraces": 0,
|
||||
"traceAddress": [
|
||||
0,
|
||||
7,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"transactionHash": "0x54160ddcdbfaf98a43a43c328ebd44aa99faa765e0daa93e61145b06815a4071",
|
||||
"transactionPosition": 102,
|
||||
"type": "create"
|
||||
}),
|
||||
}
|
||||
];
|
||||
|
||||
for (i, test_case) in test_cases.iter().enumerate() {
|
||||
let serialized = serde_json::to_string(&test_case.trace).unwrap();
|
||||
let actual_json: Value = serde_json::from_str(&serialized).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
actual_json, test_case.expected_json,
|
||||
"Test case {} failed; Trace: {:?}",
|
||||
i, test_case.trace
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_deserialize_serialize() {
|
||||
let reference_data = r#"{
|
||||
"action": {
|
||||
"from": "0xc77820eef59629fc8d88154977bc8de8a1b2f4ae",
|
||||
"callType": "call",
|
||||
"gas": "0x4a0d00",
|
||||
"input": "0x12",
|
||||
"to": "0x4f4495243837681061c4743b74b3eedf548d56a5",
|
||||
"value": "0x0"
|
||||
},
|
||||
"blockHash": "0xd5ac5043011d4f16dba7841fa760c4659644b78f663b901af4673b679605ed0d",
|
||||
"blockNumber": 18557272,
|
||||
"result": {
|
||||
"gasUsed": "0x17d337",
|
||||
"output": "0x"
|
||||
},
|
||||
"subtraces": 1,
|
||||
"traceAddress": [],
|
||||
"transactionHash": "0x54160ddcdbfaf98a43a43c328ebd44aa99faa765e0daa93e61145b06815a4071",
|
||||
"transactionPosition": 102,
|
||||
"type": "call"
|
||||
}"#;
|
||||
|
||||
let trace: LocalizedTransactionTrace = serde_json::from_str(reference_data).unwrap();
|
||||
assert!(trace.trace.action.is_call());
|
||||
let serialized = serde_json::to_string_pretty(&trace).unwrap();
|
||||
similar_asserts::assert_eq!(serialized, reference_data);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_deserialize_serialize_selfdestruct() {
|
||||
let reference_data = r#"{
|
||||
"action": {
|
||||
"address": "0xc77820eef59629fc8d88154977bc8de8a1b2f4ae",
|
||||
"balance": "0x0",
|
||||
"refundAddress": "0x4f4495243837681061c4743b74b3eedf548d56a5"
|
||||
},
|
||||
"blockHash": "0xd5ac5043011d4f16dba7841fa760c4659644b78f663b901af4673b679605ed0d",
|
||||
"blockNumber": 18557272,
|
||||
"result": {
|
||||
"gasUsed": "0x17d337",
|
||||
"output": "0x"
|
||||
},
|
||||
"subtraces": 1,
|
||||
"traceAddress": [],
|
||||
"transactionHash": "0x54160ddcdbfaf98a43a43c328ebd44aa99faa765e0daa93e61145b06815a4071",
|
||||
"transactionPosition": 102,
|
||||
"type": "suicide"
|
||||
}"#;
|
||||
|
||||
let trace: LocalizedTransactionTrace = serde_json::from_str(reference_data).unwrap();
|
||||
assert!(trace.trace.action.is_selfdestruct());
|
||||
let serialized = serde_json::to_string_pretty(&trace).unwrap();
|
||||
similar_asserts::assert_eq!(serialized, reference_data);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user