Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 48 additions & 6 deletions src/rpc/methods/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3406,12 +3406,7 @@ where
let state = ctx.state_manager.get_state_tree(&state_root)?;

let mut entries = Vec::new();
let mut msg_idx = 0;
for ir in raw_traces {
if ir.msg.from == system::ADDRESS.into() {
continue;
}
msg_idx += 1;
for (msg_idx, ir) in non_system_traces_with_positions(raw_traces) {
let tx_hash = EthGetTransactionHashByCid::handle(ctx.clone(), (ir.msg_cid,), ext).await?;
let tx_hash = tx_hash
.with_context(|| format!("cannot find transaction hash for cid {}", ir.msg_cid))?;
Expand All @@ -3425,6 +3420,19 @@ where
Ok((state, entries))
}

/// Yields non-system traces paired with 0-indexed positions matching
/// `transactionIndex` from `eth_getBlockByNumber`. System-actor messages
/// are filtered out without consuming a position.
fn non_system_traces_with_positions(
raw_traces: impl IntoIterator<Item = ApiInvocResult>,
) -> impl Iterator<Item = (i64, ApiInvocResult)> {
raw_traces
.into_iter()
.filter(|ir| ir.msg.from != system::ADDRESS.into())
.enumerate()
.map(|(idx, ir)| (idx as i64, ir))
}

async fn eth_trace_block<DB>(
ctx: &Ctx<DB>,
ts: &Tipset,
Expand Down Expand Up @@ -3989,6 +3997,40 @@ mod test {
assert_eq!(r.0, decoded.0);
}

/// `transactionPosition` must be 0-indexed and system-actor messages must
/// be filtered without consuming a position.
#[test]
fn non_system_traces_with_positions_is_zero_indexed() {
use crate::shim::address::Address as ShimAddress;
use crate::shim::message::Message_v3;

let invoc_with_from = |from: ShimAddress| -> ApiInvocResult {
ApiInvocResult {
msg: Message_v3 {
to: ShimAddress::new_id(1).into(),
from: from.into(),
..Message_v3::default()
}
.into(),
..Default::default()
}
};

let raw_traces = vec![
invoc_with_from(system::ADDRESS.into()),
invoc_with_from(ShimAddress::new_id(1000)),
invoc_with_from(system::ADDRESS.into()),
invoc_with_from(ShimAddress::new_id(1001)),
invoc_with_from(ShimAddress::new_id(1002)),
];

let positions: Vec<i64> = non_system_traces_with_positions(raw_traces)
.map(|(pos, _)| pos)
.collect();

assert_eq!(positions, vec![0, 1, 2]);
}

#[test]
fn test_abi_encoding() {
const EXPECTED: &str = "000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000510000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000001b1111111111111111111020200301000000044444444444444444010000000000";
Expand Down
2 changes: 1 addition & 1 deletion src/rpc/methods/state/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ pub struct ForestComputeStateOutput {

lotus_json_with_self!(ForestComputeStateOutput);

#[derive(Debug, Serialize, Deserialize, Clone, JsonSchema)]
#[derive(Debug, Default, Serialize, Deserialize, Clone, JsonSchema)]
#[serde(rename_all = "PascalCase")]
pub struct ApiInvocResult {
#[serde(with = "crate::lotus_json")]
Expand Down
Loading