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

[WIP] Standard Solc Compile (Multiversion) #2051

Closed
wants to merge 24 commits into from

Conversation

KPrasch
Copy link
Member

@KPrasch KPrasch commented May 27, 2020

Based on #1831, #2078; Needs rebase pre-merge.

What this does

TODO

  • Multi-version remote management
  • Arrange Constants
  • Unskip upgradeabilty test

@KPrasch KPrasch requested a review from vzotova May 27, 2020 11:03
@KPrasch KPrasch added Code Quality 🔧 Pertaining to code quality improvements Configuration Node configuration ETH Contracts labels May 27, 2020
@KPrasch KPrasch force-pushed the compile-std branch 5 times, most recently from f4b2e95 to 3c61a2b Compare June 6, 2020 00:27
@codecov
Copy link

codecov bot commented Jun 6, 2020

Codecov Report

Merging #2051 into main will decrease coverage by 0.87%.
The diff coverage is 86.04%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #2051      +/-   ##
==========================================
- Coverage   83.64%   82.76%   -0.88%     
==========================================
  Files         102      107       +5     
  Lines       15066    14733     -333     
==========================================
- Hits        12602    12194     -408     
- Misses       2464     2539      +75     
Flag Coverage Δ
#all 82.76% <86.04%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
nucypher/blockchain/eth/multisig.py 61.17% <ø> (ø)
nucypher/characters/lawful.py 89.33% <ø> (+1.40%) ⬆️
nucypher/cli/commands/multisig.py 35.46% <ø> (ø)
nucypher/blockchain/eth/sol/compile/aggregation.py 68.51% <68.51%> (ø)
nucypher/blockchain/eth/sol/compile/solc.py 75.00% <75.00%> (ø)
nucypher/config/constants.py 94.28% <75.00%> (-5.72%) ⬇️
nucypher/blockchain/eth/interfaces.py 72.24% <88.46%> (-4.09%) ⬇️
nucypher/blockchain/eth/sol/compile/collect.py 91.30% <91.30%> (ø)
nucypher/blockchain/eth/sol/compile/compile.py 100.00% <100.00%> (ø)
nucypher/blockchain/eth/sol/compile/config.py 100.00% <100.00%> (ø)
... and 44 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 85b645c...6b378bc. Read the comment docs.

@KPrasch KPrasch force-pushed the compile-std branch 3 times, most recently from 3bbe51a to fda1f3a Compare June 7, 2020 17:34
@KPrasch KPrasch changed the title [WIP] Standard Solc Compile Standard Solc Compile Jun 8, 2020
@KPrasch KPrasch marked this pull request as ready for review June 8, 2020 18:39

class SolidityCompiler:
# TODO: Is there a better way to specify complex dictionaries with variable keys?
CompiledContracts = TypeVar('CompiledContracts', bound=Dict[str, Dict[str, List[Dict[str, Union[str, List[Dict[str, str]]]]]]])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be more readable if classes are used instead of anonymous dicts.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good Idea 👍

Copy link
Member

@vzotova vzotova left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like idea to make compilation in functional way, but right now multiversion compilation is not finished which was main idea for upgradeability test

versioned: bool = version_specifier != DEFAULT_VERSION_STRING
if versioned and new_title:
existing_title = existing_version['devdoc'].get('title')
if existing_title == new_title: # This is the same contract
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use contract name here instead of title? Because contract name we use everywhere through deploy and can control it but title is just a string

Copy link
Member Author

@KPrasch KPrasch Jun 9, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think so, but it will require passing in contract name from a higher level... unless its included elsewhere in the compiler output.

Ultimately, the reason I am using title here, is because I am only handling the compiled output of a single contract out-of-context from what contract it is.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it will be hard to get contract name then current approach is ok, but anyway I would prefer to not use title

return DEFAULT_VERSION_STRING

# RE Full Match
raw_matches = DEVDOC_VERSION_PATTERN.fullmatch(devdoc_details)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extracting constants to separate file makes such things hard to read, also these constants are mostly internal for one module of compile, so what do you think about simplify this and put them closer to code where they are used?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe move DEFAULT_VERSION_STRING here too?

# It is activated together with the global optimizer setting and can be deactivated here.
# Before Solidity 0.6.0 it had to be activated through this switch. Also see 'yulDetails options'.
yul=False
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe comment out this block? because it's unused and also some of values differ from default values

Copy link
Member Author

@KPrasch KPrasch Jun 9, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which values are different form the defaults? From the docs :

The "enabled" switch above provides two defaults which can be tweaked here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yul is true by default as far as I know, for example

f"contracts={NUCYPHER_CONTRACTS_DIR.resolve()}",
f"{ZEPPELIN}={ZEPPELIN_DIR.resolve()}",
f"{ARAGON}={ARAGON_DIR.resolve()}",
]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solidity 0.6.9 introduces --base-path option, if we specify this option as base dir for contracts (SOLIDITY_SOURCE_ROOT) then no need to use remappings option at all and also allowed paths can be removed
But not sure how to put it in configuration

