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

Merged
merged 7 commits into from
Jan 27, 2025

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Note that what I have right now in the code is not actually reusable in general. It's actually the pure minimum of code needed to satisfy the autopilot's needs. The reasons:
1.CallFrame only contains subset of data that is needed for functionality used in autopilot.
2. I use only one type of calltracer here.

In general, to fully implement debug_traceTransaction function so it could be reused with all of it's different input's and outputs would require a lot more code which would be a copy paste from alloy crate.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved the current impl code into ethrpc

@sunce86 sunce86 enabled auto-merge (squash) January 27, 2025 14:19
@sunce86 sunce86 merged commit 105ff55 into main Jan 27, 2025
11 checks passed
@sunce86 sunce86 deleted the transaction-trace-2 branch January 27, 2025 14:24
@github-actions github-actions bot locked and limited conversation to collaborators Jan 27, 2025
@sunce86
Copy link
Contributor Author

sunce86 commented Jan 27, 2025

Test transactions succeeded on all networks.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
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