Update genesis block schema and processing

Hello everyone,

In this thread, I want to propose a new LIP for the roadmap objective “Update genesis block schema and processing”. This proposal defines how the generic serialization algorithm will be applied to genesis blocks and specify the appropriate JSON schema.

Looking forward to your feedback.

Here is the complete LIP draft:

LIP: <LIP number>
Title: Update genesis block schema and processing
Author: Iker Alustiza <iker@lightcurve.io>
Type: Standards Track
Created: <YYYY-MM-DD>
Updated: <YYYY-MM-DD>
Requires: BFT module LIP, LIP 0040, Update block schema and block processing LIP

Abstract

This LIP adapts the specifications of the genesis block for blockchains created with Lisk SDK introduced in LIP 0034 to the requirements and characteristics of the new state model introduced in LIP 0040. It does so by following the general block format and processing introduced in the Update block schema and block processing LIP.

Copyright

This LIP is licensed under the Creative Commons Zero 1.0 Universal.

Motivation

LIP 0034 introduced a block asset schema that allows to directly specify an initial state for blockchains created with Lisk SDK. However, with the specification of the Lisk interoperability solution and the new state model it introduces, it is necessary to redefine and update the format and processing of a genesis block for blockchains created with Lisk SDK.

Rationale

Usage of assets property of the block

The new genesis block format and processing is specified with the rationale of having a compact and self-contained way of initializing a blockchain in the Lisk ecosystem. With this in mind, this LIP defines a genesis block format and processing based on the specifications given in Update block schema and block processing LIP. In particular, the assets property contains the necessary information to initialize the state of the blockchain. Each element in the assets array contains the information necessary to set the state store for a given module. Hence, each module should define the format and processing logic for this information in the genesis block.

Processing of the genesis block

Another distinctive specification of the genesis block is its processing. The blockchain starts with an empty key-value store and in particular, all module stores are empty initially. As part of the genesis block processing modules can add key-value entries to their module store to initialize their state. They should also check the consistency of their state independently and against information provided by other modules. Also, before this is done, the framework layer has to validate the block header and the block format itself. Hence, this LIP defines steps specific to the processing of the genesis block: a step to initialize the state store per each module and the second step to verify this initial state. In particular the processing of the genesis block happens in four steps described in the sections below.

Static validation of the genesis block

The genesis block has to go through initial static checks to ensure that the serialized object follows the general structure of a block. Also, certain properties of the block header are checked at this stage. All of these checks are stateless since the state of the blockchain is yet to be initialized. The key differences as compared to the validation for the rest of the blocks in a blockchain are that there is no specific size limit for the genesis block object and that the payload must be empty, i. e., the genesis block should not contain any transaction.

Genesis state Initialization

At this stage, the genesis state initialization logic for all registered modules is executed. For this purpose, registered modules can specify processing logic considering the information in their corresponding entry of the assets property. Typically, modules will perform format and data consistency checks of their respective element in assets and then initialize their state according to the data provided in it. However, modules should not call protocol logic of other modules as the state of the respective module may not be initialized.

Genesis state finalization

At this stage, the genesis state finalization logic for all registered modules is executed. As part of the genesis state finalization logic modules may call exposed functions from other modules to cross-check the state information integrity and/or complete their own state. When this step is completed, there should be a valid initial state for our blockchain ready to process state transitions implied by the next block.

Result verification of the genesis block

Finally, the verifications for block header properties are performed for which access to the state store is required. For example, in the case of stateRoot, it requires the genesis state to be final before being checked.

Specification

In this section, we specify the schema of the genesis block and its validity and execution rules.

Constant

Name Type Value Description
EMPTY_HASH bytes SHA-256("") Hash of empty bytes.

Processing stages of the genesis block, block assets, and block header

As introduced in the Rationale section, the processing of the genesis block is performed in four different stages:

  • Static validation of the genesis block: The stateless checks to ensure the structure of the genesis block are performed. Also, the properties in the block header that do not require access to the state store are checked.
    These checks are defined in the sections below.
  • Genesis state initialization: The genesis state initialization logic for the registered modules is executed.
  • Genesis state finalization: The genesis state finalization logic for the registered modules is executed.
  • Result verification of the genesis block: The block header properties that require access to the state store are verified as specified below.

Genesis block

JSON schema

The genesis block schema is the same as the one defined in Update block schema and block processing LIP.

Validation

The genesis block is validated in the static validation stage as follows:

  • Static validation of the genesis block:
    • Check that the payload property is set to its default value, i.e., empty array.

Block ID

The genesis block ID is computed in the same way as for any other block.

Assets property of the genesis block

JSON schema

The asset schema is the same as defined in the Update block schema and block processing LIP.

Validation

The block assets property is validated as follows:

  • Static validation of the genesis block:

Header of the genesis block

JSON schema

The genesis block header schema is the same as the one defined in Update block schema and block processing LIP.

Validation

The block header is processed as follows:

  • Static validation of the genesis block:
    • Check that the block header follows the block header schema.
    • The value b.header.version can be any uint32 integer.
    • The value of b.header.transactionRoot is equal to EMPTY_HASH.
    • The value b.header.assetsRoot is validated as specified in Update block schema and block processing LIP.
    • The value b.header.timestamp is a Unix time in seconds and can be any value in the uint32 range.
    • The value b.header.height can be any value in the uint32 range.
    • The value b.header.previousBlockID can be any 32-byte value.
    • The value of b.header.generatorAddress is empty bytes.
    • The value of b.header.maxHeightPrevoted is equal to b.header.height.
    • The value b.header.maxHeightGenerated is equal to 0.
    • The value of b.header.aggregateCommit.height is 0.
    • The value of b.header.aggregateCommit.signature is empty bytes.
    • The value of b.header.aggregateCommit.aggregationBits is empty bytes.
    • The value of b.header.signature is empty bytes.
  • Result verification of the genesis block:

Backwards Compatibility

This LIP defines a new block schema and processing, but does not imply a hardfork of Lisk Mainnet.

A PR for this LIP was opened days ago in the LIP repository: