brownie icon indicating copy to clipboard operation
brownie copied to clipboard

Support "viaIR" solc option

Open BlinkyStitt opened this issue 2 years ago • 1 comments

Overview

with solidity 0.8.13, building with IR is no longer experimental. This can lead to smaller and more gas efficient contracts.

Specification

A quick (incomplete) change:

my-project $ git diff
diff --git a/brownie-config.yaml b/brownie-config.yaml
index ed34301..eae60df 100644
--- a/brownie-config.yaml
+++ b/brownie-config.yaml
@@ -12,6 +12,7 @@ compiler:
     remappings:
       - "@OpenZeppelin=OpenZeppelin/[email protected]/contracts"
+    viaIR: False
 
 dependencies:
   - OpenZeppelin/[email protected]
diff --git a/tests/taxes/test_taxes_eth.py b/tests/taxes/test_taxes_eth.py
index 0ce8a6e..b1cc1f8 100644
brownie $ git diff
diff --git a/brownie/project/compiler/__init__.py b/brownie/project/compiler/__init__.py
index b19f6b34..d05af226 100644
--- a/brownie/project/compiler/__init__.py
+++ b/brownie/project/compiler/__init__.py
@@ -58,6 +58,7 @@ def compile_and_format(
     interface_sources: Optional[Dict[str, str]] = None,
     remappings: Optional[list] = None,
     optimizer: Optional[Dict] = None,
+    viaIR: Optional[bool] = None,
 ) -> Dict:
     """Compiles contracts and returns build data.
 
@@ -136,6 +137,7 @@ def compile_and_format(
             interface_sources=interfaces,
             remappings=remappings,
             optimizer=optimizer,
+            viaIR=viaIR,
         )
 
         output_json = compile_from_input_json(input_json, silent, allow_paths)
@@ -153,6 +155,7 @@ def generate_input_json(
     interface_sources: Optional[Dict[str, str]] = None,
     remappings: Optional[list] = None,
     optimizer: Optional[Dict] = None,
+    viaIR: Optional[bool] = None,
 ) -> Dict:
 
     """Formats contracts to the standard solc input json.
@@ -166,6 +169,7 @@ def generate_input_json(
         interface_sources: dictionary of interfaces as {'path': "source code"}
         remappings: list of solidity path remappings
         optimizer: dictionary of solidity optimizer settings
+        viaIR: Change compilation pipeline to go through the Yul intermediate representation.
 
     Returns: dict
     """
@@ -188,6 +192,8 @@ def generate_input_json(
     if language == "Solidity":
         input_json["settings"]["optimizer"] = optimizer
         input_json["settings"]["remappings"] = _get_solc_remappings(remappings)
+        if viaIR is not None:
+            input_json["settings"]["viaIR"] = viaIR
     input_json["sources"] = _sources_dict(contract_sources, language)
 
     if interface_sources:
diff --git a/brownie/project/main.py b/brownie/project/main.py
index 7ab1f68b..6f459afc 100644
--- a/brownie/project/main.py
+++ b/brownie/project/main.py
@@ -108,6 +108,7 @@ class _ProjectBase:
                 allow_paths=allow_paths,
                 remappings=compiler_config["solc"].get("remappings", []),
                 optimizer=compiler_config["solc"].get("optimizer", None),
+                viaIR=compiler_config["solc"].get("viaIR", None),
             )
         finally:
             os.chdir(cwd)

However, that fails with this error:

my-project $ brownie compile
Brownie v1.18.1 - Python development framework for Ethereum

Compiling contracts...
  Solc version: 0.8.13
  Optimizer: Enabled  Runs: 2000
  EVM Version: London
Generating build data...
 - OpenZeppelin/[email protected]/Clones
 - CloneFactory
  File "/home/ski/code/brownie/brownie/_cli/__main__.py", line 64, in main
    importlib.import_module(f"brownie._cli.{cmd}").main()
  File "/home/ski/code/brownie/brownie/_cli/compile.py", line 50, in main
    proj = project.load()
  File "/home/ski/code/brownie/brownie/project/main.py", line 769, in load
    return Project(name, project_path)
  File "/home/ski/code/brownie/brownie/project/main.py", line 189, in __init__
    self.load()
  File "/home/ski/code/brownie/brownie/project/main.py", line 246, in load
    self._compile(changed, self._compiler_config, False)
  File "/home/ski/code/brownie/brownie/project/main.py", line 100, in _compile
    build_json = compiler.compile_and_format(
  File "/home/ski/code/brownie/brownie/project/compiler/__init__.py", line 144, in compile_and_format
    build_json.update(generate_build_json(input_json, output_json, compiler_data, silent))
  File "/home/ski/code/brownie/brownie/project/compiler/__init__.py", line 323, in generate_build_json
    build_json[contract_alias] = solidity._get_unique_build_json(
  File "/home/ski/code/brownie/brownie/project/compiler/solidity.py", line 260, in _get_unique_build_json
    pc_map, statement_map, branch_map = _generate_coverage_data(
  File "/home/ski/code/brownie/brownie/project/compiler/solidity.py", line 478, in _generate_coverage_data
    fn_node = source_nodes[contract_id].children(
IndexError: list index out of range

BlinkyStitt avatar Mar 19 '22 03:03 BlinkyStitt

I opened up a pull request addressing this issue, it seems that the « list index out of range » happens when brownie is building up coverage data with the viaIR setting activated in solc-c.

My best guest is that as mentioned in https://github.com/ethereum/solidity/blob/develop/docs/ir-breaking-changes.rst#internal-function-pointers the dispatch function pointer is causing trouble for brownie to match with function call in the specified source code offset range as the code as been completely rewritten by the optimizer in such way that correlation is not easy to manage.

The fix is about ignoring those jump where code could not be matched within the specified source code offset, the alternative would have been to match the whole contract instead.

Magicking avatar Jun 30 '22 15:06 Magicking

Curious if this ever got fixed

iskandr avatar Oct 08 '22 21:10 iskandr

Nop PR is still opened, no comments so far on this, I wonder how many are blocked by this issue.

Magicking avatar Dec 08 '22 11:12 Magicking

PR got merged. You can test the code using the latest HEAD from the master branch of the eth-brownie repository and add viaIR: True to your solc compiler option as below

$> cat brownie-config.yaml
[...]
compiler:
  solc:
    # viaIR option has been added in 0.8.13, you can adjust the version your need
    version: 0.8.13
    viaIR: True

Magicking avatar Apr 24 '23 20:04 Magicking

When is this going to be available in a release?

chrisenytc avatar Jun 25 '23 07:06 chrisenytc

You would have to wait for @iamdefinitelyahuman to ship a new package!

Magicking avatar Jun 30 '23 11:06 Magicking

This has been fixed since #1572 and this issue can be closed!

Magicking avatar Feb 10 '24 11:02 Magicking