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

chore: update vyper imports #46

Merged
merged 22 commits into from
Mar 7, 2023
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,5 +183,5 @@ Cast current deployed addresses to vyper contract

basic tests:
```bash
$ python -m tests.sim_veYFI
$ python -m tests.integration.sim_veYFI
```
14 changes: 7 additions & 7 deletions boa/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,10 @@ def anchor(self):
setattr(self, attr, snap[attr])


AddressT = Union[Address, bytes, str] # make mypy happy
AddressType = Union[Address, bytes, str] # make mypy happy


def _addr(addr: AddressT) -> Address:
def _addr(addr: AddressType) -> Address:
return Address(to_canonical_address(addr))


Expand Down Expand Up @@ -395,7 +395,7 @@ def get_singleton(cls):
cls._singleton = cls()
return cls._singleton

def generate_address(self, alias: Optional[str] = None) -> AddressT:
def generate_address(self, alias: Optional[str] = None) -> AddressType:
self._address_counter += 1
t = self._address_counter.to_bytes(length=20, byteorder="big")
# checksum addr easier for humans to debug
Expand All @@ -407,8 +407,8 @@ def generate_address(self, alias: Optional[str] = None) -> AddressT:

def deploy_code(
self,
deploy_to: AddressT = constants.ZERO_ADDRESS,
sender: Optional[AddressT] = None,
deploy_to: AddressType = constants.ZERO_ADDRESS,
sender: Optional[AddressType] = None,
gas: int = None,
value: int = 0,
bytecode: bytes = b"",
Expand Down Expand Up @@ -439,8 +439,8 @@ def deploy_code(

def execute_code(
self,
to_address: AddressT = constants.ZERO_ADDRESS,
sender: AddressT = None,
to_address: AddressType = constants.ZERO_ADDRESS,
sender: AddressType = None,
gas: int = None,
value: int = 0,
bytecode: bytes = b"",
Expand Down
1 change: 0 additions & 1 deletion boa/test/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ def pytest_configure(config):

@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_call(item: pytest.Item) -> Generator:

if not item.get_closest_marker("ignore_isolation"):
with boa.env.anchor():
yield
Expand Down
4 changes: 2 additions & 2 deletions boa/vm/fork.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def fetch(self, payload):

if len(batch) > 0:
res = self._raw_fetch_multi(batch)
for (i, s) in res.items():
for i, s in res.items():
k = ks[i]
ret[i] = s
self._db[k] = json.dumps(s).encode("utf-8")
Expand All @@ -115,7 +115,7 @@ def _mk_key(self, method: str, params: Any) -> Any:
def _raw_fetch_multi(self, payloads):
# TODO: batch requests
req = []
for (i, method, params) in payloads:
for i, method, params in payloads:
req.append({"jsonrpc": "2.0", "method": method, "params": params, "id": i})
res = self._session.post(self._rpc_url, json=req, timeout=TIMEOUT)
res.raise_for_status()
Expand Down
12 changes: 6 additions & 6 deletions boa/vyper/compiler_utils.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import textwrap

import vyper.ast as vy_ast
import vyper.semantics.validation as validation
import vyper.semantics.analysis as analysis
from vyper.ast.signatures.function_signature import FunctionSignature
from vyper.ast.utils import parse_to_ast
from vyper.codegen.function_definitions import generate_ir_for_function
from vyper.codegen.ir_node import IRnode
from vyper.exceptions import InvalidType
from vyper.ir import compile_ir as compile_ir
from vyper.semantics.validation.utils import get_exact_type_from_node
from vyper.utils import abi_method_id
from vyper.semantics.analysis.utils import get_exact_type_from_node
from vyper.utils import method_id_int

from boa.vyper import _METHOD_ID_VAR

Expand All @@ -28,8 +28,8 @@ def _compile_vyper_function(vyper_function, contract):

# override namespace and add wrapper code at the top
with contract.override_vyper_namespace():
validation.add_module_namespace(ast, ifaces)
validation.validate_functions(ast)
analysis.add_module_namespace(ast, ifaces)
analysis.validate_functions(ast)

ast = ast.body[0]
sig = FunctionSignature.from_definition(ast, global_ctx)
Expand All @@ -39,7 +39,7 @@ def _compile_vyper_function(vyper_function, contract):
ir = generate_ir_for_function(ast, sigs, global_ctx, False)

ir = IRnode.from_list(
["with", _METHOD_ID_VAR, abi_method_id(sig.base_signature), ir]
["with", _METHOD_ID_VAR, method_id_int(sig.base_signature), ir]
)
assembly = compile_ir.compile_to_assembly(ir, no_optimize=True)

Expand Down
43 changes: 20 additions & 23 deletions boa/vyper/contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,29 @@
import copy
import warnings
from dataclasses import dataclass
from functools import cached_property
from typing import Any, Optional

import vyper
import vyper.ast as vy_ast
import vyper.ir.compile_ir as compile_ir
import vyper.semantics.analysis as analysis
import vyper.semantics.namespace as vy_ns
import vyper.semantics.validation as validation
from eth.exceptions import VMError
from eth_typing import Address
from eth_utils import to_canonical_address, to_checksum_address
from vyper.ast.utils import parse_to_ast
from vyper.codegen.core import calculate_type_for_external_return
from vyper.codegen.function_definitions import generate_ir_for_function
from vyper.codegen.ir_node import IRnode
from vyper.codegen.module import parse_external_interfaces
from vyper.codegen.types.types import MappingType, TupleType, is_base_type
from vyper.compiler import output as compiler_output
from vyper.exceptions import VyperException
from vyper.ir.optimizer import optimize
from vyper.semantics.validation.data_positions import set_data_positions
from vyper.utils import abi_method_id, cached_property
from vyper.semantics.analysis.data_positions import set_data_positions
from vyper.semantics.types import AddressT, HashMapT, TupleT, is_type_t
from vyper.utils import method_id_int

from boa.environment import AddressT, Env, to_int
from boa.environment import AddressType, Env, to_int
from boa.profiling import LineProfile
from boa.util.exceptions import strip_internal_frames
from boa.util.lrudict import lrudict
Expand Down Expand Up @@ -72,7 +72,7 @@ def deploy(self, *args, **kwargs):
def deploy_as_blueprint(self, *args, **kwargs):
return VyperBlueprint(self.compiler_data, *args, **kwargs)

def at(self, address: AddressT) -> "VyperContract":
def at(self, address: AddressType) -> "VyperContract":
address = to_checksum_address(address)
ret = VyperContract(
self.compiler_data, override_address=address, skip_init=True
Expand Down Expand Up @@ -363,7 +363,7 @@ def _dealias(self, maybe_address):
return maybe_address

def get(self, truncate_limit=None):
if isinstance(self.typ, MappingType):
if is_type_t(self.typ, HashMapT):
tserg marked this conversation as resolved.
Show resolved Hide resolved
ret = {}
for k in self.contract.env.sstore_trace.get(self.contract.address, {}):
path = unwrap_storage_key(self.contract.env.sha3_trace, k)
Expand All @@ -386,7 +386,7 @@ def get(self, truncate_limit=None):
# decode aliases as needed/possible
dealiased_path = []
for p, t in zip(path, path_t):
if is_base_type(t, "address"):
if is_type_t(t, AddressT):
tserg marked this conversation as resolved.
Show resolved Hide resolved
p = self._dealias(p)
dealiased_path.append(p)
setpath(ret, dealiased_path, val)
Expand All @@ -401,7 +401,7 @@ def get(self, truncate_limit=None):
class StorageModel:
def __init__(self, contract):
compiler_data = contract.compiler_data
for k, v in compiler_data.global_ctx._globals.items():
for k, v in compiler_data.global_ctx.variables.items():
is_storage = not v.is_immutable
if is_storage: # check that v
slot = compiler_data.storage_layout["storage_layout"][k]["slot"]
Expand Down Expand Up @@ -430,7 +430,7 @@ def __init__(
# add all exposed functions from the interface to the contract
external_fns = {
fn.name: fn
for fn in self.global_ctx._function_defs
for fn in self.global_ctx.functions
if fn._metadata["type"].is_external
}

Expand All @@ -444,7 +444,7 @@ def __init__(

# set internal methods as class.internal attributes:
self.internal = lambda: None
for fn in self.global_ctx._function_defs:
for fn in self.global_ctx.functions:
if not fn._metadata["type"].is_internal:
continue
setattr(self.internal, fn.name, VyperInternalFunction(fn, self))
Expand Down Expand Up @@ -614,7 +614,7 @@ def decode_log(self, e):
abi_decode(typ.abi_type.selector_name(), encoded_topic)
)

tuple_typ = TupleType(arg_typs)
tuple_typ = TupleT(arg_typs)

args = abi_decode(tuple_typ.abi_type.selector_name(), data)

Expand All @@ -633,13 +633,13 @@ def marshal_to_python(self, computation, vyper_typ):
ret = abi_decode(return_typ.abi_type.selector_name(), computation.output)

# unwrap the tuple if needed
if not isinstance(vyper_typ, TupleType):
if not isinstance(vyper_typ, TupleT):
(ret,) = ret

# eth_abi does not checksum addresses. patch this in a limited
# way here, but for complex return types, we need an upstream
# fix.
if is_base_type(vyper_typ, "address"):
if is_type_t(vyper_typ, AddressT):
tserg marked this conversation as resolved.
Show resolved Hide resolved
ret = to_checksum_address(ret)

return vyper_object(ret, vyper_typ)
Expand Down Expand Up @@ -676,8 +676,8 @@ def _ast_module(self):
# do the same thing as vyper_module_folded but skip getter expansion
vy_ast.folding.fold(module)
with vy_ns.get_namespace().enter_scope():
validation.add_module_namespace(module, self.compiler_data.interface_codes)
validation.validate_functions(module)
analysis.add_module_namespace(module, self.compiler_data.interface_codes)
analysis.validate_functions(module)
# we need to cache the namespace right here(!).
# set_data_positions will modify the type definitions in place.
self._cache_namespace(vy_ns.get_namespace())
Expand Down Expand Up @@ -707,7 +707,7 @@ def override_vyper_namespace(self):
with vy_ns.override_global_namespace(self._vyper_namespace):
yield
finally:
self._vyper_namespace["self"].members.pop("__boa_debug__", None)
self._vyper_namespace["self"].typ.members.pop("__boa_debug__", None)

# for eval(), we need unoptimized assembly, since the dead code
# eliminator might prune a dead function (which we want to eval)
Expand Down Expand Up @@ -785,16 +785,13 @@ def inject_function(self, fn_source_code, force=False):

# ensure self._vyper_namespace is computed
m = self._ast_module # noqa: F841
self._vyper_namespace["self"].members.pop(fn_ast.name, None)
self._vyper_namespace["self"].typ.members.pop(fn_ast.name, None)
f = _InjectVyperFunction(self, fn_source_code)
setattr(self.inject, fn_ast.name, f)

@cached_property
def _sigs(self):
sigs = {}
global_ctx = self.compiler_data.global_ctx
if global_ctx._contracts or global_ctx._interfaces:
sigs = parse_external_interfaces(sigs, global_ctx)
sigs["self"] = self.compiler_data.function_signatures
return sigs

Expand Down Expand Up @@ -858,7 +855,7 @@ def args_abi_type(self, num_kwargs):
args_abi_type = (
"(" + ",".join(arg.typ.abi_type.selector_name() for arg in sig_args) + ")"
)
method_id = abi_method_id(self.fn_signature.name + args_abi_type).to_bytes(
method_id = method_id_int(self.fn_signature.name + args_abi_type).to_bytes(
4, "big"
)
self._signature_cache[num_kwargs] = (method_id, args_abi_type)
Expand Down
34 changes: 18 additions & 16 deletions boa/vyper/decoder_utils.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
from eth_utils import to_checksum_address
from vyper.codegen.types.types import (
ByteArrayType,
DArrayType,
SArrayType,
StringType,
is_base_type,
is_bytes_m_type,
is_integer_type,
from vyper.semantics.types import (
AddressT,
BoolT,
BytesM_T,
DArrayT,
IntegerT,
SArrayT,
StringT,
_BytestringT,
is_type_t,
)
from vyper.utils import unsigned_to_signed

Expand Down Expand Up @@ -44,32 +46,32 @@ def __getitem__(self, subscript):


def decode_vyper_object(mem, typ):
if is_bytes_m_type(typ):
if is_type_t(typ, BytesM_T):
tserg marked this conversation as resolved.
Show resolved Hide resolved
# TODO tag return value like `vyper_object` does
return mem[: typ._bytes_info.m].tobytes()
if is_base_type(typ, "address"):
if is_type_t(typ, AddressT):
return to_checksum_address(mem[12:32].tobytes())
if is_base_type(typ, "bool"):
if is_type_t(typ, BoolT):
return bool.from_bytes(mem[31:32], "big")
if is_integer_type(typ):
if is_type_t(typ, IntegerT):
ret = int.from_bytes(mem[:32], "big")
if typ._int_info.is_signed:
return unsigned_to_signed(ret, 256)
return ret
if isinstance(typ, ByteArrayType):
if is_type_t(typ, _BytestringT):
length = int.from_bytes(mem[:32], "big")
return mem[32 : 32 + length].tobytes()
if isinstance(typ, StringType):
if is_type_t(typ, StringT):
length = int.from_bytes(mem[:32], "big")
return mem[32 : 32 + length].tobytes().decode("utf-8")
if isinstance(typ, SArrayType):
if is_type_t(typ, SArrayT):
length = typ.count
n = typ.subtype.memory_bytes_required
return [
decode_vyper_object(mem[i * n : i * n + n], typ.subtype)
for i in range(length)
]
if isinstance(typ, DArrayType):
if is_type_t(typ, DArrayT):
length = int.from_bytes(mem[:32], "big")
n = typ.subtype.memory_bytes_required
ofst = 32
Expand Down
2 changes: 1 addition & 1 deletion boa/vyper/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
class Event:
log_id: int # internal py-evm log id, for ordering purposes
address: str # checksum address
event_type: Any # vyper.semantics.types.user.Event
event_type: Any # vyper.semantics.types.user.EventT
topics: List[Any] # list of decoded topics
args: List[Any] # list of decoded args

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ classifiers = ["Topic :: Software Development"]

# Requirements
dependencies = [
"vyper >= 0.3.7",
"vyper @ git+https://github.com/vyperlang/vyper.git@master",
tserg marked this conversation as resolved.
Show resolved Hide resolved
"eth-abi",
"py-evm",
"eth-typing",
Expand Down
4 changes: 2 additions & 2 deletions tests/integration/sim_veYFI.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,14 @@ def format_addr(t):
_rewards_pool_address = format_addr("rewards_pool")

veYFI = boa.load(
"tests/veYFI.vy",
"tests/integration/veYFI.vy",
YFI.address,
_rewards_pool_address,
override_address=format_addr("veYFI"),
)
timeit("load veYFI")
rewards_pool = boa.load(
"tests/RewardPool.vy",
"tests/integration/RewardPool.vy",
veYFI.address,
START_TIME,
override_address=_rewards_pool_address,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ def teardown(self):


def test_state_machine_isolation(boa_contract):

StateMachine.contract = boa_contract
StateMachine.settings = {
"max_examples": 5,
Expand Down
2 changes: 1 addition & 1 deletion tests/unitary/test/test_isolation.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def test_hypothesis_isolation(boa_contract, a, b):
assert boa_contract.b() == B_INIT
boa_contract.set_vars(a, b)
assert boa_contract.a() == a
assert boa_contract.b() == b
assert boa_contract.b() == b.lower()


# test isolation of pytest items
Expand Down