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

Simulate on user provided timestamp #27

Merged

Conversation

MartinquaXD
Copy link
Contributor

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 cowprotocol/services#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

  • added new optional field blockTimestamp to the API request
  • added documentation for the new field
  • added a test that reproduces the linked issue and catches the timestamp dependent revert
  • use dependency injection for API tests to allow overwriting defaults

@fleupold
Copy link
Contributor

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
Copy link
Contributor Author

MartinquaXD commented Dec 19, 2023

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
Copy link
Contributor

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.

@devanoneth devanoneth merged commit ee12a28 into EnsoFinance:main Dec 20, 2023
3 checks passed
@MartinquaXD
Copy link
Contributor Author

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 MartinquaXD deleted the simulate-on-provided-timestamp branch December 21, 2023 09:48
@MartinquaXD
Copy link
Contributor Author

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.

MartinquaXD added a commit to cowprotocol/services that referenced this pull request Jan 9, 2024
# Description
When we simulate a transaction in the driver we only care whether it
would work on the `pending` block and not on the `latest` block. Of
course we can't magically predict the entire state of the blockchain on
the next block but at least we could catch problems that arise of the
next block number, timestamp and basefee.
This is pretty easy to do with `tenderly` and `web3` but unfortunately
the `enso` simulator does not really support simulating on the `pending`
block.

To get closer to the desired behavior I opened a
[PR](EnsoFinance/temper#27) (not yet merged) on
the enso simulator which allows users to provide the timestamp they want
to simulate on and changed our code to produce the needed timestamp in
the `enso` simulator.

# Changes
- added `block_timestamp` to the `enso` dto
- added `current_block_stream` and `network_block_interval` to `enso`
simulator to get the needed timestamp
- added plumbing to configure `network_block_interval` in a config file
- extended `FetchBlock.sol` to also return the blocks timestamp

## How to test
Did a manual test locally. Created a test order and checked that the
enso simulator can handle the timestamp.
Unfortunately the `enso` team did not build a new docker image so I also
tested that our code doesn't break with the old `temper` version so we
should be able to merge this PR without any issues. Will contact the
team to request a new build from them.

Fixes #2174
@fleupold
Copy link
Contributor

fleupold commented Jan 9, 2024

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
Copy link
Contributor Author

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. 👌

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.

3 participants