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

Asynchronous backing: handle code upgrade signals properly #2580

Closed
rphmeier opened this issue May 15, 2023 · 1 comment
Closed

Asynchronous backing: handle code upgrade signals properly #2580

rphmeier opened this issue May 15, 2023 · 1 comment
Assignees
Labels
I3-bug The node fails to follow expected behavior.

Comments

@rphmeier
Copy link
Contributor

rphmeier commented May 15, 2023

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.

@slumber
Copy link
Contributor

slumber commented May 22, 2023

#2594

@slumber slumber closed this as completed May 22, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
I3-bug The node fails to follow expected behavior.
Projects
None yet
Development

No branches or pull requests

2 participants