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 for snapshot cheatcodes #427

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open

feat: support for snapshot cheatcodes #427

wants to merge 12 commits into from

Conversation

daejunpark
Copy link
Collaborator

@daejunpark daejunpark commented Dec 11, 2024

support for state and storage snapshots:

  • svm.snapshotStorage(address)
  • vm.snapshotState()

note: two structurally identical symbolic storages/states are given the same snapshot id, but those that are semantically equivalent may not be assigned the same snapshot id. (see SnapshotTest for examples.)

Copy link
Collaborator

@karmacoma-eth karmacoma-eth left a comment

Choose a reason for hiding this comment

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

incredibly straightforward 👌

@daejunpark daejunpark changed the title feat: support for snapshotStorage(address) cheatcode feat: support for snapshot cheatcodes Dec 12, 2024
"""
Generates a snapshot ID by hashing the current state (code, storage, and balance).
"""
m = hashlib.sha3_256()
Copy link
Collaborator

Choose a reason for hiding this comment

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

since we don't need the hash to be cryptographically secure for this, we'd be better off using a high quality regular hash function like xxh3_64 from https://pypi.org/project/xxhash/, about 10x faster:

# built-in sha3_256, not keccak
$ python -m timeit --setup="from hashlib import sha3_256" "sha3_256(b'').digest()"
500000 loops, best of 5: 892 nsec per loop

# xxh64, requires `pip install xxhash`
$ python -m timeit --setup="from xxhash import xxh64_digest" "xxh64_digest(b'')"
2000000 loops, best of 5: 101 nsec per loop

# xxh3_64, requires `pip install xxhash`
$ python -m timeit --setup="from xxhash import xxh3_64_digest" "xxh3_64_digest(b'')"
5000000 loops, best of 5: 98.3 nsec per loop

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

thanks for suggestion!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

wdyt? 7d08e7a

addr = addr if isinstance(addr, int) else addr.as_long()
m.update(int.to_bytes(addr, length=32))
# simply the object address is used, as code remains unchanged after deployment
m.update(int.to_bytes(id(code), length=32))
Copy link
Collaborator

Choose a reason for hiding this comment

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

spidey sense: I would normally avoid using the value of id in computations, since it changes from run to run

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

agree, but it's acceptable in this case. actually, i'm not sure if z3.get_id() would be guaranteed to be deterministic. we also use uuid() for unique variable naming, so they would change from run to run anyway.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants