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

Asynchronous backing: handle code upgrade signals properly #2580

@rphmeier

Description

@rphmeier

When a parachain wants to upgrade its code, it submits the new validation code to the relay chain. After some checks and a mandatory waiting period, the relay-chain sets a signal in its storage - either GoAhead or Abort. It is illegal to create a candidate that attempts to upgrade the code if there is already a pending code upgrade.

The GoAhead signal is cleared in the relay chain runtime after the first candidate which used a relay-parent at or after the relay-chain block where it was set is included. This means that the go-ahead signal may hang around in the relay-chain state for a few blocks afterwards.

pallet-parachain-system currently has this code, which panics if the GoAhead signal is set and there is no pending upgrade:

match upgrade_go_ahead_signal {
Some(relay_chain::UpgradeGoAhead::GoAhead) => {
assert!(
<PendingValidationCode<T>>::exists(),
"No new validation function found in storage, GoAhead signal is not expected",
);
let validation_code = <PendingValidationCode<T>>::take();
Self::put_parachain_code(&validation_code);
<T::OnSystemEvent as OnSystemEvent>::on_validation_code_applied();
Self::deposit_event(Event::ValidationFunctionApplied {
relay_chain_block_num: vfp.relay_parent_number,
});
},
Some(relay_chain::UpgradeGoAhead::Abort) => {
<PendingValidationCode<T>>::kill();
Self::deposit_event(Event::ValidationFunctionDiscarded);
},
None => {},
}

This means that if the parachain has scheduled a code upgrade, one candidate might see the GoAhead signal and process the code upgrade correctly, but the subsequent candidates (at the same relay-parent or within a few blocks of it) will be invalid. They will become valid again only once the relay-parent has advanced to a point where the GoAhead signal has vanished from the relay-chain state.

The issue here is just to avoid small amounts of downtime after parachains upgrade their code. The fix is to handle the code upgrade signals "properly" i.e. to ignore them when there is no pending code upgrade or the unincluded segment contains an applied/aborted code upgrade.

Metadata

Metadata

Assignees

Labels

I3-bugThe node fails to follow expected behavior.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions