cardano course
  • Welcome!
  • Video lessons
  • Handbook
    • Module 1. Building and running the node
      • Building the node
      • Running the node and connecting to a network
    • Module 2. Basic operations
      • Creating keys and addresses
      • Creating a simple transaction
      • Registering the stake address and delegating
    • Module 3. Protocol parameters and configuration files
      • Protocol parameters
      • Byron genesis file
      • Shelley genesis file
      • Alonzo genesis file
      • Conway genesis file
      • Node configuration file
      • Topology file
    • Module 4. Peer-to-peer (P2P) networking
    • Module 5. Creating a stake pool
      • The setup
      • Generating keys
      • Registering a stake pool
      • Runtime system options
      • Running the nodes
      • Stake snapshots
      • Upgrading cardano-node and cardano-cli
      • Pool operations and maintenance
      • Retiring a stake pool
    • Module 6. Monitoring the nodes
    • Module 7. Cardano governance
      • Update proposals
      • Polls
    • Module 8. Setting up a local cluster
      • Creating a local cluster
      • Spending the genesis UTXO
      • From Byron to Shelley
      • Moving funds to a Shelley address
      • Creating a first stake pool
      • Bringing decentralization parameter down to .80
      • From Shelley to Alonzo
      • Creating a second stake pool before moving to the Babbage era
      • Redelegating genesis keys
      • Vasil hard fork
      • Creating a local cluster with the mkfiles script
    • Module 9. Simple scripts and Plutus scripts
    • Module 10. New tracing system
    • Module 11. Running the SMASH server
    • Module 12. Running the token metadata server
  • Curated playlist
Powered by GitBook
On this page
  • Configuring the network and nodes
  • Requirements:
  • 1. The configuration files
  • 2. The genesis files

Was this helpful?

Edit on GitHub
  1. Handbook
  2. Module 8. Setting up a local cluster

Creating a local cluster

This tutorial has been updated to work with cardano-node v.8.0.0.

In certain situations, it may be necessary to set up a local cluster. To simplify this process, there are user-friendly tools that require minimal effort to deploy. However, to help with a deeper comprehension of the automated tools and the underlying processes involved, this tutorial will begin by setting up the cluster manually. This hands-on approach will provide valuable insights into the steps required.

The following example will initiate a cluster during the Byron era and subsequently upgrade it progressively until it reaches the Babbage era. This step-by-step process will demonstrate the evolution and advancements of the cluster in its transition through different eras.

Configuring the network and nodes

Requirements:

  • A Linux or macOS machine, see the Requirements for details

  • cardano-node and cardano-cli in your $PATH

Note: This section of the course will minimize the use of scripts. The intention is to make the process as transparent and clear as possible.

The cardano-cli genesis create-cardano command will be used to simplify the process. It will create most of the necessary files for the local cluster. You only need to supply the following template files as a starting point:

  1. Configuration

  2. Byron genesis template

  3. Shelley genesis template

  4. Alonzo genesis template

  5. Conway genesis template

1. The configuration files

Cardano World testnet templates is the source for the template files. These are the templates that IOG uses to deploy a new testnet.

Create a directory for the project:

mkdir -p cluster/template
cd cluster

Download the template files and save them in the template folder you just created:

wget -P template/ https://raw.githubusercontent.com/input-output-hk/iohk-nix/master/cardano-lib/testnet-template/alonzo.json
wget -P template/ https://raw.githubusercontent.com/input-output-hk/iohk-nix/master/cardano-lib/testnet-template/byron.json
wget -P template/ https://raw.githubusercontent.com/input-output-hk/iohk-nix/master/cardano-lib/testnet-template/config.json
wget -P template/ https://raw.githubusercontent.com/input-output-hk/iohk-nix/master/cardano-lib/testnet-template/shelley.json
wget -P template/ https://raw.githubusercontent.com/input-output-hk/iohk-nix/master/cardano-lib/testnet-template/conway.json

The system will start in the Byron era and will have only two block-producing nodes. You will add two stake pools later when you transition to the Shelley era. Make a directory for each of the nodes and a configuration folder for your configuration files:

mkdir -p bft0 bft1 configuration

The nodes must connect to each other. Each of the nodes requires a topology file that tells it which nodes to connect to.

The node bft0 will run on port 3000, and node bft1 – on port 3001. For now, use the classic topology (not P2P).

Create the topology file for bft0 with:

cat > bft0/topology.json <<EOF
{
   "Producers": [
     {
       "addr": "127.0.0.1",
       "port": 3001,
       "valency": 1
     }
   ]
 }
EOF

And for bft1 with:

cat > bft1/topology.json <<EOF
{
   "Producers": [
     {
       "addr": "127.0.0.1",
       "port": 3000,
       "valency": 1
     }
   ]
 }
EOF

2. The genesis files

Use the byron.json template file together with cardano-cli to generate a byron-genesis.json file. The template looks like this:

{
  "heavyDelThd":     "300000000000",
  "maxBlockSize":    "2000000",
  "maxTxSize":       "4096",
  "maxHeaderSize":   "2000000",
  "maxProposalSize": "700",
  "mpcThd": "20000000000000",
  "scriptVersion": 0,
  "slotDuration": "200",
  "softforkRule": {
    "initThd": "900000000000000",
    "minThd": "600000000000000",
    "thdDecrement": "50000000000000"
  },
  "txFeePolicy": {
    "multiplier": "43946000000",
    "summand": "155381000000000"
  },
  "unlockStakeEpoch": "18446744073709551615",
  "updateImplicit": "10000",
  "updateProposalThd": "100000000000000",
  "updateVoteThd": "1000000000000"
}

Note that this template uses 200 millisecond slots in the Byron era. Mainnet slots lasted 20 seconds during the Byron era and one second during Shelley and later eras.

Slots were 20 times longer in the Byron era because there was a block in every slot. This was necessary to ensure that each block had enough time to travel the world and that everybody received the block before forging the next block. In Shelley and later eras, slots are shorter but not all slots have a block. On mainnet, only 5% of the slots have a block; this is the active slot coefficient. This selection of parameters allows for Byron and Shelley epochs to have approximately the same number of blocks.

The local cluster uses two-second slots in Byron and 0.1-second slots in the following eras. The cardano-cli genesis create-cardano command automatically generates configuration files with this 20:1 ratio.

The rest of the parameters will match the mainnet ones. For detailed information about the parameters, see:

  1. Byron genesis data format

  2. Shelley era genesis

You can now make a few changes to the shelley.json template. Since there are only two nodes, bring updateQuorum down to 2, reduce the epoch length to 9000, the security parameter k to 45, and the Shelley era slots will last 1/10th of a second. To help the cluster match the progression of mainnet protocol versions, set major (protocol version) to 2. On mainnet, Shelley era is protocol version 2.0:

sed -i template/shelley.json \
-e 's/"major": 6/"major": 2/' \
-e 's/"updateQuorum": 3/"updateQuorum": 2/'
gsed -i template/shelley.json \
-e 's/"major": 6/"major": 2/' \
-e 's/"updateQuorum": 3/"updateQuorum": 2/'

A few changes are also needed to the config.json template. For now, disable P2P topology and disable the EnableDevelopment options so you can update your cluster using proper update proposals. Initially, state that your nodes are ready to move to protocol version 1.0.0 (PBFT). Logs will come very fast, so keep the minSeverity in info:

 sed -i template/config.json \
 -e 's/"ExperimentalProtocolsEnabled": true/"ExperimentalProtocolsEnabled": false/' \
 -e 's/"ExperimentalHardForksEnabled": true/"ExperimentalHardForksEnabled": false/' \
 -e 's/"LastKnownBlockVersion-Major": 3/"LastKnownBlockVersion-Major": 0/' \
 -e 's/"LastKnownBlockVersion-Minor": 1/"LastKnownBlockVersion-Minor": 0/' \
 -e 's/""minSeverity": "Debug"/"minSeverity": "Info"/' 
 gsed -i template/config.json \
 -e 's/"ExperimentalProtocolsEnabled": true/"ExperimentalProtocolsEnabled": false/' \
 -e 's/"ExperimentalHardForksEnabled": true/"ExperimentalHardForksEnabled": false/' \
 -e 's/"LastKnownBlockVersion-Major": 3/"LastKnownBlockVersion-Major": 0/' \
 -e 's/"LastKnownBlockVersion-Minor": 1/"LastKnownBlockVersion-Minor": 0/' \
 -e 's/""minSeverity": "Debug"/"minSeverity": "Info"/' 

