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

refactor[tool]: refactor storage layout export #3789

Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
a1e97b1
add n_slots to storage variables
charles-cooper Feb 19, 2024
bf2865a
refactor storage layout export
charles-cooper Feb 19, 2024
f435166
fix tests
charles-cooper Feb 20, 2024
28084c7
Merge branch 'master' into feat/refactor-storage-layout-export
charles-cooper Mar 1, 2024
64c5048
Merge branch 'feat/improve-storage-layout-export' into feat/refactor-…
charles-cooper Mar 1, 2024
aa6b40a
Merge branch 'master' into feat/refactor-storage-layout-export
charles-cooper Apr 3, 2024
d7b84b2
update a function
charles-cooper Apr 3, 2024
22946db
move a line for consistency
charles-cooper Apr 3, 2024
3785033
fix: add reentrancy key (hardcoded)
charles-cooper Apr 3, 2024
0e7d9d6
update tests
charles-cooper Apr 3, 2024
aafa930
Merge branch 'master' into feat/refactor-storage-layout-export
charles-cooper Apr 3, 2024
4ba266a
Merge branch 'master' into feat/refactor-storage-layout-export
charles-cooper Apr 4, 2024
261b2f7
fix pop
charles-cooper Apr 4, 2024
1d9a6ef
adjust another storage layout test for cancun
charles-cooper Apr 5, 2024
941c1fe
Merge branch 'master' into feat/refactor-storage-layout-export
charles-cooper Apr 5, 2024
e1b8460
don't adjust slots for overrides
charles-cooper Apr 5, 2024
ad450b0
lint
charles-cooper Apr 5, 2024
eb9007d
Merge branch 'master' into feat/refactor-storage-layout-export
charles-cooper Apr 8, 2024
1be28b8
recurse for nonreentrant key
charles-cooper Apr 9, 2024
b120086
filter empty dicts
charles-cooper Apr 9, 2024
6d89255
Merge branch 'master' into feat/refactor-storage-layout-export
charles-cooper Apr 10, 2024
ba9e7e3
Merge branch 'master' into feat/refactor-storage-layout-export
charles-cooper May 19, 2024
169977b
fix some bugs
charles-cooper May 19, 2024
3670ece
fix lint
charles-cooper May 19, 2024
1d33134
ban storage layout overrides with modules
charles-cooper May 19, 2024
8ead85f
add a couple exceptions
charles-cooper May 19, 2024
1888896
overrides can only override storage
charles-cooper May 20, 2024
33d6ac3
clean up some code
charles-cooper May 20, 2024
8020d52
Merge branch 'master' into feat/refactor-storage-layout-export
charles-cooper May 20, 2024
f144037
fix a condition
charles-cooper May 20, 2024
5777e0d
add another override unit test
charles-cooper May 20, 2024
a2ee205
fix condition again
charles-cooper May 20, 2024
461734b
improve coverage
charles-cooper May 20, 2024
10709f6
add module overrides
charles-cooper May 20, 2024
80c6388
add tests for overrides
charles-cooper May 20, 2024
b1c1e64
add another test
charles-cooper May 20, 2024
9a37547
update comment
charles-cooper May 20, 2024
56b0928
add another test for overlap
charles-cooper May 20, 2024
8fd93d6
add a comment
charles-cooper May 20, 2024
b9acf98
enforce roundtrip equality
charles-cooper May 22, 2024
0156f99
fix tests for pre-cancun
charles-cooper May 24, 2024
84aadb7
improve panic message
charles-cooper May 24, 2024
4fb1653
lint
charles-cooper May 24, 2024
cdcfb81
remove dead argument
charles-cooper May 25, 2024
1042b90
Merge branch 'master' into feat/refactor-storage-layout-export
charles-cooper May 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
charles-cooper marked this conversation as resolved.
Show resolved Hide resolved
Empty file.
80 changes: 29 additions & 51 deletions tests/unit/cli/storage_layout/test_storage_layout.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,6 @@
from vyper.compiler import compile_code
from vyper.evm.opcodes import version_check


def _adjust_storage_layout_for_cancun(layout):
def _go(layout):
for _varname, item in layout.items():
if "slot" in item and isinstance(item["slot"], int):
item["slot"] -= 1
else:
# recurse to submodule
_go(item)

if version_check(begin="cancun"):
layout["transient_storage_layout"] = {
"$.nonreentrant_key": layout["storage_layout"].pop("$.nonreentrant_key")
}
_go(layout["storage_layout"])
from .utils import adjust_storage_layout_for_cancun


