Oraichain genesis.json deep-dive

Hey ya’ll, today we’re doing something a bit different, i’ll try to explain to you what’s going on in the genesis.json, what it’s purpose is, and what the different fields in the file do / mean.

The genesis.json file sets all the initial parameters used to determine the state when starting the blockchain for the first time. So it’s quite important as you might imagine 😉

The layout of the genesis.json consists of 6 main parts that i’ll be covering below. For each part we’ll go into the details of the different subsections where necessary to give you a better understanding of the workings and why some choices have been made by the Oraichain team.

The main parts the genesis.json consists of are:

{
  "genesis_time": "2021-02-14T08:44:16.2651666Z",
  "chain_id": "Oraichain",
  "initial_height": "1",
  "consensus_params": {},
  "app_hash": "",
  "app_state": {}
}

1. genesis_time

This is nothing more and nothing less than the official time of the blockchain start.

2. chain_id

The official ID of the blockchain, this must be unique for every blockchain.

3. initial_height

Height at which the blockchain should begin. Usually this will be 1, with the exception of perhaps doing a network upgrade and needing to separate previous blocks.

4. consensus_params

Now we’re beginning to get to the interesting parts. The consensus_params define various limits for the blockchain data structures. Consensus_params consist of a few different parts:

    "block": {
      "max_bytes": "22020096",
      "max_gas": "-1",
      "time_iota_ms": "1000"
    },
    "evidence": {
      "max_age_num_blocks": "100000",
      "max_age_duration": "172800000000000",
      "max_bytes": "1048576"
    },
    "validator": {
      "pub_key_types": [
        "ed25519"
      ]
    },
    "version": {}

4.1 block

Here we’re defining the limits for a block:

  • max_bytes: Maximum size for a block in bytes, if it’s larger the block will be considered invalid.
  • max_gas: Maximum gas used per tx in the block.
  • time_iota_ms: (unused / deprecated) Minimal time between consecutive blocks.

4.2 evidence

For evidence in a block to be valid it must meet these criteria:

  • max_age_num_blocks: Max age of evidence, in blocks. The basic formula for calculating this is: MaxAgeDuration / {average block time}.
  • max_age_duration: Max age of evidence, in time. It should correspond with an app’s “unbonding period” or other similar mechanism for handling Nothing-At-Stake attacks.
  • max_bytes: This sets the maximum number of evidence that can be committed in a single block. and should fall comfortably under the max block bytes when we consider the size of each evidence.

4.3 validator

This sets the type of public keys validators must use.

4.4 version

ABCI application version.

5. app_hash

The expected application hash (as returned by the ResponseInfo ABCI message) upon genesis.

6. app_state

This defines the application state and consists of several parts again:

    "airequest": {},
    "airesult": {},
    "auth": {},
    "bank": {},
    "capability": {},
    "crisis": {},
    "distribution": {},
    "evidence": {},
    "genutil": {},
    "gov": {},
    "ibc": {},
    "mint": {},
    "provider": {},
    "slashing": {},
    "staking": {},
    "transfer": {},
    "wasm": {},
    "websocket": {}
  • airequest: This is one of the Oraichain custom modules we’ll cover in more detail below
  • airesult: This is one of the Oraichain custom modules we’ll cover in more detail below
  • auth: Authentication of accounts and transactions for Cosmos SDK application.
  • bank: Token transfer functionalities.
  • capability: Object capability implementation.
  • crisis: Halting the blockchain under certain circumstances (e.g. if an invariant is broken).
  • distribution: Fee distribution, and staking token provision distribution.
  • evidence: Evidence handling for double signing, misbehavior, etc.
  • genutil: This contains the declaration of the initial validators of the chain.
  • gov: On-chain proposals and voting.
  • ibc: IBC protocol for transport, authentication and ordering.
  • mint: Creation of new units of staking token.
  • provider: This is one of the Oraichain custom modules we’ll cover in more detail below
  • slashing: Validator punishment mechanisms.
  • staking: Proof-of-Stake layer for public blockchains.
  • transfer: Part of the IBC configuration.
  • wasm: Configuration of CosmWasm, the smart contracts module used.
  • websocket: This is one of the Oraichain custom modules we’ll cover in more detail below

6.1 airequest

    "airequest": {
      "ai_requests": [],
      "params": {
        "maximum_request_bytes": "1048576"
      }
    },

