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

Use debug traces to extract the input for settlement::Observer #3245

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

sunce86
Copy link
Contributor

@sunce86 sunce86 commented Jan 20, 2025

Description

A second attempt to resolve #3177
(first attempt was here: #3233)

Now, we try to use debug_traceTransaction instead of trace_transaction, to find call traces to extract the right one -> settle call to settlement contract.

For a difference from first attempt, review just the commits after "revert".

Changes

  • Use debug_traceTransaction to find /settle call instead of using transaction.input directly.

How to test

e2e tests show that the code is correct and that deserialization works properly.
manually tested the debug_traceTransaction on different networks and rpc nodes. (reth ok, alchemy ok, arbitrum ovh nodes ok, just to verify arbitrum nitro)

@sunce86 sunce86 self-assigned this Jan 20, 2025
@sunce86 sunce86 requested a review from a team as a code owner January 20, 2025 15:36
Copy link
Contributor

@squadgazzz squadgazzz left a comment

Choose a reason for hiding this comment

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

LGTM, I have nothing to add here. It's great that it was tested manually.

Copy link
Contributor

@mstrug mstrug left a comment

Choose a reason for hiding this comment

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

Looks, ok. One comment.

crates/autopilot/src/domain/settlement/transaction/mod.rs Outdated Show resolved Hide resolved
crates/autopilot/src/domain/settlement/mod.rs Show resolved Hide resolved
return Some(call_frame);
}
// Add all nested calls to the queue
queue.extend(&call_frame.calls);
Copy link
Contributor

Choose a reason for hiding this comment

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

I think if you were to use a Vec for the stack these callframes should be added to the stack in reverse order.
Otherwise you'd first decent down the last child call - not the first one, right?

Copy link
Contributor Author

@sunce86 sunce86 Jan 22, 2025

Choose a reason for hiding this comment

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

Yeah. So bottom line, using queue with pop-ing from front is breadth-first, while using vec with extending in reverse order would be depth-first search, if i'm not wrong. With that, I am not sure which one has a higher chance of finding the calldata faster, so both of them seem fine to me, so I went with breadth-first.

Maybe breadth-first is faster since settle calldata will probably be in one of the first layers of subcalls.

Copy link
Contributor

@MartinquaXD MartinquaXD Jan 22, 2025

Choose a reason for hiding this comment

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

Hmm, interesting. Didn't even occur to me to use BFS to analyze a call stack since DFS is the natural flow of the program. But I agree that BFS would probably find the important stack frame faster. 👍

Adding a small comment about the BFS approach would be nice, though.

Also while thinking about the differences between DFS and BFS I realized that an SC solver could execute 2 settlements in a single call. I believe this would probably trip up our indexing logic. Would be good to check what needs to be changed to accommodate that edge case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Multiple settlements per transaction are not supported by our system (this is not the only place where it would be an issue). If you are worried about it, I would suggest defining a circuit breaker rule that would forbid it.

})
}

/// Taken from alloy::rpc::types::trace::geth::CallFrame
#[derive(Clone, Debug, Default, PartialEq, Eq, Deserialize)]
pub struct CallFrame {
Copy link
Contributor

Choose a reason for hiding this comment

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

This exact type exists twice. Once in the infra module and once in the domain module. I suspect we only need one of them.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't want to have deserialization specifics in the domain.

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, I see. I wonder if this and the debug_trace logic might not be better placed in the ethrpc crate.
We might as well make this easily reusable with an extension trait. It's a bit awkward that the web3 crate does not support the debug module out of the box but AFAICS we could add a new namespace for debug which can have the trace_transaction functionality.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Make settlement indexing compatible with smart contract solvers
4 participants