Create A Private Instance of Algorand In A Testbed
A private instance of Algorand allows testing and experimental activities within a more controlled infrastructure. It provides full control over network and protocol components. For example, it enables stress testing and measurements on any node of the network. Moreover, controlling the nodes of the network allows changing the network topology, adding (or removing) nodes, configure rewards, fees, and more.
A private instance of Algorand is a perfect clone of the available Public Networks MainNet, TestNet, and BetaNet. It comes with the same L1 features, such as Algorand Standard Assets (ASAs), Atomic Transfers, Smart Contracts, and State Proofs.
This tutorial describes how to create a private instance of Algorand in a testbed. It assumes three independent Virtual Machines (VMs). Each VM represents a node of the Algorand network. Each VM runs the algod
daemon.
Requirements
- A private testbed with three independent VMs
- Algorand GOAL CLI
- Algorand KMD CLI
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 configures wallets and accounts.
Differently, this tutorial shows the configuration of an Algorand private network running on independent, interconnected, virtual machines (VMs). The testbed is a virtual environment with three VMs.
Wallets, accounts, and nodes are manually configured, offering full control to the system administrators.
Testbed Overview
Before creating the private instance of Algorand, a testbed with three separated VMs has to be settled. Each VM acts as an Algorand nodes.
There exist two distinct types of nodes, i.e. relay nodes and non-relay nodes. At least one relay node is required to forward messages.
Non-relay nodes can participate in consensus and are classified as participation nodes. They host (at least) one consensus participation key.
The testbed includes two non-relay nodes, VM_Part1 and VM_Part2, and one relay node, VM_Rel. Non-relay nodes host respectively one wallet and one online account and a registered participation key. See how to Participate in Consensus to better understand the consensus participation rules.
Attention
Before starting this tutorial, the Algorand binaries must be installed to each node. See Installing a node for more informations.
Steps
1. Prepare the environment
A private network requires its own data directory and API token. For each node run the following commands.
- Create the
data
directory and set up the environment variable pointing that directory.
mkdir ~node/testnetdata
export ALGORAND_DATA=~node/testnetdata
- Generate the
algod
API token See the docs for more details.
./goal node generatetoken
Info
The algod.token
API token will be generated and installed into the directory testnetdata
.
2. Create the Genesis File
There exists four types of Algorand networks, namely betanet
, devnet
, testnet
, and mainnet
.
The genesis file of each network is located into the ~/node/genesis
directory (/var/lib/algorand/genesis/
) for Debian and RPM installs) with the name genesis.json
. It defines the initial configuration of the network, such as the stake distribution, the consensus protocol, and more (read more here).
The genesis is a JSON file with the following structure.
{
"alloc": [
{
"addr": "7777777777777777777777777777777777777777777777777774MSJUVU",
"comment": "RewardsPool",
"state": {
"algo": 125000000000000,
"onl": 2
}
},
{
"addr": "A7NMWS3NT3IUDMLVO26ULGXGIIOUQ3ND2TXSER6EBGRZNOBOUIQXHIBGDE",
"comment": "FeeSink",
"state": {
"algo": 100000,
"onl": 2
}
},
...
],
"fees": "<latest_fees_addr>",
"id": "<net-id>",
"network": “<net-name>”,
"proto": "<latest_net_proto>",
"rwd": "<latest_rwd_addr>",
"timestamp": "<latest_timestamp_val>"
}
To build a private instance one can use the fees
, rwd
, and timestamp
parameters specified in one of the canonical networks (see the templates from the ~/node/genesis
directory), together with the RewardsPool
and FeeSink
accounts (read more on Algorand rewards here).
Create a new new file called genesis.json
and save it into the directory testnetdata
of each node of the testbed.
Attention
This solution uses an outdated genesis file as a matter of example. Please refer to the latest genesis files versions on your algod
node.
Make sure to set proto
to the latest protocol release that can be found here.
At step 6 of this tutorial, the above genesis will be populated with all the required parameters alongside with the details on the initial stake distribution.
3. Create the Wallets
Non-relay nodes can be classified as participation nodes if there is at least one online accounts with a registered participation key.
VM_Part1 and VM_Part2 are two participation nodes.
On both VM_Part1 and VM_Part2 nodee:
- Create a new wallet.
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.
Info
This tutorial assumes a network
called privatenet
with version
v1
. Please make sure that this values are reflected in the genesis.json
.
- Initialize the
kmd
process to create a new wallet.
Info
The kmd
tool allows the creation and management of wallets and accounts’ keys, visit Creation Methods to compare the different creation methods available.
The wallet new
generates a new wallet. It requires to configure a password to unlock the wallet. Afterwards, it generates the wallet’s secret 25-words mnemonic.
Info
kmd
wallets have one master key used to derive other Accounts. The 25-words mnemonic allows 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. Flag -f
will set the generated account as default account for the 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 name use the command ./goal account rename Unamed-<X> <new_account_name> -w <wallet_name>
.
5. Generate Participation Keys
Participation keys can be generated either online or offline.
5.1. Online Participation Key Generation
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.
5.2. Offline Participation Key Generation
The new CLI algokey
for key management allows to create a new set of participation keys and store them in a stand-alone file.
Run the command:
./algokey part generate --first <partkey-first-round> --last <partkey-last-round> --keyfile <key-file-name> --parent <address-of-participating-account>
Info
algokey part generate
does not need to start the node.
6. Update the Genesis and Distribute the Initial Stake
Update the genesis file with the participation keys of the online accounts.
Each account participating in consensus needs to be online and with a positive 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>
}
}
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": "privatenet",
"proto": "<latest-proto>",
"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 is called config.json
, and it must be located in the data directory. This file must specify whether the node is a relay or not. The configuration files of relay and non-relays nodes of this example are detailed below.
1. Participation nodes configuration
{
"Version": <latest-version>,
"GossipFanout": 2,
"IncomingConnectionsLimit": 0,
"DNSBootstrapID": "",
"EnableProfiler": true
}
Info
The DNSBootstrapID
needs to be “”
to overwrite the default pool of Algorand relay nodes. A new pool will be defined in the next step.
2. Relay node configuration
{
"Version": <latest-version>,
"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
A local IP pool is used to store relay addresses. In a private instance of Algorand, each node needs to replace the default pool with a custom one. There exist two options: either via the -p
flag 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.
9. Start the Network
The partkeys
created at step 5.1. generated synthetic DB files. 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.*
Warning
If the partkeys
were created offline (step 5.2) the cleanup above is not needed.
Network can now be inizialized.
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 node 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
10. Register Keys
(offline partkey only) Participation keys generated at step 5.2. need to be installed.
-
Install the participation key from file
./goal account installpartkey --partkey <key-file-name> --delete-input
Participation keys must be registered online permanently, otherwise they will last only for key dilution
rounds.
-
Register the participation key online
./goal account changeonlinestatus --address=<address-of-participating-account> --online=true
Info
If the network does not synchronize after keys installation you can stop the participation nodes and restart them before running the changeonlinestatus
command.
All done! A fully private instance of Algorand is now up and running on the testbed. Use it to experiment with all L1 futures in a private and controlled environment.