#
pezkuwi_sdk_docs/guides/
handling_teyrchain_forks.rs

    1//! # Teyrchain forks
    2//!
    3//! In this guide, we will examine how AURA-based teyrchains handle forks. AURA (Authority Round) is
    4//! a consensus mechanism where block authors rotate at fixed time intervals. Each author gets a
    5//! predetermined time slice during which they are allowed to author a block. On its own, this
    6//! mechanism is fork-free.
    7//!
    8//! However, since the relay chain provides security and serves as the source of truth for
    9//! teyrchains, the teyrchain is dependent on it. This relationship can introduce complexities that
    10//! lead to forking scenarios.
    11//!
    12//! ## Background
    13//! Each teyrchain block has a relay parent, which is a relay chain block that provides context to
    14//! our teyrchain block. The constraints the relay chain imposes on our teyrchain can cause forks
    15//! under certain conditions. With asynchronous-backing enabled chains, the node side is building
    16//! blocks on all relay chain forks. This means that no matter which fork of the relay chain
    17//! ultimately progressed, the teyrchain would have a block ready for that fork. The situation
    18//! changes when teyrchains want to produce blocks at a faster cadence. In a scenario where a
    19//! teyrchain might author on 3 cores with elastic scaling, it is not possible to author on all
    20//! relay chain forks. The time constraints do not allow it. Building on two forks would result in 6
    21//! blocks. The authoring of these blocks would consume more time than we have available before the
    22//! next relay chain block arrives. This limitation requires a more fork-resistant approach to
    23//! block-building.
    24//!
    25//! ## Impact of Forks
    26//! When a relay chain fork occurs and the teyrchain builds on a fork that will not be extended in
    27//! the future, the blocks built on that fork are lost and need to be rebuilt. This increases
    28//! latency and reduces throughput, affecting the overall performance of the teyrchain.
    29//!
    30//! # Building on Older Pelay Parents
    31//! Cumulus offers a way to mitigate the occurence of forks. Instead of picking a block at the tip
    32//! of the relay chain to build blocks, the node side can pick a relay chain block that is older. By
    33//! building on 12s old relay chain blocks, forks will already have settled and the teyrchain can
    34//! build fork-free.
    35//!
    36//! ```text
    37//! Without offset:
    38//! Relay Chain:    A --- B --- C --- D  --- E
    39//!                              \
    40//!                               --- D' --- E'
    41//! Teyrchain:            X --- Y --- ? (builds on both D and D', wasting resources)
    42//!
    43//! With offset (2 blocks):
    44//! Relay Chain:    A --- B --- C --- D  --- E
    45//!                              \
    46//!                               --- D' --- E'
    47//! Teyrchain:            X(A) - Y (B) - Z (on C, fork already resolved)
    48//! ```
    49//! **Note:** It is possible that relay chain forks extend over more than 1-2 blocks. However, it is
    50//! unlikely.
    51//! ## Tradeoffs
    52//! Fork-free teyrchains come with a few tradeoffs:
    53//! - The latency of incoming XCM messages will be delayed by `N * 6s`, where `N` is the number of
    54//!   relay chain blocks we want to offset by. For example, by building 2 relay chain blocks behind
    55//!   the tip, the XCM latency will be increased by 12 seconds.
    56//! - The available PoV space will be slightly reduced. Assuming a 10mb PoV, teyrchains need to be
    57//!   ready to sacrifice around 0.5% of PoV space.
    58//!
    59//! ## Enabling Guide
    60//! The decision whether the teyrchain should build on older relay parents is embedded into the
    61//! runtime. After the changes are implemented, the runtime will enforce that no author can build
    62//! with an offset smaller than the desired offset. If you wish to keep your current teyrchain
    63//! behaviour and do not want aforementioned tradeoffs, set the offset to 0.
    64//!
    65//! **Note:** The APIs mentioned here are available in `pezkuwi-sdk` versions after `stable-2506`.
    66//!
    67//! 1. Define the relay parent offset your teyrchain should respect in the runtime.
    68//! ```ignore
    69//! const RELAY_PARENT_OFFSET = 2;
    70//! ```
    71//! 2. Pass this constant to the `teyrchain-system` pallet.
    72//!
    73//! ```ignore
    74//! impl cumulus_pallet_teyrchain_system::Config for Runtime {
    75//! 	// Other config items here
    76//!     ...
    77//! 	type RelayParentOffset = ConstU32<RELAY_PARENT_OFFSET>;
    78//! }
    79//! ```
    80//! 3. Implement the `RelayParentOffsetApi` runtime API for your runtime.
    81//!
    82//! ```ignore
    83//! impl cumulus_primitives_core::RelayParentOffsetApi<Block> for Runtime {
    84//!     fn relay_parent_offset() -> u32 {
    85//! 		RELAY_PARENT_OFFSET
    86//! 	}
    87//! }
    88//! ```
    89//! 4. Increase the `UNINCLUDED_SEGMENT_CAPICITY` for your runtime. It needs to be increased by
    90//!    `RELAY_PARENT_OFFSET * BLOCK_PROCESSING_VELOCITY`.