Also, change a couple of Byron parameters for your local cluster. Change minThd to "1000000000000000" so that update proposals need positive votes from both genesis keys to be approved. And change "updateImplicit" to 450, so that update proposals expire if they have not accumulated enough votes after 450 slots:

sed -i template/byron.json \
-e 's/"minThd": "600000000000000"/"minThd": "1000000000000000"/' \
-e 's/"updateImplicit": "10000"/"updateImplicit": "450"/'
gsed -i template/byron.json \
-e 's/"minThd": "600000000000000"/"minThd": "1000000000000000"/' \
-e 's/"updateImplicit": "10000"/"updateImplicit": "450"/'

Now you can use the magic of cardano-cli genesis create-cardano:

cardano-cli genesis create-cardano \
--genesis-dir ./ \
--gen-genesis-keys 2 \
--gen-utxo-keys 1 \
--start-time $(date -u -d "now + 2 minutes" +%FT%Tz) \
--supply 30000000000000000 \
--security-param 45 \
--slot-length 100 \
--slot-coefficient 5/100 \
--testnet-magic 42 \
--byron-template template/byron.json \
--shelley-template template/shelley.json \
--alonzo-template template/alonzo.json \
--conway-template template/conway.json \
--node-config-template template/config.json
cardano-cli genesis create-cardano \
--genesis-dir ./ \
--gen-genesis-keys 2 \
--start-time $(gdate -u -d "now + 5 minutes" +%FT%Tz) \
--supply 30000000000000000 \
--security-param 45 \
--slot-length 100 \
--slot-coefficient 5/100 \
--testnet-magic 42 \
--byron-template template/byron.json \
--shelley-template template/shelley.json \
--alonzo-template template/alonzo.json \
--node-config-template template/config.json

Move genesis files to the configuration directory to keep things in order:

mv node-config.json configuration/config.json
mv shelley-genesis.json byron-genesis.json alonzo-genesis.json conway-genesis.json configuration/

And move your genesis delegate keys to their corresponding delegate nodes:

mv delegate-keys/byron.000* delegate-keys/shelley.000* bft0/
mv delegate-keys/byron.001* delegate-keys/shelley.001* bft1/

To simplify the process, create bash scripts to start your nodes. Bft0 will run on port 3000:

cat > bft0/startnode.sh <<EOF
#!/usr/bin/env bash

cardano-node run \
--config ../configuration/config.json \
--topology topology.json \
--database-path db \
--socket-path bft0.socket \
--port 3000 \
--delegation-certificate byron.000.cert.json \
--signing-key byron.000.key
EOF

And bft1 on port 3001:

cat > bft1/startnode.sh <<EOF
#!/usr/bin/env bash

cardano-node run \
--config ../configuration/config.json \
--topology topology.json \
--database-path db \
--socket-path bft1.socket \
--port 3001 \
--delegation-certificate byron.001.cert.json \
--signing-key byron.001.key 
EOF

Now give your scripts executable permission:

chmod +x bft0/startnode.sh bft1/startnode.sh 

Open a new terminal for each of the nodes. Go to the corresponding bft folder, and run the script from there:

cd bft0
./startnode.sh

Repeat for bft1. The nodes will idle until the start time is reached, and then they will start producing blocks.

Now you can set the environment variable CARDANO_NODE_SOCKET_PATH:

export CARDANO_NODE_SOCKET_PATH=~/cluster/bft0/bft0.socket

Next, query the tip of the chain to make sure everything is working as expected:

cardano-cli query tip --testnet-magic 42

Great, you have a network on the Byron era running locally!

PreviousModule 8. Setting up a local clusterNextSpending the genesis UTXO

Last updated 1 year ago

Was this helpful?

Page cover image