Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Expose WASM extensions in executor semantics #13811

Merged
merged 3 commits into from
Apr 4, 2023

Conversation

s0me0ne-unkn0wn
Copy link
Contributor

@s0me0ne-unkn0wn s0me0ne-unkn0wn commented Apr 3, 2023

Description

During a recent LLVM incident, we discovered that enabling and disabling WASM extensions is not only a matter of our will. Teams working on compilers and WASM runtimes stabilize things independently, and we need a mechanism to enable those extensions deterministically on a per-session basis.

Thus, paritytech/polkadot#6918 was raised. To enable the underlying execution logic to control the extensions, the Substrate has to expose corresponding handles through Wasmtime executor semantics. This PR solves that. The controlling logic will be implemented in a separate PR in the Polkadot repo.

Related issues

Closes #13809
Unblocks paritytech/polkadot#6918

Companion PRs

Polkadot companion: paritytech/polkadot#6998

@s0me0ne-unkn0wn s0me0ne-unkn0wn added A0-please_review Pull request needs code review. B0-silent Changes should not be mentioned in any release notes C1-low PR touches the given topic and has a low impact on builders. D3-trivial 🧸 PR contains trivial changes in a runtime directory that do not require an audit labels Apr 3, 2023
Copy link
Contributor

@koute koute left a comment

Choose a reason for hiding this comment

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

