Tutorials
No Results
Tutorial

Intermediate · 1 hour

Create A Private Instance of Algorand In A Testbed

Often creating a private instance of Algorand on a private testbed might be desirable for developers and researchers that want to conduct testing experiments for academic and industrial research. A testbed can be any testing environment with one or more computers running some software. Testbeds can be either physical - for example one or more servers in a data center; or virtual - for example one or more virtual machines deployed on VMware or even container instances of any container-based environment like Docker. The advantage of running Algorand in such a private testbed gives developers more control over the infrastructure and the protocol in general. For example, this could be useful for researchers running stress tests on the Algorand network and measure metrics like scalability or resources utilization. Moreover, in some cases developers might need a private network of n separate nodes and, according to particular business requirements, modify the network topology adding (or removing) nodes or even configure rewards, fees and more. A private instance of Algorand is a perfect clone of the available Public Networks MainNet, TestNet, and BetaNet, and comes with the same features like Algorand Standard Assets (ASAs), and Layer-1 Smart Contracts.

This tutorial illustrates how to create a private instance of Algorand within a virtual testbed with three independent Virtual Machines (VMs). Each VM represents a node of the Algorand network. The physical structure of each VM is one Algorand directory (with the binaries) and a single data directory with the network configuration. The main goal of this tutorial is to simulate a real scenario where different geographically separated Algorand nodes run their own (private) network.

Requirements

Background

A previous tutorial detailed how to create a private network in Algorand via the goal utility that supports commands to create, start, stop, and delete private networks via a predefined template. The network template simulates a multi-node network on a single computer, and automatically configure wallets and accounts.

Differently, this tutorial shows the implementation of a network running Algorand within a private testbed of independent, interconnected, virtual machines (VMs) - each one acting as an Algorand node. As testbed is intended any platform/development environment where a Algorand network is deployed. In this tutorial a testbed is a virtual environment with three VMs that simulates three different computers.

Wallets, accounts, and nodes are here manually configured. In this way, each node administrator has full control over the wallets and account’s keys and backup phrases, nodes communications, and consensus.

Testbed Overview

Algorand Image

Before creating the private instance of Algorand, a testbed with three separated VMs has to be implemented. The VMs act as Algorand nodes of a (private) network on which all the futures of the Algorand blockchain can be used. The Algorand network requires two distinct types of nodes, relay nodes and non-relay nodes. Relay nodes act as communication endpoints for a set of non-relay nodes. To work properly, a private instance of Algorand needs at least one relay node. Non-relay nodes participate in consensus and are classified as participation nodes when the nodes host the participation keys for one or more online account. See Algorand Node Type for more details on the relay and non-relay nodes.

This tutorial goes through the configuration of two participation nodes, VM_Part1 and VM_Part2, and one relay node, VM_Rel. VM_Part1 and VM_Part2 host two wallets with one online account respectively. To participate in consensus each node stores the account’s registered participation key. See Participate in Consensus to understand Algorand’s consensus participation accounts.

Attention

Before starting this tutorial all the Algorand binaries need to be installed on each node. See Installing a node for more information on installing the Algorand software.

Steps

1. Prepare the environment

Algornad’s nodes require a data directory hosting the node and network configuration files. A private network requires its own data folder environment.

On each node of the testbed create a data directory for the network. This folder needs to be located into the root directory with the goal binaries. Then, set the environment variable that points to that data directory.

mkdir ~node/testnetdata
export ALGORAND_DATA=~node/testnetdata

To interact with Algorand, each environment needs an algod token (learn more on the Algorand’s components). From the root folder launch the goal command used to generate a new algod token. See the docs for more details on generatetoken command

./goal node generatetoken

The algod.token API token will be generated and installed into the directory testnetdata.

2. Create the Genesis File

Algorand’s networks specify a genesis file that defines the initial state of the blockchain. With this file, developers can configure the stake distribution, the block rewards, and the transaction fees. The Algorand’s genesis file is represented in JSON format and has the followiong skeleton.

    {
      "alloc": [
      {
         "addr": "7777777777777777777777777777777777777777777777777774MSJUVU",
         "comment": "RewardsPool",
         "state": {
             "algo": 125000000000000,
             "onl": 2
         }
       },
       {
         "addr": "A7NMWS3NT3IUDMLVO26ULGXGIIOUQ3ND2TXSER6EBGRZNOBOUIQXHIBGDE",
         "comment": "FeeSink",
         "state": {
             "algo": 100000,
             "onl": 2
         }
      }
      ],
      "fees": "A7NMWS3NT3IUDMLVO26ULGXGIIOUQ3ND2TXSER6EBGRZNOBOUIQXHIBGDE",
      "id": "v1",
      "network": “privatenet”,
      "proto": "https://github.com/algorandfoundation/specs/tree/3a83c4c743f8b17adfd73944b4319c25722a6782",
      "rwd": "7777777777777777777777777777777777777777777777777774MSJUVU"
    }

Create a new new file called genesis.json and save it into the directory testnetdata of each node of the testbed.

Attention

This genesis file is just a skeleton. The final genesis.json file of the private network will be generated afterwards with the details on the stake holders – participation accounts.

3. Create the Wallets

Non-relay nodes can be classified as participation if at least one wallet has one or more accounts participating in consensus with a valid registered participation key. In this testbed, there are two participation nodes, VM_Part1 and VM_Part2, each one with one wallet and one online account participating in consensus.

On both VM_Part1 and VM_Part2 nodes create a new wallet by running the following goal commands.

mkdir ~/node/testnetdata/privatenet-v1
./goal kmd start -t 3600
./goal wallet new <wallet_name>

The first command creates the network data directory needed to host the account’s participation keys. Then the following operations initialize the kmd process, and create a new wallet. The kmd generates the wallets and account’s keys, visit Creation Methods to compare the different creation methods available.

The wallet new command asks for a wallet password that will be used to unlock the wallet, and afterwards, generates the wallet’s secret 25-words mnemonic.

Info

Wallets have one master key, represented as a 25-word mnemonic. The 25-words mnemonic consents to recover the entire wallet and all its accounts. Make sure to keep the mnemonic and the wallet’s password safe and secure.

4. Create the Accounts

./goal account new -w <wallet_name> -f

Create a new account on both wallets on VM_Part1 and VM_Part2. Flag -f sets the generated account as default account for that specified wallet.

Tip

Accounts are identified with their Algorand address and with a human-friendly name. By default, the account’s name is Unamed-<X>, where X is an integer. To change the default human-friendly name use the command ./goal account rename Unamed-<X> <new_account_name> -w <wallet_name>.

5. Generate Participation Keys

Accounts participate in consensus protocol by generating a valid participation key and then registering that key online with a special online registration transaction. In this tutorial, there are two participation nodes with one account. The accounts need to be registered for consensus via a participation key. The participation key for one account can be generated with the following goal command.

./goal account addpartkey -a <address-of-participating-account> --roundFirstValid=<partkey-first-round> --roundLastValid=<partkey-last-round> [--keyDilution=<key-dilution-value>]

The keyDilution parameter is optional – by default set to 10,000. Read more on addpartkey parameters at Generating the Participation Key.

Info

To execute the goal addpartkey command a node needs to be started. Algorand accounts and their participation keys can be generated on any node and exported/imported as desired. To use the nodes of this testbed simply start the Algorand node on both VM_Part1 and VM_Part2. At this stage both nodes will use the preliminary genesis of step 2. Hence, create the partkeys and then stop the nodes. See the Start Node to learn more on how to start/stop an Algorand node.

6. Update the Genesis and Distribute the Initial Stake

Add to the genesis file the participation keys for the online accounts of VM_Part1 and VM_Part2. At genesis, each account participating in consensus needs to be declared online and with a certain amount of stake. Retrieve participation keys details as described in View Participation Key Info and complete the genesis with a JSON object as shown below.

    {
       "addr": “<account_addr>,
       "comment": “<some_comment>”,
       "state": {
        "algo": 5000000000000000,
        "onl": 1,
        "sel": “<“sel_addr>,
        "vote": “<vote_addr>“,
        "voteKD": <key_dilution [default 10000],
        "voteLst": <last_round>
       } 
    }

The genesis file describes the initial state of account’s participation keys and their stake. For this tutorial both the participation keys are marked as online at genesis (onl:1), and the stake is equally divided between the two accounts (algo:xxx).

The final genesis.json file of the private network used in this example looks as below.

