Searchโ€ฆ
CNCLI Leader Logs๐Ÿ“‘
How to get your Stake Pools Slot Assignments for next Epoch

Build CNCLI (thanks to @AndrewWestberg)

Running it on your block-producing/Core node is the convenient way, but to save resources you may build and run cncli on another (i.e. your monitoring) device. Therefore you will need to get the stake-snapshot.json from one of your running nodes and copy the genesis files and the vrf.skey from your Core to the particular device.

Prepare Rust Environment and install Rustup

1
mkdir -p $HOME/.cargo/bin
Copied!
1
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
Copied!
Choose Option 1 (default)
1
source $HOME/.cargo/env
2
โ€‹
3
rustup install stable
4
โ€‹
5
rustup default stable
6
โ€‹
7
rustup update
8
โ€‹
9
rustup component add clippy rustfmt
Copied!
Install any necessary packages. Your system may already have most to all of these.
Monitor
Core
1
sudo apt update -y && sudo apt install -y automake \
2
build-essential pkg-config libffi-dev libgmp-dev \
3
libssl-dev libtinfo-dev libsystemd-dev zlib1g-dev \
4
make g++ tmux git jq wget libncursesw5 libtool autoconf
Copied!
1
sudo apt update -y
Copied!

Build cncli

1
# If you don't have a $HOME/git folder you can create one using:
2
# mkdir $HOME/git
3
โ€‹
4
cd $HOME/git
5
โ€‹
6
git clone --recurse-submodules https://github.com/AndrewWestberg/cncli
7
โ€‹
8
cd cncli
Copied!
Check https://github.com/AndrewWestberg/cncli for the latest tag name and adjust the command below. For the time of writing this, it's v3.1.4
1
git checkout <latest_tag_name>
Copied!
1
# This will take some time on a Raspberry Pi - be patient, it'll git r dun.
2
# Grab some coffee, check the strawberries, whatever.
3
โ€‹
4
cargo install --path . --force
Copied!
Check if the installation was successful and locate cncli
1
cncli --version
2
โ€‹
3
command -v cncli
4
โ€‹
5
echo $PATH
Copied!
The command -v should show you where the cncli executable currently lives, .cargo/bin. The echo command will show what's on your PATH.
You should have .local/bin on your PATH, but in case you don't (Core should have it), do it now and add it to your PATH:
Monitor
1
mkdir -p $HOME/.local/bin
2
echo PATH="$HOME/.local/bin:$PATH" >> $HOME/.bashrc
3
source $HOME/.bashrc
Copied!
Move cncli from it's current location to .local/bin
1
mv <path/to>/cncli $HOME/.local/bin/cncli
Copied!

Run cncli sync and deploy it as a service

CNCLI sync creates an sqlite3 database (cncli.db), and needs to be connected to your running core-node. The guide assumes you have followed the armada-alliance guide so far and use the same folder structure.
1
mkdir -p $HOME/pi-pool/cncli
2
โ€‹
3
sudo nano /etc/systemd/system/cncli-sync.service
Copied!
Paste the following, adjust ip and port, save and exit.
Monitor
Core
1
[Unit]
2
Description=CNCLI Sync
3
After=multi-user.target
4
โ€‹
5
[Service]
6
Type=simple
7
Restart=always
8
RestartSec=5
9
LimitNOFILE=131072
10
ExecStart=/home/ada/.local/bin/cncli sync --host <your_core_ip> --port <your_core_port> --db /home/ada/pi-pool/cncli/cncli.db
11
KillSignal=SIGINT
12
SuccessExitStatus=143
13
StandardOutput=syslog
14
StandardError=syslog
15
SyslogIdentifier=cncli-sync
16
โ€‹
17
[Install]
18
WantedBy=multi-user.target
Copied!
1
[Unit]
2
Description=CNCLI Sync
3
After=multi-user.target
4
โ€‹
5
[Service]
6
Type=simple
7
Restart=always
8
RestartSec=5
9
LimitNOFILE=131072
10
ExecStart=/home/ada/.local/bin/cncli sync --host 127.0.0.1 --port <cardano_node_port> --db $HOME/pi-pool/cncli/cncli.db
11
KillSignal=SIGINT
12
SuccessExitStatus=143
13
StandardOutput=syslog
14
StandardError=syslog
15
SyslogIdentifier=cncli-sync
16
โ€‹
17
[Install]
18
WantedBy=multi-user.target
Copied!
Enable the service
1
sudo systemctl daemon-reload
2
โ€‹
3
sudo systemctl enable cncli-sync.service
4
โ€‹
5
sudo systemctl start cncli-sync.service
Copied!
Make the cncli.db writable (needed for the following script)
1
cd $HOME/pi-pool/cncli
2
โ€‹
3
sudo chmod a+w cncli.db
Copied!

Create the leaderlog-stake-snapshot-v4.sh script (thanks to @sayshar)

