(sorry for the late reply, but better late than never
@kianenigma no problem - thanks for taking the time to review and respond
I’ll split my response into two sections, one for “semantic analysis for improved IDE/editor support”, and another for “security-related static analysis”.
Semantic analysis for improved IDE/editor support
I am generally still in favor of a similar tool for FRAME, but I do want to suggest querying FRAME experts to provide feedback before getting started. So, a process like this:
- You provide a gist of the rules and lints that you have in mind
- Discussion and review period on the above, ideally with fellowship and parachain teams chiming in
- Implementation and funding.
For “lints and rules”, the first/initial phase(s) will be pretty objective/uncontroversial and focus on “diagnostics”/“hard errors” (i.e. things that would not compile or things that FRAME itself would complain about).
More subjective “lints”/“soft warnings” would then be added in later phases, at which point I think more extensive discussions and reviews would be required.
In other words, for the first/initial phase(s), the semantic rules checked will be the same rules FRAME itself checks, but simply implemented using different semantic analysis infrastructure built on a lossless and resilient parser.
The analog is how rust-analyzer runs similar diagnostic checks as rustc, but using different semantic analysis infrastructure that’s better suited to the IDE/editor environment (e.g. unlike a “batch” compiler, IDEs/editors can’t just quit and stop analysis due to the presence of some errors and/or invalid syntax, because they’re expected to continue to provide intelligent editing features even in this case).
A “FRAME analyzer” would play a similar role for FRAME’s semantic rules and syntax extensions.
To give you some starting ideas:
- Probably many of the Ink! rules and techniques are applicable to FRAME macros as well.
- How do you detect syntax error and report it? ideally, your tool should be in sync with the actual FRAME semantics. The worst thing is if the analyzer says a code is wrong, but it actually compiles How does this work for ink!?
So yes, we’ll use a similar methodology as used in ink! analyzer when implementing FRAME semantic rules (i.e. FRAME implementation will be used as a reference), so “FRAME analyzer” and FRAME should indeed be “in sync”. Similar to ink! analyzer, “FRAME analyzer” will be analyzing an IR (Intermediate Representation) built from a lossless syntax tree from rust-analyzer’s ra_ap_syntax library, instead of a syn syntax tree, but applying essentially the same semantic rules as FRAME.
- Pallet Syntax: Analysis of
T
consistency · Issue #176 · paritytech/polkadot-sdk · GitHub is a good overview of some FRAME syntax peculiarities
Very useful, thanks for sharing - will definitely be reviewing.
- Your extension can handle things like:
- generate a shell pallet
- add storge item called X
- …
In LSP (Language Server Protocol) speak, these would be commands and code actions.
- “generate a shell pallet” would be similar to ink! analyzer’s “New Project” command
- “add storage item called X” would be similar to ink! analyzer’s code actions
(e.g. for adding ink! storage and eventstruct
s, ink! constructor and messagefn
s e.t.c).
In cases where code actions can fix a diagnostic error, they’re automatically suggested as “quickfixes”. An example for FRAME would be a quickfix for adding a #[pallet::pallet]
annotated struct
to a #[frame_support::pallet]
annotated mod
. This would also be similar to ink! analyzer’s quickfixes.
In general all diagnostics will include a quickfix if a reasonable one can be determined.
- This is one of the main issues with FRAME macro errors atm: Fix pallet error spam when there is really just one simple error · Issue #213 · paritytech/polkadot-sdk · GitHub
So interestingly, this one shouldn’t be an issue for the analyzer because of the infrastructure differences. I’ll definitely keep an eye on it though.
- You should start with pallet macro, but there is also the construct_runtime as a next step.
Makes sense, in the end, the idea will be to be exhaustive, but I’ll definitely be prioritizing the most frequently used macros at the beginning.
Security-related static analysis
- Some security related ideas:
- Using
type Stuff = ()
in production, especially for weights.- Using
StorageMap::<T>::iter()
which is often a mistake as it is unbounded iteration.- Using unsafe math
- [FRAME] Static analysis for HDH/ME code · Issue #165 · paritytech/polkadot-sdk · GitHub
I’m actually already working on a related project for this.
At the moment, It’s only focused on detecting potential panics and unsafe arithmetic (including those arising from reachable code from dependencies) using abstract interpretation, but the plan is to definitely expand to more vulnerability classes, so more suggestions are definitely welcome.
However, it will be a CLI tool and essentially a rust compiler plugin (invoked via a cargo subcommand) primarily analyzing MIR.
The work on detecting panics and unsafe arithmetic for this one is already funded, but I can’t say anything more about that for now .
However, you can expect an initial release (and more details) in the next 2-3 weeks.