• Sergey Pepyakin's avatar
    pvf-precheck: Integrate PVF pre-checking into paras module (#4457) · 47810dca
    Sergey Pepyakin authored
    * pvf-precheck: Integrate PVF pre-checking into paras module
    
    Closes #4009
    
    This is the most of the runtime-side change needed for #3211.
    
    Here is how it works.
    
    The PVF pre-checking can be triggered either by an upgrade or by
    onboarding (i.e. calling `schedule_para_initialize`). The PVF
    pre-checking process is identified by the PVF code hash that is being
    voted on. If there is already PVF pre-checking process running, then no
    new PVF pre-checking process will be started. Instead, we just subscribe
    to the existing one.
    
    If there is no PVF pre-checking process running but the PVF code hash
    was already saved in the storage, that necessarily means (I invite the
    reviewers to double-check this invariant) that the PVF already passed
    pre-checking. This is equivalent to instant approving of the PVF.
    
    The pre-checking process can be concluded either by obtaining a
    supermajority or if it expires.
    
    Each validator checks the list of PVFs available for voting. The vote is
    binary, i.e. accept or reject a given PVF. As soon as the supermajority
    of votes are collected for one of the sides of the vote, the voting is
    concluded in that direction and the effects of the voting are enacted.
    
    Only validators from the active set can participate in the vote. The set
    of active validators can change each session. That's why we reset the
    votes each session. A voting that observed a certain number of sessions
    will be rejected.
    
    The effects of the PVF accepting depend on the operations requested it:
    
    1. All onboardings subscribed to the approved PVF pre-checking process will
    get scheduled and after passing 2 session boundaries they will be onboarded.
    2. All upgrades subscribed to the approved PVF pre-checking process will
    get scheduled very similarly to the existing process. Upgrades with
    pre-checking are really the same process that is just delayed by the
    time required for pre-checking voting. In case of instant approval the
    mechanism is exactly the same. This is important from parachains
    compatibility standpoint since following the delayed upgrade requires
    the parachain to implement
    https://github.com/paritytech/cumulus/pull/517
    
    .
    
    In case, PVF pre-checking process was concluded with rejection, then all
    the requesting operations get cancelled. For onboarding it means it gets
    without movement: the lifecycle of such parachain is terminated on the
    `Onboarding` state and after rejection the lifecycle is none. That in
    turn means that the caller can attempt registering the parachain once
    more. For upgrading it means that the upgrade process is aborted: that
    flashes go-ahead signal with `Abort` flag.
    
    Rejection leads to removing the allegedly bad validation code from the
    chain storage. Among other things, this implies that the operation can
    be re-requested. That allows for retrying an operation in case there was
    some bug. At the same time it does not look as a DoS vector due to the
    caching performed by the nodes.
    
    PVF pre-checking can be enabled and disabled. Initially, according to
    the changes in #4420, this mechanism is disabled. Triggering the PVF
    pre-checking when it is disabled just means that we insta approve the
    requesting operation. This should lead to the behavior being unchanged.
    
    Follow-ups:
    
    - expose runtime APIs
    
    * cargo run --quiet --release --features=runtime-benchmarks -- benchmark --chain=polkadot-dev --steps=50 --repeat=20 --pallet=runtime_parachains::paras --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --header=./file_header.txt --output=./runtime/polkadot/src/weights/runtime_parachains_paras.rs
    
    * cargo run --quiet --release --features=runtime-benchmarks -- benchmark --chain=westend-dev --steps=50 --repeat=20 --pallet=runtime_parachains::paras --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --header=./file_header.txt --output=./runtime/westend/src/weights/runtime_parachains_paras.rs
    
    * cargo run --quiet --release --features=runtime-benchmarks -- benchmark --chain=kusama-dev --steps=50 --repeat=20 --pallet=runtime_parachains::paras --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --header=./file_header.txt --output=./runtime/kusama/src/weights/runtime_parachains_paras.rs
    
    * cargo run --quiet --release --features runtime-benchmarks -- benchmark --chain=rococo-dev --steps=50 --repeat=20 --pallet=runtime_parachains::paras --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --header=./file_header.txt --output=./runtime/rococo/src/weights/runtime_parachains_paras.rs
    
    * Review fixes
    
    Co-authored-by: default avatarParity Bot <[email protected]>
    47810dca