This is used to create AI requests, where it forwards the request to a specific number of validators to be executed. AI requests are stored on-chain as proof and references.

  • maximum_request_bytes – the maximum AI request size that an user can create.

6.2 airesult

    "airesult": {
      "ai_request_results": [],
      "params": {
        "expiration_count": "10",
        "total_reports": "70"
      }
    },

This one collects all the reports and stores them as a single result object on-chain for querying. It also creates the reward objects to reward providers and validators.

  • total_reports – the percentage of reports required for a result to be considered finished.
  • expiration_count (currently unused) – the maximum number of blocks starting from the block that an AI request is created that a report can be put to be considered valid. For example, a request is created at block 10, if a report from a validator comes at block 21 (default the expiration count is 10), then it will be invalid. If the report comes at block 19 or 20 then it is valid.

6.3 auth

      "params": {
        "max_memo_characters": "256",
        "tx_sig_limit": "7",
        "tx_size_cost_per_byte": "5",
        "sig_verify_cost_ed25519": "590",
        "sig_verify_cost_secp256k1": "1000"
      },
      "accounts": []
    },

The auth module is responsible for specifying the base transaction and account types for an application, since the SDK itself is agnostic to these particulars. It contains the ante handler, where all basic transaction validity checks (signatures, nonces, auxiliary fields) are performed, and exposes the account keeper, which allows other modules to read, write, and modify accounts.

Currently the default values proposed for the auth module are used.

6.4 bank

    "bank": {
      "params": {
        "send_enabled": [],
        "default_send_enabled": true
      },
      "balances": [],
      "supply": [],
      "denom_metadata": []
    },

The bank module is responsible for handling multi-asset coin transfers between accounts and tracking special-case pseudo-transfers which must work differently with particular kinds of accounts (notably delegating/undelegating for vesting accounts). It exposes several interfaces with varying capabilities for secure interaction with other modules which must alter user balances.

In addition, the bank module tracks and provides query support for the total supply of all assets used in the application.

  • send_enabled: The send enabled parameter is an array of SendEnabled entries mapping coin denominations to their send_enabled status. Entries in this list take precedence over the DefaultSendEnabled setting.
  • default_send_enabled: The default send enabled value controls send transfer capability for all coin denominations unless specifically included in the array of SendEnabled parameters.

6.5 capability

    "capability": {
      "index": "1",
      "owners": []
    },

Capability is a module that allows for provisioning, tracking, and authenticating multi-owner capabilities at runtime.

6.6 crisis

    "crisis": {
      "constant_fee": {
        "denom": "orai",
        "amount": "10000000"
      }
    },

The crisis module halts the blockchain under the circumstance that a blockchain invariant is broken. Invariants can be registered with the application during the application initialization process.

  • constant_fee: Due to the anticipated large gas cost requirement to verify an invariant (and potential to exceed the maximum allowable block gas limit) a constant fee is used instead of the standard gas consumption method. The constant fee is intended to be larger than the anticipated gas cost of running the invariant with the standard gas consumption method.

6.7 distribution

    "distribution": {
      "params": {
        "community_tax": "0.020000000000000000",
        "base_proposer_reward": "0.010000000000000000",
        "bonus_proposer_reward": "0.040000000000000000",
        "withdraw_addr_enabled": true
      },
      "fee_pool": {
        "community_pool": []
      },
      "delegator_withdraw_infos": [],
      "previous_proposer": "",
      "outstanding_rewards": [],
      "validator_accumulated_commissions": [],
      "validator_historical_rewards": [],
      "validator_current_rewards": [],
      "delegator_starting_infos": [],
      "validator_slash_events": []
    },

This simple distribution mechanism describes a functional way to passively distribute rewards between validators and delegators.

  • community_tax: The value of communitytax must be positive and cannot exceed 1.00. The community tax (2$ by default) will be charged on every block reward (including the transaction fees). The proposer will not be charged, but the other validators receiving the rewards will.
  • base_proposer_reward and bonus_proposer_reward must be positive and their sum cannot exceed 1.00. Base proposer reward and bonus proposer reward are used to specify the percentage of reward that the proposer receives. Default is 1% base reward and 4% bonus reward.

6.8 evidence

    "evidence": {
      "evidence": []
    },