def test_storage_layout():
Expand Down Expand Up @@ -55,19 +40,18 @@ def public_foo3():
pass
"""

out = compile_code(code, output_formats=["layout"])

expected = {
"storage_layout": {
"$.nonreentrant_key": {"slot": 0, "type": "nonreentrant lock"},
"foo": {"slot": 1, "type": "HashMap[address, uint256]"},
"arr": {"slot": 2, "type": "DynArray[uint256, 3]"},
"baz": {"slot": 6, "type": "Bytes[65]"},
"bar": {"slot": 10, "type": "uint256"},
"$.nonreentrant_key": {"slot": 0, "type": "nonreentrant lock", "n_slots": 1},
"foo": {"slot": 1, "type": "HashMap[address, uint256]", "n_slots": 1},
"arr": {"slot": 2, "type": "DynArray[uint256, 3]", "n_slots": 4},
"baz": {"slot": 6, "type": "Bytes[65]", "n_slots": 4},
"bar": {"slot": 10, "type": "uint256", "n_slots": 1},
}
}
_adjust_storage_layout_for_cancun(expected)
adjust_storage_layout_for_cancun(expected)

out = compile_code(code, output_formats=["layout"])
assert out["layout"] == expected


Expand All @@ -88,12 +72,9 @@ def __init__():
"SYMBOL": {"length": 64, "offset": 0, "type": "String[32]"},
"DECIMALS": {"length": 32, "offset": 64, "type": "uint8"},
},
"storage_layout": {
"$.nonreentrant_key": {"slot": 0, "type": "nonreentrant lock"},
"name": {"slot": 1, "type": "String[32]"},
},
"storage_layout": {"name": {"slot": 1, "type": "String[32]", "n_slots": 2}},
}
_adjust_storage_layout_for_cancun(expected_layout)
adjust_storage_layout_for_cancun(expected_layout)

out = compile_code(code, output_formats=["layout"])
assert out["layout"] == expected_layout
Expand Down Expand Up @@ -137,13 +118,12 @@ def __init__():
},
},
"storage_layout": {
"$.nonreentrant_key": {"slot": 0, "type": "nonreentrant lock"},
"counter": {"slot": 1, "type": "uint256"},
"counter2": {"slot": 2, "type": "uint256"},
"a_library": {"supply": {"slot": 3, "type": "uint256"}},
"counter": {"slot": 1, "type": "uint256", "n_slots": 1},
"counter2": {"slot": 2, "type": "uint256", "n_slots": 1},
"a_library": {"supply": {"slot": 3, "type": "uint256", "n_slots": 1}},
},
}
_adjust_storage_layout_for_cancun(expected_layout)
adjust_storage_layout_for_cancun(expected_layout)

out = compile_code(code, input_bundle=input_bundle, output_formats=["layout"])
assert out["layout"] == expected_layout
Expand Down Expand Up @@ -187,13 +167,12 @@ def __init__():
},
},
"storage_layout": {
"$.nonreentrant_key": {"slot": 0, "type": "nonreentrant lock"},
"counter": {"slot": 1, "type": "uint256"},
"a_library": {"supply": {"slot": 2, "type": "uint256"}},
"counter2": {"slot": 3, "type": "uint256"},
"counter": {"slot": 1, "type": "uint256", "n_slots": 1},
"a_library": {"supply": {"slot": 2, "type": "uint256", "n_slots": 1}},
"counter2": {"slot": 3, "type": "uint256", "n_slots": 1},
},
}
_adjust_storage_layout_for_cancun(expected_layout)
adjust_storage_layout_for_cancun(expected_layout)

out = compile_code(code, input_bundle=input_bundle, output_formats=["layout"])
assert out["layout"] == expected_layout
Expand Down Expand Up @@ -271,14 +250,14 @@ def bar():
},
},
"storage_layout": {
"$.nonreentrant_key": {"slot": 0, "type": "nonreentrant lock"},
"counter": {"slot": 1, "type": "uint256"},
"lib2": {"storage_variable": {"slot": 2, "type": "uint256"}},
"counter2": {"slot": 3, "type": "uint256"},
"a_library": {"supply": {"slot": 4, "type": "uint256"}},
"$.nonreentrant_key": {"slot": 0, "type": "nonreentrant lock", "n_slots": 1},
"counter": {"slot": 1, "type": "uint256", "n_slots": 1},
"lib2": {"storage_variable": {"slot": 2, "type": "uint256", "n_slots": 1}},
"counter2": {"slot": 3, "type": "uint256", "n_slots": 1},
"a_library": {"supply": {"slot": 4, "type": "uint256", "n_slots": 1}},
},
}
_adjust_storage_layout_for_cancun(expected_layout)
adjust_storage_layout_for_cancun(expected_layout)

out = compile_code(code, input_bundle=input_bundle, output_formats=["layout"])
assert out["layout"] == expected_layout
Expand Down Expand Up @@ -351,16 +330,15 @@ def foo() -> uint256:
},
},
"storage_layout": {
"$.nonreentrant_key": {"slot": 0, "type": "nonreentrant lock"},
"counter": {"slot": 1, "type": "uint256"},
"counter": {"slot": 1, "type": "uint256", "n_slots": 1},
"lib2": {
"lib1": {"supply": {"slot": 2, "type": "uint256"}},
"storage_variable": {"slot": 3, "type": "uint256"},
"lib1": {"supply": {"slot": 2, "type": "uint256", "n_slots": 1}},
"storage_variable": {"slot": 3, "type": "uint256", "n_slots": 1},
},
"counter2": {"slot": 4, "type": "uint256"},
"counter2": {"slot": 4, "type": "uint256", "n_slots": 1},
},
}
_adjust_storage_layout_for_cancun(expected_layout)
adjust_storage_layout_for_cancun(expected_layout)

out = compile_code(code, input_bundle=input_bundle, output_formats=["layout"])
assert out["layout"] == expected_layout
20 changes: 12 additions & 8 deletions tests/unit/cli/storage_layout/test_storage_layout_overrides.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,20 @@
from vyper.compiler import compile_code
from vyper.exceptions import StorageLayoutException

from .utils import adjust_storage_layout_for_cancun
Fixed Show fixed Hide fixed


def test_storage_layout_overrides():
code = """
a: uint256
b: uint256"""

storage_layout_overrides = {
"a": {"type": "uint256", "slot": 1},
"b": {"type": "uint256", "slot": 0},
"a": {"type": "uint256", "slot": 1, "n_slots": 1},
"b": {"type": "uint256", "slot": 0, "n_slots": 1},
}

expected_output = {"storage_layout": storage_layout_overrides, "code_layout": {}}
expected_output = {"storage_layout": storage_layout_overrides}

out = compile_code(
code, output_formats=["layout"], storage_layout_override=storage_layout_overrides
Expand Down Expand Up @@ -61,18 +63,20 @@ def public_foo3():
"""