{
  "alloc": [
  {
    "addr": "7777777777777777777777777777777777777777777777777774MSJUVU",
    "comment": "RewardsPool",
    "state": {
      "algo": 125000000000000,
      "onl": 2
    }
  },
  {
    "addr": "A7NMWS3NT3IUDMLVO26ULGXGIIOUQ3ND2TXSER6EBGRZNOBOUIQXHIBGDE",
    "comment": "FeeSink",
    "state": {
      "algo": 100000,
      "onl": 2
    }
  },
  {
    "addr": “<addr_part1>”,
    "comment": "wallet1",
    "state": {
      "algo": 5000000000000000,
      "onl": 1,
      "sel": “<selkey_1>”,
      "vote": “<votekey_1>”,
      "voteKD": 10000,
      "voteLst": 3000000
    }
  },
  {
    "addr": “<addr_part2>”,
    "comment": "wallet2”,
    "state": {
      "algo": 5000000000000000,
      "onl": 1,
      "sel": "<selkey_2>",
      "vote": "<votekey_2>",
      "voteKD": 10000,
      "voteLst": 3000000
    }
  }
  ],
  "fees": "A7NMWS3NT3IUDMLVO26ULGXGIIOUQ3ND2TXSER6EBGRZNOBOUIQXHIBGDE",
  "id": "v1",
  "network": "testnet2",
  "proto": "https://github.com/algorandfoundation/specs/tree/3a83c4c743f8b17adfd73944b4319c25722a6782",
  "rwd": "7777777777777777777777777777777777777777777777777774MSJUVU"
}

7. Nodes Configuration

Algorand nodes can be configured with different options. Explore the Node Configuration Settings to understand all the available parameters. The configuration file for to the algod process can be specified with the config.json file located in the data directory. This file also specifies whether a node will act in relay or non-relay mode. The configuration files of relay and non-relays nodes of this example are detailed below.

1. Participation nodes configuration

{
  "Version": 14,
  "GossipFanout": 2,
  "IncomingConnectionsLimit": 0,
  "DNSBootstrapID": "",
  "EnableProfiler": true
}

Info

The DNSBootstrapID needs to be “” to overwrite the default pool of Algorand’s relay nodes. A new pool will be defined in the next step.

2. Relay node configuration

{
  "Version": 14,
  "GossipFanout": 2,
  "NetAddress": ":4161",
  "DNSBootstrapID": "",
  "EnableProfiler": true
}

The NetAddress parameters determines on which port the relay node will listen for incoming connections (usually 4161). Read more on relay nodes configuration at Configure Node as Relay.

Warning

Make sure that the server VM_Rel is allowed to accept incoming traffic on port 4161.

8. Connect Participation and Relay nodes

In Algorand, non-relay nodes store into a local pool of IP address all the relay’s addresses. In a private instance of Algorand, each node needs to replace the default pool of relays with a custom list of addresses. There are two options to override the default relay pool of a node, either via the -p option on node startup or via the phonebook.json file.

This tutorial specifies the VM_Rel address using the phonebook file. Create a phonebook.json file with the IP address of VM_Rel into the directory with the goal binaries (root directory). See the Node Artifacts for the phonebook.json file template.

Warning

The phonebook.json file needs to be stored into the root directory containing the Algorand binaries. If the phonebook.json is stored into the data directory of the network, the algod process will use the default pool of relays.

9. Start the Network

In this tutorial, the partkeys were created at step 5 by running an Algorand node on both servers VM_Part1 and VM_Part2. This operation initialised the DB files of an Algorand blockchain with the genesis of step 1. These files conflict with the new genesis file and need to be removed from both non-relays as follows.

rm ~node/testnetdata/privatenet-v1/crash.*
rm ~node/testnetdata/privatenet-v1/ledger.*

At this point the network can be initialized. Start the nodes of the network by using the goal command.

./goal node start

Info

To facilitate the synchronization be sure to start the relay node at first.

Once all the nodes started, monitor the progression of the network from any node of the testbed through the following command.

./goal network status -w 1000

This will list the status of the node and the progression of the network. An output similar to the following will be shown.

Last committed block: 2
Time since last block: 3.5s
Sync Time: 0.0s
Last consensus protocol: https://github.com/algorandfoundation/specs/tree/4a9db6a25595c6fd097cf9cc137cc83027787eaa
Next consensus protocol: https://github.com/algorandfoundation/specs/tree/4a9db6a25595c6fd097cf9cc137cc83027787eaa
Round for next consensus protocol: 3
Next consensus protocol supported: true
Has Synced Since Startup: false

All done! A fully private instance of Algorand is now up and running on the testbed. Use it to experiment Algorand’s futures like creating new accounts, ASAs, ATs, and ASC1.

testnet

privatenetwork

goal

testing

April 08, 2021