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

vyper 0.4.0 support #179

Merged
merged 79 commits into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
f7813ff
track vyper master branch
charles-cooper Feb 13, 2024
672b168
update boa to use new APIs
charles-cooper Feb 13, 2024
725d4bd
update unit tests to use new @deploy modifier
charles-cooper Feb 13, 2024
592c602
fix internal functions
charles-cooper Feb 13, 2024
3ee3033
fix remaining tests
charles-cooper Feb 13, 2024
59b1f4b
update more tests for v0.4.0
charles-cooper Feb 13, 2024
554f233
Merge branch 'master' into vyper-0.4.0
charles-cooper Feb 13, 2024
da574d8
fix constants
charles-cooper Feb 21, 2024
f7e1bd5
Merge branch 'master' into vyper-0.4.0
charles-cooper Feb 28, 2024
7fe14fd
fix mypy
charles-cooper Feb 28, 2024
6308144
updates for some API changes
charles-cooper Feb 28, 2024
426ac8c
update a test
charles-cooper Feb 28, 2024
99a2d8e
update examples
charles-cooper Feb 28, 2024
00772ee
fixup function name
charles-cooper Feb 28, 2024
7770c99
workaround for namespace scopes
charles-cooper Feb 28, 2024
80d6e0c
update exposed_functions logic
charles-cooper Feb 28, 2024
2905c92
test updates
charles-cooper Feb 28, 2024
707cbcc
Merge branch 'master' of github.com:vyperlang/titanoboa into vyper-0.4.0
DanielSchiavini Mar 1, 2024
bcc7d91
fix for transient variables
charles-cooper Mar 7, 2024
4e43dd5
Merge branch 'master' into vyper-0.4.0
charles-cooper Mar 9, 2024
9cf289f
fix caching for modules
charles-cooper Mar 9, 2024
e6c560b
fix typos
charles-cooper Mar 9, 2024
ac21744
add a note
charles-cooper Mar 9, 2024
038f8d8
update an import for latest vyper commit
charles-cooper Mar 14, 2024
8b48cdb
Merge branch 'master' into vyper-0.4.0
charles-cooper Apr 1, 2024
52b0f73
update anchor_settings usages
charles-cooper Apr 14, 2024
2b4cd34
pass settings instead of compiler_args
charles-cooper Apr 14, 2024
50ac0fa
fix source map
charles-cooper Apr 16, 2024
8fb66a7
Merge branch 'master' into vyper-0.4.0
charles-cooper Apr 29, 2024
4ce1a70
expose private constants
DanielSchiavini May 10, 2024
4ea125f
fix test
DanielSchiavini May 10, 2024
5bfdedb
Merge branch 'master' of github.com:vyperlang/titanoboa into vyper-0.4.0
DanielSchiavini May 10, 2024
c7c06f3
Fix some tests
DanielSchiavini May 10, 2024
8e12cd7
Fix more tests
DanielSchiavini May 13, 2024
7744cba
Merge branch 'refs/heads/vyper-0.4.0' into feat/private-constants
DanielSchiavini May 13, 2024
ae553ff
Use getpos to retrieve ast source
DanielSchiavini May 13, 2024
8c67881
Merge branch 'master' of github.com:vyperlang/titanoboa into vyper-0.4.0
DanielSchiavini May 15, 2024
24c626a
Merge branch 'master' into vyper-0.4.0
charles-cooper May 16, 2024
3320554
Merge branch 'vyper-0.4.0' of github.com:vyperlang/titanoboa into vyp…
DanielSchiavini May 16, 2024
d6f0096
Interface name
DanielSchiavini May 16, 2024
6fba877
Update FileInput to match vyper-0.4.0.rc5
ritzdorf May 16, 2024
784c6b7
Add error when we cannot reach the backend
DanielSchiavini May 14, 2024
4d3478b
Update documentation
DanielSchiavini May 14, 2024
b163e16
Move Jupyter installation to README
DanielSchiavini May 14, 2024
151abf4
Merge branch 'vyper-0.4.0' of github.com:vyperlang/titanoboa into fea…
DanielSchiavini May 16, 2024
2e39bea
Merge pull request #227 from ritzdorf/patch-2
charles-cooper May 16, 2024
7cd3acb
Merge branch 'vyper-0.4.0' of github.com:vyperlang/titanoboa into vyp…
DanielSchiavini May 17, 2024
3e61164
refactor: extract _get_ir_pos function
DanielSchiavini May 17, 2024
b431d4e
Use copy.copy
DanielSchiavini May 17, 2024
625a884
Merge pull request #220 from DanielSchiavini/vyper-0.4.0
charles-cooper May 17, 2024
c643765
Merge branch 'vyper-0.4.0' of github.com:vyperlang/titanoboa into fea…
DanielSchiavini May 17, 2024
1d24c2b
Review comment
DanielSchiavini May 17, 2024
8fce5c9
Merge branch 'vyper-0.4.0' of github.com:vyperlang/titanoboa into fix…
DanielSchiavini May 21, 2024
e655529
handle stack traces in constructor
DanielSchiavini May 21, 2024
18d28bd
Merge branch 'refs/heads/fix/get-logs-constructor' into fix/get-logs-…
DanielSchiavini May 21, 2024
2d1ec97
Merge branch 'master' of github.com:vyperlang/titanoboa into vyper-0.4.0
DanielSchiavini May 22, 2024
6df6b97
Merge branch 'vyper-0.4.0' of github.com:vyperlang/titanoboa into fix…
DanielSchiavini May 22, 2024
abba158
Merge branch 'refs/heads/fix/get-logs-constructor' into fix/get-logs-…
DanielSchiavini May 22, 2024
6fd249e
Merge branch 'vyper-0.4.0' of github.com:vyperlang/titanoboa into fea…
DanielSchiavini May 24, 2024
594302d
get_folded_value + comment
DanielSchiavini May 24, 2024
94d2261
Lint
DanielSchiavini May 24, 2024
9466071
Merge pull request #215 from DanielSchiavini/feat/private-constants
charles-cooper May 24, 2024
2904dfe
Merge branch 'master' of github.com:vyperlang/titanoboa into vyper-0.4.0
DanielSchiavini May 27, 2024
aa5c7e3
Merge branch 'vyper-0.4.0' of github.com:vyperlang/titanoboa into fix…
DanielSchiavini May 27, 2024
de8fc4b
Update test to 0.4.0
DanielSchiavini May 27, 2024
0e0f9cd
Fix events for 0.4.0
DanielSchiavini May 27, 2024
a29d956
Review comments
DanielSchiavini May 29, 2024
2a3e9e8
unneeded line, it's already in base class
DanielSchiavini May 29, 2024
3330576
Fix comment typo
DanielSchiavini May 31, 2024
7576f71
Merge pull request #234 from DanielSchiavini/fix/get-logs-constructor…
charles-cooper May 31, 2024
561c293
Merge branch 'master' of github.com:vyperlang/titanoboa into vyper-0.4.0
DanielSchiavini Jun 17, 2024
cce39fc
Merge branch 'master' of github.com:vyperlang/titanoboa into vyper-0.4.0
DanielSchiavini Jun 17, 2024
67f33f5
Fix tests
DanielSchiavini Jun 17, 2024
e2fcc69
Bad print
DanielSchiavini Jun 17, 2024
be6a6c8
Merge branch 'master' into vyper-0.4.0
charles-cooper Jun 20, 2024
573d796
Merge branch 'master' of github.com:vyperlang/titanoboa into vyper-0.4.0
DanielSchiavini Jun 21, 2024
e7efc7f
fix vyper pin now that it's been released
charles-cooper Jul 19, 2024
44956ed
bump version
charles-cooper Jul 23, 2024
9f1af8c
Merge branch 'master' into vyper-0.4.0
charles-cooper Jul 23, 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
10 changes: 0 additions & 10 deletions boa/contracts/vyper/ast_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from typing import Any, Optional

import vyper.ast as vy_ast
from vyper.codegen.core import getpos


def get_block(source_code: str, lineno: int, end_lineno: int) -> str:
Expand Down Expand Up @@ -44,15 +43,6 @@ def reason_at(
return None


# build a reverse map from the format we have in pc_pos_map to AST nodes
def ast_map_of(ast_node):
ast_map = {}
nodes = [ast_node] + ast_node.get_descendants(reverse=True)
for node in nodes:
ast_map[getpos(node)] = node
return ast_map


def get_fn_name_from_lineno(ast_map: dict, lineno: int) -> str:
# TODO: this could be a performance bottleneck
for source_map, node in ast_map.items():
Expand Down
54 changes: 30 additions & 24 deletions boa/contracts/vyper/compiler_utils.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import contextlib
import textwrap

import vyper.ast as vy_ast
import vyper.semantics.analysis as analysis
from vyper.ast.utils import parse_to_ast
from vyper.codegen.core import anchor_opt_level
from vyper.codegen.function_definitions import generate_ir_for_function
from vyper.ast.parse import parse_to_ast
from vyper.codegen.function_definitions import (
generate_ir_for_external_function,
generate_ir_for_internal_function,
)
from vyper.codegen.ir_node import IRnode
from vyper.evm.opcodes import anchor_evm_version
from vyper.codegen.module import _runtime_reachable_functions
from vyper.compiler.settings import anchor_settings
from vyper.exceptions import InvalidType
from vyper.ir import compile_ir, optimizer
from vyper.semantics.analysis.utils import get_exact_type_from_node
Expand All @@ -18,13 +20,6 @@
_METHOD_ID_VAR = "_calldata_method_id"


@contextlib.contextmanager
def anchor_compiler_settings(compiler_data):
settings = compiler_data.settings
with anchor_opt_level(settings.optimize), anchor_evm_version(settings.evm_version):
yield


def compile_vyper_function(vyper_function, contract):
"""Compiles a vyper function and appends it to the top of the IR of a
contract. This is useful for vyper `eval` and internal functions, where
Expand All @@ -35,22 +30,20 @@ def compile_vyper_function(vyper_function, contract):

compiler_data = contract.compiler_data

with anchor_compiler_settings(compiler_data):
global_ctx = contract.global_ctx
ifaces = compiler_data.interface_codes
ast = parse_to_ast(vyper_function, ifaces)
vy_ast.folding.fold(ast)
with anchor_settings(compiler_data.settings):
module_t = contract.module_t
ast = parse_to_ast(vyper_function)

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

ast = ast.body[0]
func_t = ast._metadata["type"]
func_t = ast._metadata["func_type"]

external_func_info = generate_ir_for_function(ast, global_ctx, False)
ir = external_func_info.common_ir
contract.ensure_id(func_t)
funcinfo = generate_ir_for_external_function(ast, module_t)
ir = funcinfo.common_ir

entry_label = func_t._ir_info.external_function_base_entry_label

Expand All @@ -63,7 +56,20 @@ def compile_vyper_function(vyper_function, contract):
# all labels are present, and then optimize all together
# (use unoptimized IR, ir_executor can't handle optimized selector tables)
_, contract_runtime = contract.unoptimized_ir
ir = IRnode.from_list(["seq", ir, contract_runtime])
ir_list = ["seq", ir, contract_runtime]
reachable = func_t.reachable_internal_functions

already_compiled = _runtime_reachable_functions(module_t, contract)
missing_functions = reachable.difference(already_compiled)
# TODO: cache function compilations or something
for f in missing_functions:
assert f.ast_def is not None
contract.ensure_id(f)
ir_list.append(
generate_ir_for_internal_function(f.ast_def, module_t, False).func_ir
)

ir = IRnode.from_list(ir_list)
ir = optimizer.optimize(ir)

assembly = compile_ir.compile_to_assembly(ir)
Expand Down Expand Up @@ -119,7 +125,7 @@ def generate_bytecode_for_arbitrary_stmt(source_code, contract):
"""Wraps arbitrary stmts with external fn and generates bytecode"""

ast = parse_to_ast(source_code)
vy_ast.folding.fold(ast)

ast = ast.body[0]

return_sig = ""
Expand Down
45 changes: 31 additions & 14 deletions boa/contracts/vyper/ir_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@
from eth.exceptions import Revert as VMRevert
from eth.exceptions import WriteProtection
from eth_hash.auto import keccak
from vyper.ast.nodes import VyperNode
from vyper.codegen.ir_node import IRnode
from vyper.compiler.phases import CompilerData
from vyper.evm.opcodes import OPCODES
from vyper.utils import mkalphanum, unsigned_to_signed
from vyper.ir.compile_ir import getpos
from vyper.utils import unsigned_to_signed

from boa.util.lrudict import lrudict
from boa.vm.fast_mem import FastMem
Expand All @@ -27,6 +30,11 @@ def keccak256(x):
return _keccak_cache.setdefault_lambda(x, keccak)


def _mkalphanum(string):
# map a string to only-alphanumeric chars
return "".join([c if c.isalnum() else "_" for c in string])


@dataclass
class _Line:
indentation_level: int
Expand Down Expand Up @@ -97,10 +105,10 @@ def freshvar(self, name=""):

@cached_property
def contract_name(self):
return mkalphanum(PurePath(self.vyper_compiler_data.contract_name).name)
return _mkalphanum(PurePath(self.vyper_compiler_data.contract_path).name)

def translate_label(self, label):
return f"{self.contract_name}_{self.uuid}_{label}"
return _mkalphanum(f"{self.contract_name}_{self.uuid}_{label}")

def add_unique_symbol(self, symbol):
if symbol in self.unique_symbols: # pragma: no cover
Expand Down Expand Up @@ -236,7 +244,7 @@ def compile(self, out=None, out_typ=None):
def _compile(self, context): # pragma: no cover
raise RuntimeError("must be overridden in subclass!")

def compile_main(self, contract_path=""):
def compile_main(self, contract_name=""):
self.builder.extend("import vyper.utils\nimport _operator")

main_name = self.compile_ctx.translate_label("main")
Expand All @@ -248,7 +256,7 @@ def compile_main(self, contract_path=""):
self.builder.extend("\n\n")
func.compile_func()

py_file = f"{contract_path}{self.compile_ctx.uuid}.py"
py_file = f"{contract_name}{self.compile_ctx.uuid}.py"

# uncomment for debugging the python code:
# with open(py_file, "w") as f:
Expand Down Expand Up @@ -838,7 +846,7 @@ def _compile(self, test):
self.builder.extend(
f"""
if not bool({test}):
VM.vyper_source_pos = {repr(self.ir_node.source_pos)}
VM.vyper_source_pos = {repr(_get_ir_pos(self.ir_node))}
VM.vyper_error_msg = {repr(self.ir_node.error_msg)}
raise VMRevert("") # venom assert
"""
Expand All @@ -854,7 +862,7 @@ def _compile(self, ptr, size):
self.builder.extend(
f"""
VM.output = VM.memory_read_bytes({ptr}, {size})
VM.vyper_source_pos = {repr(self.ir_node.source_pos)}
VM.vyper_source_pos = {repr(_get_ir_pos(self.ir_node))}
VM.vyper_error_msg = {repr(self.ir_node.error_msg)}
raise VMRevert(VM.output) # venom revert
"""
Expand Down Expand Up @@ -1114,24 +1122,27 @@ def compile(self, **kwargs):
val.compile(out=variable.out_name, out_typ=int)


def _ensure_source_pos(ir_node, source_pos=None, error_msg=None):
if ir_node.source_pos is None:
ir_node.source_pos = source_pos
def _ensure_ast_source(
ir_node: IRnode, ast_source: VyperNode = None, error_msg: str = None
):
if ir_node.ast_source is None:
ir_node.ast_source = ast_source
if ir_node.error_msg is None:
ir_node.error_msg = error_msg
for arg in ir_node.args:
_ensure_source_pos(arg, ir_node.source_pos, ir_node.error_msg)
_ensure_ast_source(arg, ir_node.ast_source, ir_node.error_msg)


def executor_from_ir(ir_node, vyper_compiler_data) -> Any:
_ensure_source_pos(ir_node)
ret = _executor_from_ir(ir_node, CompileContext(vyper_compiler_data))
_ensure_ast_source(ir_node)
ctx = CompileContext(vyper_compiler_data)
ret = _executor_from_ir(ir_node, ctx)

ret = ret.analyze()

# TODO: rename this, this is "something.vy", but we maybe want
# "something.py <compiled from .vy>"
ret.compile_main(vyper_compiler_data.contract_name)
ret.compile_main(ctx.contract_name)
return ret


Expand All @@ -1152,3 +1163,9 @@ def _executor_from_ir(ir_node, compile_ctx) -> Any:
assert len(ir_node.args) == 0, ir_node
assert isinstance(ir_node.value, str)
return StringExecutor(compile_ctx, ir_node.value)


def _get_ir_pos(ir_node):
if ir_node.ast_source is None:
return None
return getpos(ir_node.ast_source)
Loading
Loading