Monitor
Core
1
mkdir -p $HOME/pi-pool/scripts
2
sudo nano $HOME/pi-pool/scripts/leaderlog-stake-snapshot-v4.sh
Copied!
1
sudo nano $HOME/pi-pool/scripts/leaderlog-stake-snapshot-v4.sh
Copied!
Paste the following, adjust parameters, save and exit.
Monitor
Core
1
#!/bin/bash
2
โ€‹
3
##############################################################
4
################### To be filled ##########################
5
##############################################################
6
โ€‹
7
POOLID="type pool ID"
8
โ€‹
9
VRFSKEY=$HOME/pi-pool/cncli/vrf.skey
10
โ€‹
11
BYRON=$HOME/pi-pool/cncli/mainnet-byron-genesis.json
12
โ€‹
13
SHELLEY=$HOME/pi-pool/cncli/mainnet-shelley-genesis.json
14
โ€‹
15
CNCLIDB=$HOME/pi-pool/cncli/cncli.db #Ensure you point to the correct folder after running cncli sync.
16
โ€‹
17
TZ="America/Los_Angeles" #https://en.wikipedia.org/wiki/List_of_tz_database_time_zones [default: America/Los_Angeles].
18
โ€‹
19
EPOCH="current" #prev or next for last and next epoch respectively. Default is current.
20
โ€‹
21
##############################################################
22
โ€‹
23
โ€‹
24
if [ "$EPOCH" = "current" ] || [ "$EPOCH" = "prev" ] || [ "$EPOCH" = "next" ]; then
25
if [ "$EPOCH" = "current" ]; then
26
echo ""
27
echo "Please be patient. Generating leaderlogs for the current epoch."
28
echo ""
29
POOLSTAKE=`cat stake-snapshot.json | awk '$1 ~ /poolStakeSet/ {print $NF+0}'`
30
ACTIVESTAKE=`cat stake-snapshot.json | awk '$1 ~ /activeStakeSet/ {print $NF+0}'`
31
fi
32
if [ "$EPOCH" = "next" ]; then
33
echo ""
34
echo "Please be patient. Generating leaderlogs for the next epoch."
35
echo ""
36
POOLSTAKE=`cat stake-snapshot.json | awk '$1 ~ /poolStakeMark/ {print $NF+0}'`
37
ACTIVESTAKE=`cat stake-snapshot.json | awk '$1 ~ /activeStakeMark/ {print $NF+0}'`
38
fi
39
if [ "$EPOCH" = "prev" ]; then
40
echo ""
41
echo "Please be patient. Generating leaderlogs for the previous epoch."
42
echo ""
43
POOLSTAKE=`cat stake-snapshot.json | awk '$1 ~ /poolStakeGo/ {print $NF+0}'`
44
ACTIVESTAKE=`cat stake-snapshot.json | awk '$1 ~ /activeStakeGo/ {print $NF+0}'`
45
fi
46
cncli leaderlog --pool-id $POOLID --pool-vrf-skey $VRFSKEY --byron-genesis $BYRON --shelley-genesis $SHELLEY --pool-stake $POOLSTAKE --active-stake $ACTIVESTAKE --db $CNCLIDB --tz $TZ --ledger-set $EPOCH > slot.json
47
else
48
echo ""
49
echo "Invalid EPOCH entry"
50
echo ""
51
fi
52
โ€‹
53
if [ -f ./slot.json ]; then
54
epoch=`cat slot.json | awk '$1 ~ /"epoch":/ {print $NF+0}'`
55
mv slot.json slot_$epoch.json
56
echo ""
57
echo "Previewing leaderlogs slots for epoch $epoch"
58
echo ""
59
cat slot_$epoch.json
60
echo ""
61
if [ -f ./slot_.json ]; then
62
rm slot_.json
63
fi
64
else
65
echo ""
66
echo "Leaderlogs could not be generated. Please check parameters and try again. Also ensure system has adequate RAM if failure repeats."
67
echo ""
68
fi
Copied!
1
#!/bin/bash
2
โ€‹
3
##############################################################
4
################### To be filled ##########################
5
##############################################################
6
โ€‹
7
POOLID="type pool ID"
8
โ€‹
9
VRFSKEY=$HOME/pi-pool/vrf.skey
10
โ€‹
11
BYRON=$HOME/pi-pool/files/mainnet-byron-genesis.json
12
โ€‹
13
SHELLEY=$HOME/pi-pool/files/mainnet-shelley-genesis.json
14
โ€‹
15
CNCLIDB=$HOME/pi-pool/cncli/cncli.db #Ensure you point to the correct folder after running cncli sync.
16
โ€‹
17
TZ="America/Los_Angeles" #https://en.wikipedia.org/wiki/List_of_tz_database_time_zones [default: America/Los_Angeles].
18
โ€‹
19
EPOCH="current" #prev or next for last and next epoch respectively. Default is current.
20
โ€‹
21
##############################################################
22
โ€‹
23
if [ ! -f stake-snapshot.json ];then
24
cardano-cli query stake-snapshot --stake-pool-id $POOLID --mainnet > stake-snapshot.json
25
echo ""
26
cat stake-snapshot.json
27
echo ""
28
else
29
ANS="N"
30
echo ""
31
echo "The file stake-snapshot.json is detected. Would you like to recreate it? y/N"
32
echo ""
33
read ANS
34
fi
35
โ€‹
36
if [ $ANS = "y" ] || [ $ANS = "Y" ]; then
37
echo ""
38
echo "Generating new stake-snapshot.json."
39
echo ""
40
cardano-cli query stake-snapshot --stake-pool-id $POOLID --mainnet > stake-snapshot.json
41
echo ""
42
echo "Previewing stake-snapshot.json"
43
echo ""
44
cat stake-snapshot.json
45
echo ""
46
else
47
echo ""
48
echo "Previewing stake-snapshot.json"
49
echo ""
50
cat stake-snapshot.json
51
echo ""
52
fi
53
โ€‹
54
if [ "$EPOCH" = "current" ] || [ "$EPOCH" = "prev" ] || [ "$EPOCH" = "next" ]; then
55
if [ "$EPOCH" = "current" ]; then
56
echo ""
57
echo "Please be patient. Generating leaderlogs for the current epoch."
58
echo ""
59
POOLSTAKE=`cat stake-snapshot.json | awk '$1 ~ /poolStakeSet/ {print $NF+0}'`
60
ACTIVESTAKE=`cat stake-snapshot.json | awk '$1 ~ /activeStakeSet/ {print $NF+0}'`
61
fi
62
if [ "$EPOCH" = "next" ]; then
63
echo ""
64
echo "Please be patient. Generating leaderlogs for the next epoch."
65
echo ""
66
POOLSTAKE=`cat stake-snapshot.json | awk '$1 ~ /poolStakeMark/ {print $NF+0}'`
67
ACTIVESTAKE=`cat stake-snapshot.json | awk '$1 ~ /activeStakeMark/ {print $NF+0}'`
68
fi
69
if [ "$EPOCH" = "prev" ]; then
70
echo ""
71
echo "Please be patient. Generating leaderlogs for the previous epoch."
72
echo ""
73
POOLSTAKE=`cat stake-snapshot.json | awk '$1 ~ /poolStakeGo/ {print $NF+0}'`
74
ACTIVESTAKE=`cat stake-snapshot.json | awk '$1 ~ /activeStakeGo/ {print $NF+0}'`
75
fi
76
cncli leaderlog --pool-id $POOLID --pool-vrf-skey $VRFSKEY --byron-genesis $BYRON --shelley-genesis $SHELLEY --pool-stake $POOLSTAKE --active-stake $ACTIVESTAKE --db $CNCLIDB --tz $TZ --ledger-set $EPOCH > slot.json
77
else
78
echo ""
79
echo "Invalid EPOCH entry"
80
echo ""
81
fi
82
โ€‹
83
if [ -f ./slot.json ]; then
84
epoch=`cat slot.json | awk '$1 ~ /"epoch":/ {print $NF+0}'`
85
mv slot.json slot_$epoch.json
86
echo ""
87
echo "Previewing leaderlogs slots for epoch $epoch"
88
echo ""
89
cat slot_$epoch.json
90
echo ""
91
if [ -f ./slot_.json ]; then
92
rm slot_.json
93
fi
94
else
95
echo ""
96
echo "Leaderlogs could not be generated. Please check parameters and try again. Also ensure system has adequate RAM if failure repeats."
97
echo ""
98
fi
Copied!
Make it executable
1
sudo chmod +x leaderlog-stake-snapshot-v4.sh
Copied!
If you installed cncli on your Core continue with "Run leaderlog script", otherwise you have to do some more steps:
Run the following command on your Core. Make sure to add your pool id.
Core
1
cardano-cli query stake-snapshot --stake-pool-id <your_pool_id> --mainnet > stake-snapshot.json
Copied!
Then copy vrf.skey, mainnet-byron-genesis.json, mainnet-shelley-genesis.json stake-snapshot.json from your Core to your cncli device. (via USB-stick, scp or rsync...) Move them to the right directory:
Monitor
1
mv /path/to/vrf.skey $HOME/pi-pool/cncli/vrf.skey
2
mv /path/to/mainnet-byron-genesis.json $HOME/pi-pool/cncli/mainnet-byron-genesis.json
3
mv /path/to/mainnet-shelley-genesis.json $HOME/pi-pool/cncli/mainnet-shelley-genesis.json
4
mv /path/to/stake-snapshot.json $HOME/pi-pool/scripts/stake-snapshot.json
Copied!

Run leaderlog script

Every time you run the script you need a fresh stake-snapshot.json, except your stake didn't change for the last few epochs.
1
cd $HOME/pi-pool/scripts
2
./leaderlog-stake-snapshot-v4.sh
Copied!
The schedule is saved to slot_number-of-epoch.json.
The script calculates the schedule for the current epoch by default. You can run it for the next epoch 1.5 days before. (Or at 70% into the current epoch.) Just change the epoch parameter in the script from "current" to "next".
Be careful to keep your block leader schedule private, as attackers could use this information to strategically attack your pool.
Last modified 1mo ago