storage_layout_override = {
"$.nonreentrant_key": {"type": "nonreentrant lock", "slot": 8},
"foo": {"type": "HashMap[address, uint256]", "slot": 1},
"baz": {"type": "Bytes[65]", "slot": 2},
"bar": {"type": "uint256", "slot": 6},
"$.nonreentrant_key": {"type": "nonreentrant lock", "slot": 8, "n_slots": 1},
"foo": {"type": "HashMap[address, uint256]", "slot": 1, "n_slots": 1},
"baz": {"type": "Bytes[65]", "slot": 2, "n_slots": 4},
"bar": {"type": "uint256", "slot": 6, "n_slots": 1},
}

expected_output = {"storage_layout": storage_layout_override, "code_layout": {}}
expected_output = {"storage_layout": storage_layout_override}

out = compile_code(
code, output_formats=["layout"], storage_layout_override=storage_layout_override
)

adjust_storage_layout_for_cancun(expected_output, do_adjust_slots=False)

assert out["layout"] == expected_output


Expand Down
18 changes: 18 additions & 0 deletions tests/unit/cli/storage_layout/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from vyper.evm.opcodes import version_check


def adjust_storage_layout_for_cancun(layout, do_adjust_slots=True):
def _go(layout):
for _varname, item in layout.items():
if "slot" in item and isinstance(item["slot"], int):
if do_adjust_slots:
item["slot"] -= 1
else:
# recurse to submodule
_go(item)

if version_check(begin="cancun"):
nonreentrant = layout["storage_layout"].pop("$.nonreentrant_key", None)
if nonreentrant is not None:
layout["transient_storage_layout"] = {"$.nonreentrant_key": nonreentrant}
_go(layout["storage_layout"])
5 changes: 4 additions & 1 deletion vyper/compiler/phases.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from vyper.exceptions import StructureException
from vyper.ir import compile_ir, optimizer
from vyper.semantics import analyze_module, set_data_positions, validate_compilation_target
from vyper.semantics.analysis.data_positions import generate_layout_export
from vyper.semantics.types.function import ContractFunctionT
from vyper.semantics.types.module import ModuleT
from vyper.typing import StorageLayout
Expand Down Expand Up @@ -167,7 +168,9 @@ def compilation_target(self):
@cached_property
def storage_layout(self) -> StorageLayout:
module_ast = self.compilation_target
return set_data_positions(module_ast, self.storage_layout_override)
set_data_positions(module_ast, self.storage_layout_override)

return generate_layout_export(module_ast)

@property
def global_ctx(self) -> ModuleT:
Expand Down
Loading
Loading