Skip to main content

Genesis creation

Horizen initial state is not empty, but reflects the data present in both previous Horizen's chains: ZEND Mainchain and EON.

The pre-calculated initial state, mandatory to start a new collator node, is available for download at this URL: [TODO]

To verify its correctness, anyone can follow the instructions in this tutorial and regenerate the same data.

Prerequisites:

The following software is needed:

  1. Fully synched ZEND Mainchain node with dump support enabled:

  2. Fully synched EON Chain node with dump support enabled:

    • Download latest EON release node
    • Add the following fragment in the config file to enable state dump support (important: the fragment must be added BEFORE starting to synch the chain):
    evmStateDump {
    enabled = true
    }
    • Start the node and have it fully synched with the old mainchain

Instructions:

The ZEND Mainchain height that marks the migration will be an input parameter of the process: we will call it MC_MIGRATION_HEIGHT.

  1. Execute a dump of ZEND balances at that specified height:

    killall zend
    ./src/dumper -H MC_MIGRATION_HEIGHT > utxos.csv

    Please note the following:

    • killall is needed because ZEND must be stopped while performing the dump
    • If executing a dump of the testnet you must add the flag: -t
    • MC_MIGRATION_HEIGHT must be not too old in the past compared to the latest tip: maximum supported height is tip-100
  2. Determination of the EON blockhash to be used for the dump:

    we need to identify the EON block that contains a reference to the mainchain block used for the dump in step 1.

    Execute the following call on the EON node, replacing the MC_MIGRATION_HEIGHT with the correct value:

    curl -sX POST 'http://127.0.0.1:9085/mainchain/blockReferenceInfoBy' -H 'Content-Type: application/json' -H 'accept: application/json' -d '{"height":MC_MIGRATION_HEIGHT, "format": true}' 

    In the response result:

    • hash: corresponds to the mainchain block hash at height MC_MIGRATION_HEIGHT
    • mainchainHeaderSidechainBlockId: it's the EON blockhash of the migration, we'll call it EON_MIGRATION_HASH
  3. Dump of EON State:

    Execute the following call on the EON node:
    First parameter of the method must be replaced by EON_MIGRATION_HASH, second one is the local-path of the output dump.

     curl --request POST 'http://127.0.0.1:9085/ethv1' -H 'Content-Type: application/json' -H 'accept: application/json' -d '{ "jsonrpc":"2.0", "method":"zen_dump", "params":["0xbda76ab769c4e158f8e8add81bdf17c9d919fb54cd5e32f1c83cebdfc3dc363c","/zendata/horizen/genesis/TESTNET_1574340/eon_gobi.dump"], "id":1 }'  
  4. Execute the dump of the EON stakes:

    Can be executed by calling the script get_all_forger_stakes.py:

    (Replace parameter EON_MIGRATION_HEIGHT with the height of the block EON_MIGRATION_HASH)

    python3 get_all_forger_stakes.py EON_MIGRATION_HEIGHT
  5. Convert ZEND csv dump in json format, with the script zend_to_horizen.py:

    Replace the parameter with the path of the file generated at step 1

    python3 zend_to_horizen.py /zendata/horizen/genesis/TESTNET_1574340/utxos.csv
  6. Obtain the plain chain spec template:

    This file contains the intial settings of the parachain, excluded any dump of previous states. For the final testnet/mainnet will be provided by HorizenLabs.

  7. Merge all the previous artifacts to obtain the final chain spec in plain format with the python script setup_eon2_genesis_json.py:

    python3 setup_eon2_genesis_json.py <step3_file> <step4_file> <step5_file> <step6_file> 
  8. Generate the final artifacts starting from the outcome of the previous step:

    In orded to do this you will need a modified docker image able to handle "big size" spec files.
    It is published on DockerHub on every tag, at the docker url: horizen/horizen-spec-builder:< version_number >
    (for example, for Horizen 0.1.0 you can use the image: horizen/horizen-spec-builder:0.1.0
    The artifacts can be generated by interacting with the docker image, as in the following examples:

    1. Raw chain spec:

      docker run --rm -v <step_7_file>:/tmp/para-spec.json --entrypoint horizen-spec-builder $DOCKER_RELEASE build-spec --chain /tmp/para-spec.json  --disable-default-bootnode --raw   > <output_file>


    2. Genesis wasm runtime:

      docker run --rm -v <step_8.1_file>:/tmp/para-spec-raw.json --entrypoint horizen-spec-builder $DOCKER_RELEASE export-genesis-wasm --chain "/tmp/para-spec-raw.json" > <output_wasm>


    3. Genesis state:

      docker run --rm -v <step_8.1_file>:/tmp/para-spec-raw.json --entrypoint horizen-spec-builder $DOCKER_RELEASE export-genesis-state --chain "/tmp/para-spec-raw.json" > <output_genesis_state>

The output of step 8.3 will be a hash of the entire genesis data. By verifying that it matches the one published by Horizen Labs, you can ensure that no data has been tampered with.