# Renew KES Keys

UPDATED: 12/12/24 to include conway CLI comands

{% hint style="info" %}
Credits to <img src="https://earncoinpool.com/images/coin_v3.png" alt="" data-size="line"> [Earn Coin Pool](https://earncoinpool.com/) for documenting the procedure.
{% endhint %}

{% hint style="info" %}
Please note: paths in this guide are based on [Coincashew](https://www.coincashew.com/coins/overview-ada/guide-how-to-build-a-haskell-stakepool-node/) guide on how to build a stake pool. Please adjust paths as necessary.
{% endhint %}

## Step 1 - Find the starting KES period

On node run the following commands:

```
slotNo=$(cardano-cli conway 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}
```

{% hint style="warning" %}
Write down this number you will need it when you run the steps on your Air Gapped Machine.
{% endhint %}

## Step 2 - Look up Operational Certificate Numbers

There are two different methods you can use, please review and select your preferred method.

{% tabs %}
{% tab title="CLI Method" %}
When it's time to update your KES you can run the following command on your block producer to confirm you have the correct Operational Certificate Numbers

{% hint style="info" %}
Note path to node.cert and adjust if needed. Path in example is based off [Coincashew](https://www.coincashew.com/coins/overview-ada/guide-how-to-build-a-haskell-stakepool-node/) guide for setting up a stake pool.
{% endhint %}

```
cardano-cli conway query kes-period-info --mainnet  \
  --op-cert-file $NODE_HOME/node.cert
```

\
Results should look similar to the following:

```
✓ The operational certificate counter agrees with the node protocol state counter
✓ Operational certificate's kes period is within the correct KES period interval
{
    "qKesNodeStateOperationalCertificateNumber": 4,
    "qKesCurrentKesPeriod": 505,
    "qKesOnDiskOperationalCertificateNumber": 4,
    "qKesRemainingSlotsInKesPeriod": 6832926,
    "qKesMaxKESEvolutions": 62,
    "qKesKesKeyExpiry": "2022-09-22T21:44:51Z",
    "qKesEndKesInterval": 558,
    "qKesStartKesInterval": 496,
    "qKesSlotsPerKesPeriod": 129600
}
```

{% hint style="info" %}
This line is the Operational Certificate that your pool used to mint its last block\
\
"qKes**NodeState**OperationalCertificateNumber": 4,
{% endhint %}

{% hint style="info" %}
This line is the counter number of your current Operational Certificate:\
"qKes**OnDisk**OperationalCertificateNumber": 4,
{% endhint %}

{% hint style="danger" %}
If these number are **NOT** the same, as for the example above **NodeState**=4 and **OnDisk**=5 then you need to rollback your counter. In this case the node counter would need to be rolled back from 5 to 4

Also If you have never made a block then you will need to rollback your counter to 0

To rollback your counter see our guide [here](https://ecp.gitbook.io/how-to-guides-for-coincashew-method-cardano-spos/maintenance-and-daily-operations/how-to-guides-for-spos-using-coincashew-method/adjust-node.counter-for-kes)\
\
If, for example, **NodeState** and **OnDisk** =4, then you are all set and can proceed.<br>
{% endhint %}
{% endtab %}

{% tab title="Manual Method" %}
Before you move to your air gapped machine, with Vasil upgrade your node.counter for KES must be just one count higher than the last OpCertC value for your last block. You can find this value on resources like adapool.org under blocks tab.

Navigate to your pool on [adapools.org](https://adapools.org/). Once on your pool page click on the blocks tab and look at your last block. Look at the OpCertC column and make note of the number.\
![](https://2549074837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8PjW7zFPfe4PgCsPtkZx%2Fuploads%2FzN7JGdXee9Bh5q3W4XLX%2Fada_pools_OpCertC.png?alt=media\&token=175e1439-65ba-454e-a315-0f567bc4fe09)
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
Write down this number you will need it when you run the steps on your Air Gapped Machine.
{% endhint %}

## Step 3 - Make a new KES pair

{% hint style="info" %}
KES files in this example with be created to our $NODE\_HOME directory. Adjust if needed.
{% endhint %}

In this step we will create a new KES pair (kes.vkey and kes.skey)

:warning:**ON AIR GAPPED MACHINE**: run the following commands:

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

## Step 4 - Verify the current value of your node.counter is valid.

:warning:**STILL ON AIR GAPPED MACHINE**:

navigate to where your node.counter file is. :file\_folder:In this example it's located in our home directory in a folder called: cold-keys. So we run this command to output node.counter information.

```javascript
cat $HOME/cold-keys/node.counter
```

:writing\_hand:Take note that "Next certificate issue number: x"&#x20;

{% hint style="info" %}
node.counter MUST be **ONE** greater than the most recently created block's OpCertC or "qKes**NodeState**OperationalCertificateNumber" value.\
\
Depending which method you used in [Step 2](#step-2-look-up-operational-certificate-numbers)
{% endhint %}

For example, if your OpCertC value is 4 for your last block, then your node.counter should read "Next certificate issue number: 5"\
\
Likewise if you used CLI method if "qKes**NodeState**OperationalCertificateNumber": 4, our node.counter should read "Next certificate issue number: 5"

If your "Next certificate issue number" is **one** higher you are all set and can continue to the [Step 5.](#step-5-create-the-new-node.cert)

{% hint style="warning" %}
:warning:If it's not one higher you will need to adjust your node.counter see our guide [here](https://ecp.gitbook.io/how-to-guides-for-coincashew-method-cardano-spos/maintenance-and-daily-operations/adjust-node.counter-for-kes#welcome)\
\
:warning:If you just rolled back your node.counter then "description" will be blank. This is okay, it will correct itself after you run the [next step](#step-5-create-the-new-node.cert).
{% endhint %}

## Step 5 - Create the new node.cert

:warning:**STILL ON AIR GAPPED MACHINE**: Create a new node.cert file with the following command.

Update \<startKesPeriod> with the value from above from [Step 1](#step-1-find-the-starting-kes-period)

Then run this command by replacing "\<startKesPeriod>" with correct number from [Step 1](#step-1-find-the-starting-kes-period)\
Example: --kes-period 503 \\

```
cd $NODE_HOME
cardano-cli conway 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
```

## Step 6 - Copy node.cert and kes.skey back to your block producer node.

Copy your new node.cert and kes.skey file to your block producer node&#x20;

## Step 7 - Restart Node on block producer

Now restart cardano node on your block producer with following command

```
sudo systemctl restart cardano-node
```

## Step 8 - Check if correct

Once you update your KES you can run the following command on your block producer to confirm you have the correct OpCertC

{% hint style="info" %}
Note path to node.cert and adjust if needed. Path in example is based off [Coincashew](https://www.coincashew.com/coins/overview-ada/guide-how-to-build-a-haskell-stakepool-node/) guide for setting up a stake pool.
{% endhint %}

```
cardano-cli conway query kes-period-info --mainnet  \
  --op-cert-file $NODE_HOME/node.cert
```

Results should look similar to the following:

```
✓ The operational certificate counter agrees with the node protocol state counter
✓ Operational certificate's kes period is within the correct KES period interval
{
    "qKesNodeStateOperationalCertificateNumber": 4,
    "qKesCurrentKesPeriod": 505,
    "qKesOnDiskOperationalCertificateNumber": 5,
    "qKesRemainingSlotsInKesPeriod": 6832926,
    "qKesMaxKESEvolutions": 62,
    "qKesKesKeyExpiry": "2022-09-22T21:44:51Z",
    "qKesEndKesInterval": 558,
    "qKesStartKesInterval": 496,
    "qKesSlotsPerKesPeriod": 129600
}
```

{% hint style="info" %}
The first line after checks should show last node counter. For our example the last OpCertC number for our last block was 4. \
\
So it should read:\
"qKes**NodeState**OperationalCertificateNumber": 4,
{% endhint %}

{% hint style="success" %}
The third line should match the next certificate issue number that we wanted. So, for our example it needed to be 5, **ONE** number higher than the OpCertC of 4.\
\
So it should look like:\
"qKes**OnDisk**OperationalCertificateNumber": 5,
{% endhint %}

{% hint style="info" %}
Make note of "qKesKesKeyExpiry": date.
{% endhint %}

### Congratulations you did it!

## Step 10 - Back up

If update successful:

{% hint style="info" %}
Best practice recommendation: It's now a good time to make a new backup of your new node.counter file and cold-keys directory to another USB drive or other offline location.
{% endhint %}

## Contributors&#x20;

Thanks to the following pools for helping to put together these guides. Please consider delegating to their pools to support them.  Are you a pool? Consider buying them a coffee

![](https://img.cexplorer.io/a/5/7/2/1/pool12wpfng6cu7dz38yduaul3ngfm44xhv5xmech68m5fwe4wu77udd.png) [Apex Cardano Pool - Ticker: APEX](https://cexplorer.io/pool/pool12wpfng6cu7dz38yduaul3ngfm44xhv5xmech68m5fwe4wu77udd)

![](https://img.cexplorer.io/7/e/1/9/f/pool16cdtqyk0fvxzfkhjg3esjcuty4tnlpds5lj0lkmqmwdjyzaj7p8.png)  [Earn Coin Pool - Ticker: ECP](https://cexplorer.io/pool/pool16cdtqyk0fvxzfkhjg3esjcuty4tnlpds5lj0lkmqmwdjyzaj7p8)

&#x20;![](https://img.cexplorer.io/9/0/1/d/4/pool1zn4wnk52kmfjy9mw4z85p6wn9kzrn94l9h5gys8r2k2w57mdnhh.png) [Envy Stake Pool - Ticker ENVY](https://cexplorer.io/pool/pool1zn4wnk52kmfjy9mw4z85p6wn9kzrn94l9h5gys8r2k2w57mdnhh)

![](https://2549074837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8PjW7zFPfe4PgCsPtkZx%2Fuploads%2FljMQsj8QrPi6cWmKyBZK%2Fpgwad_new_90x50.png?alt=media\&token=cb1ee893-6992-42e4-b480-04067a6ed701) [PGWAD](https://twitter.com/PgwadaS)&#x20;

![xSPO Alliance Logo](https://2549074837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8PjW7zFPfe4PgCsPtkZx%2Fuploads%2F0sqzqoHnqVXizi2RHABd%2FxSPO_NFT_64x64.png?alt=media\&token=1c1b130e-26df-4b1e-8e0e-e85fae1ee73e) [xSPO Alliance](http://xspo-alliance.org/discord)
