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

Introduce Shanghai version and push0 support #14107

Merged
merged 5 commits into from
Apr 12, 2023
Merged

Introduce Shanghai version and push0 support #14107

merged 5 commits into from
Apr 12, 2023

Conversation

hrkrshnn
Copy link
Member

Partially implements #14073. The remaining will be done in future PRs.

  • Introduces version Shanghai.
  • Assembler supports use of push0 from EVM versions starting at Shanghai.
  • Basic tests and docs.

See https://eips.ethereum.org/EIPS/eip-3855

Note: `push0` costs 2 gas, i.e., `Tier::Base` unlike other pushes.
@github-actions
Copy link

Thank you for your contribution to the Solidity compiler! A team member will follow up shortly.

If you haven't read our contributing guidelines and our review checklist before, please do it now, this makes the reviewing process and accepting your contribution smoother.

If you have any questions or need our help, feel free to post them in the PR or talk to us directly on the #solidity-dev channel on Matrix.

@@ -544,6 +544,7 @@ LinkerObject const& Assembly::assemble() const
bytesRequiredIncludingData += static_cast<unsigned>(sub->assemble().bytecode.size());

unsigned bytesPerDataRef = numberEncodingSize(bytesRequiredIncludingData);
// TODO can this return push0?
Copy link
Member

Choose a reason for hiding this comment

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

Nope - this would only ever return zero, if there was neither code nor data, in which case we'd not do anything anyways - but since bytesRequiredIncludingData is always strictly positive, bytesPerDataRef will be so as well, so dataRefPush will always be at least a PUSH1.


EVMVersion(Version _version): m_version(_version) {}

// FIXME update the default EVM version in a future PR
Copy link
Member

Choose a reason for hiding this comment

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

We don't really need the comment - we'll do it once Shanghai goes live, s.t. the first release after defaults to Shanghai.

ekpyron
ekpyron previously approved these changes Apr 11, 2023
Copy link
Member

@ekpyron ekpyron left a comment

Choose a reason for hiding this comment

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

The main "issue" I'm seeing with this is that AssemblyItem::bytesRequired, resp. evmasm::bytesRequiredreturn wrong values for PUSH0 - which is a bit annoying, since they will now depend on the EVM version.

It's not that big of a deal for now, though, since at worst this will result in reserving too much space for tags, if push1 0 vs push0 let the codesize estimate drop sufficiently. It will/would be more of a problem for EOF, for which it's nicer if we can accurately predict code size. So this should be adjusted, even if this means passing down evm versions even more - but I'm fine with doing it separately.

Not entirely sure about some of the syntax tests, but fine.

So I'm fine with merging this - we could still remove the comments I'm commenting about, but apart from that, this is good enough for a first version and we can do the rest separately.

@NunoFilipeSantos NunoFilipeSantos added this to the 0.8.20 milestone Apr 11, 2023
@invocamanman
Copy link

invocamanman commented Apr 11, 2023

Since this uses a new opcode, and it's used "underneath", so the user does not have fully control over it, it totally breaks compatibility with previous forks. For instance if you try to deploy any contract compiled with the 0.8.20 in any fork previous to Shanghai it will break the contract ( since the push0 will be processed as an INVALID).
This could break contracts on others EVM compatible chains therefore I suggest to apply this change in a major version change such as 0.9

Thank you^^

@ekpyron
Copy link
Member

ekpyron commented Apr 11, 2023

Since this uses a new opcode, and it's used "underneath", so the user does not have fully control over it, it totally breaks compatibility with previous forks. For instance if you try to deploy any contract compiled with the 0.8.20 in any fork previous to Shanghai it will break the contract ( since the push0 will be processed as an INVALID). This could break contracts on others EVM compatible chains therefore I suggest to apply this change in a major version change such as 0.9

Thank you^^

That's true for any previous hard-forks as well - the compiler can be set up to the EVM version you want and is backwards-compatible up until homestead. It has generally always followed EVM mainnet in the default version, so in the first solc release after the hardfork we will switch the default (note that this PR does not switch the default, but merely adds support upon explicit request for now).

Overriding this default especially in the connection with other EVM-compatible chains is a job for the framework involved, for the compiler I strongly tend towards sticking to the traditional convention.

@ekpyron
Copy link
Member

ekpyron commented Apr 11, 2023

@hrkrshnn Can you squash the commits and remove the comments? Then I'd probably just merge this for now.
We can then try to raise some more input on switching the default before the hard-fork, to give people the chance to sway my mind on just switching the default with the fork :-).

@hrkrshnn
Copy link
Member Author

hrkrshnn commented Apr 11, 2023

Can you squash the commits and remove the comments?

Ah come on, I painfully separated all the commits 😢 Will fix the pending comments today.

@ekpyron
Copy link
Member

ekpyron commented Apr 11, 2023

Can you squash the commits and remove the comments?

Ah come on, I painfully separated all the commits cry Will fix the pending comments today.

Haha, ok, just removing the comments is also just fine :-).

@ekpyron
Copy link
Member

ekpyron commented Apr 11, 2023

We can then try to raise some more input on switching the default before the hard-fork, to give people the chance to sway my mind on just switching the default with the fork

Not that there's that much time left before Shanghai to decide this :-). But we can also leave it as paris as default for the next release and ultimately decide for the release after, we've been lagging behind slightly in the past already anyways. Or we still take some time to get input on this before releasing.

Note: Paris is still the default
1. `push0_disallowed.yul`: checks if `push0()` is a valid builtin in strict Yul
2. `push0_disallowed.sol`: checks if `push0()` is a valid builtin in inline assembly
3. `push0.sol`: simple semantic test that returns 0
4. `evmone_support.sol`: tests if push0 works properly in evmone
5. Updated some bytecode too large tests to use `shanghai` as version
6. Updated various tests where `push1 0` was hardcoded in different forms / expectations on bytecode
size (`Assembler.cpp`, `GasCosts.cpp`, `SolidityCompiler.cpp`, `SolidityExpressionCompiler.cpp`)
@hrkrshnn
Copy link
Member Author

Just removed both the comments (the todo and fixme).

@ekpyron ekpyron merged commit 82bde40 into develop Apr 12, 2023
@ekpyron ekpyron deleted the push0 branch April 12, 2023 08:10
@invocamanman
Copy link

Thank you so much for your responses and also for taking into account the suggestion^^ 😊

@@ -4,6 +4,8 @@ Language Features:


Compiler Features:
* Assembler: Use ``push0`` for placing ``0`` in the stack for EVM versions starting from "Shanghai". This decreases the deployment costs.
Copy link
Member

Choose a reason for hiding this comment

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

This decreases runtime cost too, 3 gas vs 2 gas.

Copy link
Member Author

Choose a reason for hiding this comment

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

Will add it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

6 participants