-
Notifications
You must be signed in to change notification settings - Fork 265
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
Remove non-struct NatSpec from namespaced storage layout compilation #1051
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've only had a cursory look at this PR, it looks reasonable but someone else might want to review it more thoroughly.
// from https://github.com/NomicFoundation/hardhat-vscode/blob/development/server/src/parser/slangHelpers.ts | ||
import { getPlatform } from './operatingSystem'; | ||
|
||
const SUPPORTED_PLATFORMS = [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would say though that this seems very wrong to me. Slang should self-report on what platforms it supports to avoid issues when platforms are added or removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will suggest this for Slang.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Importing Slang in an unsupported platform will actually throw an error, so to support other platforms you should only import it dynamically, which may be somewhat annoying.
You can still use import type
in the top-level scope of your files though.
At the same time, this could also help you build an alternative isSlangSupported
function, like this:
function isSlangSupported() : boolean {
try {
require("@nomicfoundation/slang");
} catch (e) {
if ("message" in e && typeof e.message == "string") {
return e.message === 'Failed to load native binding' || e.message.startsWith('Unsupported architecture') || e.message.startsWith('Unsupported OS');
}
throw e;
}
}
This was written inside the GitHub UI, so it may not even compile, but it shows the general idea. The error messages are available in @nomicfoundation/slang/napi-bindings/generated/index.js
. Unfortunately, the generated bindings use a plain Error
.
Finally, two other notes:
- We've seen virtually no usage of Hardhat in platforms other than the ones listed here, so we strongly believe that it covers most, if not all, the Ethereum ecosystem.
- Once we switch to wasm, this won't be needed anymore :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the suggestion, and I agree with you that this should be improved. We are in the process of moving to WASM (in Q3), which will remove the need for platform-specific binaries in any case, so that won't be needed in the future.
In the meantime, the list of supported platforms can be read from the package.json
dependencies
, and listed here as well:
https://www.npmjs.com/package/@nomicfoundation/slang?activeTab=dependencies
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the feedback, everyone. I've changed this to try importing Slang dynamically and if it has an error, we can simply assume the platform is not supported and skip this code path (this way we can avoid checking the error messages since those are not part of the stable API).
One topic to consider is whether this removal of all NatSpec aside from those attached to struct definitions would cause the plugin to lose information about other annotations. For example, the My assessment is that these are unrelated. The solc output resulting from this modified source code is only used to extract the storage layout here. This is an optional parameter to the When extracting storage layouts, there are additional possible annotations to allow renaming/retyping, which are checked here and here. These come from the original The only place that uses annotations from the namespaced output should be in In summary, deleting NatSpec other than for struct definitions is fine for namespaced storage layout purposes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
New and removed dependencies detected. Learn more about Socket for GitHub ↗︎
|
When making a modified copy of solc input to extract namespaced storage layout, many previously encountered bugs were due to unexpected compilation errors when NatSpec no longer matches the modified source for various reasons (e.g. parameter or return parameter changes in functions, or NatSpec being orphaned after nodes are deleted).
We were previously unable to reliably delete these NatSpec nodes using the Solidity AST, because some NatSpec nodes are not included in the Solidity AST, for example NatSpec-style comments which were orphaned in the first place.
Now with Slang, if Slang supports the current platform where this plugin is run from, we can use it to do a separate parse of the source code and another set of modifications: we traverse the CST to look for any NatSpec not associated with a struct, and delete them. This would increase reliability on platforms where Slang is supported.
However, it is important to only do this if the NatSpec is indeed not part of a struct -- we must keep all struct NatSpec since those may contain ERC7201 storage location annotations, and this modified copy of solc input is used for namespace validations in the Hardhat Upgrades plugin.