EnsoFinance / temper

Temper your expectations - Ethereum Transaction Simulator
MIT License
348 stars 44 forks source link

Simulate on user provided timestamp #27

Closed MartinquaXD closed 9 months ago

MartinquaXD commented 10 months ago

At CoW Protocol there are circumstances where we actually want to know whether a given transaction would simulate on the pending block rather than the latest block (temper's default). (see https://github.com/cowprotocol/services/issues/2174 to get more context) Ideally temper would provide an option to also provide bock settings like latest and pending that takes care of that but that seems like a way bigger change.

One way to get closer to simulating on the pending block would be to allow users to overwrite the used block timestamp. That way we could at least catch reverts that depend on the timestamp. Unfortunately this is still not enough to catch reverts caused by code depending on the actual block number or base fee which would be caught by an actual simulation on pending, though.

Changes

fleupold commented 10 months ago

Unfortunately this is still not enough to catch reverts caused by code depending on the actual block number or base fee which would be caught by an actual simulation on pending, though.

Is it possible to supply a block number that is in the future (ie latest + 1)? It seems to be possible for bundle simulation (temper seem to keep incrementing block number if the second tx in the bundle is on a different block), but I'm not sure if it works for single order simulation.

MartinquaXD commented 10 months ago

temper seem to keep incrementing block number if the second tx in the bundle is on a different block

temper initialises the EVM with the state of the block specified in the first tx and then updates the block number as it goes through the tx (if it changes throughout the bundle). But if I'm not mistaken temper always requires the initial block number to be an existing one to be able to fetch the state. In our case we'd like to immediately set the block number to a block that does not have any state, yet.

A strategy to deal with that could be to fetch the state of the user provided block and if it can't be found simply use the state of the latest block and only overwrite the block number. This seems mostly reasonable for blocks in the future but for example in the case where the state is actually missing because you want to simulate on a very old block (and don't have an archive node) using the latest state does not seem reasonable.

My impression is that patching in exactly what CoW Protocol needs would be easy but making that work consistently for any use case is not straight forward.

devanoneth commented 9 months ago

Thanks for your contribution @MartinquaXD, looks great!

Regarding your specific use case, I do like the idea of doing so automatically if the user provides a block number which is in the future.

In the case you mentioned where state is missing, we could avoid this by checking the latest block number on the node and only setting the EVM to a "future" block if user_block_number > latest_block_number, that way we won't end up in situations where state is missing and the user is unaware they are on a "future" block. I do think we should also document this behavior, but in general I'm fine with it. Would be a powerful addition!

Let me know your thoughts. Will merge this anyway as it's also a great addition.

MartinquaXD commented 9 months ago

Sounds good to me. We already brainstormed ideas how to override the block number in case we couldn't implement it directly in temper but since you are fine with it and it seems possible I'll open another PR for that in temper.

MartinquaXD commented 9 months ago

Hey guys, could you please build a new official docker image including this PR? We'd like to start using it at cowswap but would prefer to continue using your official version from ghcr.

fleupold commented 9 months ago

CI builds on whenever a PR is merged into main, so you could pin our release to this sha hash and should be able to get the latest code: https://github.com/EnsoFinance/temper/actions/runs/7281198410/job/19841226414

MartinquaXD commented 9 months ago

Looks like we don't even have to pin it. This repo publishes 2 packages (transaction-simulator and temper). I looked at the published versions of the wrong one. All good then. :ok_hand: