Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(rpc-types): implement serialization for LocalizedTransactionTrace #5446

128 changes: 67 additions & 61 deletions crates/rpc/rpc-types/src/eth/trace/parity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,15 @@ impl Action {
pub fn is_reward(&self) -> bool {
matches!(self, Action::Reward(_))
}

pub fn kind(&self) -> ActionKind {
match self {
Action::Call(_) => ActionKind::Call,
Action::Create(_) => ActionKind::Create,
Action::Selfdestruct(_) => ActionKind::Selfdestruct,
Action::Reward(_) => ActionKind::Reward,
}
}
}

/// An external action type.
Expand All @@ -190,6 +199,14 @@ pub enum ActionType {
Reward,
}

#[derive(Debug)]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#[derive(Debug)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]

pub enum ActionKind {
Call,
Create,
Selfdestruct,
Reward,
}

/// Call type.
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
Expand Down Expand Up @@ -357,17 +374,17 @@ impl Serialize for LocalizedTransactionTrace {
let mut s = serializer.serialize_struct("LocalizedTransactionTrace", 8)?;

match &self.trace.action {
Action::Call(_call_action) => {
s.serialize_field("action", _call_action)?;
Action::Call(call_action) => {
s.serialize_field("action", call_action)?;
}
Action::Create(_create_action) => {
s.serialize_field("action", _create_action)?;
Action::Create(create_action) => {
s.serialize_field("action", create_action)?;
}
Action::Selfdestruct(_selfdestruct_action) => {
s.serialize_field("action", _selfdestruct_action)?;
Action::Selfdestruct(selfdestruct_action) => {
s.serialize_field("action", selfdestruct_action)?;
}
Action::Reward(_reward_action) => {
s.serialize_field("action", _reward_action)?;
Action::Reward(reward_action) => {
s.serialize_field("action", reward_action)?;
}
}
if let Some(block_hash) = self.block_hash {
Expand All @@ -394,17 +411,17 @@ impl Serialize for LocalizedTransactionTrace {
s.serialize_field("subtraces", &self.trace.subtraces)?;
s.serialize_field("traceAddress", &self.trace.trace_address)?;

match &self.trace.action {
Action::Call(_call_action) => {
match &self.trace.action.kind() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can be simplified with a single s.serialize_field("type", kind())?; call if ActionKind serializes accordingly

ActionKind::Call => {
s.serialize_field("type", "call")?;
}
Action::Create(_create_action) => {
ActionKind::Create => {
s.serialize_field("type", "create")?;
}
Action::Selfdestruct(_selfdestruct_action) => {
ActionKind::Selfdestruct => {
s.serialize_field("type", "selfdestruct")?;
}
Action::Reward(_reward_action) => {
ActionKind::Reward => {
s.serialize_field("type", "reward")?;
}
}
Expand Down Expand Up @@ -601,56 +618,11 @@ mod tests {
value: U256::from(0),
}),
error: None,
result: Some(TraceOutput::Call(CallOutput { gas_used: U64::from(183114), 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",
"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"
}),
},
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::Call(CallOutput { gas_used: U64::from(183114), output: Bytes::new() })),
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, 10, 0],
trace_address: vec![0, 7, 0, 0],
},
block_hash: Some(B256::ZERO),
block_hash: Some(B256::from_str("0xd5ac5043011d4f16dba7841fa760c4659644b78f663b901af4673b679605ed0d").unwrap()),
block_number: Some(18557272),
transaction_hash: Some(B256::from_str("0x54160ddcdbfaf98a43a43c328ebd44aa99faa765e0daa93e61145b06815a4071").unwrap()),
transaction_position: Some(102),
Expand Down Expand Up @@ -694,4 +666,38 @@ mod tests {
);
}
}

#[test]
fn test_deserialize_serialize() {
let reference_data = r#"{
"action": {
"from": "0x4f4495243837681061c4743b74b3eedf548d56a5",
"gas": "0x388b4f",
"init": "0x6080604052600160005534801561001557600080fd5b50610324806100256000396000f3fe608060405234801561001057600080fd5b50600436106100355760003560e01c8062f55d9d1461003a5780631cff79cd1461004f575b600080fd5b61004d6100483660046101da565b610079565b005b61006261005d3660046101fc565b6100bb565b60405161007092919061027f565b60405180910390f35b6002600054141561009d5760405163caa30f5560e01b815260040160405180910390fd5b600260005573ffffffffffffffffffffffffffffffffffffffff8116ff5b60006060600260005414156100e35760405163caa30f5560e01b815260040160405180910390fd5b600260005573ffffffffffffffffffffffffffffffffffffffff85163b610136576040517f6f7c43f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8473ffffffffffffffffffffffffffffffffffffffff16848460405161015d9291906102de565b6000604051808303816000865af19150503d806000811461019a576040519150601f19603f3d011682016040523d82523d6000602084013e61019f565b606091505b50600160005590969095509350505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101d557600080fd5b919050565b6000602082840312156101ec57600080fd5b6101f5826101b1565b9392505050565b60008060006040848603121561021157600080fd5b61021a846101b1565b9250602084013567ffffffffffffffff8082111561023757600080fd5b818601915086601f83011261024b57600080fd5b81358181111561025a57600080fd5b87602082850101111561026c57600080fd5b6020830194508093505050509250925092565b821515815260006020604081840152835180604085015260005b818110156102b557858101830151858201606001528201610299565b818111156102c7576000606083870101525b50601f01601f191692909201606001949350505050565b818382376000910190815291905056fea264697066735822122032cb5e746816b7fac95205c068b30da37bd40119a57265be331c162cae74712464736f6c63430008090033",
"value": "0x0"
},
"blockHash": "0xd5ac5043011d4f16dba7841fa760c4659644b78f663b901af4673b679605ed0d",
"blockNumber": 18557272,
"result": {
"address": "0x0292ddd2c4d72bf26602fe5d55de16f50dc535e1",
"code": "0x608060405234801561001057600080fd5b50600436106100355760003560e01c8062f55d9d1461003a5780631cff79cd1461004f575b600080fd5b61004d6100483660046101da565b610079565b005b61006261005d3660046101fc565b6100bb565b60405161007092919061027f565b60405180910390f35b6002600054141561009d5760405163caa30f5560e01b815260040160405180910390fd5b600260005573ffffffffffffffffffffffffffffffffffffffff8116ff5b60006060600260005414156100e35760405163caa30f5560e01b815260040160405180910390fd5b600260005573ffffffffffffffffffffffffffffffffffffffff85163b610136576040517f6f7c43f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8473ffffffffffffffffffffffffffffffffffffffff16848460405161015d9291906102de565b6000604051808303816000865af19150503d806000811461019a576040519150601f19603f3d011682016040523d82523d6000602084013e61019f565b606091505b50600160005590969095509350505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101d557600080fd5b919050565b6000602082840312156101ec57600080fd5b6101f5826101b1565b9392505050565b60008060006040848603121561021157600080fd5b61021a846101b1565b9250602084013567ffffffffffffffff8082111561023757600080fd5b818601915086601f83011261024b57600080fd5b81358181111561025a57600080fd5b87602082850101111561026c57600080fd5b6020830194508093505050509250925092565b821515815260006020604081840152835180604085015260005b818110156102b557858101830151858201606001528201610299565b818111156102c7576000606083870101525b50601f01601f191692909201606001949350505050565b818382376000910190815291905056fea264697066735822122032cb5e746816b7fac95205c068b30da37bd40119a57265be331c162cae74712464736f6c63430008090033",
"gasUsed": "0x2cb4a"
},
"subtraces": 0,
"traceAddress": [
0,
6,
0,
0
],
"transactionHash": "0x54160ddcdbfaf98a43a43c328ebd44aa99faa765e0daa93e61145b06815a4071",
"transactionPosition": 102,
"type": "create"
}"#;

let trace: Value = serde_json::from_str(&reference_data).unwrap();
let serialized = serde_json::to_string(&trace).unwrap();

assert_eq!(serialized, reference_data);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this check is redundant,

this needs to deserialize into trace object not Value

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some issues with this. Is there an easier way to test this than implement deserialize?

let trace: LocalizedTransactionTrace = serde_json::from_str(&reference_data).unwrap();
let _serialized = serde_json::to_string(&trace).unwrap();
// thread 'eth::trace::parity::tests::test_deserialize_serialize' panicked at crates/rpc/rpc-types/src/eth/trace/parity.rs:685:86:
// called `Result::unwrap()` on an `Err` value: Error("missing field `trace`", line: 25, column: 1)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

possible that I gave you incorrect test data.

will check, but this looks great now!

}
}