Note: this will also need either a) changes in parity-wasm or b) nuking parity-wasm and migrating to wasmparser + wasm-encoder to actually work (which I have started work on, but it's on a backburner for now)

client/executor/wasmtime/src/runtime.rs Outdated Show resolved Hide resolved
Copy link
Member

@bkchr bkchr left a comment

Choose a reason for hiding this comment

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

During a recent LLVM incident, we discovered that enabling and disabling WASM extensions is not only a matter of our will.

This makes no sense! This pr would not solve anything when there is a compiler bug enabling some features that we don't support. The reasoning makes no sense. You are right that we need a way to enable these features in a sensible way when the time has come. However, we currently have these features disabled and will not randomly enable them. We should not add features for stuff that we don't need. Or do we want to enable any of these features in the near future?

@s0me0ne-unkn0wn
Copy link
Contributor Author

This makes no sense! This pr would not solve anything when there is a compiler bug enabling some features that we don't support. The reasoning makes no sense.

I agree that the LLVM incident was an outstanding event, and this PR doesn't defend us against breaking changes in the compiler. Nothing can protect us from breaking changes in the compiler, tbh. I hope they've learned the lesson, and next time we'll see some announcements like "we're enabling multi-value in two months". And when we see it, we'll be prepared.

You are right that we need a way to enable these features in a sensible way when the time has come. However, we currently have these features disabled and will not randomly enable them. We should not add features for stuff that we don't need.

And when the time comes, should we do it in panic mode again, releasing hotfixes? Right now, we don't have the means to enable WASM features deterministically. So when we need them, they're better to be there already.
Besides, bringing those features to the semantics control structure is not a complication; it's a natural flow. I'd understand your concerns if it involved complex logic and breaking changes. But it's just three booleans that were hardcoded and now become configurable. Nothing really changes (until we need to change it, as you mentioned).

Or do we want to enable any of these features in the near future?

Well, I would've enabled SIMD already if it were solely my decision 😁 But hopefully not, we're not enabling anything out of the blue. It's just about preparedness; better safe than sorry.

@bkchr
Copy link
Member

bkchr commented Apr 3, 2023

And when the time comes, should we do it in panic mode again, releasing hotfixes? Right now, we don't have the means to enable WASM features deterministically. So when we need them, they're better to be there already.

In what world should we ever require to release a new language feature in a hurry? Nothing will happen and require that we enable SIMD tomorrow without any preparation. Even if Rust decides to enable the feature tomorrow, you can still continue using the old compiler until we have done all the changes and released them. With PVF pre-checking any PVF that will want to enable a not supported feature will just be rejected.

But it's just three booleans that were hardcoded and now become configurable. Nothing really changes (until we need to change it, as you mentioned).

This is only the case for Substrate, you will also need to add code to Polkadot and then write some migration (because the current executor params are not designed to be easily extended) etc.

@s0me0ne-unkn0wn
Copy link
Contributor Author

Even if Rust decides to enable the feature tomorrow, you can still continue using the old compiler until we have done all the changes and released them.

Yes, until we do the changes, then release them, then wait for the supermajority to upgrade the node software, etc etc etc. Instead of governance just turning the switch, "we want this feature enabled beginning from session 10453". The latter seems to be the more natural path of evolution of the network, isn't it?

With PVF pre-checking any PVF that will want to enable a not supported feature will just be rejected.

And with this change, we can have PVFs with the feature enabled before the network enables it to be rejected and the PVFs with the feature enabled after the network enables it to be accepted. That sounds like network-wide determinism to me!

This is only the case for Substrate, you will also need to add code to Polkadot and then write some migration (because the current executor params are not designed to be easily extended)

The code is trivial, and I don't think the migration is needed. Those features are just new variants of the enum. We should start using them after the validators get upgraded. Those who didn't wouldn't be able to decode a new enum variant and wouldn't be able to process new PVFs (and probably would be slashed for not upgrading in time, I'm not sure).

All in all, I cannot get your concern about this PR. When we were implementing execution environment parameters themselves, a monstrous PR introducing somewhat breaking features that are not supposed to be used shortly, you weren't against it. Can you please explain why this little change matters so much? Maybe I could rework it to make it more acceptable.

@bkchr
Copy link
Member

bkchr commented Apr 3, 2023

(and probably would be slashed for not upgrading in time, I'm not sure).

There is no slashing for not upgrading.

All in all, I cannot get your concern about this PR. When we were implementing execution environment parameters themselves, a monstrous PR introducing somewhat breaking features that are not supposed to be used shortly, you weren't against it. Can you please explain why this little change matters so much? Maybe I could rework it to make it more acceptable.

If you go back and look at what I complained about it was "feature creep", aka adding configurations for things that we don't need to configure. Here we again try to introduce configuration options for stuff that we may need at some point or that we may never enable.

@koute
Copy link
Contributor

koute commented Apr 4, 2023

@bkchr In general I don't like adding stuff we won't immediately need/use right now, but I was under impression that @s0me0ne-unkn0wn 's going to work on this right now:

I've just started working on this

which is why I OK'd this. And at least we do want to enable the bulk memory feature (since it improves performance significantly), and the other features are part of the core WASM spec at this point so they are somewhat reasonable to maybe experiment with. But I guess you're right that for the rest of them we don't have any immediate plans/need to enable them.

@bkchr
Copy link
Member

bkchr commented Apr 4, 2023

@bkchr In general I don't like adding stuff we won't immediately need/use right now, but I was under impression that @s0me0ne-unkn0wn 's going to work on this right now:

But this says that this feature is already enabled since 3 years?

And at least we do want to enable the bulk memory feature (since it improves performance significantly),

But given this, I'm going to release my block here. Still, we should not add configuration options for all the things, when we don't need them. Removing them otherwise will be almost impossible. In Polkadot please only start with exposing the bulk memory as executor param @s0me0ne-unkn0wn. And a refactor of executor param to support unknown variants (by ignoring them) should also be done. This can be achieved by putting the length of every variant in front of it when encoding it.

@koute
Copy link
Contributor

koute commented Apr 4, 2023

But this says that this feature is already enabled since 3 years?

The signed ops feature, yes, that is enabled in wasmtime and for that there's no feature knob. But this doesn't matter in practice as any runtime which uses it won't load anyway as parity-wasm will choke on it.

But you do have a good point, this does remind me, @s0me0ne-unkn0wn currently the fact that wasmtime supports e.g. signed ops but we don't load such runtimes is entirely accidental and we should fix this ASAP. That is, we should probably:

  1. enable the sign_ext feature in parity-wasm,
  2. explicitly detect runtimes which use these instructions reject them, (instead of relying on the feature flag in parity-wasm not being enabled and only implicitly rejecting those runtimes, which brings in the risk of it being accidentally enabled through a transitive dependency without us noticing)
  3. (optionally, in a later step) consider enabling the sign_ext, which would entail adding a new feature flag like in this PR which would disable the check that the runtime doesn't use the feature.

@bkchr
Copy link
Member

bkchr commented Apr 4, 2023

@koute please create an issue for this.

@koute
Copy link
Contributor

koute commented Apr 4, 2023

@koute please create an issue for this.

Right, good idea! Done: paritytech/polkadot-sdk#15

@eskimor
Copy link
Member

eskimor commented Apr 4, 2023

And a refactor of executor param to support unknown variants (by ignoring them) should also be done.

This is not a good idea. Those executor params are meant to make it possible to change semantics in a consensus preserving way. If some validators just ignore the value, because they don't know it, then we don't have consensus on semantics. For validators it is better to fail decoding (and punt on participation) than to happily decode, ignore and then dispute a candidate because it used the wrong parameters.

@bkchr
Copy link
Member

bkchr commented Apr 4, 2023

And a refactor of executor param to support unknown variants (by ignoring them) should also be done.

This is not a good idea. Those executor params are meant to make it possible to change semantics in a consensus preserving way. If some validators just ignore the value, because they don't know it, then we don't have consensus on semantics. For validators it is better to fail decoding (and punt on participation) than to happily decode, ignore and then dispute a candidate because it used the wrong parameters.

Valid point. I would still find it better to not fail on decoding and just stay away from validating a candidate if we found an unknown variant.

@s0me0ne-unkn0wn
Copy link
Contributor Author

bot merge

@paritytech-processbot paritytech-processbot bot merged commit 8548a97 into master Apr 4, 2023
@paritytech-processbot paritytech-processbot bot deleted the s0me0ne/wasm-expose-exts branch April 4, 2023 15:10
Comment on lines 332 to 334
config.wasm_multi_memory(false);
config.wasm_threads(false);
config.wasm_memory64(false);
Copy link

Choose a reason for hiding this comment

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

Why are these not exposed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link

Choose a reason for hiding this comment

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

Thanks. A comment would have been nice, but it's too late now for my nits. 😛

paritytech-processbot bot pushed a commit to paritytech/polkadot that referenced this pull request Apr 4, 2023
* Companion for paritytech/substrate#13811

* Add comment

* update lockfile for {"substrate"}

* Update Substrate

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>

* Fix pallet weight warnings

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>

---------

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
Co-authored-by: parity-processbot <>
Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
@eskimor
Copy link
Member

eskimor commented Apr 5, 2023

Valid point. I would still find it better to not fail on decoding and just stay away from validating a candidate if we found an unknown variant.

Wouldn't the end result be the same? The decoding should only fail if an unknown variant was actually used. So those two should be equivalent. Considering other cases for decoding errors (some corruption), the treatment should also be the same.

Not really arguing that having an explicit error "unknown variant found" would not be better, but maybe decoding could actually tell us that? What I am pushing against a bit in particular is buying this "we can decode whatever" at the expense of type safety.

ordian added a commit to paritytech/polkadot that referenced this pull request Apr 11, 2023
* master: (28 commits)
  Remove years from copyright notes (#7034)
  Onchain scraper in `dispute-coordinator` will scrape `SCRAPED_FINALIZED_BLOCKS_COUNT` blocks before finality (#7013)
  PVF: Minor refactor in workers code (#7012)
  Expose WASM bulk memory extension in execution environment parameters (#7008)
  Co #13699: Remove old calls (#7003)
  Companion for paritytech/substrate#13811 (#6998)
  PR review rules, include all rs files except weights (#6990)
  Substrate companion: Remove deprecated batch verification (#6999)
  Added `origin` to config for `universal_origin` benchmark (#6986)
  Cache `SessionInfo` on new activated leaf in `dispute-distribution` (#6993)
  Update Substrate to fix Substrate companions (#6994)
  Consolidate subsystem spans so they are all children of the leaf-activated root span (#6458)
  Avoid redundant clone. (#6989)
  bump zombienet version (#6985)
  avoid triggering unwanted room_id for the release notifs (#6984)
  Add crowdloan to SafeCallFilter (#6903)
  Drop timers for new requests of active participations (#6974)
  Use `SIGTERM` instead of `SIGKILL` on PVF worker version mismatch (#6981)
  Tighter bound on asset types teleported so that weight is cheaper (#6980)
  staking miner: less aggresive submissions (#6978)
  ...
ordian added a commit to paritytech/polkadot that referenced this pull request Apr 12, 2023
* master: (25 commits)
  [Deps] bump scale-info to be in line with cumulus (#7049)
  Invoke cargo build commands with `--locked` (#7057)
  use stable rust toolchain in ci
  apply clippy 1.68 suggestions
  Remove years from copyright notes (#7034)
  Onchain scraper in `dispute-coordinator` will scrape `SCRAPED_FINALIZED_BLOCKS_COUNT` blocks before finality (#7013)
  PVF: Minor refactor in workers code (#7012)
  Expose WASM bulk memory extension in execution environment parameters (#7008)
  Co #13699: Remove old calls (#7003)
  Companion for paritytech/substrate#13811 (#6998)
  PR review rules, include all rs files except weights (#6990)
  Substrate companion: Remove deprecated batch verification (#6999)
  Added `origin` to config for `universal_origin` benchmark (#6986)
  Cache `SessionInfo` on new activated leaf in `dispute-distribution` (#6993)
  Update Substrate to fix Substrate companions (#6994)
  Consolidate subsystem spans so they are all children of the leaf-activated root span (#6458)
  Avoid redundant clone. (#6989)
  bump zombienet version (#6985)
  avoid triggering unwanted room_id for the release notifs (#6984)
  Add crowdloan to SafeCallFilter (#6903)
  ...
ordian added a commit to paritytech/polkadot that referenced this pull request Apr 12, 2023
…slashing-client

* ao-past-session-slashing-runtime: (25 commits)
  [Deps] bump scale-info to be in line with cumulus (#7049)
  Invoke cargo build commands with `--locked` (#7057)
  use stable rust toolchain in ci
  apply clippy 1.68 suggestions
  Remove years from copyright notes (#7034)
  Onchain scraper in `dispute-coordinator` will scrape `SCRAPED_FINALIZED_BLOCKS_COUNT` blocks before finality (#7013)
  PVF: Minor refactor in workers code (#7012)
  Expose WASM bulk memory extension in execution environment parameters (#7008)
  Co #13699: Remove old calls (#7003)
  Companion for paritytech/substrate#13811 (#6998)
  PR review rules, include all rs files except weights (#6990)
  Substrate companion: Remove deprecated batch verification (#6999)
  Added `origin` to config for `universal_origin` benchmark (#6986)
  Cache `SessionInfo` on new activated leaf in `dispute-distribution` (#6993)
  Update Substrate to fix Substrate companions (#6994)
  Consolidate subsystem spans so they are all children of the leaf-activated root span (#6458)
  Avoid redundant clone. (#6989)
  bump zombienet version (#6985)
  avoid triggering unwanted room_id for the release notifs (#6984)
  Add crowdloan to SafeCallFilter (#6903)
  ...
ukint-vs pushed a commit to gear-tech/substrate that referenced this pull request Apr 13, 2023
* Expose WASM extensions in executor semantics

* Fix benches

* Remove redundant extensions
gpestana pushed a commit that referenced this pull request Apr 23, 2023
* Expose WASM extensions in executor semantics

* Fix benches

* Remove redundant extensions
gshep pushed a commit to gear-tech/substrate that referenced this pull request Jul 4, 2023
* Expose WASM extensions in executor semantics

* Fix benches

* Remove redundant extensions
nathanwhit pushed a commit to nathanwhit/substrate that referenced this pull request Jul 19, 2023
* Expose WASM extensions in executor semantics

* Fix benches

* Remove redundant extensions
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
A0-please_review Pull request needs code review. B0-silent Changes should not be mentioned in any release notes C1-low PR touches the given topic and has a low impact on builders. D3-trivial 🧸 PR contains trivial changes in a runtime directory that do not require an audit
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Expose WASM extensions in Wasmtime executor semantics
5 participants