Wartung eines Cardano-Pools im Mainnet

Gültigkeit der KES Keys und damit des node.cert abfragen

Folgendes Kommando kann genutzt werden, um die Gültigkeit des node Zertifikats abzufragen.

Hinwei: –$(NODE_CONFIG) ist in der regel –mainnet

cd $NODE_HOME
cardano-cli query kes-period-info \
--${NODE_CONFIG} \
--op-cert-file node.cert
Gültiges Node Zertifikat
2 Grüne Haken – Das Node Zertifikat ist gültig.

Erneuern der KES Keys

Die KES Keys müssen alle 90 Tage erneuert werden, wenn der Pool im Mainnet betrieben wird.

KES steht für “key evolving signature”, KES-Keys wurden eingeführt, um den Pool vor Hackern zu schützen, welche versuchen könnten die Keys zu kompromittieren.

Die KES-Keys müssen alle 90 Tage erneuert werden.

Prüfen der NodeCertificateNumber

Das Kommando:

cardano-cli query kes-period-info

gibt 2 Variablen aus:

qKesOnDiskOperationalCertificateNumber

und

qKesNodeStateOperationalCertificateNumber

Die Variable: qKesOnDiskOperationalCertificateNumber ergibt sich aus dem node.counter file. Sie muss bei einen neu erstellten Zertifikat EXAKT um 1 größer sein, als qKesNodeStateOperationalCertificateNumber.

Beim aufsetzen eines Cardano Stake Pools, haben wir einen node.counter file erzeugt. Hat der Pool seit dem letzten erneuern der Zertifikate, mindestens einen Block gemintet, dann müssen wir hier nichts tun. Weil:

Dann ist bei Aufruf des Kommandos:

cardano-cli query kes-period-info

Der:

qKesOnDiskOperationalCertificateNumber

gleich:

qKesNodeStateOperationalCertificateNumber

Das später verwendete Kommando:

cardano-cli node issue-op-cert

Wird den node Counter automatisch um 1 inkrementieren und damit ist alles gut.

Ansonsten muss der Node Counter file neu gesetzt werden, dies geschieht mit:

cd $HOME/cold-keys
cardano-cli node new-counter \
--cold-verification-key-file $HOME/cold-keys/node.vkey \
--counter-value $(( <NodeCertificateNumber> + 1 )) \
--operational-certificate-issue-counter-file node.counter

Generieren eines neuen Node Zertifikats

Schritt 1: Herausfinden der aktuellen KES-Periode.

cd $NODE_HOME
slotNo=$(cardano-cli query tip --mainnet | jq -r '.slot')
slotsPerKESPeriod=$(cat $NODE_HOME/${NODE_CONFIG}-shelley-genesis.json | jq -r '.slotsPerKESPeriod')
kesPeriod=$((${slotNo} / ${slotsPerKESPeriod}))
startKesPeriod=${kesPeriod}
echo startKesPeriod: ${startKesPeriod}

Jetzt kennen wir die Start-KES-Periode.

Schritt 2: Erzeugen eines neuen KES-Paares:

cd $NODE_HOME
cardano-cli node key-gen-KES \
--verification-key-file kes.vkey \
--signing-key-file kes.skey

Nun haben wir das neue KES-Schlüssel-Paar. Dieses werden wir auf der Offline-Maschine signieren.

Schritt 3: Kopieren von kes.vkey und kes.skey auf die Offline-Maschine.

Schritt 4: Signieren des KES-Schlüssel-Paar auf der Offline-Maschine.

cd $NODE_HOME
chmod u+rwx $HOME/cold-keys
cardano-cli node issue-op-cert \
--kes-verification-key-file kes.vkey \
--cold-signing-key-file $HOME/cold-keys/node.skey \
--operational-certificate-issue-counter $HOME/cold-keys/node.counter \
--kes-period <startKesPeriod> \
--out-file node.cert
chmod a-rwx $HOME/cold-keys

Nun haben wir ein neues node.cert. Dieses kopieren wir auf den Block-Producer.

Schritt 5: Kopieren von node.cert auf den Block-Producer in $HOME/cardano-my-node.

Schritt 6: Neustarten des Block-Producer

sudo systemctl restart cardano-node

Nun sollten die neuen KES-Keys aktiv sein. Für 90 Tage haben wir Ruhe.

Prüfen einer Balance

cardano-cli query utxo --address $(cat payment.addr) --mainnet

Prüfen auf Rewards und Rewards Claimen

Wenn eine Epoche zu Ende geht und wir annehmen erfolgreich einen Block geminted zu haben können wir die Rewards mit folgenden Kommando prüfen:

cardano-cli query stake-address-info \ --address $(cat stake.addr) \ --mainnet

Auf dem Block Producer

Den momentan Slot herausfinden und in Variable speichern:

currentSlot=$(cardano-cli query tip --mainnet | jq -r '.slot')
echo Current Slot: $currentSlot

Die reward Balance in Variable speichern:

rewardBalance=$(cardano-cli query stake-address-info \
--mainnet \
--address $(cat stake.addr) | jq -r ".[0].rewardAccountBalance")
echo rewardBalance: $rewardBalance

Destination Adresse setzen:

destinationAddress=$(cat payment.addr)
echo destinationAddress: $destinationAddress

Den withdrawel String für die Transaktion speichern:

cardano-cli query utxo \
--address $(cat payment.addr) \
--mainnet > fullUtxo.out

tail -n +3 fullUtxo.out | sort -k3 -nr > balance.out

cat balance.out

tx_in=""
total_balance=0
while read -r utxo; do
type=$(awk '{ print $6 }' <<< "${utxo}")
if [[ ${type} == 'TxOutDatumNone' ]]
then
in_addr=$(awk '{ print $1 }' <<< "${utxo}")
idx=$(awk '{ print $2 }' <<< "${utxo}")
utxo_balance=$(awk '{ print $3 }' <<< "${utxo}")
total_balance=$((${total_balance}+${utxo_balance}))
echo TxHash: ${in_addr}#${idx}
echo ADA: ${utxo_balance}
tx_in="${tx_in} --tx-in ${in_addr}#${idx}"
fi
done < balance.out
txcnt=$(cat balance.out | wc -l)
echo Total available ADA balance: ${total_balance}
echo Number of UTXOs: ${txcnt}

withdrawalString="$(cat stake.addr)+${rewardBalance}"

Die “rohe Transaktion” aufbauen, dass heißt die Transaktion ohne fees:

cardano-cli transaction build-raw \
${tx_in} \
--tx-out $(cat payment.addr)+0 \
--invalid-hereafter $(( ${currentSlot} + 10000)) \
--fee 0 \
--withdrawal ${withdrawalString} \
--out-file tx.tmp

Die minimum Fee berechnen:

fee=$(cardano-cli transaction calculate-min-fee \
--tx-body-file tx.tmp \
--tx-in-count ${txcnt} \
--tx-out-count 1 \
--mainnet \
--witness-count 2 \
--byron-witness-count 0 \
--protocol-params-file params.json | awk '{ print $1 }')
echo fee: $fee

Den nach der Transaktion auf der Sender Adresse verbleibenden Value berechnen:

txOut=$((${total_balance}-${fee}+${rewardBalance}))
echo Change Output: ${txOut}

Die endgültige Transaktion bauen:

cardano-cli transaction build-raw \
${tx_in} \
--tx-out $(cat payment.addr)+${txOut} \
--invalid-hereafter $(( ${currentSlot} + 10000)) \
--fee ${fee} \
--withdrawal ${withdrawalString} \
--out-file tx.raw

Diese Transaktion holen wir jetzt auf einen USB Stick

Auf dem  air gapped device

cardano-cli transaction sign \
--tx-body-file tx.raw \
--signing-key-file payment.skey \
--signing-key-file stake.skey \
--mainnet \
--out-file tx.signed

Die signierte Transaktion übertragen wir wieder zu unserer online node

Auf dem Block Producer

cardano-cli transaction submit \
--tx-file tx.signed \
--mainnet

Zur Kontrolle fragen wir die balance auf unserer Zieladresse ab:

cardano-cli query utxo \
--address ${destinationAddress} \
--mainnet

Update des Pledge und der Pool Daten

Um den Pledge eines Pools zu ändern, muss das Zertifikat neu hochgeladen werden. Dazu muss der Prozess der Zertifikatserstellung so wie hier oder hier neu durchgemacht werden. Dort dann entsprechend den Pledge anpassen.

Scroll to Top