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

"vm.setBlockhash" cheatcode #7929

Closed
zomglings opened this issue May 14, 2024 · 8 comments · Fixed by #8258
Closed

"vm.setBlockhash" cheatcode #7929

zomglings opened this issue May 14, 2024 · 8 comments · Fixed by #8258
Assignees
Labels
good first issue Good for newcomers T-feature Type: feature

Comments

@zomglings
Copy link

zomglings commented May 14, 2024

Component

cheatcodes

Describe the feature you would like

A vm.setBlockhash cheat code would be very convenient for testing code that uses the Solidity blockhash function.

This is how it would be used:

vm.roll(block.number + 1);
vm.setBlockhash(block.number - 1, "1234");
assertEq(blockhash(block.number - 1), "1234");

Currently, the easiest way to test code that calls blockhash is to wrap the blockhash call in a virtual, internal method and then create a test class that overrides that method to mock blockhash calls.

I'd rather just have the mocking performed at the level of the vm.

If this is considered sufficiently useful, I would be happy to try my hand at adding this cheat code. Just don't want to learn rust, etc. to add this only to have a PR rejected if the feature isn't seen as useful.

Additional context

No response

@zomglings zomglings added the T-feature Type: feature label May 14, 2024
@zomglings
Copy link
Author

@onbjerg
Copy link
Member

onbjerg commented May 14, 2024

Unsure if this makes sense to add if https://eips.ethereum.org/EIPS/eip-2935 is included in Prague, as this could be emulated with just setting the appropriate slot on the contract

@mattsse mattsse added the good first issue Good for newcomers label May 14, 2024
@zomglings
Copy link
Author

Unsure if this makes sense to add if https://eips.ethereum.org/EIPS/eip-2935 is included in Prague, as this could be emulated with just setting the appropriate slot on the contract

In that case, wouldn't vm.setBlockhash still be a useful shorthand to set that slot?

@mattsse
Copy link
Member

mattsse commented May 15, 2024

yeah for setting a slot this will still be useful imo

@jrmncos
Copy link

jrmncos commented Jun 11, 2024

Hello, is it still available? I would like to work on this one

@mattsse
Copy link
Member

mattsse commented Jun 11, 2024

this is available and should be similar to

/// Gets the current `block.timestamp`.
/// You should use this instead of `block.timestamp` if you use `vm.warp`, as `block.timestamp` is assumed to be constant across a transaction,
/// and as a result will get optimized out by the compiler.
/// See https://github.com/foundry-rs/foundry/issues/6180
#[cheatcode(group = Evm, safety = Safe)]
function getBlockTimestamp() external view returns (uint256 timestamp);

impl Cheatcode for getBlockTimestampCall {
fn apply_full<DB: DatabaseExt>(&self, ccx: &mut CheatsCtxt<DB>) -> Result {
let Self {} = self;
Ok(ccx.ecx.env.block.timestamp.abi_encode())
}
}

the impl would need to update the hash of the number argument in the database

if you need more pointers, please open a draft pr and we take it from there

@TropicalDog17
Copy link
Contributor

Hi @mattsse, it appears the previous assignee hasn't started on this task yet so I'd like to work on it. I've created a draft PR but I'm having trouble accessing the database in apply_full to update the blockhash. Could you provide some guidance on this? Thank you!

@jrmncos
Copy link

jrmncos commented Jun 26, 2024

hey @mattsse you can re-assign the issue to @TropicalDog17 . Sorry for delay

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good for newcomers T-feature Type: feature
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants