Skip to main content

CNCLI Leader Logs 📑

info

CNCLI method still works, but before you start building, take a look at this method by ADA Snake Pool.

"Lightweight and Portable Scheduled Blocks Checker for Next, Current and Previous Epochs. No cardano-node Required, data is taken from blockfrost.io and armada-alliance.com."

Build CNCLI (thanks to @AndrewWestberg)

caution

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

>_ Terminal
mkdir -p $HOME/.cargo/bin
>_ Terminal
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Choose Option 1 (default)

>_ Terminal
source $HOME/.cargo/env

rustup install stable

rustup default stable

rustup update

rustup component add clippy rustfmt

Install any necessary packages. Your system may already have most to all of these.

>_ Terminal
sudo apt update -y && sudo apt install -y automake \ 
build-essential pkg-config libffi-dev libgmp-dev \
libssl-dev libtinfo-dev libsystemd-dev zlib1g-dev \
make g++ tmux git jq wget libncursesw5 libtool autoconf

Build cncli

>_ Terminal
# If you don't have a $HOME/git folder you can create one using:
# mkdir $HOME/git

cd $HOME/git

git clone --recurse-submodules https://github.com/AndrewWestberg/cncli

cd cncli

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

>_ Terminal
git checkout <latest_tag_name>
>_ Terminal
# This will take some time on a Raspberry Pi - be patient, it'll git r dun.
# Grab some coffee, check the strawberries, whatever.

cargo install --path . --force

Check if the installation was successful and locate cncli

>_ Terminal
cncli --version

command -v cncli

echo $PATH

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
mkdir -p $HOME/.local/bin
echo PATH="$HOME/.local/bin:$PATH" >> $HOME/.bashrc
source $HOME/.bashrc

Move cncli from it's current location to .local/bin

>_ Terminal
mv <path/to>/cncli $HOME/.local/bin/cncli

Run cncli sync and deploy it as a service

info

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.

>_ Terminal
mkdir -p $HOME/pi-pool/cncli

sudo nano /etc/systemd/system/cncli-sync.service

Paste the following, adjust ip and port, save and exit.

>_ Terminal
[Unit]
Description=CNCLI Sync
After=multi-user.target

[Service]
Type=simple
Restart=always
RestartSec=5
LimitNOFILE=131072
ExecStart=/home/ada/.local/bin/cncli sync --host <your_core_ip> --port <your_core_port> --db /home/ada/pi-pool/cncli/cncli.db
KillSignal=SIGINT
SuccessExitStatus=143
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=cncli-sync

[Install]
WantedBy=multi-user.target

Enable the service

>_ Terminal
sudo systemctl daemon-reload

sudo systemctl enable cncli-sync.service

sudo systemctl start cncli-sync.service

Make the cncli.db writable (needed for the following script)

>_ Terminal
cd $HOME/pi-pool/cncli

sudo chmod a+w cncli.db

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

>_ Terminal
    mkdir -p $HOME/pi-pool/scripts
sudo nano $HOME/pi-pool/scripts/leaderlog-stake-snapshot-v4.sh

Paste the following, adjust parameters, save and exit.

>_ Terminal
#!/bin/bash

##############################################################
################### To be filled ##########################
##############################################################

POOLID="type pool ID"

VRFSKEY=$HOME/pi-pool/cncli/vrf.skey

BYRON=$HOME/pi-pool/cncli/mainnet-byron-genesis.json

SHELLEY=$HOME/pi-pool/cncli/mainnet-shelley-genesis.json

CNCLIDB=$HOME/pi-pool/cncli/cncli.db #Ensure you point to the correct folder after running cncli sync.

TZ="America/Los_Angeles" #https://en.wikipedia.org/wiki/List_of_tz_database_time_zones [default: America/Los_Angeles].

EPOCH="current" #prev or next for last and next epoch respectively. Default is current.

##############################################################


if [ "$EPOCH" = "current" ] || [ "$EPOCH" = "prev" ] || [ "$EPOCH" = "next" ]; then
if [ "$EPOCH" = "current" ]; then
echo ""
echo "Please be patient. Generating leaderlogs for the current epoch."
echo ""
POOLSTAKE=`cat stake-snapshot.json | awk '$1 ~ /poolStakeSet/ {print $NF+0}'`
ACTIVESTAKE=`cat stake-snapshot.json | awk '$1 ~ /activeStakeSet/ {print $NF+0}'`
fi
if [ "$EPOCH" = "next" ]; then
echo ""
echo "Please be patient. Generating leaderlogs for the next epoch."
echo ""
POOLSTAKE=`cat stake-snapshot.json | awk '$1 ~ /poolStakeMark/ {print $NF+0}'`
ACTIVESTAKE=`cat stake-snapshot.json | awk '$1 ~ /activeStakeMark/ {print $NF+0}'`
fi
if [ "$EPOCH" = "prev" ]; then
echo ""
echo "Please be patient. Generating leaderlogs for the previous epoch."
echo ""
POOLSTAKE=`cat stake-snapshot.json | awk '$1 ~ /poolStakeGo/ {print $NF+0}'`
ACTIVESTAKE=`cat stake-snapshot.json | awk '$1 ~ /activeStakeGo/ {print $NF+0}'`
fi
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
else
echo ""
echo "Invalid EPOCH entry"
echo ""
fi

if [ -f ./slot.json ]; then
epoch=`cat slot.json | awk '$1 ~ /"epoch":/ {print $NF+0}'`
mv slot.json slot_$epoch.json
echo ""
echo "Previewing leaderlogs slots for epoch $epoch"
echo ""
cat slot_$epoch.json
echo ""
if [ -f ./slot_.json ]; then
rm slot_.json
fi
else
echo ""
echo "Leaderlogs could not be generated. Please check parameters and try again. Also ensure system has adequate RAM if failure repeats."
echo ""
fi

Make it executable

>_ Terminal
sudo chmod +x leaderlog-stake-snapshot-v4.sh
caution

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
cardano-cli query stake-snapshot --stake-pool-id <your_pool_id> --mainnet > stake-snapshot.json

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
mv /path/to/vrf.skey $HOME/pi-pool/cncli/vrf.skey
mv /path/to/mainnet-byron-genesis.json $HOME/pi-pool/cncli/mainnet-byron-genesis.json
mv /path/to/mainnet-shelley-genesis.json $HOME/pi-pool/cncli/mainnet-shelley-genesis.json
mv /path/to/stake-snapshot.json $HOME/pi-pool/scripts/stake-snapshot.json

Run leaderlog script

caution

Every time you run the script you need a fresh stake-snapshot.json, except your stake didn't change for the last few epochs.

>_ Terminal
cd $HOME/pi-pool/scripts
./leaderlog-stake-snapshot-v4.sh

The schedule is saved to slot_number-of-epoch.json.

caution

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".

danger

Be careful to keep your block leader schedule private, as attackers could use this information to strategically attack your pool.