-
-
Notifications
You must be signed in to change notification settings - Fork 813
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
Keep the vyper compiler version signature in the runtime code #3549
Comments
i can appreciate that vyper optimizes for runtime over off-chain tooling, so just sharing some perspective. i don't think the version being at a random position before immutables vs at the end poses a big problem, we can just regex. but it not being in runtime code is more serious because you need to spent significantly more effort to find it. without using an explorer like etherscan to just look it up, you need to perform several steps:
this would require an archive node with tracing capabilities which is not practical or even available on some networks. this would probably turn people to centralized services or indexers which is not optimal for decentralization. quickly finding all contracts of a certain version could be crucial in certain situations like one that has just unfolded. |
Another issue which might be relevant (although it can be considered orthogonally as an entirely separate issue) is whether it could be worth it to include length of the data + immutables sections in the runtime and/or initcode. This would make disassembling contracts easier, and for the issue noted above it would make it not matter whether the signature or immutable section comes first. |
by the way, (per @banteg) otterscan |
i was able to modify @pcaversaccio 's dune query (https://dune.com/pcaversaccio/vyper-deployment-statistics) to output all vyper contracts >= 0.3.4 based on creation trace, and the query took 60 seconds. so yes, this is a bit of a centralization risk, but also keeping track of all relevant chains is by its very nature somewhat of a centralized task, so i don't see it as too big of an issue. |
@charles-cooper to my knowledge Dune's "creation traces" does not have the creation code (initcode) but the runtime code (docs). So these results will not have Vyper contracts 0.3.10 and onwards |
You're right - I pinged Dune with the feature request. Let's see. |
Now I have a better grasp of things, I'd argue another reason to keep the cbor metadata in runtime bytecode is because the information there is actually referencing the runtime bytecode. But it is only stored in the creation (init) bytecode. E.g. this CBOR metadata (playground)
is decoded as [167, [10], 96, {"vyper": [0, 4, 0]}] From what I can see |
yes, that's on purpose. it saves on runtime bytecode (which is expensive and subject to a hard limit), and also makes the data fully unreachable from the runtime code. |
Simple Summary
Per @banteg on twitter I learned that vyper 0.3.10 plans to move the version metdata from the initcode to creation code (ref #3471)
I suggest keeping this in the initcode.
Motivation
Finding initcode is much harder than finding runtime code. Given an address, it's trivial to query for it's runteime code using
eth_getCode
and parse the vyper version out of it. It's much harder to binary search across all blocks to find when a contract was deployed, then trace each transaction in that block to find creation code (You could of course rely on etherscan or other data providers, to provide this, but IMO minimizing reliance on other services and ensuring data is easy to find is a better approach)My understanding is that the rationale was that moving it to the creation code was either (1) cheaper, and/or (2) more robust since there's no initcode size limit.
My opinion is that the gas savings from (2) don't outweigh the benefits of having the version in the runtime code, as easy access to contract version numbers can be critical and time-sensitive during exploits. Additionally often times you might fetch code from an RPC and use tools like heimdall-rs or whatsabi to analyze it (there are many tools that operate on runtime code), so having more info in runtime code avoids introducing reliace on e.g. etherscan
From talking with @big-tech-sux, some arguments on the other side are that currently the version is at the end of the runtime code, but followed by immutables. So you still need the source, immutables layout, or a regex to parse the version. One idea is to move the version to the end after immutables, but it makes the implementation a bit more complicated and complexity compounds
Ultimately I just wanted to raise the other side of the decision here since I didn't see it much discussed in the PR, and IME often times you have runtime code from a node + local tools but don't want to introduce indexers to provide e.g. creation code.
Specification
I think just revert #3471? Basically, ensure the CBOR encoded vyper version (and other other metadata) is present in deployed code, not creation code.
Backwards Compatibility
My understanding is that 0.3.9 has the behavior being requested here, so there are no backwards compatibility issues unless 0.3.10 is released with the behavior from #3471
Dependencies
N/A
References
Twitter convos (nothing new here, all the same info as above, just linking the threads for completeness)
Copyright
Copyright and related rights waived via CC0
The text was updated successfully, but these errors were encountered: