Add and remove QBFT validators
Prerequisites
A QBFT network as configured in the QBFT tutorial.
Add a validator
Create a working directory for the new node that needs to be added:
mkdir -p Node-5/data/keystore
In the
artifacts
directory, generate one new validator using the Quorum Genesis Tool:npx quorum-genesis-tool \
--validators 1 \
--members 0 \
--bootnodes 0 \
--outputPath artifactsCopy the latest generated artifacts:
cd artifacts/2022-04-21-08-10-29/validator0
cp nodekey* address ../../../Node-5/data
cp account* ../../../Node-5/data/keystoreCopy the address of the validator and propose it from more than half the number of current validators.
Attach a
geth
console to the node:- geth attach
- Result
cd ..
geth attach node0/data/geth.ipcWelcome to the Geth JavaScript console!
instance: Geth/v1.8.18-stable-bb88608c(quorum-v2.2.3)/darwin-amd64/go1.10.2
coinbase: 0x4c1ccd426833b9782729a212c857f2f03b7b4c0d
at block: 137 (Tue, 11 Jun 2019 16:32:47 BST)
datadir: /Users/username/fromscratchistanbul/node0/data
modules: admin:1.0 debug:1.0 eth:1.0 istanbul:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0Check existing validators:
- geth console request
- JSON result
istanbul.getValidators();
[
"0x189d23d201b03ae1cf9113672df29a5d672aefa3",
"0x44b07d2c28b8ed8f02b45bd84ac7d9051b3349e6",
"0x4c1ccd426833b9782729a212c857f2f03b7b4c0d",
"0x7ae555d0f6faad7930434abdaac2274fd86ab516",
"0xc1056df7c02b6f1a353052eaf0533cc7cb743b52"
]Propose the new validator using the command
istanbul.propose(<address>, true)
with<address>
replaced by the new validator candidate node address:- geth console request
- JSON result
istanbul.propose("0x2aabbc1bb9bacef60a09764d1a1f4f04a47885c1", true);
null
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.noteTo drop a currently running validator candidate and stop further votes from being cast either for or against it, use
istanbul.discard
.Verify that the new validator is now in the list of validators by running
istanbul.getValidators
in ageth
console attached to any of your nodes:- geth console request
- JSON result
istanbul.getValidators();
[
"0x189d23d201b03ae1cf9113672df29a5d672aefa3",
"0x2aabbc1bb9bacef60a09764d1a1f4f04a47885c1",
"0x44b07d2c28b8ed8f02b45bd84ac7d9051b3349e6",
"0x4c1ccd426833b9782729a212c857f2f03b7b4c0d",
"0x7ae555d0f6faad7930434abdaac2274fd86ab516",
"0xc1056df7c02b6f1a353052eaf0533cc7cb743b52"
]The list of validators contains six addresses now.
Copy
static-nodes.json
andgenesis.json
from the existing chain, placingstatic-nodes.json
into the new node's data directory:cd node5
cp ../node0/static-nodes.json data
cp ../node0/genesis.json dataEdit
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
qbft 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"
]Initialize the new node with the following command:
- geth command
- Result
geth --datadir data init data/genesis.json
INFO [06-11|16:42:27.120] Maximum peer count ETH=25 LES=0 total=25
INFO [06-11|16:42:27.130] Allocated cache and file handles database=/Users/username/fromscratchistanbul/node5/data/geth/chaindata cache=16 handles=16
INFO [06-11|16:42:27.138] Writing custom genesis block
INFO [06-11|16:42:27.138] Persisted trie from memory database nodes=6 size=1.01kB time=163.024µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [06-11|16:42:27.139] Successfully wrote genesis state database=chaindata hash=b992be…533db7
INFO [06-11|16:42:27.139] Allocated cache and file handles database=/Users/username/fromscratchistanbul/node5/data/geth/lightchaindata cache=16 handles=16
INFO [06-11|16:42:27.141] Writing custom genesis block
INFO [06-11|16:42:27.142] Persisted trie from memory database nodes=6 size=1.01kB time=94.57µs gcnodes=0 gcsize=0.00B gctime=0s livenodes=1 livesize=0.00B
INFO [06-11|16:42:27.142] Successfully wrote genesis state database=lightchaindata hash=b992be…533db7In 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,qbft \
--ws.api admin,trace,db,eth,debug,miner,net,shh,txpool,personal,web3,quorum,istanbul,qbft \
--unlock ${ADDRESS} --allow-insecure-unlock --password ./data/keystore/accountPassword \
--port 30305Check that node 5 is validator:
geth attach http://localhost:22005
> istanbul.isValidator()
true
Remove a validator
Attach a
geth
console to a running validator, runistanbul.getValidators
, and identify the address of the validator that needs to be removed:- geth attach
- Result
geth attach node0/data/geth.ipc
Welcome to the Geth JavaScript console!
instance: Geth/v1.8.18-stable-bb88608c(quorum-v2.2.3)/darwin-amd64/go1.10.2
coinbase: 0xc1056df7c02b6f1a353052eaf0533cc7cb743b52
at block: 181 (Tue, 11 Jun 2019 16:36:27 BST)
datadir: /Users/username/fromscratchistanbul/node0/data
modules: admin:1.0 debug:1.0 eth:1.0 istanbul:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0Run
istanbul.getValidators
:- geth console request
- JSON result
istanbul.getValidators();
[
"0x189d23d201b03ae1cf9113672df29a5d672aefa3",
"0x2aabbc1bb9bacef60a09764d1a1f4f04a47885c1",
"0x44b07d2c28b8ed8f02b45bd84ac7d9051b3349e6",
"0x4c1ccd426833b9782729a212c857f2f03b7b4c0d",
"0x7ae555d0f6faad7930434abdaac2274fd86ab516",
"0xc1056df7c02b6f1a353052eaf0533cc7cb743b52"
]We will remove
0x2aabbc1bb9bacef60a09764d1a1f4f04a47885c1
from the validator list in this tutorial.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:- geth console request
- JSON result
istanbul.propose("0x2aabbc1bb9bacef60a09764d1a1f4f04a47885c1", false);
null
Repeat
istanbul.propose("0x2aabbc1bb9bacef60a09764d1a1f4f04a47885c1",false)
for node 1, node 2, and node 3.Verify that the validator has been removed by running
istanbul.getValidators
in one of the nodes' attachedgeth
console:- geth console request
- JSON result
istanbul.getValidators();
[
"0x189d23d201b03ae1cf9113672df29a5d672aefa3",
"0x44b07d2c28b8ed8f02b45bd84ac7d9051b3349e6",
"0x4c1ccd426833b9782729a212c857f2f03b7b4c0d",
"0x7ae555d0f6faad7930434abdaac2274fd86ab516",
"0xc1056df7c02b6f1a353052eaf0533cc7cb743b52"
]The validator
0x2aabbc1bb9bacef60a09764d1a1f4f04a47885c1
was removed and the validators list now only has five addresses.Check that node 5 is not validator:
geth attach http://localhost:22005
> istanbul.isValidator()
falseStop the
geth
process corresponding to the validator that was removed:- Command
- Result
ps
PID TTY TIME CMD
10554 ttys000 0:00.11 -bash
21829 ttys001 0:00.03 -bash
9125 ttys002 0:00.94 -bash
36432 ttys002 0:31.93 geth --datadir data --nodiscover --istanbul.blockperiod 5 --syncmode full --mine --minerthreads 1 --verbosity 5 --networkid 10 --http --http.addr 0.0.0.0 --http.port 22000 --http.api admin,
36433 ttys002 0:30.75 geth --datadir data --nodiscover --istanbul.blockperiod 5 --syncmode full --mine --minerthreads 1 --verbosity 5 --networkid 10 --http --http.addr 0.0.0.0 --http.port 22001 --http.api admin,
36434 ttys002 0:31.72 geth --datadir data --nodiscover --istanbul.blockperiod 5 --syncmode full --mine --minerthreads 1 --verbosity 5 --networkid 10 --http --http.addr 0.0.0.0 --http.port 22002 --http.api admin,
36435 ttys002 0:31.65 geth --datadir data --nodiscover --istanbul.blockperiod 5 --syncmode full --mine --minerthreads 1 --verbosity 5 --networkid 10 --http --http.addr 0.0.0.0 --http.port 22003 --http.api admin,
36436 ttys002 0:31.63 geth --datadir data --nodiscover --istanbul.blockperiod 5 --syncmode full --mine --minerthreads 1 --verbosity 5 --networkid 10 --http --http.addr 0.0.0.0 --http.port 22004 --http.api admin,
36485 ttys002 0:06.86 geth --datadir data --nodiscover --istanbul.blockperiod 5 --syncmode full --mine --minerthreads 1 --verbosity 5 --networkid 10 --http --http.addr 0.0.0.0 --http.port 22005 --http.api admin,
36455 ttys003 0:00.05 -bash
36493 ttys003 0:00.22 geth attach node4/data/geth.ipcKill the
geth
process that uses port22005
, corresponding to node 5 as indicated instart5.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.