Skip to content

Conversation

grandizzy
Copy link
Collaborator

@grandizzy grandizzy commented Sep 9, 2025

Motivation

  • some tests are writing files using writeFile cheatcode and then reading with readFile cheatcode and assert content
  • encountered race condition on one project where readFile issued after several writes in the same file failed with
├─ [0] VM::keyExists("<JSON file>", ".addresses.accessManager") [staticcall]
    │   └─ ← [Revert] vm.keyExists: failed parsing JSON: EOF while parsing a value at line 1 column 0
    └─ ← [Revert] vm.keyExists: failed parsing JSON: EOF while parsing a value at line 1 column 0

even if traces were showing write just above the read
image

Solution

  • introduce fs utility functions to lock/unlock file on write and lock_shared/unlock on read. Adds new fs errors variant for lock and unlock file

PR Checklist

  • Added Tests
  • Added Documentation
  • Breaking changes

0xrusowsky
0xrusowsky previously approved these changes Sep 9, 2025
Copy link
Contributor

@0xrusowsky 0xrusowsky left a comment

Choose a reason for hiding this comment

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

i think this makes sense

@zerosnacks
Copy link
Member

Makes sense to me, small nit

zerosnacks
zerosnacks previously approved these changes Sep 10, 2025
Copy link
Contributor

@onbjerg onbjerg left a comment

Choose a reason for hiding this comment

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

is it important that we flush all data (incl metadata) to disk for this to work? or can we just do File::sync_data?

@grandizzy
Copy link
Collaborator Author

is it important that we flush all data (incl metadata) to disk for this to work? or can we just do File::sync_data?

good point, yeah, I guess we can omit metadata

@DaniPopes
Copy link
Member

DaniPopes commented Sep 10, 2025

this makes sense however i wonder if we should lock the file instead of syncing during cheatcode execution? this is on stable now so you can just call file.lock() for write, .lock_shared() for read, and .unlock() and should avoid fs

@grandizzy
Copy link
Collaborator Author

this makes sense however i wonder if we should lock the file instead of syncing during cheatcode execution? this is on stable now so you can just call file.lock() for write, .lock_shared() for read, and .unlock() and should avoid fs

warning: current MSRV (Minimum Supported Rust Version) is `1.88.0` but this item is stable since `1.89.0`
   --> crates/cheatcodes/src/fs.rs:154:14
    |
154 |         file.lock_shared()?;

should I bump?

@DaniPopes
Copy link
Member

yes

@grandizzy grandizzy marked this pull request as draft September 10, 2025 16:54
@grandizzy
Copy link
Collaborator Author

grandizzy commented Sep 11, 2025

yes

done, please recheck. CI failure due to new node not supporting wss, will ask to open. thanks

@grandizzy grandizzy marked this pull request as ready for review September 11, 2025 08:05
@grandizzy grandizzy requested a review from DaniPopes September 12, 2025 05:30
@DaniPopes
Copy link
Member

please update title/description

@grandizzy grandizzy changed the title fix(cheatcodes): ensure file sync on vm.writeFile fix(cheatcodes): lock files on reads / writes Sep 12, 2025
@grandizzy grandizzy merged commit a8dc5ae into foundry-rs:master Sep 12, 2025
25 checks passed
@github-project-automation github-project-automation bot moved this to Done in Foundry Sep 12, 2025
@grandizzy grandizzy deleted the write-sync branch September 12, 2025 12:48
@grandizzy grandizzy self-assigned this Sep 15, 2025
@grandizzy grandizzy moved this from Done to Completed in Foundry Sep 15, 2025
MerkleBoy pushed a commit to MerkleBoy/foundry that referenced this pull request Sep 17, 2025
* fix(cheatcodes): ensure file sync on vm.writeFile

* Consolidate common fs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Completed
Development

Successfully merging this pull request may close these issues.

5 participants