Crate pallet_sidechain

Source
Expand description

Pallet that establishes a Partner Chain as a Cardano sidechain

§Purpose of this pallet

This pallet serves as the starting point for building a Partner Chain runtime. It stores its genesis UTXO which serves as its global identifier and divides Partner Chain slots into Partner Chain epochs.

§Genesis UTXO

When a Partner Chain governance is initialized on Cardano, the transaction spends a special genesis UTXO. This UTXO serves multiple crucial roles:

  • it serves as the unique identifier of the Partner Chain
  • it affects the addresses of all Partner Chain Toolkit’s Plutus smart contracts to allow multiple Partner Chains to exist
  • it is included in messages signed by various participants of the Partner Chain when submitting transactions (on both Cardano and the Partner Chain) to prevent replay attacks

The genesis UTXO is immutable throughout the lifetime of a Partner Chain in order to preserve its identity.

§Partner Chain Epochs

When producing blocks, Partner Chains divide time into slots in which a single block can be produced. These slots are in turn grouped into epochs which other Partner Chains features use as boundaries for some of their state transitions (eg. a Partner Chain block producing committees change at epoch boundaries). Both slot and epoch durations are constant and immutable throughout a Partner Chain’s lifetime.

§Usage

§Prerequisites

Before a Partner Chain can be started, its Cardano governance must be established by running the init transaction, which also determines the genesis UTXO of the Partner Chain. Consult docs/user-guides/governance/governance.md for instructions.

As Partner Chains operate on the basis of slots and epochs, your Substrate node should use a slot-based consensus mechanism such as Aura.

§Optional - defining a new epoch hook

A Partner Chain may need to perform custom logic when a new epoch starts, eg. pay out block production rewards, update chain participant standings etc. For this purpose, the pallet can be configured with a handler that will be triggered during initialization of each first block of a new epoch.

To create a new epoch handler, simply define a type and have it implement the [OnNewEpoch] trait:

use sidechain_domain::{ ScEpochNumber, ScSlotNumber };
use sp_runtime::Weight;

struct MyNewEpochHandler;
impl sp_sidechain::OnNewEpoch for MyNewEpochHandler {
    fn on_new_epoch(old_epoch: ScEpochNumber, new_epoch: ScEpochNumber) -> Weight {
        log::info!("Partner Chain epoch changed from {old_epoch} to {new_epoch}");
        Weight::zero()
    }
}

The weight returned by on_new_epoch should match its real resource use.

§Adding to runtime

The pallet requires minimal configuration, as it is only mandatory to inject the function that provides the current slot. Assuming that Aura consensus is used, the pallet can be configured like the following:

impl pallet_sidechain::Config for Runtime {
    fn current_slot_number() -> ScSlotNumber {
        ScSlotNumber(*pallet_aura::CurrentSlot::<Self>::get())
    }
    type OnNewEpoch = MyNewEpochHandler;
}

Optionally, a new epoch handler can be configured like in the example above. Partner Chains that do not need to run additional logic at epoch change can use the empty implementation available for [()]:

type OnNewEpoch = MyNewEpochHandler;

If multiple handlers need to be added, a tuple can be used for convenience:

type OnNewEpoch = (NewEpochHandler1, NewEpochHandler2);

§Genesis configuration

After the pallet is added to the runtime, configure it in your rust node code:

pallet_sidechain::GenesisConfig::<Runtime> {
    genesis_utxo: UtxoId::from_str("0000000000000000000000000000000000000000000000000000000000000000#0").unwrap(),
    slots_per_epoch: SlotsPerEpoch(60),
    ..Default::default()
}

or via a chain spec Json file:

{
    "sidechain_pallet": {
        "genesisUtxo": "0000000000000000000000000000000000000000000000000000000000000000#0",
        "slotsPerEpoch": 60
    }
}

Re-exports§

pub use pallet::*;

Modules§

pallet
The pallet module in each FRAME pallet hosts the most important items needed to construct this pallet.