From eca50a5c834d2b93e24e09871897a30cdab78258 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Thu, 1 Feb 2024 10:26:09 -0600 Subject: [PATCH 1/2] foundry: `vm.dumpState` skips empty accounts Update `vm.dumpState` to also skip empty accounts. Empty accounts are not particularly useful and would otherwise require a postprocessing step after the state dump to remove. Adds a unit test showing that it works and updates an old unit test as an empty account is defined by a nonce of 0, no balance and no code. If there is storage, it still counts as an empty account. cargo fmt --- crates/cheatcodes/src/evm.rs | 9 +++++---- testdata/cheats/dumpState.t.sol | 16 +++++++++++++++- .../Json/test_dump_state_empty_account.json | 1 + 3 files changed, 21 insertions(+), 5 deletions(-) create mode 100644 testdata/fixtures/Json/test_dump_state_empty_account.json diff --git a/crates/cheatcodes/src/evm.rs b/crates/cheatcodes/src/evm.rs index 5bd7750cfe29..41ae1e486049 100644 --- a/crates/cheatcodes/src/evm.rs +++ b/crates/cheatcodes/src/evm.rs @@ -97,14 +97,15 @@ impl Cheatcode for dumpStateCall { let Self { pathToStateJson } = self; let path = Path::new(pathToStateJson); - // Do not include system accounts in the dump. - let skip = |key: &Address| { + // Do not include system account or empty accounts in the dump. + let skip = |key: &Address, val: &Account| { key == &CHEATCODE_ADDRESS || key == &CALLER || key == &HARDHAT_CONSOLE_ADDRESS || key == &TEST_CONTRACT_ADDRESS || key == &ccx.caller || - key == &ccx.state.config.evm_opts.sender + key == &ccx.state.config.evm_opts.sender || + val.is_empty() }; let alloc = ccx @@ -112,7 +113,7 @@ impl Cheatcode for dumpStateCall { .journaled_state .state() .into_iter() - .filter(|(key, _)| !skip(key)) + .filter(|(key, val)| !skip(key, val)) .map(|(key, val)| { ( key, diff --git a/testdata/cheats/dumpState.t.sol b/testdata/cheats/dumpState.t.sol index 51d6eb38ab8f..acbf25baeec6 100644 --- a/testdata/cheats/dumpState.t.sol +++ b/testdata/cheats/dumpState.t.sol @@ -63,6 +63,7 @@ contract DumpStateTest is DSTest { vm.setNonce(address(0x100), 1); vm.deal(address(0x200), 1 ether); + vm.setNonce(address(0x300), 1); vm.store(address(0x300), bytes32(uint256(1)), bytes32(uint256(2))); vm.etch(address(0x400), hex"af"); @@ -85,7 +86,7 @@ contract DumpStateTest is DSTest { assertEq(0, vm.parseJsonKeys(json, string.concat(".", vm.toString(address(0x200)), ".storage")).length); assertEq(4, vm.parseJsonKeys(json, string.concat(".", vm.toString(address(0x300)))).length); - assertEq(0, vm.parseJsonUint(json, string.concat(".", vm.toString(address(0x300)), ".nonce"))); + assertEq(1, vm.parseJsonUint(json, string.concat(".", vm.toString(address(0x300)), ".nonce"))); assertEq(0, vm.parseJsonUint(json, string.concat(".", vm.toString(address(0x300)), ".balance"))); assertEq(hex"", vm.parseJsonBytes(json, string.concat(".", vm.toString(address(0x300)), ".code"))); assertEq(1, vm.parseJsonKeys(json, string.concat(".", vm.toString(address(0x300)), ".storage")).length); @@ -120,4 +121,17 @@ contract DumpStateTest is DSTest { vm.removeFile(path); } + + function testDumpStateEmptyAccount() public { + string memory path = string.concat(vm.projectRoot(), "/fixtures/Json/test_dump_state_empty_account.json"); + + SimpleContract s = new SimpleContract(); + vm.etch(address(s), hex""); + vm.resetNonce(address(s)); + + vm.dumpState(path); + string memory json = vm.readFile(path); + string[] memory keys = vm.parseJsonKeys(json, ""); + assertEq(keys.length, 0); + } } diff --git a/testdata/fixtures/Json/test_dump_state_empty_account.json b/testdata/fixtures/Json/test_dump_state_empty_account.json new file mode 100644 index 000000000000..9e26dfeeb6e6 --- /dev/null +++ b/testdata/fixtures/Json/test_dump_state_empty_account.json @@ -0,0 +1 @@ +{} \ No newline at end of file From 38c2de7feff792e21534b7d83bf373cc311099d9 Mon Sep 17 00:00:00 2001 From: Mark Tyneway Date: Thu, 1 Feb 2024 10:35:34 -0600 Subject: [PATCH 2/2] testdata: cleanup --- testdata/cheats/dumpState.t.sol | 2 ++ testdata/fixtures/Json/test_dump_state_empty_account.json | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) delete mode 100644 testdata/fixtures/Json/test_dump_state_empty_account.json diff --git a/testdata/cheats/dumpState.t.sol b/testdata/cheats/dumpState.t.sol index acbf25baeec6..387865a1bf9d 100644 --- a/testdata/cheats/dumpState.t.sol +++ b/testdata/cheats/dumpState.t.sol @@ -133,5 +133,7 @@ contract DumpStateTest is DSTest { string memory json = vm.readFile(path); string[] memory keys = vm.parseJsonKeys(json, ""); assertEq(keys.length, 0); + + vm.removeFile(path); } } diff --git a/testdata/fixtures/Json/test_dump_state_empty_account.json b/testdata/fixtures/Json/test_dump_state_empty_account.json deleted file mode 100644 index 9e26dfeeb6e6..000000000000 --- a/testdata/fixtures/Json/test_dump_state_empty_account.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file