nucypher/blockchain/eth/sol/compile/constants.py Outdated Show resolved Hide resolved
return compiler_output


def multiversion_compile(solidity_source_dirs: Tuple[Path, ...], compiler_version_check: bool = True) -> VersionedContractOutputs:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this method can't fully compile multiple versions from multiple sources, because tuple of paths uses same configuration including remappings. For example, we add test file that uses new logic of new main contract, and when we will test upgreadability this method will use same remmapings both for old and new contracts. And as a result - fail when it should not

for version, data in contract_data.items():
data.pop("ast")
# TODO: Remove AST because id in tree node depends on compilation scope <<< Still relevant?
interfaces = multiversion_compile(solidity_source_dirs=testerchain.SOURCES)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this does not test initial idea, because for both contract sets used same input tuple and there are no merging between same two equal version of contracts as it was before

@@ -93,17 +92,15 @@ def deploy_earliest_contract(blockchain_interface: BlockchainDeployerInterface,
pass # Skip errors related to initialization


@pytest.mark.slow
@pytest.mark.skip('GH 403') # FIXME
def test_upgradeability(temp_dir_path, token_economics):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All stuff with multi version compilation initially was done to use it here, so it's sort of marker of readiness of this PR, so I think that this can't be skipped in this set of changes

@KPrasch KPrasch changed the title Standard Solc Compile [WIP] Standard Solc Compile Jun 9, 2020
@KPrasch KPrasch force-pushed the compile-std branch 3 times, most recently from 754b3e3 to ccf8afb Compare August 7, 2020 18:20
@KPrasch KPrasch requested a review from vzotova August 7, 2020 18:22
versioned: bool = version_specifier != DEFAULT_VERSION_STRING
if versioned and new_title:
existing_title = existing_version['devdoc'].get('title')
if existing_title == new_title: # This is the same contract
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it will be hard to get contract name then current approach is ok, but anyway I would prefer to not use title

return DEFAULT_VERSION_STRING

# RE Full Match
raw_matches = DEVDOC_VERSION_PATTERN.fullmatch(devdoc_details)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe move DEFAULT_VERSION_STRING here too?


# Prepare Solc Command
solc_binary_path: str = get_executable(version=compiler_version)
SOLC_LOGGER.info(f"Compiling with base path") # TODO: Add base path
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is log variable few lines upper, and here some constant logger, I guess should be only one


_allow_paths = f'{SOLIDITY_SOURCE_ROOT},{TEST_SOLIDITY_SOURCE_ROOT}'
if allow_paths:
_allow_paths += ','.join(str(p) for p in allow_paths)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

allow paths will always come from source bundle (or at least should), so how about to remove constants from here?

@@ -217,7 +217,7 @@ def create_policy(self, bob: "Bob", label: bytes, **policy_params):
policy = FederatedPolicy(alice=self, **payload)

else:
# Sample from blockchain via PolicyManager
# Sample from nucypher.blockchain.via PolicyManager
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like autoreplacement mistype

@@ -25,7 +25,7 @@ def test_token_deployer_and_agent(testerchain, deployment_progress, test_registr

origin = testerchain.etherbase_account

# Trying to get token from blockchain before it's been published fails
# Trying to get token from nucypher.blockchain.before it's been published fails
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mistype

@@ -175,7 +181,7 @@ def estimate_gas(analyzer: AnalyzeGas = None) -> None:
compiled_contract = testerchain._raw_contract_cache[contract_name]

version = list(compiled_contract).pop()
bin_runtime = compiled_contract[version]['bin-runtime']
bin_runtime = compiled_contract[version]['evm']['bytecode']['object']
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these values fully identical?

SOURCES: Tuple[SourceBundle, ...] = (
*BlockchainDeployerInterface.SOURCES,
SourceBundle(base_path=TEST_SOLIDITY_SOURCE_ROOT)
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be one source bundle (same as BlockchainDeployerInterface.SOURCES), and I'm still for variable to hold source bundles :)

blockchain_interface.connect()
blockchain_interface = BlockchainDeployerInterface(provider_uri='tester://pyevm/2')
blockchain_interface.connect(compile_now=False)
blockchain_interface._raw_contract_cache = compiled_contracts
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This way to test exclude all multiversion compilation handling inside BlockchainDeployerInterface and test becomes less meaningful

@KPrasch
Copy link
Member Author

KPrasch commented Oct 29, 2020

Closing for staleness - to be revisited. Opened #2413

@KPrasch KPrasch closed this Oct 29, 2020
@KPrasch KPrasch deleted the compile-std branch October 25, 2023 18:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Code Quality 🔧 Pertaining to code quality improvements Configuration Node configuration
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Decorator to skip circleCI
3 participants