How XOR N₳ND Secured their Stake Pool
Stake pool operators, like XOR N₳ND [XORN], run the Cardano network. It's at the heart of what SPOs do. It includes monitoring, alerting, and reporting to Pooltool and AdaPools to ensure operations and stability, as well as transparency to our delegates and the wider Cardano community.
It also involves securing the stake pool. This post is about the steps XOR N₳ND took to secure their stake pool.
XOR N₳ND deployed one block producer and a few relays. That is exactly what most stake pool operators deploy.
The block producer at XOR N₳ND runs in a docker container at a data centre, and isn't publicly accessible. It doesn't even have a public IP address and can therefore not be reached from the internet.
The relays connect to the block producer over encrypted reverse SSH tunnels that are initiated by the block producer and authenticated using SSH keys. Password authentication is disabled.
The nodes are sending real time node information to the Cardano RT View monitoring server; again via encrypted reverse SSH tunnels. And Prometheus is polling the monitoring metrics in the same way.
XOR N₳ND shares the node metrics from the block producer with AdaPools and Pooltool. Node metrics from relays are not shared. It would be a security risk to share metrics from relays, since these nodes are public facing.
A few weeks ago XOR N₳ND moved their pool pledge, from wallet keys on an air-gapped Raspberry Pi, to hardware wallets. There are several guides available online outlining how to use hardware wallets to secure stake pool operations. Most of these guides involve exporting the public stake key using cardano-hw-cli.
XOR N₳ND has seen many fellow stake pool operators asking about the process of securing the pledged funds with hardware wallets in the Cardano Stake Pool Best Practice Workgroup on Telegram. They created a guide which shows how to secure your stake pool with hardware wallets without the need to export keys from your hardware wallet device.
XOR N₳ND used AdaLite to sign the pool registration transaction. AdaLite is a web UI for your hardware wallet that runs locally in your web browser. It is developed by VacuumLabs, the same company that developed the Cardano application for Ledger and Trezor devices, and is currently developing a Cardano blockchain explorer for Emurgo.
1. Open AdaLite.io in a web browser and login using your hardware wallet.
2. Delegate your hardware wallet to your pool. You need to sign the transaction on your hardware wallet. This will submit the delegation certificate for your hardware wallet to the chain.
3. Download the public staking key from the Advanced tab. Let's name this file hwstake.vkey. You will use this public stake key to create the pool registration transaction.
4. Copy the public hwstake.vkey to your air-gapped machine and create a pool registration certificate with it. In this example the pool rewards are going to the hardware wallet and the old stake key is a co-owner together with the hardware wallet.
cardano-cli stake-pool registration-certificate \ --cold-verification-key-file keys/cold.vkey \ --vrf-verification-key-file keys/vrf.vkey \ --pool-pledge <pool pledge> \ --pool-cost <pool cost> \ --pool-margin <pool margin> \ --pool-owner-stake-verification-key-file keys/stake.vkey \ --pool-owner-stake-verification-key-file hwstake.vkey \ --pool-reward-account-verification-key-file hwstake.vkey \ --single-host-pool-relay relay1.yourdomain.io \ --pool-relay-port 3001 \ --single-host-pool-relay relay2.yourdomain.io \ --pool-relay-port 3001 \ --single-host-pool-relay relay3.yourdomain.io \ --pool-relay-port 3001 \ --metadata-url https://www.yourdomain.io/pool_metadata.json \ --metadata-hash <metadata hash> \ --mainnet \ --out-file certs/pool-registration.cert
5. Calculate the transaction fee and build the transaction.
cardano-cli transaction build-raw \ --tx-in <UTxO> \ --tx-out $(cat payment.addr)+<tx change> \ --invalid-hereafter <ttl> \ --fee <fee> \ --certificate-file certs/pool-registration.cert \ --mary-era \ --mainnet \ --out-file tx_pool_reg.raw
6. Upload the tx_pool_reg.raw transaction file to AdaLite.
7. Sign the transaction on your hardware wallet.
8. Download the signature file and copy it over to your air-gapped machine. Let's name this file hwstake.witness.
9. You also need to sign this transaction with your cold, old stake, and payment private keys on your air-gapped machine.
cardano-cli transaction witness \ --tx-body-file tx_pool_reg.raw \ --signing-key-file keys/cold.skey \ --mainnet \ --out-file cold.witness cardano-cli transaction witness \ --tx-body-file tx_pool_reg.raw \ --signing-key-file keys/stake.skey \ --mainnet \ --out-file stake.witness cardano-cli transaction witness \ --tx-body-file tx_pool_reg.raw \ --signing-key-file keys/payment.skey \ --mainnet \ --out-file payment.witness
10. Use the downloaded signature file to sign the transaction together with the other witness signatures.
cardano-cli transaction assemble \ --tx-body-file tx_pool_reg.raw \ --witness-file cold.witness \ --witness-file stake.witness \ --witness-file payment.witness \ --witness-file hwstake.witness \ --out-file tx_pool_reg.signed
11. Copy the signed transaction file tx_pool_reg.signed to your hot environment and submit it to the chain.
cardano-cli transaction submit \ --tx-file tx_pool_reg.signed \ --mainnet
Now you need to wait two epochs when your new pool registration takes effect. After that you can move your funds to your hardware wallet. Reward changes take another 2 epochs to take effect.