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

feat: support forking at any transaction #3262

Merged
merged 4 commits into from
Sep 19, 2022

Conversation

mattsse
Copy link
Member

@mattsse mattsse commented Sep 18, 2022

Motivation

Ref #2191

this adds additional cheatcodes for create(select)Fork and rollFork that accept transaction hashes instead of blocks.

this will fork off the block the transaction was mined in and replays all prior transaction in the block, not including the transaction. Perhaps this should be inclusive?

needs some tests

Solution

@mattsse mattsse added T-feature Type: feature A-cheatcodes Area: cheatcodes labels Sep 18, 2022
@gakonst
Copy link
Member

gakonst commented Sep 18, 2022

this will fork off the block the transaction was mined in and replays all prior transaction in the block, not including the transaction. Perhaps this should be inclusive?

@CodeForcer what is the expected behavior here? inclusive or not?

Comment on lines +723 to +727
let block = fork
.db
.db
.get_full_block(BlockNumber::Latest)?
.number
Copy link
Member

Choose a reason for hiding this comment

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

can you not do eth_blockNumber here instead of asking for the full block?

Copy link
Member Author

Choose a reason for hiding this comment

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

can do that by adding another request variant for eth_blockNumber

Comment on lines +742 to +750
let fork = self.inner.get_fork_by_id_mut(id)?;
let full_block =
fork.db.db.get_full_block(BlockNumber::Number(env.block.number.as_u64().into()))?;

for tx in full_block.transactions.into_iter() {
if tx.hash().eq(&tx_hash) {
// found the target transaction
return Ok(Some(tx))
}
Copy link
Member

Choose a reason for hiding this comment

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

can we cache this somehow to disk? so that forking a txhash does not replay all txs each time, and can maybe save the pre-tx hash state (or including it)?

Copy link
Member Author

Choose a reason for hiding this comment

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

would require adding another mapping to how forks are tracked rn, basically (endpoint, block, tx index).

would be possible but requires a bit of refactoring effort, I'd leave this for a follow up for perf

@gakonst gakonst merged commit 0c5e82b into foundry-rs:master Sep 19, 2022
@gakonst
Copy link
Member

gakonst commented Sep 19, 2022

Merging and we can iterate with @CodeForcer feedback

iFrostizz pushed a commit to iFrostizz/foundry that referenced this pull request Nov 9, 2022
* feat: add get full block request

* feat: add transaction request

* feat: integrate cheatcodes

* feat: support forking at any transaction
@CodeForcer
Copy link

Thanks team!

@ChinW
Copy link

ChinW commented Sep 8, 2023

does anvil also support this?

@gakonst
Copy link
Member

gakonst commented Sep 8, 2023

Nope I believe Anvil only forks by block height, but feel free to open an issue to potentially support it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-cheatcodes Area: cheatcodes T-feature Type: feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants