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: Add bb and bb_runtime output options #3700

Merged
43 changes: 29 additions & 14 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@ def pytest_addoption(parser):
parser.addoption("--enable-compiler-debug-mode", action="store_true")


@pytest.fixture(scope="module")
def output_formats():
output_formats = compiler.OUTPUT_FORMATS.copy()
del output_formats["bb"]
del output_formats["bb_runtime"]
return output_formats


@pytest.fixture(scope="module")
def optimize(pytestconfig):
flag = pytestconfig.getoption("optimize")
Expand Down Expand Up @@ -281,15 +289,22 @@ def ir_compiler(ir, *args, **kwargs):


def _get_contract(
w3, source_code, optimize, *args, override_opt_level=None, input_bundle=None, **kwargs
w3,
source_code,
optimize,
output_formats,
*args,
override_opt_level=None,
input_bundle=None,
**kwargs,
):
settings = Settings()
settings.evm_version = kwargs.pop("evm_version", None)
settings.optimize = override_opt_level or optimize
out = compiler.compile_code(
source_code,
# test that all output formats can get generated
output_formats=list(compiler.OUTPUT_FORMATS.keys()),
output_formats=output_formats,
settings=settings,
input_bundle=input_bundle,
show_gas_estimates=True, # Enable gas estimates for testing
Expand All @@ -309,17 +324,17 @@ def _get_contract(


@pytest.fixture(scope="module")
def get_contract(w3, optimize):
def get_contract(w3, optimize, output_formats):
def fn(source_code, *args, **kwargs):
return _get_contract(w3, source_code, optimize, *args, **kwargs)
return _get_contract(w3, source_code, optimize, output_formats, *args, **kwargs)

return fn


@pytest.fixture
def get_contract_with_gas_estimation(tester, w3, optimize):
def get_contract_with_gas_estimation(tester, w3, optimize, output_formats):
def get_contract_with_gas_estimation(source_code, *args, **kwargs):
contract = _get_contract(w3, source_code, optimize, *args, **kwargs)
contract = _get_contract(w3, source_code, optimize, output_formats, *args, **kwargs)
for abi_ in contract._classic_contract.functions.abi:
if abi_["type"] == "function":
set_decorator_to_contract_function(w3, tester, contract, source_code, abi_["name"])
Expand All @@ -329,15 +344,15 @@ def get_contract_with_gas_estimation(source_code, *args, **kwargs):


@pytest.fixture
def get_contract_with_gas_estimation_for_constants(w3, optimize):
def get_contract_with_gas_estimation_for_constants(w3, optimize, output_formats):
def get_contract_with_gas_estimation_for_constants(source_code, *args, **kwargs):
return _get_contract(w3, source_code, optimize, *args, **kwargs)
return _get_contract(w3, source_code, optimize, output_formats, *args, **kwargs)

return get_contract_with_gas_estimation_for_constants


@pytest.fixture(scope="module")
def get_contract_module(optimize):
def get_contract_module(optimize, output_formats):
"""
This fixture is used for Hypothesis tests to ensure that
the same contract is called over multiple runs of the test.
Expand All @@ -350,18 +365,18 @@ def get_contract_module(optimize):
w3.eth.set_gas_price_strategy(zero_gas_price_strategy)

def get_contract_module(source_code, *args, **kwargs):
return _get_contract(w3, source_code, optimize, *args, **kwargs)
return _get_contract(w3, source_code, optimize, output_formats, *args, **kwargs)

return get_contract_module


def _deploy_blueprint_for(w3, source_code, optimize, initcode_prefix=b"", **kwargs):
def _deploy_blueprint_for(w3, source_code, optimize, output_formats, initcode_prefix=b"", **kwargs):
settings = Settings()
settings.evm_version = kwargs.pop("evm_version", None)
settings.optimize = optimize
out = compiler.compile_code(
source_code,
output_formats=list(compiler.OUTPUT_FORMATS.keys()),
output_formats=output_formats,
settings=settings,
show_gas_estimates=True, # Enable gas estimates for testing
)
Expand Down Expand Up @@ -394,9 +409,9 @@ def factory(address):


@pytest.fixture(scope="module")
def deploy_blueprint_for(w3, optimize):
def deploy_blueprint_for(w3, optimize, output_formats):
def deploy_blueprint_for(source_code, *args, **kwargs):
return _deploy_blueprint_for(w3, source_code, optimize, *args, **kwargs)
return _deploy_blueprint_for(w3, source_code, optimize, output_formats, *args, **kwargs)

return deploy_blueprint_for

Expand Down
11 changes: 8 additions & 3 deletions tests/unit/cli/vyper_json/test_compile_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,18 +113,23 @@ def test_keyerror_becomes_jsonerror(input_json):

def test_compile_json(input_json, input_bundle):
foo_input = input_bundle.load_file("contracts/foo.vy")
# remove bb and bb_runtime from output formats
# because they require venom (experimental)
output_formats = OUTPUT_FORMATS.copy()
del output_formats["bb"]
del output_formats["bb_runtime"]
foo = compile_from_file_input(
foo_input, output_formats=OUTPUT_FORMATS, input_bundle=input_bundle
foo_input, output_formats=output_formats, input_bundle=input_bundle
)

library_input = input_bundle.load_file("contracts/library.vy")
library = compile_from_file_input(
library_input, output_formats=OUTPUT_FORMATS, input_bundle=input_bundle
library_input, output_formats=output_formats, input_bundle=input_bundle
)

bar_input = input_bundle.load_file("contracts/bar.vy")
bar = compile_from_file_input(
bar_input, output_formats=OUTPUT_FORMATS, input_bundle=input_bundle
bar_input, output_formats=output_formats, input_bundle=input_bundle
)

compile_code_results = {
Expand Down
4 changes: 4 additions & 0 deletions vyper/compiler/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
# requires ir_node
"external_interface": output.build_external_interface_output,
"interface": output.build_interface_output,
"bb": output.build_bb_output,
"bb_runtime": output.build_bb_runtime_output,
"ir": output.build_ir_output,
"ir_runtime": output.build_ir_runtime_output,
"ir_dict": output.build_ir_dict_output,
Expand Down Expand Up @@ -84,6 +86,8 @@ def compile_from_file_input(
two arguments - the name of the contract, and the exception that was raised
no_bytecode_metadata: bool, optional
Do not add metadata to bytecode. Defaults to False
experimental_codegen: bool
Use experimental codegen. Defaults to False

Returns
-------
Expand Down
8 changes: 8 additions & 0 deletions vyper/compiler/output.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,14 @@ def build_interface_output(compiler_data: CompilerData) -> str:
return out


def build_bb_output(compiler_data: CompilerData) -> IRnode:
return compiler_data.venom_functions[0]


def build_bb_runtime_output(compiler_data: CompilerData) -> IRnode:
return compiler_data.venom_functions[1]


def build_ir_output(compiler_data: CompilerData) -> IRnode:
if compiler_data.show_gas_estimates:
IRnode.repr_show_gas = True
Expand Down
8 changes: 2 additions & 6 deletions vyper/compiler/phases.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,9 +174,7 @@ def global_ctx(self) -> ModuleT:
@cached_property
def _ir_output(self):
# fetch both deployment and runtime IR
return generate_ir_nodes(
self.global_ctx, self.settings.optimize, self.settings.experimental_codegen
)
return generate_ir_nodes(self.global_ctx, self.settings.optimize)

@property
def ir_nodes(self) -> IRnode:
Expand Down Expand Up @@ -272,9 +270,7 @@ def generate_annotated_ast(
return vyper_module, symbol_tables


def generate_ir_nodes(
global_ctx: ModuleT, optimize: OptimizationLevel, experimental_codegen: bool
) -> tuple[IRnode, IRnode]:
def generate_ir_nodes(global_ctx: ModuleT, optimize: OptimizationLevel) -> tuple[IRnode, IRnode]:
"""
Generate the intermediate representation (IR) from the contextualized AST.

Expand Down
Loading