Evidence is a module, that allows for the submission and handling of arbitrary evidence of misbehavior such as equivocation and counterfactual signing.

The evidence module differs from standard evidence handling which typically expects the underlying consensus engine, e.g. Tendermint, to automatically submit evidence when it is discovered by allowing clients and foreign chains to submit more complex evidence directly.

6.9 genutil

This contains the declaration of the initial validators of the chain.

6.10 gov

    "gov": {
      "starting_proposal_id": "1",
      "deposits": [],
      "votes": [],
      "proposals": [],
      "deposit_params": {
        "min_deposit": [
          {
            "denom": "orai",
            "amount": "10000000"
          }
        ],
        "max_deposit_period": "172800s"
      },
      "voting_params": {
        "voting_period": "600s"
      },
      "tally_params": {
        "quorum": "0.334000000000000000",
        "threshold": "0.500000000000000000",
        "veto_threshold": "0.334000000000000000"
      }
    },

The module enables an on-chain governance system. In this system, holders of the native staking token of the chain can vote on proposals on a 1 token 1 vote basis.

  • deposit_params - min_deposit: Minimum deposit for a proposal to enter voting period. The default value of 10000000 is currently used.
  • deposit_params - max_deposit_period: Maximum period for ORAI holders to deposit on a proposal. The default value of 48 hours (172800 seconds) is currently used.
  • voting_params - voting_period: Length of the voting period. The default value for the voting period is 48 hours, currently a value of 10 minutes is used.
  • tally_params - quorum: Minimum percentage of stake that needs to vote for a proposal to be considered valid. This means that at least 1/3 (33.3%, the default value) of the voting power need to vote for the results to count.
  • tally_params - threshold: Minimum proportion of Yes votes for proposal to pass. The default is 50%.
  • tally_params - veto_threshold: Minimum proportion of Veto votes to Total votes ratio for proposal to be vetoed. The default value is 1/3 (33.3%).

For a proposal to pass with the current configuration it must fullfill the following requirements:

  • At least 1/3 of voting power needs to cast it’s vote.
  • At least 50% of people voting need to vote Yes.
  • No more than 1/3 of people may vote No with a veto vote.

6.11 ibc

    "ibc": {
      "client_genesis": {
        "clients": [],
        "clients_consensus": [],
        "clients_metadata": [],
        "params": {
          "allowed_clients": [
            "06-solomachine",
            "07-tendermint"
          ]
        },
        "create_localhost": false,
        "next_client_sequence": "0"
      },
      "connection_genesis": {
        "connections": [],
        "client_connection_paths": [],
        "next_connection_sequence": "0"
      },
      "channel_genesis": {
        "channels": [],
        "acknowledgements": [],
        "commitments": [],
        "receipts": [],
        "send_sequences": [],
        "recv_sequences": [],
        "ack_sequences": [],
        "next_channel_sequence": "0"
      }
    },

The IBC module configures the inter-blockchain protocol settings.

6.12 mint

    "mint": {
      "minter": {
        "inflation": "0.130000000000000000",
        "annual_provisions": "0.000000000000000000"
      },
      "params": {
        "mint_denom": "orai",
        "inflation_rate_change": "0.130000000000000000",
        "inflation_max": "0.200000000000000000",
        "inflation_min": "0.070000000000000000",
        "goal_bonded": "0.670000000000000000",
        "blocks_per_year": "6311200"
      }
    },

The minting mechanism was designed to:

  • allow for a flexible inflation rate determined by market demand targeting a particular bonded-stake ratio
  • effect a balance between market liquidity and staked supply

In order to best determine the appropriate market rate for inflation rewards, a moving change rate is used. The moving change rate mechanism ensures that if the % bonded is either over or under the goal %-bonded, the inflation rate will adjust to further incentivize or disincentivize being bonded, respectively. Setting the goal %-bonded at less than 100% encourages the network to maintain some non-staked tokens which should help provide some liquidity.

  • minter - inflation: current annual inflation rate. This is set at the default value of 13%.
  • minter - annual_provisions: current annual expected provisions.
  • params - mint_denom: type of coin to mint.
  • params - inflation_rate_change: maximum annual change in inflation rate. This is set at the default value of 13%.
  • params - inflation_max: maximum inflation rate. This is set at the default value of 20%.
  • params - inflation_min: minimum inflation rate. This is set at the default value of 7%.
  • params - goal_bonded: goal of percent bonded ORAIs. This is set at the default value of 67%.
  • params - blocks_per_year: expected blocks per year. The default value for this field is 6311520, currently it is set to 6311200

