Skip to content

Commit 2d11fd4

Browse files
fix codegen failure with nonreentrant keys
codegen now fails (stops compiling) as of eae0eaf. This is because the storage layout is generated correctly but the type metadata is not updated after the first function that references a nonreentrancy key. This commit also adds a codegen test to check codegen of repeated nonreentrancy keys.
1 parent 4b9d860 commit 2d11fd4

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

tests/parser/features/decorators/test_nonreentrant.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ def updated_protected():
2323
interface Callback:
2424
def updated(): nonpayable
2525
def updated_protected(): nonpayable
26+
interface Self:
27+
def protected_function2(val: String[100], do_callback: bool) -> uint256: nonpayable
2628
2729
special_value: public(String[100])
2830
callback: public(Callback)
@@ -42,6 +44,15 @@ def protected_function(val: String[100], do_callback: bool) -> uint256:
4244
else:
4345
return 2
4446
47+
@external
48+
@nonreentrant('protect_special_value')
49+
def protected_function2(val: String[100], do_callback: bool) -> uint256:
50+
self.special_value = val
51+
if do_callback:
52+
Self(self).protected_function2(val, False)
53+
return 1
54+
return 2
55+
4556
@external
4657
def unprotected_function(val: String[100], do_callback: bool):
4758
self.special_value = val
@@ -66,6 +77,12 @@ def unprotected_function(val: String[100], do_callback: bool):
6677

6778
assert_tx_failed(lambda: reentrant_contract.protected_function("zzz value", True, transact={}))
6879

80+
reentrant_contract.protected_function2("another value", False, transact={})
81+
assert reentrant_contract.special_value() == "another value"
82+
83+
assert_tx_failed(lambda: reentrant_contract.protected_function2("zzz value", True, transact={}))
84+
85+
6986

7087
def test_disallow_on_init_function(get_contract):
7188
# nonreentrant has no effect when used on the __init__ fn

vyper/semantics/validation/data_positions.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,11 @@ def set_storage_slots(vyper_module: vy_ast.Module) -> StorageLayout:
3838
variable_name = f"nonreentrant.{type_.nonreentrant}"
3939

4040
# a nonreentrant key can appear many times in a module but it
41-
# only takes one slot. ignore it after the first time we see it.
41+
# only takes one slot. after the first time we see it, do not
42+
# increment the storage slot.
4243
if variable_name in ret:
44+
_slot = ret[variable_name]["slot"]
45+
type_.set_reentrancy_key_position(StorageSlot(_slot))
4346
continue
4447

4548
type_.set_reentrancy_key_position(StorageSlot(storage_slot))

0 commit comments

Comments
 (0)