Dynamic Membership Changement

Blockchain that uses the RAFT consensus can add or remove members dynamically through enterprise transactions. You do not have to restart running nodes or change the config file at this time. For a description of enterprise transactions, see transacion-types.

This article assumes the Aergo blockchain using raft consensus consisting of 3 nodes.

Abstaction

Note

Membership changes must be made after the completion of one. When adding a new node, do not add another node again until blockchain synchronization is over, since the new node becomes unavailable until the chain is synchronized and up to date. If more than half of the nodes are out of sync, the cluster stops.

Validation

When executing a membership change transaction, leader node checks if the current cluster status is changeable.

  • When adding a new node

    If any node is not properly synchronized in the whole network, it will fail. The node is either in a shutdown state or a state where synchronization is slowed down due to a failure.

  • When removing a node

    If the cluster can be stopped when the node is excluded, the delete request will fail. Deletion to a failed node always succeeds.

Prework

You need set up and unlock ENTERPRISE ADMIN ACCOUNT to execute commands with Enterprise Transaction. See the page transacion-types.

Add Member

Execute Add Node command

Send an enterprise transaction to one of the cluster nodes.

aergocli -p [RPC PORT] contract call --governance [ADMIN ACCOUNT] aergo.enterprise changeCluster [ { "command": "add", "name": "[NODE NAME]", "address": "[PEER ADDRESS]", "peerid":"[PEER ID]" } ]

example> aergocli -p 10001 contract call --governance AmQJ6HTxMzq5eios54xubENE2wAe4puF3GDuaFxBzXkWa4KpfnWr aergo.enterprise changeCluster [ { "command": "add", "name": "raft4", "address": "/ip4/127.0.0.1/tcp/11004", "peerid":"16Uiu2HAmQti7HLHC9rXqkeABtauv2YsCPG3Uo1WLqbXmbuxpbjmF" } ]

Check the command result

Query enterprise transaction results on one of the cluster nodes. The hash of enterprise transaction must be given as an argument.

aergocli -p [RPC PORT] enterprise tx "[ENTERPRISE TX HASH]" --timeout=[VALUE IN SECONDS]

The changed cluster status can be checked using getconsensusinfo RPC. "Total" represents the total number of nodes and "Bps" contains the block producer list.

aergocli -p 10001 getconsensusinfo

Write configuration for a new node (new node only)

In the config file of the node to add, set the peer addresses of the block producers to the [p2p] npaddpeers. If possible, register the peer address of all members currently registered in the raft cluster. However if necessary, only one connectable node can be set.

[p2p]
...
npaddpeers = [
"/ip4/[IP ADDRESS FROM BP 01]/tcp/7846/p2p/[PEER ID FROM BP 01]",
"/ip4/[IP ADDRESS FROM BP 02]/tcp/7846/p2p/[PEER ID FROM BP 02]",
"/ip4/[IP ADDRESS FROM BP 03]/tcp/7846/p2p/[PEER ID FROM BP 03]"
]
...

[consensus.raft]
newcluster=false
name="[NICKNAME OF NEW BP]"

Running

See the page Configuring a Network to start a new node.

Note

You should wait for the added node to finish synchronizing with the existing blockchain.

  • Check if the new node recognized the raft leader node

    If the leader node is recognized, ConsensusInfo.Status.Leader is set to one of the node names.

    aergocli -p 10004 blockchain
    > {"Hash":"3ivEw2o97WkpEvarBkVEYWCAQXhQ7BpHwmzs2L4WXUzJ","Height":7302,"ConsensusInfo":{"Type":"raft","Status":{"Leader":"raft1","Total":3,"Name":"raft4","RaftId":"dd44cf1a06727dc5","Status":null}},"ChainIdHash":"A9gpZUsFS9BVEfpUy6gbJ7YtGuHsYAmzamWkhDo54cak"}
    
  • Make sure the BlockChain Height of the new node matches the Leader

    aergocli -p [RPC PORT OF LEADER] blockchain
    aergocli -p [RPC PORT OF NEW NODE] blockchain
    

Remove Member

Get RAFT ID to remove

To delete a node, you should get RAFT ID of the node. RAFT ID is a value assigned after a node is added to RAFT. It is a value to idenity each node in RAFT Consensus.

You can get it in the result of blockchain RPC. In the example above, dd44cf1a06727dc5 is the Raft ID of the “raft4” node.

aergocli -p 10004 blockchain
> {"Hash":"...","Height":7302,"ConsensusInfo":{"Type":"raft","Status":{"Leader":"raft1","Total":4,"Name":"raft4","RaftId":"dd44cf1a06727dc5","Status":null}},"ChainIdHash":"..."}

Run enterprise transaction

aergocli -p [RPC PORT] contract call --governance [ADMIN ACCOUNT] aergo.enterprise changeCluster [ { "command": "remove", "id": "[RAFT ID]" } ]

example> aergocli -p 10001 contract call --governance AmQJ6HTxMzq5eios54xubENE2wAe4puF3GDuaFxBzXkWa4KpfnWr aergo.enterprise changeCluster '[ { "command": "remove", "id": "dd44cf1a06727dc5" } ]'

Check result of enterprise transaction

As with adding a node case, you should check “Total” and “Bps” in the results of the getconsensusinfo RPC.

aergocli -p 10001 getconsensusinfo

Wait shutdown removed node

If Enterprise Transaction is executed on the node to be deleted, the node terminates itself.

Add Member with Backup

After adding a new node, it takes a long time to synchronize the existing blockchain. To reduce this time, you can add a new node by using backup data files obtained from existing member nodes. There is no conflict because the new node resets all the cluster-related information from the given backup data files at the first startup.

Prepare backup datafiles

The bakcup datafiles can be obtained by shutting down an existing node and copying the data directory.

Note

Since the blockchain is already created in the data file, there is no need to create the genesis block.

Write Configuration file

When using backup data files, usebackup must be set to true. Set the backup data directory to datadir field.

datadir="[copied data directory]"

[p2p]
...
npaddpeers = [
"/ip4/[IP ADDRESS FROM BP 01]/tcp/7846/p2p/[PEER ID FROM BP 01]",
"/ip4/[IP ADDRESS FROM BP 02]/tcp/7846/p2p/[PEER ID FROM BP 02]",
"/ip4/[IP ADDRESS FROM BP 03]/tcp/7846/p2p/[PEER ID FROM BP 03]"
]
...

[consensus.raft]
newcluster=false
    usebackup=true
name="[NICKNAME OF NEW BP]"

The rest of the process is the same as adding members without using backup.