6.13 provider

    "provider": {
      "AIDataSources": [],
      "OracleScripts": [],
      "TestCases": [],
      "params": {
        "oracle_script_reward_percentage": "60",
        "maximum_code_bytes": "1048576"
      }
    },

This module is used to store metadata information of the providers that create smart contracts as well as fees required to use their contracts.

  • oracle_script_reward_percentage – the percentage of reward that belongs to the providers, while the rest goes to the validators. If we have 1 ORAI token reward, then 0.6 goes to the providers, and 0.4 goes to the validators.
  • maximum_code_bytes (currently unused) – maximum smart contract size that one can deploy.

6.14 slashing

    "slashing": {
      "params": {
        "signed_blocks_window": "30000",
        "min_signed_per_window": "0.050000000000000000",
        "downtime_jail_duration": "600s",
        "slash_fraction_double_sign": "0.050000000000000000",
        "slash_fraction_downtime": "0.000100000000000000"
      },
      "signing_infos": [],
      "missed_blocks": []
    },

The slashing module enables Cosmos SDK-based blockchains to disincentivize any attributable action by a protocol-recognized actor with value at stake by penalizing them (“slashing”).

  • signed_blocks_window: defines the size (number of blocks) of the sliding window used to track validator liveness. The default value is 100, currently it’s set at 30000.
  • min_signed_per_window: used to determine the maximum number of blocks missed and crosses below the liveness threshold: SignedBlocksWindow - (MinSignedPerWindow * SignedBlocksWindow). The default value for this parameter is 0.5, it is currently set at 0.05.
  • downtime_jail_duration: time for which the validator is jailed due to liveness downtime. This is set at the default value of 600 seconds.
  • slash_fraction_double_sign: amount validator will be slashed by on occurrence of double sign. This is set at the default value of 0,05.
  • slash_fraction_downtime: amount validator will be slashed by on occurrence of liveness downtime. The default value for this parameter is 0,01, it is currently set at 0,0001.

6.15 staking

    "staking": {
      "params": {
        "unbonding_time": "7200s",
        "max_validators": 100,
        "max_entries": 7,
        "historical_entries": 1000,
        "bond_denom": "orai"
      },
      "last_total_power": "0",
      "last_validator_powers": [],
      "validators": [],
      "delegations": [],
      "unbonding_delegations": [],
      "redelegations": [],
      "exported": false
    },

The module enables Cosmos-SDK based blockchain to support an advanced Proof-of-Stake system. In this system, holders of the native staking token of the chain can become validators and can delegate tokens to validators, ultimately determining the effective validator set for the system.

  • unbonding_time: Time that delegations must wait upon unbonding of the validator before moving/receiving their tokens to their accounts from the BondedPool. This is currently set at 2 hours, the default value is 259200 seconds, which is 72 hours.
  • max_validators: Maximum number of validators. This is set at the default value of 100.
  • max_entries: Maximum number of entries for UnbondingDelegations or Redelegation. This is set at the default value of 7.
  • historical_entries: Maximum number of HistoricalInfo objects that are stored and pruned at each block. This is set to 1000 entries, the default value is 3.

6.16 transfer

    "transfer": {
      "port_id": "transfer",
      "denom_traces": [],
      "params": {
        "send_enabled": true,
        "receive_enabled": true
      }
    },

Holds part of the IBC configuration.

6.17 wasm

    "wasm": {
      "params": {
        "code_upload_access": {
          "permission": "Everybody",
          "address": ""
        },
        "instantiate_default_permission": "Everybody",
        "max_wasm_code_size": "614400"
      },
      "codes": [],
      "contracts": [],
      "sequences": [],
      "gen_msgs": []
    },

Configuration of CosmWasm, the smart contracts module used.

6.18 websocket

    "websocket": {
      "Reports": [],
      "Reporters": []
    }

The websocket module is used to execute the AI requests separately by the validators. After executing, validators create reports to store on-chain as proof to receive reward.

And that’s it, now you know what the details are on the genesis.json and hopefully understand the setup of Oraichain better.

If you have questions hit me up on telegram, or ask in the Orai Technical Channel.

Leave a comment