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:
-
Fully synched ZEND Mainchain node with dump support enabled:
- Download latest ZEND release from here: https://github.com/HorizenOfficial/zen/releases
- Follow the instructions here https://github.com/HorizenLabs/migration-tools/tree/main/snapshot to patch the ZEND node in order to have dump support enabled
- Compile the node, start and have it fully synched with the old mainchain
-
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.
-
Execute a dump of ZEND balances at that specified height:
killall zend
./src/dumper -H MC_MIGRATION_HEIGHT > utxos.csvPlease 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
-
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
-
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 }'
-
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
-
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
-
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.
-
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>
-
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:-
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>
-
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>
-
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.