Running your own Testnet ======================== This tutorial shows you how to create your own testnet network if you want more freedom to develop your dapp or to test your baking infrastructure locally. We will suppose that you want your network to be called ``APPNET``. Building a new Branch ``appnet`` -------------------------------- First, clone the sources of Dune Network from `https://gitlab.com/dune-network/dune-network `__, and checkout either the ``testnet`` branch (current Testnet) or the ``next`` branch (development branch). Build it. Now, create your own branch (it will make it easier for other devs to use your network):: git checkout -b appnet You will need to modify the file ``src/lib_config/set_config_testnet.ml`` under a new name, and make it available as ``set_config.ml``:: cd src/lib_config cp set_config_testnet.ml set_config_appnet.ml ln -sf set_config_appnet.ml set_config.ml git add set_config.ml set_config_appnet.ml Now, you can edit the content of ``set_config_appnet.ml``: * Change the name of the network ``network`` to ``"Appnet"`` * Change the ``genesis_time`` to the current date (it will prevent your network to connect to the official Testnet) * Create a new genesis initial block. For that, run the following command with the date that you have chosen:: $ dune-client dune generate genesis hash -d 2019-06-24T12:00:00Z Date: 2019-06-24T12:00:00Z Hash: BLockGenesisGenesisGenesisGenesisGenesis5e671cK5Xad Use the hash in ``genesis_block``. * Change ``bootstrap_peers`` with the address:port of the first node of your network (other nodes will try to connect to it automatically) * Change ``prefix_dir`` if you don't want to conflict with Dune's configuration file. For example, if you set ``prefix_dir`` to ``app``, the ``dune-node`` command will look for its files in ``$HOME/.app-node`` and the ``dune-client`` in ``$HOME/.app-client``. * Change the ``genesis_key`` to the public key (``edpk``) of an account that you will use to activate the network. If you want to create such a key, you can use:: $ dune-client gen keys app-activator Key app-activator registered $dune-client show address app-activator Hash: dn1XA5ieuGaBfFRTBY5bR3VUT8LHV2Q5CSK2 Public Key: edpkvMberySJBQ71TdWo7Fg4bryxNX72JBLjwM8N9WcX9cNPnYdAtU Now, you can clean and rebuild:: make clean make Normally, you should see messages like ``Network Config: Appnet`` in the build log. Starting the Network -------------------- If you have not changed the ``prefix_dir`` in the previous stage, beware that you will need to specify your own directory for the node (using ``--data-dir``) or you need to remove the files/directories ``context`` and ``store`` in ``$HOME/.dune-node``. If you start the node now, the node will start in the genesis protocol, called ``Ps9mPmXa``, from where the only block you can create is to activate a new protocol. To simplify these steps, you can use the scripts available in the ``run-scripts`` directory of Dune Network. To activate a new protocol, you will need some files, so let's start by creating a directory to store these new files:: mkdir $HOME/genesis-appnet The scripts in ``run-scripts`` use a configuration script called ``$HOME/dune-env.sh``. Let's create it:: #!/bin/sh DUNE_EXECDIR=$HOME/dune-appnet-2019-06-24 DUNE_NET_PORT=9733 DUNE_RPC_ADDR=127.0.0.1 DUNE_RPC_PORT=8733 GENESIS_DIR=$HOME/genesis-appnet DUNE_BOOTSTRAP_THRESHOLD=0 The first variable ``DUNE_EXECDIR`` is used to set a top directory where all executable ran by ``run-scripts`` are executed. For example, ``dune-node`` will have its data directory in ``$HOME/dune-appnet-2019-06-24/dune``, whereas the logs will be in ``$HOME/dune-appnet-2019-06-24/logs``. The variable ``GENESIS_DIR`` is where the scripts will expect to find the configuration to activate the network. The variable ``DUNE_BOOTSTRAP_THRESHOLD`` is set to ``0`` to allow the client to inject transactions without requiring the node to be connected to others. For now, let's start the node:: $ ./run-scripts/01-dune-node.sh start Executing $HOME/dune-env.sh [Dune Node] == Starting == dune-node is not running Initializing Dune node Network Config: Appnet Generating a new identity... (level: 26.00) Stored the new identity (idtkDumzLmYsQG7kQC4BwapiGG7Fvv) into '$HOME/dune-appnet-2019-06-24/dune/identity.json'. Dune node started... dune-node is running ! (pid=9425) You can watch the log: tail -f $HOME/dune-appnet-2019-06-24/log/dune-node.log As you can see, the node has been started after generating a new identity. If you stop and restart the node, the identity will be kept between runs. You can stop the node (later, not now !), if you want, using:: $ ./run-scripts/01-dune-node.sh stop Executing $HOME/dune-env.sh [Dune Node] == Stoping == dune-node is running ! (pid=9425) dune-node is running (pid=9425)... Process received signal INTR. Waiting 5 seconds... ./run-scripts/stop-process.sh: 33: kill: No such process dune-node is down. Removing pid file. Activating the new Protocol --------------------------- To activate the new protocol, the scripts in ``run-scripts`` expect two files in ``$HOME/genesis-appnet``: * A script ``genesis-env.sh`` with the new protocol, the activator key and the initial baker key * A configuration file ``protocol_parameters.json`` to initialize the protocol (for example, with a supply of tokens) Let's start with ``genesis-env.sh``. It should look like:: #!/bin/sh PROTO_NUM=004 PROTO_HASH=Pt24m4xiPbLDhVgVfABUjirbmda3yohdN82Sp9FeuAXJ4eV9otd ACTIVATOR_KEYHASH=dn1XA5ieuGaBfFRTBY5bR3VUT8LHV2Q5CSK2 ACTIVATOR_PUBKEY=edpkvMberySJBQ71TdWo7Fg4bryxNX72JBLjwM8N9WcX9cNPnYdAtU ACTIVATOR_PRIVKEY=edsk3WcShEmqBWT6TpC5JGCvZTDQiMtcQJUdEgT6Rk88LMCitHFW4z BAKER_KEYHASH=dn1b2TKR532nymdE4tAkGDbJoc34PZb677x9 BAKER_PUBKEY=edpktpwqiAh3AKnrM6GVYhXtrSRYwRAuMdd7o748LHCQpUcTYSvhz2 BAKER_PRIVKEY=edsk4CKXSgR4DSasxGjCDjxjaHNG2BnGABjzHkurzfRiHijTatmYbN * The ``PROTO_NUM`` and ``PROTO_HASH`` are used to specify the protocol to activate. You will find these values by looking into Dune Network sources. There should be a directory ``src/proto_???_????????``, indicating the value for ``PROTO_NUM``, and you can then check the first line of ``lib_protocol/TEZOS_PROTOCOL`` in that directory for the value of ``PROTO_HASH``. * For the ``ACTIVATOR`` variables, you must use the same key as we used in ``set_config_appnet.ml``:: $ dune-client show address app-activator -S Hash: dn1XA5ieuGaBfFRTBY5bR3VUT8LHV2Q5CSK2 Public Key: edpkvMberySJBQ71TdWo7Fg4bryxNX72JBLjwM8N9WcX9cNPnYdAtU Secret Key: unencrypted:edsk3WcShEmqBWT6TpC5JGCvZTDQiMtcQJUdEgT6Rk88LMCitHFW4z You need to specify the Hash, the Public Key and the Secret Key (without the ``unencrypted:`` prefix. * Finally, for the ``BAKER`` variables, you can create a specific key:: $ dune-client gen keys app-baker Key app-baker registered $ dune-client show address app-baker -S Hash: dn1b2TKR532nymdE4tAkGDbJoc34PZb677x9 Public Key: edpktpwqiAh3AKnrM6GVYhXtrSRYwRAuMdd7o748LHCQpUcTYSvhz2 Secret Key: unencrypted:edsk4CKXSgR4DSasxGjCDjxjaHNG2BnGABjzHkurzfRiHijTatmYbN We can now move to the ``protocol_parameters.json`` file. It should look like:: { "bootstrap_accounts": [ [ "dn1XA5ieuGaBfFRTBY5bR3VUT8LHV2Q5CSK2", "1000000000000" ], [ "edpktpwqiAh3AKnrM6GVYhXtrSRYwRAuMdd7o748LHCQpUcTYSvhz2", "10000000000" ] ], "time_between_blocks" : [ "30" ], "preserved_cycles":3, "blocks_per_cycle":2048, "blocks_per_roll_snapshot":128, "hard_gas_limit_per_operation":"400000", "hard_gas_limit_per_block":"4000000", "michelson_maximum_type_size":1000, "seed_nonce_revelation_tip":"0", "origination_size":0, "block_security_deposit":"0", "endorsement_security_deposit":"0", "block_reward":"0", "endorsement_reward":"0", "cost_per_byte":"0", "hard_storage_limit_per_operation":"60000" } In this file, we have set several things: * We gave our two initial keys some tokens (in nano tokens units). You can of course add more keys, and not give the ``app-activator`` any tokens (it does not need them). Here, we gave ``app-activator`` 1,000,000 tokens, and ``app-baker`` 10,000 tokens (one roll, the minimum for him to bake). We used the public key (``edpk``) of ``app-baker`` instead of its key hash because we want it to be set as a delegate immediately to be able to bake. * We also set some parameters. For example, 30s between blocks (it can be useful), and no rewards/no deposits. There are also other constants for running contracts. We can now activate this protocol:: $ ./run-scripts/01-dune-node.sh activate This command should end up injecting the new protocol. We can then start the initial bakers and endorsers for this network:: $ ./run-scripts/02-dune-baker.sh start $ ./run-scripts/03-dune-endorser.sh start At this point, you should be able to check in the logs that the baker and endorsers are working. You can also use ``./run-scripts/01-dune-node.sh head`` to check that new blocks are being added. Note that, you can also execute client-related commands via ``./run-scripts/01-dune-node.sh client ``. We are done ! You can now publish your ``appnet`` branch to other developers or start it on other computers for them to use your Appnet testnet. Resetting the new Testnet ------------------------- Now that you have done it once, you may want at some point to reset a new testnet, while keeping the former configuration. It is now much easier: * Edit ``set/lib_config/set_config_appnet.ml``, but just modify the ``genesis_time`` and ``genesis_block``. Clean (``make clean``) and rebuild (``make``). * Change the ``DUNE_EXECDIR`` in ``$HOME/dune-env.sh`` for a new directory. Stop any previous node, start the new one and activate it:: $ ./run-scripts/01-dune-node.sh stop $ ./run-scripts/01-dune-node.sh start $ ./run-scripts/01-dune-node.sh activate $ ./run-scripts/02-dune-baker.sh start $ ./run-scripts/03-dune-endorser.sh start Your new testnet should be up and ready for other nodes.