Skip to main content

Add and remove IBFT validators

Prerequisites

An IBFT network as configured in the IBFT tutorial.

Add a validator

  1. Create a working directory for the new node that needs to be added:

    mkdir -p Node-5/data/keystore
  2. In the artifacts directory, generate one new validator using the Quorum Genesis Tool:

    npx quorum-genesis-tool \
    --validators 1 \
    --members 0 \
    --bootnodes 0 \
    --outputPath artifacts
  3. Copy the latest generated artifacts:

    cd artifacts/2022-04-21-08-10-29/validator0
    cp nodekey* address ../../../Node-5/data
    cp account* ../../../Node-5/data/keystore
  4. Copy the address of the validator and propose it from more than half the number of current validators.

    Attach a geth console to the node:

cd ..
geth attach node0/data/geth.ipc

Check existing validators:

istanbul.getValidators();

Propose the new validator using the command istanbul.propose(<address>, true) with <address> replaced by the new validator candidate node address:

istanbul.propose("0x2aabbc1bb9bacef60a09764d1a1f4f04a47885c1", true);

Exit the console:

exit;

Repeat the proposal process for this candidate node by connecting your geth console to node 1, node 2, and node 3.

note

To drop a currently running validator candidate and stop further votes from being cast either for or against it, use istanbul.discard.

  1. Verify that the new validator is now in the list of validators by running istanbul.getValidators in a geth console attached to any of your nodes:
istanbul.getValidators();

The list of validators contains six addresses now.

  1. Copy static-nodes.json and genesis.json from the existing chain, placing static-nodes.json into the new node's data directory:

    cd node5
    mkdir -p data/geth
    cp ../node0/static-nodes.json data
    cp ../node0/genesis.json .
  2. Edit static-nodes.json and add the new validator's node info to the end of the file.

    The new validator's node info can be retrieved from the output of istanbul setup --num 1 --verbose --quorum --save in step 2. Update the IP address and port of the node info to match the IP address of the validator and port you want to use.

    [
    "enode://dd333ec28f0a8910c92eb4d336461eea1c20803eed9cf2c056557f986e720f8e693605bba2f4e8f289b1162e5ac7c80c914c7178130711e393ca76abc1d92f57@127.0.0.1:30300?discport=0",
    "enode://1bb6be462f27e56f901c3fcb2d53a9273565f48e5d354c08f0c044405b29291b405b9f5aa027f3a75f9b058cb43e2f54719f15316979a0e5a2b760fff4631998@127.0.0.1:30301?discport=0",
    "enode://0df02e94a3befc0683780d898119d3b675e5942c1a2f9ad47d35b4e6ccaf395cd71ec089fcf1d616748bf9871f91e5e3d29c1cf6f8f81de1b279082a104f619d@127.0.0.1:30302?discport=0",
    "enode://3fe0ff0dd2730eaac7b6b379bdb51215b5831f4f48fa54a24a0298ad5ba8c2a332442948d53f4cd4fd28f373089a35e806ef722eb045659910f96a1278120516@127.0.0.1:30303?discport=0",
    "enode://e53e92e5a51ac2685b0406d0d3c62288b53831c3b0f492b9dc4bc40334783702cfa74c49b836efa2761edde33a3282704273b2453537b855e7a4aeadcccdb43e@127.0.0.1:30304?discport=0",
    "enode://273eaf48591ce0e77c800b3e6465811d6d2f924c4dcaae016c2c7375256d17876c3e05f91839b741fe12350da0b5a741da4e30f39553fe8790f88503c64f6ef9@127.0.0.1:30305?discport=0"
    ]
  3. Initialize the new node with the following command:

geth --datadir data init data/genesis.json
  1. In the Node-5 directory, start the first node:

    export ADDRESS=$(grep -o '"address": *"[^"]*"' ./data/keystore/accountKeystore | grep -o '"[^"]*"$' | sed 's/"//g')
    export PRIVATE_CONFIG=ignore
    geth --datadir data \
    --networkid 1337 --nodiscover --verbosity 5 \
    --syncmode full --nousb \
    --istanbul.blockperiod 5 --mine --miner.threads 1 --miner.gasprice 0 --emitcheckpoints \
    --http --http.addr 127.0.0.1 --http.port 22005 --http.corsdomain "*" --http.vhosts "*" \
    --ws --ws.addr 127.0.0.1 --ws.port 32005 --ws.origins "*" \
    --http.api admin,trace,db,eth,debug,miner,net,shh,txpool,personal,web3,quorum,istanbul \
    --ws.api admin,trace,db,eth,debug,miner,net,shh,txpool,personal,web3,quorum,istanbul \
    --unlock ${ADDRESS} --allow-insecure-unlock --password ./data/keystore/accountPassword \
    --port 30305
  2. Check that node 5 is validator:

    geth attach http://localhost:22005
    > istanbul.isValidator()
    true

Remove a validator

  1. Attach a geth console to a running validator, run istanbul.getValidators, and identify the address of the validator that needs to be removed:
geth attach node0/data/geth.ipc

Run istanbul.getValidators:

istanbul.getValidators();

We will remove 0x2aabbc1bb9bacef60a09764d1a1f4f04a47885c1 from the validator list in this tutorial.

  1. Run istanbul.propose(<address>, false) by passing the address of the validator that needs to be removed from more than half of the current validators:
istanbul.propose("0x2aabbc1bb9bacef60a09764d1a1f4f04a47885c1", false);

Repeat istanbul.propose("0x2aabbc1bb9bacef60a09764d1a1f4f04a47885c1",false) for node 1, node 2, and node 3.

  1. Verify that the validator has been removed by running istanbul.getValidators in one of the nodes' attached geth console:
istanbul.getValidators();

The validator 0x2aabbc1bb9bacef60a09764d1a1f4f04a47885c1 was removed and the validators list now only has five addresses.

  1. Check that node 5 is not validator:

    geth attach http://localhost:22005
    > istanbul.isValidator()
    false
  2. Stop the geth process corresponding to the validator that was removed:

ps

Kill the geth process that uses port 22005, corresponding to node 5 as indicated in start5.sh:

kill 36485

Add a non-validator node

Same instructions as adding a validator excluding step 4, which proposes the node as validator.

Remove a non-validator node

Just execute step 5 from removing a validator.