You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The autopilot indexes transactions with Settlement events coming from the settlement contract. It decodes the call data for the call and extracts some relevant information from it.
This code splits the entire calldata of the tx into data (settle() call) and metadata (auction_id added at the end). The data later gets parsed here.
That logic only works if an EOA directly called settle(). If instead there was a smart contract solver (or some other helper contract for that matter) the calldata of the transaction would not contain the call to the settle() function but rather to some other contract. This is a completely different function call which would cause the current decoding logic to fail.
To accommodate these new use cases we'd have to make use of trace_call functionality. That way we could resimulate the entire transaction, step through the individual traces and find the trace for the actual settle() call (target address is settlement contract and function selector is 0x13d79a0b).
Details
The suggested course of action looks like this:
1. implement actual change
First of all we need a convenient way to resimulate a tx and get trace calls out of it. This should be easily doable by calling web3.trace().transaction(settlement_tx_hash).
This will return a bunch of traces from the particular tx_hash which needs to be parsed to get the correct gas_used, calldata and the solver that actually initiated the call.
To identify the actual settle() call find the trace where action.to == 0x9008d19f58aabd9ed0d60971565aa8510560ab41 and action.input.starts_with(0x13d79a0b).
Naively we could assume that whoever calls settle() is the actual solver address but that does not work with helper contracts that sit between solver contract and settlement contract.
To handle these correctly we could configure a list of allow listed helper contracts. Start from settle() and go up the call stack until the caller is no longer one of the configured contracts.
That would allow us to correctly identify the real solver address for all these cases (from regular to exotic):
EOA -> settle()
EOA -> helper() -> settle()
EOA -> helper() -> helper() -> settle()
EOA -> SC solver -> helper() -> helper() -> settle()
2. e2e test
Ultimately this change should be tested by an e2e test. Examples can be found here. For the CI to correctly pick up the new test it should be flagged with #[ignore] and the name should start with local_node (to indicate that it should be run with anvil). Here is how the CI will run the tests. To run the tests yourself you can run the same command locally. Just make sure to also run the necessary DB docker containers too (run docker compose up -d in the root directory).
The biggest hurdle will likely be setting up a smart contract solver for the e2e test. The problem is that this feature is not supported out of the box by the reference driver. So in order to test this you'll likely have to create a mock driver that you can tell which exact API response to return. For inspiration take a lock at the existing mock solver.
Acceptance criteria
Ultimately the e2e test should assert that the data indexed in the DB is correct.
solver address is the smart contract instead of the EOA that initiated the transaction
settlement could be parsed because the calldata was extracted correctly from the simulation traces
The text was updated successfully, but these errors were encountered:
Background
The
autopilot
indexes transactions withSettlement
events coming from the settlement contract. It decodes the call data for the call and extracts some relevant information from it.This code splits the entire calldata of the tx into data (
settle()
call) and metadata (auction_id
added at the end). Thedata
later gets parsed here.That logic only works if an EOA directly called
settle()
. If instead there was a smart contract solver (or some other helper contract for that matter) the calldata of the transaction would not contain the call to thesettle()
function but rather to some other contract. This is a completely different function call which would cause the current decoding logic to fail.To accommodate these new use cases we'd have to make use of
trace_call
functionality. That way we could resimulate the entire transaction, step through the individual traces and find the trace for the actualsettle()
call (target address is settlement contract and function selector is0x13d79a0b
).Details
The suggested course of action looks like this:
1. implement actual change
First of all we need a convenient way to resimulate a tx and get trace calls out of it. This should be easily doable by calling
web3.trace().transaction(settlement_tx_hash)
.This will return a bunch of traces from the particular tx_hash which needs to be parsed to get the correct
gas_used
,calldata
and thesolver
that actually initiated the call.To identify the actual
settle()
call find the trace whereaction.to == 0x9008d19f58aabd9ed0d60971565aa8510560ab41
andaction.input.starts_with(0x13d79a0b)
.Naively we could assume that whoever calls
settle()
is the actual solver address but that does not work with helper contracts that sit between solver contract and settlement contract.To handle these correctly we could configure a list of allow listed helper contracts. Start from
settle()
and go up the call stack until the caller is no longer one of the configured contracts.That would allow us to correctly identify the real solver address for all these cases (from regular to exotic):
EOA -> settle()
EOA -> helper() -> settle()
EOA -> helper() -> helper() -> settle()
EOA -> SC solver -> helper() -> helper() -> settle()
2. e2e test
Ultimately this change should be tested by an e2e test. Examples can be found here. For the CI to correctly pick up the new test it should be flagged with
#[ignore]
and the name should start withlocal_node
(to indicate that it should be run withanvil
).Here is how the CI will run the tests. To run the tests yourself you can run the same command locally. Just make sure to also run the necessary DB docker containers too (run
docker compose up -d
in the root directory).The biggest hurdle will likely be setting up a smart contract solver for the e2e test. The problem is that this feature is not supported out of the box by the reference driver. So in order to test this you'll likely have to create a mock driver that you can tell which exact API response to return. For inspiration take a lock at the existing mock solver.
Acceptance criteria
Ultimately the e2e test should assert that the data indexed in the DB is correct.
The text was updated successfully, but these errors were encountered: