From 01892ead38c49690ed97798fc1647fd256a8982f Mon Sep 17 00:00:00 2001 From: Jean-Philippe Raynaud Date: Mon, 21 Oct 2024 18:27:29 +0200 Subject: [PATCH] docs: enhance the era markers runbook --- docs/runbook/era-markers/README.md | 180 ++++++++++++++++++++--------- 1 file changed, 128 insertions(+), 52 deletions(-) diff --git a/docs/runbook/era-markers/README.md b/docs/runbook/era-markers/README.md index 3d7d79f2957..c123fa453d4 100644 --- a/docs/runbook/era-markers/README.md +++ b/docs/runbook/era-markers/README.md @@ -4,7 +4,8 @@ This is the process for storing Mithril activation eras markers on the Cardano chain (bootstrap and update operations). -:warning: The process described in this document can lead to disturbed service of the associated Mihtril network. Thus it should be manipulated by experts only. +> [!IMPORTANT] +> :fire: The process described in this document can lead to disturbed service of the associated Mihtril network. Thus it should be manipulated by experts only. ## Pre-requisites @@ -16,36 +17,119 @@ This is the process for storing Mithril activation eras markers on the Cardano c ## Setup +### Setup environment variables + Export the environment variables needed to complete the process: ```bash -$ export CARDANO_NODE_SOCKET_PATH=**PATH_TO_YOUR_NODE_SOCKET** -$ export CARDANO_TESTNET_MAGIC=**YOUR_TESTNET_MAGIC** -$ export CARDANO_WALLET_PATH=**PATH_TO_YOUR_KEYPAIRS** -$ export ERA_ACTIVATION_SECRET_KEY=**YOUR_ERA_ACTIVATION_SECRET_KEY** -$ export ASSETS_PATH=**YOUR_ASSETS_PATH** +export CARDANO_CLI=**CARDANO_CLI_COMMAND** +export CARDANO_NODE_SOCKET_PATH=**PATH_TO_YOUR_NODE_SOCKET** +export CARDANO_WALLET_PATH=**PATH_TO_YOUR_KEYPAIRS** +export ERA_ACTIVATION_SECRET_KEY=**YOUR_ERA_ACTIVATION_SECRET_KEY** +export ASSETS_PATH=**YOUR_ASSETS_PATH** +export SCRIPT_TX_VALUE=**MINIUM_SCRIPT_TX_VALUE** +``` + +A common value for the transaction amount used when a script transaction is made is: + +```bash +export SCRIPT_TX_VALUE=2000000 +``` + +Compute the network magic parameter that handles both the Cardano mainnet and Cardano test networks: + +- If this is for a testing network + +```bash +export CARDANO_TESTNET_MAGIC=**YOUR_TESTNET_MAGIC** +export CARDANO_NETWORK_MAGIC="--testnet-magic $CARDANO_TESTNET_MAGIC" +``` + +- If this is for the `mainnet` + +```bash +export CARDANO_NETWORK_MAGIC="--mainnet" ``` Compute the current Cardano era: ```bash -CARDANO_ERA=$(cardano-cli query tip --testnet-magic $CARDANO_TESTNET_MAGIC | jq -r '.era |= ascii_downcase | .era') +export CARDANO_ERA=$($CARDANO_CLI query tip $CARDANO_NETWORK_MAGIC --socket-path $CARDANO_NODE_SOCKET_PATH | jq -r '.era |= ascii_downcase | .era') +``` + +### Prepare era markers + +> [!IMPORTANT] +> :fire: A misconfiguration of the era markers can cause disturbed service on a Mithril network. The `CURRENT_ERA_EPOCH` and `NEXT_ERA_EPOCH` must be selected very cautiously. + +#### If there is only one supported era + +Set the epoch at which the era is active: + +```bash +export CURRENT_ERA_EPOCH=**ERA_FIRST_ACTIVATION_EPOCH** +``` + +Create the datum file for a unique era: + +```bash +./mithril-aggregator era generate-tx-datum --current-era-epoch $CURRENT_ERA_EPOCH --era-markers-secret-key $ERA_ACTIVATION_SECRET_KEY --target-path $ASSETS_PATH/mithril-era-datum.json ``` -Set the transaction amount used when a script transaction is made: +#### If there are two supported eras + +Set the epoch at which the current era and the next era are active (the `CURRENT_ERA_EPOCH` must be lower than the current epoch and the `NEXT_ERA_EPOCH` must be set to a strictly greater epoch than the current epoch): ```bash -$ export SCRIPT_TX_VALUE=2000000 +export CURRENT_ERA_EPOCH=**CURRENT_ERA_FIRST_ACTIVATION_EPOCH** +export NEXT_ERA_EPOCH=**NEXT_ERA_FIRST_ACTIVATION_EPOCH** +``` + +Create the datum file for two eras: + +```bash +./mithril-aggregator era generate-tx-datum --current-era-epoch $CURRENT_ERA_EPOCH --next-era-epoch $NEXT_ERA_EPOCH --era-markers-secret-key $ERA_ACTIVATION_SECRET_KEY --target-path $ASSETS_PATH/mithril-era-datum.json +``` + +#### Verify the produced era marker + +> [!IMPORTANT] +> :fire: The `mithril-aggregator` binary used to create the era markers must imperatively be compiled with all the targeted supported eras. + +Verify that the produced era markers are exactly what is expected with the following command: + +```bash +cat $ASSETS_PATH/mithril-era-datum.json| jq -r '.fields[].bytes' | tr '\n' ' ' | xxd -r -p | jq +``` + +An example output of the command is: + +```json +{ + "markers": [ + { + "name": "thales", + "epoch": 1 + }, + { + "name": "pythagoras", + "epoch": 723 + } + ], + "signature": "fdcd45debabc148ef11c0bf71e42b7e583102dd5b8e486cd621a18e56136a57ff4f7bf9d036aed6148328a30a20eb6e79422ea4d1cc613e0bf97e14da64a5f00" +} ``` ## Bootstrap Era Markers: Write a transaction with the first version of datum on chain -:warning: This step must be done only once for an address +> [!IMPORTANT] +> :fire: This step must be done only once for an address when no prior datum has been written in a UTxO. +> Otherwise, you need to refer to this [section](#update-era-markers-write-a-new-version-of-datum-on-chain) Verify that the payment address has funds: ```bash -$ cardano-cli query utxo --address $(cat $CARDANO_WALLET_PATH/payment.addr) --testnet-magic $CARDANO_TESTNET_MAGIC +$CARDANO_CLI query utxo --address $(cat $CARDANO_WALLET_PATH/payment.addr) $CARDANO_NETWORK_MAGIC --socket-path $CARDANO_NODE_SOCKET_PATH TxHash TxIx Amount -------------------------------------------------------------------------------------- f0c0345f151f9365fbbb4e7afa217e56b987d9e91fd754ca609d9dfec97275c7 0 10000000000 lovelace + TxOutDatumNone @@ -54,57 +138,53 @@ f0c0345f151f9365fbbb4e7afa217e56b987d9e91fd754ca609d9dfec97275c7 0 10 And create the variable `TX_IN={TxHash}#{TxIn}` by replacing with values from the previous command: ```bash -$ TX_IN=f0c0345f151f9365fbbb4e7afa217e56b987d9e91fd754ca609d9dfec97275c7#0 -``` - -Create the initial datum file: - -```bash -$ ./mithril-aggregator era generate-tx-datum --current-era-epoch 1 --era-markers-secret-key $ERA_ACTIVATION_SECRET_KEY --target-path $ASSETS_PATH/mithril-era-datum-1.json +TX_IN=f0c0345f151f9365fbbb4e7afa217e56b987d9e91fd754ca609d9dfec97275c7#0 ``` Now create the bootstrap transaction with datum: ```bash -$ cardano-cli $CARDANO_ERA transaction build --testnet-magic $CARDANO_TESTNET_MAGIC \ +$CARDANO_CLI $CARDANO_ERA transaction build $CARDANO_NETWORK_MAGIC \ --tx-in $TX_IN \ --tx-out $(cat $CARDANO_WALLET_PATH/payment.addr)+$SCRIPT_TX_VALUE \ - --tx-out-inline-datum-file $ASSETS_PATH/mithril-era-datum-1.json \ + --tx-out-inline-datum-file $ASSETS_PATH/mithril-era-datum.json \ --change-address $(cat $CARDANO_WALLET_PATH/payment.addr) \ - --out-file $ASSETS_PATH/tx.raw + --out-file $ASSETS_PATH/tx.raw \ + --socket-path $CARDANO_NODE_SOCKET_PATH Estimated transaction fee: Lovelace 168669 ``` Then sign the transaction: ```bash -$ cardano-cli $CARDANO_ERA transaction sign \ +$CARDANO_CLI $CARDANO_ERA transaction sign \ --tx-body-file $ASSETS_PATH/tx.raw \ --signing-key-file $CARDANO_WALLET_PATH/payment.skey \ - --testnet-magic $CARDANO_TESTNET_MAGIC \ + $CARDANO_NETWORK_MAGIC \ --out-file $ASSETS_PATH/tx.signed ``` And submit it: ```bash -$ cardano-cli $CARDANO_ERA transaction submit \ - --testnet-magic $CARDANO_TESTNET_MAGIC \ - --tx-file $ASSETS_PATH/tx.signed +$CARDANO_CLI $CARDANO_ERA transaction submit \ + $CARDANO_NETWORK_MAGIC \ + --tx-file $ASSETS_PATH/tx.signed \ + --socket-path $CARDANO_NODE_SOCKET_PATH Transaction successfully submitted. ``` Also get the transaction id: ```bash -$ cardano-cli transaction txid --tx-file $ASSETS_PATH/tx.signed +$CARDANO_CLI transaction txid --tx-file $ASSETS_PATH/tx.signed 6518b3cea0b49b55746ec61148e7c60ab042959d534f6bb6e8f6a844d4af69fb ``` We need to wait a few seconds before the transaction is available and we can see the initial datum for the script address: ```bash -$ cardano-cli query utxo --address $(cat $CARDANO_WALLET_PATH/payment.addr) --testnet-magic $CARDANO_TESTNET_MAGIC +$CARDANO_CLI query utxo --address $(cat $CARDANO_WALLET_PATH/payment.addr) $CARDANO_NETWORK_MAGIC --socket-path $CARDANO_NODE_SOCKET_PATH TxHash TxIx Amount -------------------------------------------------------------------------------------- 6518b3cea0b49b55746ec61148e7c60ab042959d534f6bb6e8f6a844d4af69fb 0 1500000 lovelace + TxOutDatumInline ReferenceTxInsScriptsInlineDatumsInBabbageEra (ScriptDataConstructor 0 [ScriptDataBytes "[{\"n\":\"thales\",\"e\":1}]",ScriptDataBytes "\165\143\232\227\&6\244e\222\211\187\167\197\167\175\229\181\162o/\182[|Nnt.h\ACKE\241=\242\139\242\182:a\204r\217\200&\190I\SO,\US\DLE\152\217U\223P5\128\164\232\153\181\ETB8\132\227\SO"]) @@ -116,7 +196,7 @@ Optional: We can retrieve the initial value stored in the datum with the cardano The full utxo json representation: ```bash -$ cardano-cli query utxo --address $(cat $CARDANO_WALLET_PATH/payment.addr) --testnet-magic $CARDANO_TESTNET_MAGIC --out-file temp.json && cat temp.json | jq '. [] | select(.inlineDatum | . != null and . != "")' +$CARDANO_CLI query utxo --address $(cat $CARDANO_WALLET_PATH/payment.addr) $CARDANO_NETWORK_MAGIC --socket-path $CARDANO_NODE_SOCKET_PATH --out-file temp.json && cat temp.json | jq '. [] | select(.inlineDatum | . != null and . != "")' { "address": "addr_test1qzzngukkj9ydjemqjlgfn42sevy2xnvauay46weushlpuq9thd4ray00csjssf4sxftv04xeequ3xfx72nujg9y4d5ysgkxxlh", "datum": null, @@ -141,12 +221,14 @@ $ cardano-cli query utxo --address $(cat $CARDANO_WALLET_PATH/payment.addr) --te ## Update Era Markers: Write a new version of datum on chain -:warning: This step must be used anytime the era markers must be updated on chain +> [!IMPORTANT] +> :fire: This step must be used anytime the era markers must be updated on chain for an address when prior datum has already been written in a UTxO. +> Otherwise, you need to refer to this [section](#bootstrap-era-markers-write-a-transaction-with-the-first-version-of-datum-on-chain) Retrieve the utxo of the payment address: ```bash -$ cardano-cli query utxo --address $(cat $CARDANO_WALLET_PATH/payment.addr) --testnet-magic $CARDANO_TESTNET_MAGIC +$CARDANO_CLI query utxo --address $(cat $CARDANO_WALLET_PATH/payment.addr) $CARDANO_NETWORK_MAGIC --socket-path $CARDANO_NODE_SOCKET_PATH TxHash TxIx Amount -------------------------------------------------------------------------------------- 6518b3cea0b49b55746ec61148e7c60ab042959d534f6bb6e8f6a844d4af69fb 0 1500000 lovelace + TxOutDatumInline ReferenceTxInsScriptsInlineDatumsInBabbageEra (ScriptDataConstructor 0 [ScriptDataBytes "[{\"n\":\"thales\",\"e\":1}]",ScriptDataBytes "\165\143\232\227\&6\244e\222\211\187\167\197\167\175\229\181\162o/\182[|Nnt.h\ACKE\241=\242\139\242\182:a\204r\217\200&\190I\SO,\US\DLE\152\217U\223P5\128\164\232\153\181\ETB8\132\227\SO"]) @@ -156,66 +238,60 @@ $ cardano-cli query utxo --address $(cat $CARDANO_WALLET_PATH/payment.addr) --te And create the variable `TX_IN_DATUM={TxHash}#{TxIn}` by replacing with values from the previous command (where inline datumn are available): ```bash -$ TX_IN_DATUM=6518b3cea0b49b55746ec61148e7c60ab042959d534f6bb6e8f6a844d4af69fb#0 +TX_IN_DATUM=6518b3cea0b49b55746ec61148e7c60ab042959d534f6bb6e8f6a844d4af69fb#0 ``` And create the variable `TX_IN_NO_DATUM={TxHash}#{TxIn}` by replacing with values from the previous command (where inline datumn are not available): ```bash -$ TX_IN_NO_DATUM=6518b3cea0b49b55746ec61148e7c60ab042959d534f6bb6e8f6a844d4af69fb#1 -``` - -Create the updated datum file: - -:warning: The options provided in the following command are for example only, you need to use adequately the options of the `era generate-tx-datum` command, which will depend on the operation you want to execute: announce an upcoming era or activate an upcoming era. This operation should be done very cautiously as a misconfiguration can lead to disturbed service of the network. - -```bash -$ ./mithril-aggregator era generate-tx-datum --current-era-epoch 1 --era-markers-secret-key $ERA_ACTIVATION_SECRET_KEY --target-path $ASSETS_PATH/mithril-era-datum-2.json +TX_IN_NO_DATUM=6518b3cea0b49b55746ec61148e7c60ab042959d534f6bb6e8f6a844d4af69fb#1 ``` Now create the update transaction with datum: ```bash -$ cardano-cli $CARDANO_ERA transaction build --testnet-magic $CARDANO_TESTNET_MAGIC \ +$CARDANO_CLI $CARDANO_ERA transaction build $CARDANO_NETWORK_MAGIC \ --tx-in $TX_IN_DATUM \ --tx-in $TX_IN_NO_DATUM \ --tx-out $(cat $CARDANO_WALLET_PATH/payment.addr)+$SCRIPT_TX_VALUE \ - --tx-out-inline-datum-file $ASSETS_PATH/mithril-era-datum-2.json \ + --tx-out-inline-datum-file $ASSETS_PATH/mithril-era-datum.json \ --change-address $(cat $CARDANO_WALLET_PATH/payment.addr) \ - --out-file $ASSETS_PATH/tx.raw + --out-file $ASSETS_PATH/tx.raw \ + --socket-path $CARDANO_NODE_SOCKET_PATH Estimated transaction fee: Lovelace 179889 ``` Then sign the transaction: ```bash -$ cardano-cli $CARDANO_ERA transaction sign \ +$CARDANO_CLI $CARDANO_ERA transaction sign \ --tx-body-file $ASSETS_PATH/tx.raw \ --signing-key-file $CARDANO_WALLET_PATH/payment.skey \ - --testnet-magic $CARDANO_TESTNET_MAGIC \ + $CARDANO_NETWORK_MAGIC \ --out-file $ASSETS_PATH/tx.signed ``` And submit it: ```bash -$ cardano-cli $CARDANO_ERA transaction submit \ - --testnet-magic $CARDANO_TESTNET_MAGIC \ - --tx-file $ASSETS_PATH/tx.signed +$CARDANO_CLI $CARDANO_ERA transaction submit \ + $CARDANO_NETWORK_MAGIC \ + --tx-file $ASSETS_PATH/tx.signed \ + --socket-path $CARDANO_NODE_SOCKET_PATH Transaction successfully submitted. ``` Also get the transaction id: ```bash -$ cardano-cli transaction txid --tx-file $ASSETS_PATH/tx.signed +$CARDANO_CLI transaction txid --tx-file $ASSETS_PATH/tx.signed 1fd4d3e131afe3c8b212772a3f3083d2fbc6b2a7b20e54e4ff08e001598818d8 ``` We need to wait a few seconds before the transaction is available and we can see the updated datum for the script address: ```bash -$ cardano-cli query utxo --address $(cat $CARDANO_WALLET_PATH/payment.addr) --testnet-magic $CARDANO_TESTNET_MAGIC +$CARDANO_CLI query utxo --address $(cat $CARDANO_WALLET_PATH/payment.addr) $CARDANO_NETWORK_MAGIC --socket-path $CARDANO_NODE_SOCKET_PATH TxHash TxIx Amount -------------------------------------------------------------------------------------- 1f139b47017c9c90d4622ac768e249d25d37ad4461db44a20486b7da72a78915 0 2000000 lovelace + TxOutDatumInline ReferenceTxInsScriptsInlineDatumsInBabbageEra (ScriptDataConstructor 0 [ScriptDataBytes "[{\"n\":\"thales\",\"e\":1},{\"n\":\"pythagoras\",\"e\":null}]",ScriptDataBytes "^P\EOT\248k3\196/\139\tU\173H\138\FS\194MD\240\153\227\142z\181\134\213\168\&2\222\219i1\246\NAK\\]\247\154U\143-^vmtq\204\207#\236\213\f\201\&1\152\145(\161\ETX;\183\128\195\r"]) @@ -227,7 +303,7 @@ We can retrieve the updated value stored in the datum with the cardano cli: The full utxo json representation: ```bash -$ cardano-cli query utxo --address $(cat $CARDANO_WALLET_PATH/payment.addr) --testnet-magic $CARDANO_TESTNET_MAGIC --out-file temp.json && cat temp.json | jq '. [] | select(.inlineDatum | . != null and . != "")' +$CARDANO_CLI query utxo --address $(cat $CARDANO_WALLET_PATH/payment.addr) $CARDANO_NETWORK_MAGIC --socket-path $CARDANO_NODE_SOCKET_PATH --out-file temp.json && cat temp.json | jq '. [] | select(.inlineDatum | . != null and . != "")' { "address": "addr_test1qzzngukkj9ydjemqjlgfn42sevy2xnvauay46weushlpuq9thd4ray00csjssf4sxftv04xeequ3xfx72nujg9y4d5ysgkxxlh", "datum": null,