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

Using solc to compare bytecode on specific contracts #461

Merged
merged 3 commits into from
Apr 16, 2021

Conversation

Janther
Copy link
Contributor

@Janther Janther commented Mar 31, 2021

There are 3 different cases where we make changes to the AST while parsing.

  1. HexLiteral: if the plugin needs to change the quote of a HexLiteral because of the singleQuote setting, this is better done while parsing to avoid throwing an error in the tests for a different AST after formatting.
  2. Types and Alias: uint and int are aliases for uint256 and int256 respectively. These will generate different ASTs when using a different setting for explicitTypes
  3. Parentheses: To help the reading of mathematic expressions, we enforce the use the use of Parentheses in specific cases.
    - ie: a / b * c will be formatted as (a / b) * c.
    This clearly implies a change in the AST.

As nice as these changes to the AST can be for formatting, the compiled bytecode should remain the same. To enforce this, this PR will add the ability to compare the bytecode of some contracts designed to trigger all of these AST changes.

// - A worker process has failed to exit gracefully and has been force
// exited. This is likely caused by tests leaking due to improper
// teardown. Try running with --detectOpenHandles to find leaks.
const compileContract = require('./utils/compile-contract');
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'd appreciate if someone could investigate how to include the compiler, without incurring in greater testing times.

Copy link
Member

@fvictorio fvictorio Apr 14, 2021

Choose a reason for hiding this comment

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

There is a way to improve the time: download a native compiler and use that instead. It's significantly faster. But this means:

  1. Downloading the correct compiler according to the OS (and falling back to the WASM one if the OS is not supported)
  2. Avoiding a re-download if it was previously download
  3. (Optional) Cache it in the CI

I can do this since we do something similar (even more involved) in Hardhat.

That being said, it takes 1m to run all the tests with the AST and bytecode checks, so I don't think it's worth it? I'd rather re-visit this in the future if it's a problem, but for now I would say that we just run npm test during development and use npm run test:all before pushing (or just checking the result of the CI).

@Janther Janther force-pushed the comparing-bytecode branch from 6ad2779 to c169ab4 Compare April 1, 2021 03:05
@Janther Janther requested review from mattiaerre and fvictorio April 1, 2021 22:01
@Janther Janther added enhancement New feature or request help wanted Extra attention is needed labels Apr 7, 2021
@Janther Janther force-pushed the comparing-bytecode branch 3 times, most recently from 5cc6b8d to 81f17d8 Compare April 12, 2021 00:30
@@ -38,6 +38,35 @@ const unstableAstTests = new Map(
})
);

const astChangedTests = new Map(
Copy link
Member

Choose a reason for hiding this comment

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

Two questions here:

  1. Is the name of this variable accurate?
  2. Why is the bytecode comparison only done for these files? Why don't we do it for all of them?

Copy link
Member

Choose a reason for hiding this comment

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

Ohh, the bytecode comparison is only done for these files, I understand now. I still think the name of the variable is not very descriptive.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

  1. Just changed the name slightly to be more precise.
  2. For now I believe AST comparison should be enough and byte-code comparison applies only on the cases when we choose to change the AST.
    I agree that best case would be to ultimately compare byte codes but I also see all of the work needed to do that properly.
    Making sure every test is compilable and also keeping track of major syntax changes across different compilers.

@fvictorio
Copy link
Member

I would love to run this bytecode comparison in all our test files. This is a lot of work, because:

  • We need to make all our test files valid
  • We need to support multiple compilers. This can be done either by adding a compiler downloader or installing multiple solc dependencies with different versions (there is a way to do this with npm)
  • Since we support multiple versions, we'll need to split our files so that we cover different scenarios (for example, functions with and without visibility)

But I think this PR is already too big, and it covers good ground. I think we can merge it and create an issue to do the full thing another day.

@Janther Janther force-pushed the comparing-bytecode branch from dc25fba to 6aadd9f Compare April 15, 2021 23:18
Copy link
Member

@mattiaerre mattiaerre left a comment

Choose a reason for hiding this comment

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

👍

@mattiaerre mattiaerre merged commit 36825d7 into master Apr 16, 2021
@mattiaerre mattiaerre deleted the comparing-bytecode branch April 16, 2021 01:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants