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(cheatcodes): getArtifactPathByCode and getArtifactPathByDeployedCode #8938

Merged
merged 19 commits into from
Sep 26, 2024

Conversation

yash-atreya
Copy link
Member

@yash-atreya yash-atreya commented Sep 23, 2024

Motivation

Closes #7634

Solution

Adds new cheatcodes
function getArtifactPathByCode(bytes calldata code) external returns (string memory path);
function getArtifactPathByDeployedCode(bytes calldata deployedCode) external returns (string memory path);

Copy link
Member

@mattsse mattsse left a comment

Choose a reason for hiding this comment

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

makes sense, wdyt @grandizzy

needs test

crates/cheatcodes/src/fs.rs Outdated Show resolved Hide resolved
@grandizzy
Copy link
Collaborator

grandizzy commented Sep 23, 2024

this is great to have but doesn't really solve #7634 which requests an address (or bytecode) to be passed as param and then match the deployed bytecode > use bytecode_diff_score to identify the contract / it's path (ContractsByArtifact.find_by_code kind of what we're doing for coverage)

@grandizzy
Copy link
Collaborator

re failing test - we're at a point when a new cheatcode added breaks it so seed should be updated, pls see https://github.com/foundry-rs/foundry/pull/8882/files#diff-d6c9e2f7cec6e686d5693fd6c6bd6400e4f617e1dea2695df29cab51549ba797R163

@yash-atreya
Copy link
Member Author

this is great to have but doesn't really solve #7634 which requests an address (or bytecode) to be passed as param and then match the deployed bytecode > use bytecode_diff_score to identify the contract / it's path (ContractsByArtifact.find_by_code kind of what we're doing for coverage)

+1. Added vm.getArtifactPath(creationCode), removing vm.getArtifactPath(contractName). Not sure how we can look up artifact path using deployed address? wdyt @grandizzy ?

@grandizzy
Copy link
Collaborator

+1. Added vm.getArtifactPath(creationCode), removing vm.getArtifactPath(contractName). Not sure how we can look up artifact path using deployed address? wdyt @grandizzy ?

yeah, don't see a way to match by address, but looks like vm.getArtifactPath(creationCode) is good for #7634

Copy link
Member

@mattsse mattsse left a comment

Choose a reason for hiding this comment

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

lgtm, defer to @grandizzy on how to proceed.

Comment on lines 1534 to 1536
/// Gets the artifact path from the creation code.
#[cheatcode(group = Filesystem)]
function getArtifactPath(bytes calldata creationCode) external view returns (string memory path);
Copy link
Member

Choose a reason for hiding this comment

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

imo it's not obvious what this function accepts as argument. should we make this more explicit, like getArtifactPathByCode or smth @grandizzy ?

Copy link
Collaborator

@grandizzy grandizzy Sep 24, 2024

Choose a reason for hiding this comment

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

agree that getArtifactPathByCode is cleaner, also since for getCode we have getCode(artifactPath) and getDeployedCode(artifactPath) maybe we need to add a getArtifactPathByDeployedCode too? (where the only difference is that ContractsByArtifact.find_by_deployed_code instead find_by_creation_code is called)
@yash-atreya wdyt?

Copy link
Member Author

Choose a reason for hiding this comment

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

+1 to both.

Makes sense to name them explicitly, also avoids signature conflicts.

@@ -160,7 +160,7 @@ async fn test_scrape_bytecode() {
let filter = Filter::new(".*", ".*", ".*fuzz/FuzzScrapeBytecode.t.sol");
let mut runner = TEST_DATA_DEFAULT.runner();
runner.test_options.fuzz.runs = 2000;
runner.test_options.fuzz.seed = Some(U256::from(100u32));
runner.test_options.fuzz.seed = Some(U256::from(120u32));
Copy link
Member

Choose a reason for hiding this comment

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

Why is this needed?

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Collaborator

Choose a reason for hiding this comment

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

when we fuzz we use test contract bytecode which changed with adding the new cheatcode so there are now different fuzzed inputs, had similar here: https://github.com/foundry-rs/foundry/pull/8882/files#diff-d6c9e2f7cec6e686d5693fd6c6bd6400e4f617e1dea2695df29cab51549ba797R163
ref #8115

Copy link
Member

@DaniPopes DaniPopes Sep 24, 2024

Choose a reason for hiding this comment

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

I don't see how changing an interface (Vm) change bytecode of an unrelated contract, where can I see this error? If this is actually a problem when adding cheatcodes, this should be hotfixed ASAP

Copy link
Collaborator

Choose a reason for hiding this comment

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

the issue can be reproduced in master by appending a line like function writeToml() external; in testdata/cheats/Vm.sol and cargo test test_scrape_bytecode will start failing. It can make it pass if bumping fuzz runs from 2000 to 5000. let me create a simpler repro to expose such

Copy link
Collaborator

Choose a reason for hiding this comment

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

I made some more tests with a simpler repro and figured out that happens because test has target contract in test contract, so they get inline, if they're split then issue is not reproducible and test pass without changing the seed, here's a draft PR #8953
@DaniPopes

Copy link
Collaborator

@grandizzy grandizzy Sep 25, 2024

Choose a reason for hiding this comment

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

this change is no longer needed, the flaky test was fixed and PR updated

@yash-atreya yash-atreya enabled auto-merge (squash) September 24, 2024 12:00
@grandizzy grandizzy changed the title feat(cheatcodes): vm.getArtifactPath feat(cheatcodes): vm.getArtifactPathByCode/getArtifactPathByDeployedCode Sep 25, 2024
@grandizzy grandizzy changed the title feat(cheatcodes): vm.getArtifactPathByCode/getArtifactPathByDeployedCode feat(cheatcodes): getArtifactPathByCode and getArtifactPathByDeployedCode Sep 25, 2024
@grandizzy grandizzy requested a review from DaniPopes September 25, 2024 11:51
@yash-atreya yash-atreya enabled auto-merge (squash) September 26, 2024 09:25
Copy link
Member

@DaniPopes DaniPopes left a comment

Choose a reason for hiding this comment

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

lgtm

@yash-atreya yash-atreya merged commit c59d97e into master Sep 26, 2024
21 checks passed
@yash-atreya yash-atreya deleted the yash/vm-get-artifact-path branch September 26, 2024 10:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

feat(cheatcodes): add a vm.getArtifactPath cheatcode that gets the artifact path for a given contract address
4 participants