diff --git a/configuration/cardano/alonzo/shelley_qa_cost-model.json b/configuration/cardano/alonzo/shelley_qa_cost-model.json deleted file mode 100644 index 6a279c81d2c..00000000000 --- a/configuration/cardano/alonzo/shelley_qa_cost-model.json +++ /dev/null @@ -1,306 +0,0 @@ -{ - "less_than_integer": { - "memory": { - "arguments": 1, - "type": "constant_cost" - }, - "cpu": { - "arguments": { - "slope": 4.3328524294545e-4, - "intercept": 2.10575839518836 - }, - "type": "min_size" - } - }, - "verify_signature": { - "memory": { - "arguments": 1, - "type": "constant_cost" - }, - "cpu": { - "arguments": 2.71491123389651, - "type": "constant_cost" - } - }, - "take_byte_string": { - "memory": { - "arguments": 2, - "type": "constant_cost" - }, - "cpu": { - "arguments": 2.0365567048005, - "type": "constant_cost" - } - }, - "less_than_eq_integer": { - "memory": { - "arguments": 1, - "type": "constant_cost" - }, - "cpu": { - "arguments": { - "slope": 3.37112224357207e-4, - "intercept": 2.09702447231695 - }, - "type": "min_size" - } - }, - "lt_byte_string": { - "memory": { - "arguments": 1, - "type": "constant_cost" - }, - "cpu": { - "arguments": { - "slope": 2.46159434917543e-4, - "intercept": 2.07414622772793 - }, - "type": "min_size" - } - }, - "if_then_else": { - "memory": { - "arguments": 1, - "type": "constant_cost" - }, - "cpu": { - "arguments": 1, - "type": "constant_cost" - } - }, - "greater_than_integer": { - "memory": { - "arguments": 1, - "type": "constant_cost" - }, - "cpu": { - "arguments": { - "slope": 4.3328524294545e-4, - "intercept": 2.10575839518836 - }, - "type": "min_size" - } - }, - "multiply_integer": { - "memory": { - "arguments": { - "slope": 1, - "intercept": 0 - }, - "type": "added_sizes" - }, - "cpu": { - "arguments": { - "slope": 1.17628612553361e-2, - "intercept": 1.9243156681313 - }, - "type": "added_sizes" - } - }, - "eq_integer": { - "memory": { - "arguments": 1, - "type": "constant_cost" - }, - "cpu": { - "arguments": { - "slope": 5.73299088778534e-4, - "intercept": 2.08823964398551 - }, - "type": "min_size" - } - }, - "quotient_integer": { - "memory": { - "arguments": { - "slope": 1, - "intercept": 0, - "orientation": "y" - }, - "type": "linear_size" - }, - "cpu": { - "arguments": { - "model_split_const_intercept": 2.19257116593296, - "model_split_const_slope": 5.12624141673763e-4 - }, - "type": "split_const_multi" - } - }, - "add_integer": { - "memory": { - "arguments": { - "slope": 1, - "intercept": 1 - }, - "type": "max_size" - }, - "cpu": { - "arguments": { - "slope": 1.10910717654586e-3, - "intercept": 2.11737234677083 - }, - "type": "max_size" - } - }, - "drop_byte_string": { - "memory": { - "arguments": 2, - "type": "constant_cost" - }, - "cpu": { - "arguments": 2.0324988684539, - "type": "constant_cost" - } - }, - "greater_than_eq_integer": { - "memory": { - "arguments": 1, - "type": "constant_cost" - }, - "cpu": { - "arguments": { - "slope": 3.37112224357207e-4, - "intercept": 2.09702447231695 - }, - "type": "min_size" - } - }, - "gt_byte_string": { - "memory": { - "arguments": 1, - "type": "constant_cost" - }, - "cpu": { - "arguments": { - "slope": 2.46159434917543e-4, - "intercept": 2.07414622772793 - }, - "type": "min_size" - } - }, - "mod_integer": { - "memory": { - "arguments": { - "minimum": 1, - "slope": 1, - "intercept": 0 - }, - "type": "subtracted_sizes" - }, - "cpu": { - "arguments": { - "model_split_const_intercept": 2.19257116593296, - "model_split_const_slope": 5.12624141673763e-4 - }, - "type": "split_const_multi" - } - }, - "concatenate": { - "memory": { - "arguments": { - "slope": 1, - "intercept": 0 - }, - "type": "added_sizes" - }, - "cpu": { - "arguments": { - "slope": 4.99167767731152e-4, - "intercept": 2.67153236270497 - }, - "type": "added_sizes" - } - }, - "divide_integer": { - "memory": { - "arguments": { - "minimum": 1, - "slope": 1, - "intercept": 0 - }, - "type": "subtracted_sizes" - }, - "cpu": { - "arguments": { - "model_split_const_intercept": 2.19257116593296, - "model_split_const_slope": 5.12624141673763e-4 - }, - "type": "split_const_multi" - } - }, - "subtract_integer": { - "memory": { - "arguments": { - "slope": 1, - "intercept": 1 - }, - "type": "max_size" - }, - "cpu": { - "arguments": { - "slope": 1.24644768853139e-3, - "intercept": 2.11084612123977 - }, - "type": "max_size" - } - }, - "sha2": { - "memory": { - "arguments": 4, - "type": "constant_cost" - }, - "cpu": { - "arguments": { - "slope": 2.96456821195969e-2, - "intercept": 3.86834707882836, - "orientation": "x" - }, - "type": "linear_cost" - } - }, - "eq_byte_string": { - "memory": { - "arguments": 1, - "type": "constant_cost" - }, - "cpu": { - "arguments": { - "slope": 2.4746426691108e-4, - "intercept": 2.09360627536428 - }, - "type": "min_size" - } - }, - "remainder_integer": { - "memory": { - "arguments": { - "slope": 1, - "intercept": 0, - "orientation": "y" - }, - "type": "linear_size" - }, - "cpu": { - "arguments": { - "model_split_const_intercept": 2.19257116593296, - "model_split_const_slope": 5.12624141673763e-4 - }, - "type": "split_const_multi" - } - }, - "sha3": { - "memory": { - "arguments": 4, - "type": "constant_cost" - }, - "cpu": { - "arguments": { - "slope": 8.19185039380989e-2, - "intercept": 1.18696087943684, - "orientation": "x" - }, - "type": "linear_cost" - } - } -} \ No newline at end of file diff --git a/configuration/cardano/mainnet-topology.json b/configuration/cardano/mainnet-topology.json index 267c34a44b1..0433be94d68 100644 --- a/configuration/cardano/mainnet-topology.json +++ b/configuration/cardano/mainnet-topology.json @@ -27,5 +27,5 @@ "advertise": false } ], - "useLedgerAfterSlot": 128908821 + "useLedgerAfterSlot": 148350000 } diff --git a/configuration/cardano/shelley_qa-alonzo-genesis.json b/configuration/cardano/shelley_qa-alonzo-genesis.json deleted file mode 100644 index de05d3d9e46..00000000000 --- a/configuration/cardano/shelley_qa-alonzo-genesis.json +++ /dev/null @@ -1,188 +0,0 @@ -{ - "collateralPercentage": 150, - "costModels": { - "PlutusV1": [ - 197209, - 0, - 1, - 1, - 396231, - 621, - 0, - 1, - 150000, - 1000, - 0, - 1, - 150000, - 32, - 2477736, - 29175, - 4, - 29773, - 100, - 29773, - 100, - 29773, - 100, - 29773, - 100, - 29773, - 100, - 29773, - 100, - 100, - 100, - 29773, - 100, - 150000, - 32, - 150000, - 32, - 150000, - 32, - 150000, - 1000, - 0, - 1, - 150000, - 32, - 150000, - 1000, - 0, - 8, - 148000, - 425507, - 118, - 0, - 1, - 1, - 150000, - 1000, - 0, - 8, - 150000, - 112536, - 247, - 1, - 150000, - 10000, - 1, - 136542, - 1326, - 1, - 1000, - 150000, - 1000, - 1, - 150000, - 32, - 150000, - 32, - 150000, - 32, - 1, - 1, - 150000, - 1, - 150000, - 4, - 103599, - 248, - 1, - 103599, - 248, - 1, - 145276, - 1366, - 1, - 179690, - 497, - 1, - 150000, - 32, - 150000, - 32, - 150000, - 32, - 150000, - 32, - 150000, - 32, - 150000, - 32, - 148000, - 425507, - 118, - 0, - 1, - 1, - 61516, - 11218, - 0, - 1, - 150000, - 32, - 148000, - 425507, - 118, - 0, - 1, - 1, - 148000, - 425507, - 118, - 0, - 1, - 1, - 2477736, - 29175, - 4, - 0, - 82363, - 4, - 150000, - 5000, - 0, - 1, - 150000, - 32, - 197209, - 0, - 1, - 1, - 150000, - 32, - 150000, - 32, - 150000, - 32, - 150000, - 32, - 150000, - 32, - 150000, - 32, - 150000, - 32, - 3345831, - 1, - 1 - ] - }, - "executionPrices": { - "prMem": 5.77e-2, - "prSteps": 7.21e-5 - }, - "lovelacePerUTxOWord": 34482, - "maxBlockExUnits": { - "exUnitsMem": 50000000, - "exUnitsSteps": 40000000000 - }, - "maxCollateralInputs": 3, - "maxTxExUnits": { - "exUnitsMem": 10000000, - "exUnitsSteps": 10000000000 - }, - "maxValueSize": 5000 -} \ No newline at end of file diff --git a/configuration/cardano/shelley_qa-byron-genesis.json b/configuration/cardano/shelley_qa-byron-genesis.json deleted file mode 100644 index 869d3c89467..00000000000 --- a/configuration/cardano/shelley_qa-byron-genesis.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "avvmDistr": {}, - "blockVersionData": { - "heavyDelThd": "300000000000", - "maxBlockSize": "2000000", - "maxHeaderSize": "2000000", - "maxProposalSize": "700", - "maxTxSize": "4096", - "mpcThd": "20000000000000", - "scriptVersion": 0, - "slotDuration": "20000", - "softforkRule": { - "initThd": "900000000000000", - "minThd": "600000000000000", - "thdDecrement": "50000000000000" - }, - "txFeePolicy": { - "multiplier": "43946000000", - "summand": "155381000000000" - }, - "unlockStakeEpoch": "18446744073709551615", - "updateImplicit": "10000", - "updateProposalThd": "100000000000000", - "updateVoteThd": "1000000000000" - }, - "bootStakeholders": { - "50edbd4a0f6f58387fcb1643457ec100b22b312a74a995a67c52003b": 1, - "79ee950420bb30d0460f4c468b6a638267b40ecbd17cdd4b009d0de5": 1, - "f9519425faad1097d31f34bd16f8e9bf22308d66da0556df22174625": 1 - }, - "heavyDelegation": { - "50edbd4a0f6f58387fcb1643457ec100b22b312a74a995a67c52003b": { - "cert": "3f117cc145405bf95919af619efd92cfb360435911c66421e48e1a0f1ac0accd87c25e9cd31579dadab44051a6d504e3c4bd91be2e8fdf468d946d81cd154809", - "delegatePk": "n3ZSsfCwTs5u1wf2dc6FbgijVbNsMeYhDsL56Q9ixm/mmlAM6baH/xTZKQ56cOS2AXF4Hu4pv0lWP0ojk8E5+w==", - "issuerPk": "Vtg7ptYWEoY8+2HmqA7QhB3UfmfeGWZHAy9LThmNMyzVS76vQw1jz7vNaDJX10OmDMFkiL3UweyddKQZZ+j6gg==", - "omega": 0 - }, - "79ee950420bb30d0460f4c468b6a638267b40ecbd17cdd4b009d0de5": { - "cert": "b8d74865d1837857803c9b618be8253897bc10e50b45b3993c0f5c13c0b1173835bf3e96fbf04cccbc94a12c5786023ede287ba825f9c193d84a8151f0911f09", - "delegatePk": "g+h1Ncr8O11CqVYNEuRcHk+ExC7DFJmwYwR8MdVFZP3aLFCLzuR/Q5WdueQaHhlQnLFH11uxrWlUfFf+2zLKGg==", - "issuerPk": "j/a0OEzGIazhtHfxrjLsCqeiX22SPoXunjyxPVXQod9hxJJ4Z+st9nzwnIaNlHZKIDj/h5KfgS8vG6il9EEdqg==", - "omega": 0 - }, - "f9519425faad1097d31f34bd16f8e9bf22308d66da0556df22174625": { - "cert": "3202b810145c291035318729207ef279ce520bbb5190bf406757a215613cad780f6534fa2ff2e48269915ee39397912579a026ff8741319c1bd70696834b9505", - "delegatePk": "Av1BL28n7Cw7VjC5YfYICAAfpDLownzsV2eKurrYh3XgB51yqqzfNr1rxkH6gcn6b3t0NcU1KvyCZFPN1Arvtg==", - "issuerPk": "ri35xUj10Jn+ZwwEa1vx9f9L+7i6leIno4dxssO1ECovrRtEynU//8eFRoPlz1wR4ZCMSfBiskQDtZqUpTaZ6w==", - "omega": 0 - } - }, - "nonAvvmBalances": { - "FHnt4NL7yPXvkoejcLdesSW6e7XQUC5yyVnfW8FYW4QTH2VHtmU3FRMHonLHmPj": "0", - "FHnt4NL7yPY3yKGAzSFJJCxJBbZaRQmDb34LRDvLkjRSeRsBnF6BLNfGd1evRCB": "0", - "FHnt4NL7yPYA4GPM9yrmzdtMdrmqyAgqhKT9GWzpMEeeAXM4F6uikvsY8dzHp8o": "30000000000000000", - "FHnt4NL7yPYCoPxaPPLdxR7ybBnuEASwZjqjj8qpkDZUDSCMXi3265EygJeT5VC": "0" - }, - "protocolConsts": { - "k": 36, - "protocolMagic": 3 - }, - "startTime": 1689206400 -} diff --git a/configuration/cardano/shelley_qa-shelley-genesis.json b/configuration/cardano/shelley_qa-shelley-genesis.json deleted file mode 100644 index e6aa88db9bc..00000000000 --- a/configuration/cardano/shelley_qa-shelley-genesis.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "activeSlotsCoeff": 5.0e-2, - "epochLength": 7200, - "genDelegs": { - "3ed8dd8d9637c5fb64ef950add70d5482c19c52cac82bdd17a7ae42e": { - "delegate": "451bbcfe22dc9c5b8cc4ad21c7b2815e021a2df52a1e43e7d77a9420", - "vrf": "7db2d5fdd3ccdae264bb087bbd8f5bb3393e9fe9c3d61070072ca873bf6c9f86" - }, - "4db37fb1de328572e88c4be152afd49ad68d192725391a56c19f37a9": { - "delegate": "2452a6adf035ca226e332aedc3af7a9cddec3b121223a9b7c26c471c", - "vrf": "cd974709ece7fc6ef0a939f0c21a5c4ab49a82c74b8c0af301edabeea453d703" - }, - "7d5a43fd31277b955c75d381383c49fca5629649305175578341b4d6": { - "delegate": "eac211a2828841be37031438fe2444a95374a1a6f3f59f040336e0f9", - "vrf": "11c1c8427e2af2c71f8e43207a57a8890b4a2ad67b64d771ca251e499e5e36bc" - } - }, - "initialFunds": {}, - "maxKESEvolutions": 62, - "maxLovelaceSupply": 45000000000000000, - "networkId": "Testnet", - "networkMagic": 3, - "protocolParams": { - "a0": 0.3, - "decentralisationParam": 1.0, - "eMax": 18, - "extraEntropy": { - "tag": "NeutralNonce" - }, - "keyDeposit": 2000000, - "maxBlockBodySize": 65536, - "maxBlockHeaderSize": 1100, - "maxTxSize": 16384, - "minFeeA": 44, - "minFeeB": 155381, - "minPoolCost": 340000000, - "minUTxOValue": 1000000, - "nOpt": 150, - "poolDeposit": 500000000, - "protocolVersion": { - "major": 6, - "minor": 0 - }, - "rho": 3.0e-3, - "tau": 0.2 - }, - "securityParam": 36, - "slotLength": 1, - "slotsPerKESPeriod": 129600, - "staking": { - "pools": {}, - "stake": {} - }, - "systemStart": "2023-07-13T00:00:00Z", - "updateQuorum": 3 -} \ No newline at end of file diff --git a/configuration/cardano/testnet-template-alonzo.json b/configuration/cardano/testnet-template-alonzo.json new file mode 100644 index 00000000000..01231284a21 --- /dev/null +++ b/configuration/cardano/testnet-template-alonzo.json @@ -0,0 +1,194 @@ +{ + "lovelacePerUTxOWord": 34482, + "executionPrices": { + "prSteps": { + "numerator": 721, + "denominator": 10000000 + }, + "prMem": { + "numerator": 577, + "denominator": 10000 + } + }, + "maxTxExUnits": { + "exUnitsMem": 10000000, + "exUnitsSteps": 10000000000 + }, + "maxBlockExUnits": { + "exUnitsMem": 50000000, + "exUnitsSteps": 40000000000 + }, + "maxValueSize": 5000, + "collateralPercentage": 150, + "maxCollateralInputs": 3, + "costModels": { + "PlutusV1": { + "sha2_256-memory-arguments": 4, + "equalsString-cpu-arguments-constant": 1000, + "cekDelayCost-exBudgetMemory": 100, + "lessThanEqualsByteString-cpu-arguments-intercept": 103599, + "divideInteger-memory-arguments-minimum": 1, + "appendByteString-cpu-arguments-slope": 621, + "blake2b-cpu-arguments-slope": 29175, + "iData-cpu-arguments": 150000, + "encodeUtf8-cpu-arguments-slope": 1000, + "unBData-cpu-arguments": 150000, + "multiplyInteger-cpu-arguments-intercept": 61516, + "cekConstCost-exBudgetMemory": 100, + "nullList-cpu-arguments": 150000, + "equalsString-cpu-arguments-intercept": 150000, + "trace-cpu-arguments": 150000, + "mkNilData-memory-arguments": 32, + "lengthOfByteString-cpu-arguments": 150000, + "cekBuiltinCost-exBudgetCPU": 29773, + "bData-cpu-arguments": 150000, + "subtractInteger-cpu-arguments-slope": 0, + "unIData-cpu-arguments": 150000, + "consByteString-memory-arguments-intercept": 0, + "divideInteger-memory-arguments-slope": 1, + "divideInteger-cpu-arguments-model-arguments-slope": 118, + "listData-cpu-arguments": 150000, + "headList-cpu-arguments": 150000, + "chooseData-memory-arguments": 32, + "equalsInteger-cpu-arguments-intercept": 136542, + "sha3_256-cpu-arguments-slope": 82363, + "sliceByteString-cpu-arguments-slope": 5000, + "unMapData-cpu-arguments": 150000, + "lessThanInteger-cpu-arguments-intercept": 179690, + "mkCons-cpu-arguments": 150000, + "appendString-memory-arguments-intercept": 0, + "modInteger-cpu-arguments-model-arguments-slope": 118, + "ifThenElse-cpu-arguments": 1, + "mkNilPairData-cpu-arguments": 150000, + "lessThanEqualsInteger-cpu-arguments-intercept": 145276, + "addInteger-memory-arguments-slope": 1, + "chooseList-memory-arguments": 32, + "constrData-memory-arguments": 32, + "decodeUtf8-cpu-arguments-intercept": 150000, + "equalsData-memory-arguments": 1, + "subtractInteger-memory-arguments-slope": 1, + "appendByteString-memory-arguments-intercept": 0, + "lengthOfByteString-memory-arguments": 4, + "headList-memory-arguments": 32, + "listData-memory-arguments": 32, + "consByteString-cpu-arguments-intercept": 150000, + "unIData-memory-arguments": 32, + "remainderInteger-memory-arguments-minimum": 1, + "bData-memory-arguments": 32, + "lessThanByteString-cpu-arguments-slope": 248, + "encodeUtf8-memory-arguments-intercept": 0, + "cekStartupCost-exBudgetCPU": 100, + "multiplyInteger-memory-arguments-intercept": 0, + "unListData-memory-arguments": 32, + "remainderInteger-cpu-arguments-model-arguments-slope": 118, + "cekVarCost-exBudgetCPU": 29773, + "remainderInteger-memory-arguments-slope": 1, + "cekForceCost-exBudgetCPU": 29773, + "sha2_256-cpu-arguments-slope": 29175, + "equalsInteger-memory-arguments": 1, + "indexByteString-memory-arguments": 1, + "addInteger-memory-arguments-intercept": 1, + "chooseUnit-cpu-arguments": 150000, + "sndPair-cpu-arguments": 150000, + "cekLamCost-exBudgetCPU": 29773, + "fstPair-cpu-arguments": 150000, + "quotientInteger-memory-arguments-minimum": 1, + "decodeUtf8-cpu-arguments-slope": 1000, + "lessThanInteger-memory-arguments": 1, + "lessThanEqualsInteger-cpu-arguments-slope": 1366, + "fstPair-memory-arguments": 32, + "modInteger-memory-arguments-intercept": 0, + "unConstrData-cpu-arguments": 150000, + "lessThanEqualsInteger-memory-arguments": 1, + "chooseUnit-memory-arguments": 32, + "sndPair-memory-arguments": 32, + "addInteger-cpu-arguments-intercept": 197209, + "decodeUtf8-memory-arguments-slope": 8, + "equalsData-cpu-arguments-intercept": 150000, + "mapData-cpu-arguments": 150000, + "mkPairData-cpu-arguments": 150000, + "quotientInteger-cpu-arguments-constant": 148000, + "consByteString-memory-arguments-slope": 1, + "cekVarCost-exBudgetMemory": 100, + "indexByteString-cpu-arguments": 150000, + "unListData-cpu-arguments": 150000, + "equalsInteger-cpu-arguments-slope": 1326, + "cekStartupCost-exBudgetMemory": 100, + "subtractInteger-cpu-arguments-intercept": 197209, + "divideInteger-cpu-arguments-model-arguments-intercept": 425507, + "divideInteger-memory-arguments-intercept": 0, + "cekForceCost-exBudgetMemory": 100, + "blake2b-cpu-arguments-intercept": 2477736, + "remainderInteger-cpu-arguments-constant": 148000, + "tailList-cpu-arguments": 150000, + "encodeUtf8-cpu-arguments-intercept": 150000, + "equalsString-cpu-arguments-slope": 1000, + "lessThanByteString-memory-arguments": 1, + "multiplyInteger-cpu-arguments-slope": 11218, + "appendByteString-cpu-arguments-intercept": 396231, + "lessThanEqualsByteString-cpu-arguments-slope": 248, + "modInteger-memory-arguments-slope": 1, + "addInteger-cpu-arguments-slope": 0, + "equalsData-cpu-arguments-slope": 10000, + "decodeUtf8-memory-arguments-intercept": 0, + "chooseList-cpu-arguments": 150000, + "constrData-cpu-arguments": 150000, + "equalsByteString-memory-arguments": 1, + "cekApplyCost-exBudgetCPU": 29773, + "quotientInteger-memory-arguments-slope": 1, + "verifySignature-cpu-arguments-intercept": 3345831, + "unMapData-memory-arguments": 32, + "mkCons-memory-arguments": 32, + "sliceByteString-memory-arguments-slope": 1, + "sha3_256-memory-arguments": 4, + "ifThenElse-memory-arguments": 1, + "mkNilPairData-memory-arguments": 32, + "equalsByteString-cpu-arguments-slope": 247, + "appendString-cpu-arguments-intercept": 150000, + "quotientInteger-cpu-arguments-model-arguments-slope": 118, + "cekApplyCost-exBudgetMemory": 100, + "equalsString-memory-arguments": 1, + "multiplyInteger-memory-arguments-slope": 1, + "cekBuiltinCost-exBudgetMemory": 100, + "remainderInteger-memory-arguments-intercept": 0, + "sha2_256-cpu-arguments-intercept": 2477736, + "remainderInteger-cpu-arguments-model-arguments-intercept": 425507, + "lessThanEqualsByteString-memory-arguments": 1, + "tailList-memory-arguments": 32, + "mkNilData-cpu-arguments": 150000, + "chooseData-cpu-arguments": 150000, + "unBData-memory-arguments": 32, + "blake2b-memory-arguments": 4, + "iData-memory-arguments": 32, + "nullList-memory-arguments": 32, + "cekDelayCost-exBudgetCPU": 29773, + "subtractInteger-memory-arguments-intercept": 1, + "lessThanByteString-cpu-arguments-intercept": 103599, + "consByteString-cpu-arguments-slope": 1000, + "appendByteString-memory-arguments-slope": 1, + "trace-memory-arguments": 32, + "divideInteger-cpu-arguments-constant": 148000, + "cekConstCost-exBudgetCPU": 29773, + "encodeUtf8-memory-arguments-slope": 8, + "quotientInteger-cpu-arguments-model-arguments-intercept": 425507, + "mapData-memory-arguments": 32, + "appendString-cpu-arguments-slope": 1000, + "modInteger-cpu-arguments-constant": 148000, + "verifySignature-cpu-arguments-slope": 1, + "unConstrData-memory-arguments": 32, + "quotientInteger-memory-arguments-intercept": 0, + "equalsByteString-cpu-arguments-constant": 150000, + "sliceByteString-memory-arguments-intercept": 0, + "mkPairData-memory-arguments": 32, + "equalsByteString-cpu-arguments-intercept": 112536, + "appendString-memory-arguments-slope": 1, + "lessThanInteger-cpu-arguments-slope": 497, + "modInteger-cpu-arguments-model-arguments-intercept": 425507, + "modInteger-memory-arguments-minimum": 1, + "sha3_256-cpu-arguments-intercept": 0, + "verifySignature-memory-arguments": 1, + "cekLamCost-exBudgetMemory": 100, + "sliceByteString-cpu-arguments-intercept": 150000 + } + } +} diff --git a/configuration/cardano/testnet-template-byron.json b/configuration/cardano/testnet-template-byron.json new file mode 100644 index 00000000000..039c966335f --- /dev/null +++ b/configuration/cardano/testnet-template-byron.json @@ -0,0 +1,23 @@ +{ + "heavyDelThd": "300000000000", + "maxBlockSize": "2000000", + "maxTxSize": "4096", + "maxHeaderSize": "2000000", + "maxProposalSize": "700", + "mpcThd": "20000000000000", + "scriptVersion": 0, + "slotDuration": "200", + "softforkRule": { + "initThd": "900000000000000", + "minThd": "600000000000000", + "thdDecrement": "50000000000000" + }, + "txFeePolicy": { + "multiplier": "43946000000", + "summand": "155381000000000" + }, + "unlockStakeEpoch": "18446744073709551615", + "updateImplicit": "10000", + "updateProposalThd": "100000000000000", + "updateVoteThd": "1000000000000" +} diff --git a/configuration/cardano/shelley_qa-config.json b/configuration/cardano/testnet-template-config.json similarity index 61% rename from configuration/cardano/shelley_qa-config.json rename to configuration/cardano/testnet-template-config.json index 046b2e3d39c..f168da12138 100644 --- a/configuration/cardano/shelley_qa-config.json +++ b/configuration/cardano/testnet-template-config.json @@ -1,31 +1,29 @@ { - "AlonzoGenesisFile": "shelley_qa-alonzo-genesis.json", - "AlonzoGenesisHash": "8bedcaea62107d8a79ed5293b0027b3f8706a4bc2422f33380cb1fd01c6fa6ec", - "ByronGenesisFile": "shelley_qa-byron-genesis.json", - "ByronGenesisHash": "273cd12237b98d02f108c9c50063d29a8d1d7f32e9a75ade7cd48e08b3070258", - "ConwayGenesisFile": "shelley_qa-conway-genesis.json", - "ConwayGenesisHash": "91bedad42212c07f6abdafedb7e7c8577fbd07152c695ffae1ab2a528741c6e4", - "EnableP2P": true, - "ExperimentalHardForksEnabled": true, - "ExperimentalProtocolsEnabled": true, + "ByronGenesisFile": "byron-genesis.json", + "ShelleyGenesisFile": "shelley-genesis.json", + "AlonzoGenesisFile": "alonzo-genesis.json", + "ConwayGenesisFile": "conway-genesis.json", + "ApplicationName": "cardano-sl", + "ApplicationVersion": 0, "LastKnownBlockVersion-Alt": 0, "LastKnownBlockVersion-Major": 3, "LastKnownBlockVersion-Minor": 1, - "MinNodeVersion": "10.1.4", - "PeerSharing": true, + "MaxConcurrencyDeadline": 4, + "MaxKnownMajorProtocolVersion": 2, + "PBftSignatureThreshold": 1.1, "Protocol": "Cardano", "RequiresNetworkMagic": "RequiresMagic", - "ShelleyGenesisFile": "shelley_qa-shelley-genesis.json", - "ShelleyGenesisHash": "73a9f6bdb0aa97f5e63190a6f14a702bd64a21f2bec831cbfc28f6037128b952", - "ConsensusMode": "PraosMode" - "TargetNumberOfActivePeers": 20, - "TargetNumberOfEstablishedPeers": 40, - "TargetNumberOfKnownPeers": 150, - "TargetNumberOfRootPeers": 60, + "TestShelleyHardForkAtEpoch": 0, "TestAllegraHardForkAtEpoch": 0, - "TestAlonzoHardForkAtEpoch": 0, "TestMaryHardForkAtEpoch": 0, - "TestShelleyHardForkAtEpoch": 0, + "TestAlonzoHardForkAtEpoch": 0, + "EnableP2P": true, + "ExperimentalProtocolsEnabled": true, + "ExperimentalHardForksEnabled": true, + "TargetNumberOfActivePeers": 20, + "TargetNumberOfEstablishedPeers": 40, + "TargetNumberOfKnownPeers": 100, + "TargetNumberOfRootPeers": 100, "TraceAcceptPolicy": true, "TraceBlockFetchClient": false, "TraceBlockFetchDecisions": false, @@ -43,18 +41,17 @@ "TraceDiffusionInitialization": true, "TraceErrorPolicy": true, "TraceForge": true, - "TraceHandshake": true, + "TraceHandshake": false, "TraceInboundGovernor": true, "TraceIpSubscription": true, "TraceLedgerPeers": true, "TraceLocalChainSyncProtocol": false, - "TraceLocalConnectionManager": true, "TraceLocalErrorPolicy": true, - "TraceLocalHandshake": true, + "TraceLocalHandshake": false, "TraceLocalRootPeers": true, "TraceLocalTxSubmissionProtocol": false, "TraceLocalTxSubmissionServer": false, - "TraceMempool": true, + "TraceMempool": false, "TraceMux": false, "TracePeerSelection": true, "TracePeerSelectionActions": true, @@ -66,30 +63,15 @@ "TracingVerbosity": "NormalVerbosity", "TurnOnLogMetrics": true, "TurnOnLogging": true, - "UseTraceDispatcher": false, - "defaultBackends": [ - "KatipBK" - ], - "defaultScribes": [ - [ - "StdoutSK", - "stdout" - ] - ], + "defaultBackends": ["KatipBK"], + "defaultScribes": [["StdoutSK", "cardano"]], "hasEKG": 12788, - "hasPrometheus": [ - "127.0.0.1", - 12798 - ], + "hasPrometheus": ["0.0.0.0", 12798], "minSeverity": "Debug", "options": { "mapBackends": { - "cardano.node.metrics": [ - "EKGViewBK" - ], - "cardano.node.resources": [ - "EKGViewBK" - ] + "cardano.node.metrics": ["EKGViewBK"], + "cardano.node.resources": ["EKGViewBK"] }, "mapSubtrace": { "cardano.node.metrics": { @@ -102,15 +84,12 @@ "rpLogLimitBytes": 5000000, "rpMaxAgeHours": 24 }, - "setupBackends": [ - "KatipBK" - ], + "setupBackends": ["KatipBK"], "setupScribes": [ { "scFormat": "ScText", "scKind": "StdoutSK", - "scName": "stdout", - "scRotation": null + "scName": "cardano" } ] } diff --git a/configuration/cardano/shelley_qa-conway-genesis.json b/configuration/cardano/testnet-template-conway.json similarity index 100% rename from configuration/cardano/shelley_qa-conway-genesis.json rename to configuration/cardano/testnet-template-conway.json diff --git a/configuration/cardano/testnet-template-shelley.json b/configuration/cardano/testnet-template-shelley.json new file mode 100644 index 00000000000..6d866fa6307 --- /dev/null +++ b/configuration/cardano/testnet-template-shelley.json @@ -0,0 +1,39 @@ +{ + "activeSlotsCoeff": 0.05, + "protocolParams": { + "protocolVersion": { + "minor": 0, + "major": 6 + }, + "decentralisationParam": 1, + "eMax": 18, + "extraEntropy": { + "tag": "NeutralNonce" + }, + "maxTxSize": 16384, + "maxBlockBodySize": 65536, + "maxBlockHeaderSize": 1100, + "minFeeA": 44, + "minFeeB": 155381, + "minUTxOValue": 1000000, + "poolDeposit": 500000000, + "minPoolCost": 340000000, + "keyDeposit": 2000000, + "nOpt": 150, + "rho": 0.003, + "tau": 0.2, + "a0": 0.3 + }, + "genDelegs": {}, + "updateQuorum": 3, + "networkId": "Testnet", + "initialFunds": {}, + "maxLovelaceSupply": 45000000000000000, + "networkMagic": 42, + "epochLength": 432000, + "systemStart": "1970-01-01T00:00:00Z", + "slotsPerKESPeriod": 129600, + "slotLength": 1, + "maxKESEvolutions": 62, + "securityParam": 108 +} diff --git a/configuration/cardano/shelley_qa-topology.json b/configuration/cardano/testnet-template-topology-empty-p2p.json similarity index 53% rename from configuration/cardano/shelley_qa-topology.json rename to configuration/cardano/testnet-template-topology-empty-p2p.json index ac45f742b2a..dd46b411d7e 100644 --- a/configuration/cardano/shelley_qa-topology.json +++ b/configuration/cardano/testnet-template-topology-empty-p2p.json @@ -1,15 +1,8 @@ { - "bootstrapPeers": [ - { - "address": "shelley-qa-node.play.dev.cardano.org", - "port": 3001 - } - ], "localRoots": [ { "accessPoints": [], "advertise": false, - "trustable": false, "valency": 1 } ], @@ -19,5 +12,5 @@ "advertise": false } ], - "useLedgerAfterSlot": 31348805 + "useLedgerAfterSlot": -1 } diff --git a/configuration/cardano/update-config-files.sh b/configuration/cardano/update-config-files.sh index a702143ed26..e2b8213a18d 100755 --- a/configuration/cardano/update-config-files.sh +++ b/configuration/cardano/update-config-files.sh @@ -1,32 +1,48 @@ #!/usr/bin/env bash +set -euo pipefail -set -e +OUT=$(dirname "$(realpath "$0")") +ROOT=$(realpath "${OUT}/../..") -OUT=$(dirname $(realpath $0)) -ROOT=$(realpath ${OUT}/../..) -nix build "${ROOT}"#hydraJobs.cardano-deployment -SRC="${ROOT}/result" +# Provide access to iohkNix environment configs +IOHK_NIX_CFGS=$(nix build --print-out-paths --no-link "${ROOT}"#hydraJobs.cardano-deployment) -copyFile() { - echo $1 - cp ${SRC}/$1 ${OUT}/$1 +# Provide access to iohkNix testnet templates +IOHK_NIX_OUT=$(nix eval --raw --impure \ + --expr "let f = builtins.getFlake \"git+file://\${toString $ROOT}\"; in f.inputs.iohkNix.outPath") + +copyCfg() { + echo "$1" + cp "${IOHK_NIX_CFGS}/$1" "${OUT}/$1" +} + +copyTmplCfg() { + echo "testnet-template-$1" + cp "${IOHK_NIX_OUT}/cardano-lib/testnet-template/$1" "${OUT}/testnet-template-$1" } -echo "#################" -echo "# Copying files #" -echo "#################" - -copyFile "mainnet-alonzo-genesis.json" -copyFile "mainnet-byron-genesis.json" -copyFile "mainnet-conway-genesis.json" -copyFile "mainnet-config.json" -copyFile "mainnet-config-new-tracing.json" -copyFile "mainnet-shelley-genesis.json" -copyFile "mainnet-topology.json" - -copyFile "shelley_qa-conway-genesis.json" -copyFile "shelley_qa-alonzo-genesis.json" -copyFile "shelley_qa-byron-genesis.json" -copyFile "shelley_qa-config.json" -copyFile "shelley_qa-shelley-genesis.json" -copyFile "shelley_qa-topology.json" +echo "################################" +echo "# Copying Network Config Files #" +echo "################################" + +# Mainnet +copyCfg "mainnet-alonzo-genesis.json" +copyCfg "mainnet-byron-genesis.json" +copyCfg "mainnet-config.json" +copyCfg "mainnet-conway-genesis.json" +copyCfg "mainnet-shelley-genesis.json" +copyCfg "mainnet-topology.json" + +# IohkNix new tracing config placeholder +# copyCfg "mainnet-config-new-tracing.json" + +# Testnet-template +copyTmplCfg "alonzo.json" +copyTmplCfg "byron.json" +copyTmplCfg "config.json" +copyTmplCfg "conway.json" +copyTmplCfg "shelley.json" +copyTmplCfg "topology-empty-p2p.json" + +# Prevent write errors on script retries due to nix store no-write default perm +chmod -R +w "${OUT}" diff --git a/flake.lock b/flake.lock index b38fd9af8d0..9f4fad19c95 100644 --- a/flake.lock +++ b/flake.lock @@ -839,15 +839,16 @@ "sodium": "sodium" }, "locked": { - "lastModified": 1738874249, - "narHash": "sha256-oyPD/zIhs5AUEdYXZHluMAOmT5ynJSgjV2bNIXt5aKE=", + "lastModified": 1740088827, + "narHash": "sha256-0sF0RUsnFVdRMoS9amtRQs6TnCFynDFdbzn8zBLD5Bg=", "owner": "input-output-hk", "repo": "iohk-nix", - "rev": "e26038d47df5d17187288fd7c8f5b915c9447b2e", + "rev": "6fa379b38ed2c6899f93fc0b97084c73e74eecf4", "type": "github" }, "original": { "owner": "input-output-hk", + "ref": "jl/env-reduce", "repo": "iohk-nix", "type": "github" } diff --git a/flake.nix b/flake.nix index 5b253a234c1..ab86698bfd7 100644 --- a/flake.nix +++ b/flake.nix @@ -27,7 +27,7 @@ }; utils.url = "github:numtide/flake-utils"; iohkNix = { - url = "github:input-output-hk/iohk-nix"; + url = "github:input-output-hk/iohk-nix/jl/env-reduce"; inputs.nixpkgs.follows = "nixpkgs"; }; ops-lib = { @@ -255,7 +255,7 @@ (mkFlakeAttrs (pkgs.extend (prev: final: { cardanoNodeProject = p; }))).ciJobs ) project.projectVariants; ciJobs = { - cardano-deployment = pkgs.cardanoLib.mkConfigHtml { inherit (pkgs.cardanoLib.environments) mainnet preview preprod shelley_qa; }; + cardano-deployment = pkgs.cardanoLib.mkConfigHtml { inherit (pkgs.cardanoLib.environments) mainnet preview preprod; }; } // optionalAttrs (system == "x86_64-linux") { native = packages // { shells = devShells; @@ -425,6 +425,10 @@ imports = [ ./nix/nixos/cardano-submit-api-service.nix ]; services.cardano-submit-api.cardanoNodePackages = lib.mkDefault (mkCardanoNodePackages flake.project.${pkgs.system}); }; + cardano-tracer = { pkgs, lib, ... }: { + imports = [ ./nix/nixos/cardano-tracer-service.nix ]; + services.cardano-tracer.cardanoNodePackages = lib.mkDefault (mkCardanoNodePackages flake.project.${pkgs.system}); + }; }; }; } diff --git a/nix/binary-release.nix b/nix/binary-release.nix index aa61fdcfa44..38240c0b8ba 100644 --- a/nix/binary-release.nix +++ b/nix/binary-release.nix @@ -18,7 +18,7 @@ let name = "cardano-node-${version}-${platform}"; environments = lib.getAttrs - [ "mainnet" "preprod" "preview" "sanchonet" ] + [ "mainnet" "preprod" "preview" ] pkgs.cardanoLib.environments; diff --git a/nix/nixos/cardano-node-service.nix b/nix/nixos/cardano-node-service.nix index 1bd8c458736..7bbb392cf09 100644 --- a/nix/nixos/cardano-node-service.nix +++ b/nix/nixos/cardano-node-service.nix @@ -7,25 +7,25 @@ with lib; with builtins; let cfg = config.services.cardano-node; envConfig = cfg.environments.${cfg.environment}; - runtimeDir = i : if cfg.runtimeDir i == null then cfg.stateDir i else "${cfg.runDirBase}${lib.removePrefix cfg.runDirBase (cfg.runtimeDir i)}"; + runtimeDir = i : if cfg.runtimeDir i == null then cfg.stateDir i else "${cfg.runDirBase}${removePrefix cfg.runDirBase (cfg.runtimeDir i)}"; suffixDir = base: i: "${base}${optionalString (i != 0) "-${toString i}"}"; nullOrStr = types.nullOr types.str; funcToOr = t: types.either t (types.functionTo t); newTopology = i: { localRoots = map (g: { - accessPoints = map (e: builtins.removeAttrs e ["valency"]) g.accessPoints; + accessPoints = map (e: removeAttrs e ["valency"]) g.accessPoints; advertise = g.advertise or false; valency = g.valency or (length g.accessPoints); trustable = g.trustable or false; }) (cfg.producers ++ (cfg.instanceProducers i)); publicRoots = map (g: { - accessPoints = map (e: builtins.removeAttrs e ["valency"]) g.accessPoints; + accessPoints = map (e: removeAttrs e ["valency"]) g.accessPoints; advertise = g.advertise or false; }) (cfg.publicProducers ++ (cfg.instancePublicProducers i)); bootstrapPeers = cfg.bootstrapPeers; - } // optionalAttrs (cfg.usePeersFromLedgerAfterSlot != null) { - useLedgerAfterSlot = cfg.usePeersFromLedgerAfterSlot; + } // optionalAttrs (cfg.useLedgerAfterSlot != null) { + useLedgerAfterSlot = cfg.useLedgerAfterSlot; } // optionalAttrs (cfg.peerSnapshotFile i != null) { peerSnapshotFile = cfg.peerSnapshotFile i; }; @@ -56,11 +56,11 @@ let selectTopology = i: if cfg.topology != null then cfg.topology - else toFile "topology.yaml" (toJSON (if (cfg.useNewTopology) then assertNewTopology i else oldTopology i)); + else toFile "topology.json" (toJSON (if (cfg.useNewTopology) then assertNewTopology i else oldTopology i)); topology = i: if cfg.useSystemdReload - then "/etc/cardano-node/topology-${toString i}.yaml" + then "/etc/cardano-node/topology-${toString i}.json" else selectTopology i; mkScript = cfg: @@ -106,59 +106,59 @@ let else toFile "config-${toString cfg.nodeId}-${toString i}.json" (toJSON instanceConfig); consensusParams = { RealPBFT = [ - "${lib.optionalString (cfg.signingKey != null) + "${optionalString (cfg.signingKey != null) "--signing-key ${cfg.signingKey}"}" - "${lib.optionalString (cfg.delegationCertificate != null) + "${optionalString (cfg.delegationCertificate != null) "--delegation-certificate ${cfg.delegationCertificate}"}" ]; TPraos = [ - "${lib.optionalString (cfg.vrfKey != null) + "${optionalString (cfg.vrfKey != null) "--shelley-vrf-key ${cfg.vrfKey}"}" - "${lib.optionalString (cfg.kesKey != null) + "${optionalString (cfg.kesKey != null) "--shelley-kes-key ${cfg.kesKey}"}" - "${lib.optionalString (cfg.operationalCertificate != null) + "${optionalString (cfg.operationalCertificate != null) "--shelley-operational-certificate ${cfg.operationalCertificate}"}" ]; Cardano = [ - "${lib.optionalString (cfg.signingKey != null) + "${optionalString (cfg.signingKey != null) "--signing-key ${cfg.signingKey}"}" - "${lib.optionalString (cfg.delegationCertificate != null) + "${optionalString (cfg.delegationCertificate != null) "--delegation-certificate ${cfg.delegationCertificate}"}" - "${lib.optionalString (cfg.vrfKey != null) + "${optionalString (cfg.vrfKey != null) "--shelley-vrf-key ${cfg.vrfKey}"}" - "${lib.optionalString (cfg.kesKey != null) + "${optionalString (cfg.kesKey != null) "--shelley-kes-key ${cfg.kesKey}"}" - "${lib.optionalString (cfg.operationalCertificate != null) + "${optionalString (cfg.operationalCertificate != null) "--shelley-operational-certificate ${cfg.operationalCertificate}"}" ]; }; instanceDbPath = cfg.databasePath i; utxoLmdbParams = ["--utxos-on-disk"] - ++ lib.optionals (cfg.lmdbDatabasePath i != null) + ++ optionals (cfg.lmdbDatabasePath i != null) [ "--utxos-database-path ${cfg.lmdbDatabasePath i}" ]; - cmd = builtins.filter (x: x != "") [ + cmd = filter (x: x != "") [ "${cfg.executable} run" "--config ${nodeConfigFile}" "--database-path ${instanceDbPath}" "--topology ${topology i}" - ] ++ lib.optionals (!cfg.systemdSocketActivation) ([ + ] ++ optionals (!cfg.systemdSocketActivation) ([ "--host-addr ${cfg.hostAddr}" "--port ${if (cfg.shareIpv4port || cfg.shareIpv6port) then toString cfg.port else toString (cfg.port + i)}" "--socket-path ${cfg.socketPath i}" - ] ++ lib.optionals (cfg.ipv6HostAddr i != null) [ + ] ++ optionals (cfg.ipv6HostAddr i != null) [ "--host-ipv6-addr ${cfg.ipv6HostAddr i}" - ]) ++ lib.optionals (cfg.tracerSocketPathAccept i != null) [ + ]) ++ optionals (cfg.tracerSocketPathAccept i != null) [ "--tracer-socket-path-accept ${cfg.tracerSocketPathAccept i}" - ] ++ lib.optionals (cfg.tracerSocketPathConnect i != null) [ + ] ++ optionals (cfg.tracerSocketPathConnect i != null) [ "--tracer-socket-path-connect ${cfg.tracerSocketPathConnect i}" - ] ++ lib.optionals (cfg.withUtxoHdLmdb i) utxoLmdbParams + ] ++ optionals (cfg.withUtxoHdLmdb i) utxoLmdbParams ++ consensusParams.${cfg.nodeConfig.Protocol} ++ cfg.extraArgs ++ cfg.rtsArgs; in '' echo "Starting: ${concatStringsSep "\"\n echo \"" cmd}" echo "..or, once again, in a single line:" echo "${toString cmd}" - ${lib.optionalString (i > 0) '' + ${optionalString (i > 0) '' # If exist copy state from existing instance instead of syncing from scratch: if [ ! -d ${instanceDbPath} ] && [ -d ${cfg.databasePath 0} ]; then echo "Copying existing immutable db from ${cfg.databasePath 0}" @@ -167,14 +167,20 @@ let ''} ${toString cmd}''; in { + imports = [ + # Update the option name for consistency with the cardano-node topology file key. + (mkRenamedOptionModule + [ "services" "cardano-node" "usePeersFromLedgerAfterSlot" ] [ "services" "cardano-node" "useLedgerAfterSlot" ]) + ]; + options = { services.cardano-node = { enable = mkOption { type = types.bool; default = false; description = '' - Enable cardano-node, a node implementing ouroboros protocols - (the blockchain protocols running cardano). + Enable cardano-node, a node implementing ouroboros protocols; + the blockchain protocols running cardano. ''; }; @@ -182,7 +188,7 @@ in { type = types.int; default = 1; description = '' - Number of instance of the service to run. + Number of instances of the service to run. ''; }; @@ -192,13 +198,32 @@ in { }; profiling = mkOption { - type = types.enum ["none" "time" "time-detail" "space" "space-cost" "space-module" "space-closure" "space-type" "space-retainer" "space-bio" "space-heap"]; + type = types.enum [ + "none" + "space" + "space-bio" + "space-closure" + "space-cost" + "space-heap" + "space-module" + "space-retainer" + "space-type" + "time" + "time-detail" + ]; default = "none"; + description = '' + Haskell profiling types which are available and will be applied to + the cardano-node binary if declared. + ''; }; eventlog = mkOption { type = types.bool; default = false; + description = '' + Whether to enable eventlog profiling. + ''; }; asserts = mkOption { @@ -214,9 +239,9 @@ in { default = pkgs.cardanoNodePackages or (import ../. { inherit (pkgs) system; }).cardanoNodePackages; defaultText = "cardano-node packages"; description = '' - The cardano-node packages and library that should be used. - Main usage is sharing optimization: - reduce eval time when service is instantiated multiple times. + The cardano-node packages and library that should be used. The main + use case is for a sharing optimization which reduces eval time when + cardano node packages are instantiated multiple times. ''; }; @@ -229,7 +254,7 @@ in { else cfg.cardanoNodePackages.cardano-node; defaultText = "cardano-node"; description = '' - The cardano-node package that should be used + The cardano-node package that should be used. ''; }; @@ -238,23 +263,23 @@ in { default = "exec ${cfg.package}/bin/cardano-node"; defaultText = "cardano-node"; description = '' - The cardano-node executable invocation to use + The cardano-node executable invocation to use. ''; }; - environments = mkOption { - type = types.attrs; - default = cfg.cardanoNodePackages.cardanoLib.environments; + environment = mkOption { + type = types.enum (attrNames cfg.environments); + default = "preview"; description = '' - environment node will connect to + The environment cardano-node will connect to. ''; }; - environment = mkOption { - type = types.enum (builtins.attrNames cfg.environments); - default = "testnet"; + environments = mkOption { + type = types.attrs; + default = cfg.cardanoNodePackages.cardanoLib.environments; description = '' - environment node will connect to + The environments cardano-node will possibly utilize. ''; }; @@ -263,7 +288,7 @@ in { default = false; description = '' Whether this node is intended to be a producer. - Internal option for inter-module communication. + An internal option for inter-module communication. ''; }; @@ -273,7 +298,7 @@ in { type = types.nullOr (types.either types.str types.path); default = null; description = '' - Signing key + The signing key. ''; }; @@ -281,7 +306,7 @@ in { type = types.nullOr (types.either types.str types.path); default = null; description = '' - Delegation certificate + The delegation certificate. ''; }; @@ -291,14 +316,14 @@ in { type = types.nullOr (types.either types.str types.path); default = null; description = '' - Signing key + The KES or key evolving signature key. ''; }; vrfKey = mkOption { type = types.nullOr (types.either types.str types.path); default = null; description = '' - Signing key + The VRF or verifable random function key. ''; }; @@ -306,7 +331,7 @@ in { type = types.nullOr (types.either types.str types.path); default = null; description = '' - Operational certificate + The operational certificate. ''; }; @@ -314,14 +339,14 @@ in { type = types.str; default = "127.0.0.1"; description = '' - The host address to bind to + The host address to bind to. ''; }; ipv6HostAddr = mkOption { type = funcToOr nullOrStr; default = _: null; - apply = ip: if (builtins.isFunction ip) then ip else _: ip; + apply = ip: if isFunction ip then ip else _: ip; description = '' The ipv6 host address to bind to. Set to null to disable. ''; @@ -331,7 +356,7 @@ in { type = types.functionTo (types.listOf types.str); default = _: []; description = '' - List of additional sockets to listen to. Only available with `systemdSocketActivation`. + A List of additional sockets to listen to. Only available with `systemdSocketActivation`. ''; }; @@ -339,16 +364,16 @@ in { type = types.str; default = "/var/lib/"; description = '' - Base directory to store blockchain data, for each instance. + The base directory to store blockchain data. ''; }; stateDir = mkOption { type = funcToOr types.str; default = "${cfg.stateDirBase}cardano-node"; - apply = x : if (builtins.isFunction x) then x else i: x; + apply = x : if isFunction x then x else i: x; description = '' - Directory to store blockchain data, for each instance. + The directory to store blockchain data, for each instance. ''; }; @@ -356,32 +381,32 @@ in { type = types.str; default = "/run/"; description = '' - Base runtime directory, for each instance. + The base runtime directory. ''; }; runtimeDir = mkOption { type = funcToOr nullOrStr; default = i: ''${cfg.runDirBase}${suffixDir "cardano-node" i}''; - apply = x : if builtins.isFunction x then x else if x == null then _: null else "${cfg.runDirBase}${suffixDir "cardano-node" x}"; + apply = x : if isFunction x then x else if x == null then _: null else "${cfg.runDirBase}${suffixDir "cardano-node" x}"; description = '' - Runtime directory relative to ${cfg.runDirBase}, for each instance + The runtime directory relative to ${cfg.runDirBase}, for each instance. ''; }; databasePath = mkOption { type = funcToOr types.str; default = i : "${cfg.stateDir i}/${cfg.dbPrefix i}"; - apply = x : if builtins.isFunction x then x else _ : x; - description = ''Node database path, for each instance.''; + apply = x : if isFunction x then x else _ : x; + description = ''The node database path, for each instance.''; }; lmdbDatabasePath = mkOption { type = funcToOr nullOrStr; default = null; - apply = x : if builtins.isFunction x then x else if x == null then _: null else _: x; + apply = x : if isFunction x then x else if x == null then _: null else _: x; description = '' - Node UTxO-HD LMDB path for performant disk I/O, for each instance. + A node UTxO-HD LMDB path for performant disk I/O, for each instance. This could point to a direct-access SSD, with a specifically created journal-less file system and optimized mount options. ''; }; @@ -389,16 +414,16 @@ in { socketPath = mkOption { type = funcToOr types.str; default = i : "${runtimeDir i}/node.socket"; - apply = x : if builtins.isFunction x then x else _ : x; - description = ''Local communication socket path, for each instance.''; + apply = x : if isFunction x then x else _ : x; + description = ''A local communication socket path, for each instance.''; }; tracerSocketPathAccept = mkOption { type = funcToOr nullOrStr; default = null; - apply = x : if builtins.isFunction x then x else _ : x; + apply = x : if isFunction x then x else _ : x; description = '' - Listen for incoming cardano-tracer connection on a local socket, + Listen for an incoming cardano-tracer connection on a local socket, for each instance. ''; }; @@ -406,9 +431,9 @@ in { tracerSocketPathConnect = mkOption { type = funcToOr nullOrStr; default = null; - apply = x : if builtins.isFunction x then x else _ : x; + apply = x : if isFunction x then x else _ : x; description = '' - Connect to cardano-tracer listening on a local socket, + Connect to a cardano-tracer listening on a local socket, for each instance. ''; }; @@ -417,8 +442,8 @@ in { type = types.str; default = "cardano-node"; description = '' - systemd socket group owner. - Note: only applies to sockets created by systemd + The systemd socket group owner. + Note: this only applies to sockets created by systemd (ie. when `systemdSocketActivation` is turned on). ''; }; @@ -436,7 +461,7 @@ in { }; default = i: {}; description = '' - Extra systemd service config (apply to all instances). + Extra systemd service config which applies to all instances. ''; }; @@ -447,17 +472,17 @@ in { }; default = i: {}; description = '' - Extra systemd socket config (apply to all instances). + Extra systemd socket config which applies to all instances. ''; }; dbPrefix = mkOption { type = types.either types.str (types.functionTo types.str); default = suffixDir "db-${cfg.environment}"; - apply = x : if builtins.isFunction x then x else suffixDir x; + apply = x : if isFunction x then x else suffixDir x; description = '' - Prefix of database directories inside `stateDir`. - (eg. for "db", there will be db-0, etc.). + The prefix of database directories inside `stateDir`. + (eg. for "db", there will be db-0, etc.), for each instance. ''; }; @@ -465,7 +490,7 @@ in { type = types.either types.int types.str; default = 3001; description = '' - The port number + The port number to listen on. ''; }; @@ -473,9 +498,9 @@ in { type = types.bool; default = cfg.systemdSocketActivation; description = '' - Should instances on same machine share ipv4 port. - Default: true if systemd activated socket. Otherwise false. - If false use port increments starting from `port`. + Whether instances on the same machine should share an ipv4 port. + Default: true if the socket is systemd activated, otherwise false. + If false, use port increments starting from `port`. ''; }; @@ -483,9 +508,9 @@ in { type = types.bool; default = cfg.systemdSocketActivation; description = '' - Should instances on same machine share ipv6 port. - Default: true if systemd activated socket. Otherwise false. - If false use port increments starting from `port`. + Whether instances on the same machine should share an ipv6 port. + Default: true if the socket is systemd activated, otherwise false. + If false, use port increments starting from `port`. ''; }; @@ -493,7 +518,7 @@ in { type = types.int; default = 0; description = '' - The ID for this node + The ID for this node. ''; }; @@ -507,13 +532,20 @@ in { }]; advertise = false; }]; - description = ''Routes to public peers. Only used if slot < usePeersFromLedgerAfterSlot''; + description = '' + Routes to public peers. Only used if slot is less than + useLedgerAfterSlot. + ''; }; instancePublicProducers = mkOption { type = types.functionTo (types.listOf types.attrs); default = _: []; - description = ''Routes to public peers. Only used if slot < usePeersFromLedgerAfterSlot and specific to a given instance (when multiple instances are used).''; + description = '' + Routes to public peers. Only used if slot is less than + useLedgerAfterSlot and specific to a given instance when + multiple instances are used. + ''; }; producers = mkOption { @@ -534,7 +566,8 @@ in { type = types.functionTo (types.listOf types.attrs); default = _: []; description = '' - Static routes to local peers, specific to a given instance (when multiple instances are used). + Static routes to local peers, specific to a given instance when + multiple instances are used. ''; }; @@ -542,7 +575,7 @@ in { type = types.bool; default = cfg.nodeConfig.EnableP2P or false; description = '' - Use new, p2p/ledger peers compatible topology. + Use new, peer to peer and ledger peers compatible topology. ''; }; @@ -554,14 +587,15 @@ in { ''; }; - usePeersFromLedgerAfterSlot = mkOption { + useLedgerAfterSlot = mkOption { type = types.nullOr types.int; default = if cfg.kesKey != null then null - else envConfig.usePeersFromLedgerAfterSlot or null; + else envConfig.useLedgerAfterSlot or null; description = '' If set, bootstraps from public roots until it reaches given slot, - then it switches to using the ledger as a source of peers. It maintains a connection to its local roots. - Default to null for block producers. + then it switches to using the ledger as a source of peers. It + maintains a connection to its local roots. Defaults to null for block + producers. ''; }; @@ -569,9 +603,9 @@ in { type = types.nullOr (types.listOf types.attrs); default = map (e: {address = e.addr; inherit (e) port;}) envConfig.edgeNodes; description = '' - If set, it will enable bootstrap peers. - To disable, set this to null. - To enable, set this to a list of attributes of address and port, example: [{ address = "addr"; port = 3001; }] + If set, it will enable bootstrap peers. To disable, set this to null. + To enable, set this to a list of attributes of address and port, + example: [{ address = "addr"; port = 3001; }] ''; }; @@ -579,7 +613,8 @@ in { type = types.nullOr (types.either types.str types.path); default = null; description = '' - Cluster topology. If not set `producers` array is used to generated topology file. + The cluster topology. If not set the `producers` array is used to + generate a topology file. ''; }; @@ -591,7 +626,7 @@ in { if only the topology file has changed and p2p is in use. Cardano-node topology files will be stored in /etc as: - /etc/cardano-node/topology-''${toString i}.yaml + /etc/cardano-node/topology-''${toString i}.json Enabling this option will also allow direct topology edits for tests when a full service re-deployment is not desired. @@ -603,21 +638,21 @@ in { merge = loc: foldl' (res: def: recursiveUpdate res def.value) {}; }; default = envConfig.nodeConfig; - description = ''Internal representation of the config.''; + description = ''The internal representation of the config.''; }; targetNumberOfRootPeers = mkOption { type = types.int; default = cfg.nodeConfig.TargetNumberOfRootPeers or 100; - description = "Limits the maximum number of root peers the node will know about"; + description = "The target number of root peers the node will know about."; }; targetNumberOfKnownPeers = mkOption { type = types.int; default = cfg.nodeConfig.TargetNumberOfKnownPeers or cfg.targetNumberOfRootPeers; description = '' - Target number for known peers (root peers + peers known through gossip). - Default to targetNumberOfRootPeers. + The target number of known peers, counting root peers and peers known + through gossip. Defaults to targetNumberOfRootPeers. ''; }; @@ -625,16 +660,20 @@ in { type = types.int; default = cfg.nodeConfig.TargetNumberOfEstablishedPeers or (cfg.targetNumberOfKnownPeers / 2); - description = ''Number of peers the node will be connected to, but not necessarily following their chain. - Default to half of targetNumberOfKnownPeers. + description = '' + The target number of peers the node will be connected to, but not + necessarily following their chain. Defaults to half of the + targetNumberOfKnownPeers. ''; }; targetNumberOfActivePeers = mkOption { type = types.int; default = cfg.nodeConfig.TargetNumberOfActivePeers or (2 * cfg.targetNumberOfEstablishedPeers / 5); - description = ''Number of peers your node is actively downloading headers and blocks from. - Default to 2/5 of targetNumberOfEstablishedPeers. + description = '' + Target number of peers the node is actively downloading headers and + blocks from. Defaults to the node config spec or two-fifths of the + targetNumberOfEstablishedPeers. ''; }; @@ -658,33 +697,33 @@ in { nodeConfigFile = mkOption { type = nullOrStr; default = null; - description = ''Actual configuration file (shell expression).''; + description = ''The actual configuration file.''; }; forceHardForks = mkOption { type = types.attrsOf types.int; default = {}; description = '' - A developer-oriented dictionary option to force hard forks for given eras at given epochs. Maps capitalised era names (Shelley, Allegra, Mary, etc.) to hard fork epoch number. - ''; - }; - - withCardanoTracer = mkOption { - type = types.bool; - default = false; + A developer-oriented dictionary option to force hard forks for given + eras at given epochs. Maps capitalised era names (Shelley, Allegra, + Mary, etc) to hard fork epoch number. + ''; }; withUtxoHdLmdb = mkOption { type = funcToOr types.bool; default = false; - apply = x: if builtins.isFunction x then x else _: x; - description = ''On an UTxO-HD enabled node, the in-memory backend is the default. This activates the on-disk backend (LMDB) instead.''; + apply = x: if isFunction x then x else _: x; + description = '' + On a UTxO-HD enabled node, the in-memory backend is the default. + This activates the on-disk backend (LMDB) instead. + ''; }; extraArgs = mkOption { type = types.listOf types.str; default = []; - description = ''Extra CLI args for 'cardano-node'.''; + description = ''Extra CLI args for cardano-node.''; }; rts_flags_override = mkOption { @@ -699,13 +738,13 @@ in { apply = args: if (args != [] || cfg.profilingArgs != [] || cfg.rts_flags_override != []) then ["+RTS"] ++ cfg.profilingArgs ++ args ++ cfg.rts_flags_override ++ ["-RTS"] else []; - description = ''Extra CLI args for 'cardano-node', to be surrounded by "+RTS"/"-RTS"''; + description = ''Extra CLI args for cardano-node, to be surrounded by "+RTS"/"-RTS"''; }; profilingArgs = mkOption { type = types.listOf types.str; default = let commonProfilingArgs = ["--machine-readable" "-tcardano-node.stats" "-pocardano-node"] - ++ lib.optional (cfg.eventlog) "-l"; + ++ optional (cfg.eventlog) "-l"; in if cfg.profiling == "time" then ["-p"] ++ commonProfilingArgs else if cfg.profiling == "time-detail" then ["-P"] ++ commonProfilingArgs else if cfg.profiling == "space" then ["-h"] ++ commonProfilingArgs @@ -724,7 +763,7 @@ in { type = funcToOr nullOrStr; default = null; example = i: "/etc/cardano-node/peer-snapshot-${toString i}.json"; - apply = x: if builtins.isFunction x then x else _: x; + apply = x: if isFunction x then x else _: x; description = '' If set, cardano-node will load a peer snapshot file from the declared absolute path. @@ -738,10 +777,10 @@ in { }; config = mkIf cfg.enable ( let - lmdbPaths = filter (x: x != null) (map (e: cfg.lmdbDatabasePath e) (builtins.genList lib.trivial.id cfg.instances)); + lmdbPaths = filter (x: x != null) (map (e: cfg.lmdbDatabasePath e) (genList trivial.id cfg.instances)); genInstanceConf = f: listToAttrs (if cfg.instances > 1 then genList (i: let n = "cardano-node-${toString i}"; in nameValuePair n (f n i)) cfg.instances - else [ (nameValuePair "cardano-node" (f "cardano-node" 0)) ]); in lib.mkMerge [ + else [ (nameValuePair "cardano-node" (f "cardano-node" 0)) ]); in mkMerge [ { users.groups.cardano-node.gid = 10016; users.users.cardano-node = { @@ -752,7 +791,7 @@ in { }; environment.etc = mkIf cfg.useSystemdReload (foldl' - (acc: i: recursiveUpdate acc {"cardano-node/topology-${toString i}.yaml".source = selectTopology i;}) {} + (acc: i: recursiveUpdate acc {"cardano-node/topology-${toString i}.json".source = selectTopology i;}) {} (range 0 (cfg.instances - 1))); ## TODO: use http://hackage.haskell.org/package/systemd for: @@ -775,19 +814,19 @@ in { Group = "cardano-node"; ExecReload = mkIf (cfg.useSystemdReload && cfg.useNewTopology) "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; Restart = "always"; - RuntimeDirectory = lib.mkIf (!cfg.systemdSocketActivation) - (lib.removePrefix cfg.runDirBase (runtimeDir i)); + RuntimeDirectory = mkIf (!cfg.systemdSocketActivation) + (removePrefix cfg.runDirBase (runtimeDir i)); WorkingDirectory = cfg.stateDir i; # This assumes cfg.stateDirBase is a prefix of cfg.stateDir. # This is checked as an assertion below. - StateDirectory = lib.removePrefix cfg.stateDirBase (cfg.stateDir i); - NonBlocking = lib.mkIf cfg.systemdSocketActivation true; - # time to sleep before restarting a service + StateDirectory = removePrefix cfg.stateDirBase (cfg.stateDir i); + NonBlocking = mkIf cfg.systemdSocketActivation true; + # Time to sleep before restarting a service RestartSec = 1; }; } (cfg.extraServiceConfig i)); - systemd.sockets = genInstanceConf (n: i: lib.mkIf cfg.systemdSocketActivation (recursiveUpdate { + systemd.sockets = genInstanceConf (n: i: mkIf cfg.systemdSocketActivation (recursiveUpdate { description = "Socket of the ${n} service."; wantedBy = [ "sockets.target" ]; partOf = [ "${n}.service" ]; @@ -796,7 +835,7 @@ in { ++ optional (cfg.ipv6HostAddr i != null) "[${cfg.ipv6HostAddr i}]:${toString (if cfg.shareIpv6port then cfg.port else cfg.port + i)}" ++ (cfg.additionalListenStream i) ++ [(cfg.socketPath i)]; - RuntimeDirectory = lib.removePrefix cfg.runDirBase (cfg.runtimeDir i); + RuntimeDirectory = removePrefix cfg.runDirBase (cfg.runtimeDir i); NoDelay = "yes"; ReusePort = "yes"; SocketMode = "0660"; @@ -807,8 +846,8 @@ in { } (cfg.extraSocketConfig i))); } { - # oneshot service start allows to easily control all instances at once. - systemd.services.cardano-node = lib.mkIf (cfg.instances > 1) { + # Oneshot service start allows to easily control all instances at once. + systemd.services.cardano-node = mkIf (cfg.instances > 1) { description = "Control all ${toString cfg.instances} at once."; enable = true; wants = genList (i: "cardano-node-${toString i}.service") cfg.instances; @@ -819,15 +858,15 @@ in { Group = "cardano-node"; ExecStart = "${pkgs.coreutils}/bin/echo Starting ${toString cfg.instances} cardano-node instances"; WorkingDirectory = cfg.stateDir i; - StateDirectory = lib.removePrefix cfg.stateDirBase (cfg.stateDir i); + StateDirectory = removePrefix cfg.stateDirBase (cfg.stateDir i); }; }; } { assertions = [ { - assertion = builtins.all (i : lib.hasPrefix cfg.stateDirBase (cfg.stateDir i)) - (builtins.genList lib.trivial.id cfg.instances); + assertion = all (i : hasPrefix cfg.stateDirBase (cfg.stateDir i)) + (genList trivial.id cfg.instances); message = "The option services.cardano-node.stateDir should have ${cfg.stateDirBase} as a prefix, for each instance!"; } @@ -840,7 +879,7 @@ in { message = "Systemd socket activation cannot be used with p2p topology due to a systemd socket re-use issue."; } { - assertion = (length lmdbPaths) == (length (lib.lists.unique lmdbPaths)); + assertion = (length lmdbPaths) == (length (lists.unique lmdbPaths)); message = "When configuring multiple LMDB enabled nodes on one instance, lmdbDatabasePath must be unique."; } ]; diff --git a/nix/nixos/cardano-tracer-service-legacy.nix b/nix/nixos/cardano-tracer-service-legacy.nix new file mode 100644 index 00000000000..b803e72021e --- /dev/null +++ b/nix/nixos/cardano-tracer-service-legacy.nix @@ -0,0 +1,112 @@ +# The legacy cardano-tracer module requires commonLib from the overlay +# which makes a simple non-flake service module import convoluted +# and also requires knowledge of the cardano-node commonLib functions to use. +# This makes this legacy module suitable for internal purposes, but not ideal +# for a general purpose single import cardano-tracer module. +# +# The module at nix/nixos/cardano-tracer-service.nix is the preferred module +# for general purpose use. +pkgs: +let serviceConfigToJSON = + cfg: + { + inherit (cfg) networkMagic resourceFreq metricsHelp; + # loRequestNum = 100; + network = + if cfg.acceptingSocket != null + then { + tag = "AcceptAt"; + contents = cfg.acceptingSocket; + } else if cfg.connectToSocket != null + then { + tag = "ConnectTo"; + contents = cfg.connectToSocket; + } else + throw "cardano-tracer-service: either acceptingSocket or connectToSocket must be provided."; + logging = [{ + inherit (cfg) logRoot; + + logMode = "FileMode"; + logFormat = "ForMachine"; + }]; + rotation = { + rpFrequencySecs = 15; + rpKeepFilesNum = 10; + rpLogLimitBytes = 1000000000; + rpMaxAgeHours = 24; + } // (cfg.rotation or {}); + + hasEKG = { + epHost = "127.0.0.1"; + epPort = cfg.ekgPortBase; + }; + ekgRequestFreq = 1; + hasPrometheus = { + epHost = "127.0.0.1"; + epPort = 3200; ## supervisord.portShiftPrometheus + } // (cfg.prometheus or {}); + # Just an example for metrics compatibility mapping. + # An entry means the first entry has the second entry as alias. + # The Metrics is then avalable, both with the original and the mapped name. + # Only one mapping per message is supported. + # metricsComp = { + # "Mempool.TxsInMempool" = "Mempool.TxsInMempool.Mapped"; + # "ChainDB.SlotNum" = "ChainDB.SlotNum.Mapped"; + # }; + } // pkgs.lib.optionalAttrs ((cfg.RTView or {}) != {}) + { + hasRTView = cfg.RTView; + }; +in pkgs.commonLib.defServiceModule + (lib: with lib; + { svcName = "cardano-tracer"; + svcDesc = "Cardano trace processor"; + + svcPackageSelector = + pkgs: ## Local: + pkgs.cardanoNodePackages.cardano-tracer + ## Imported by another repo, that adds an overlay: + or pkgs.cardano-tracer; + ## TODO: that's actually a bit ugly and could be improved. + ## This exe has to be available in the selected package. + exeName = "cardano-tracer"; + + extraOptionDecls = { + ### You can actually change those! + networkMagic = opt int 764824073 "Network magic (764824073 for Cardano mainnet)."; + acceptingSocket = mayOpt str "Socket path: as acceptor."; + connectToSocket = mayOpt str "Socket path: connect to."; + logRoot = opt str null "Log storage root directory."; + rotation = opt attrs {} "Log rotation overrides: see cardano-tracer documentation."; + RTView = opt attrs {} "RTView config overrides: see cardano-tracer documentation."; + ekgPortBase = opt int 3100 "EKG port base."; + ekgRequestFreq = opt int 1 "EKG request frequency"; + prometheus = opt attrs {} "Prometheus overrides: see cardano-tracer documentation."; + resourceFreq = mayOpt int "Frequency (1/ms) for tracing resource usage."; + metricsHelp = mayOpt str "JSON file containing metrics help annotations for Prometheus"; + + ### Here be dragons, on the other hand.. + configFile = mayOpt str + "Config file path override -- only set if you know what you're doing. Shudder. Your 'eminence'.."; + configJSONfn = opt (functionTo attrs) serviceConfigToJSON + "This is NOT meant to be overridden, at all -- we only expose it so it's externally accessible."; + }; + + configExeArgsFn = cfg: [ + "--config" (if cfg.configFile != null then cfg.configFile + else "${pkgs.writeText "cardano-tracer-config.json" + (__toJSON (serviceConfigToJSON cfg))}") + ]; + + configSystemdExtraConfig = _: {}; + + configSystemdExtraServiceConfig = + cfg: with cfg; { + Type = "exec"; + User = "cardano-node"; + Group = "cardano-node"; + Restart = "always"; + # RuntimeDirectory = localNodeConf.runtimeDir; + # WorkingDirectory = localNodeConf.stateDir; + }; + }) diff --git a/nix/nixos/cardano-tracer-service.nix b/nix/nixos/cardano-tracer-service.nix index cf6ce6ec7d1..c584902404f 100644 --- a/nix/nixos/cardano-tracer-service.nix +++ b/nix/nixos/cardano-tracer-service.nix @@ -1,104 +1,598 @@ -pkgs: -let serviceConfigToJSON = - cfg: - { - inherit (cfg) networkMagic resourceFreq metricsHelp; - # loRequestNum = 100; - network = - if cfg.acceptingSocket != null - then { - tag = "AcceptAt"; - contents = cfg.acceptingSocket; - } else if cfg.connectToSocket != null - then { - tag = "ConnectTo"; - contents = cfg.connectToSocket; - } else - throw "cardano-tracer-service: either acceptingSocket or connectToSocket must be provided."; - logging = [{ - inherit (cfg) logRoot; - - logMode = "FileMode"; - logFormat = "ForMachine"; - }]; - rotation = { - rpFrequencySecs = 15; - rpKeepFilesNum = 10; - rpLogLimitBytes = 1000000000; - rpMaxAgeHours = 24; - } // (cfg.rotation or {}); - - hasEKG = { - epHost = "127.0.0.1"; - epPort = cfg.ekgPortBase; - }; - ekgRequestFreq = 1; - hasPrometheus = { - epHost = "127.0.0.1"; - epPort = 3200; ## supervisord.portShiftPrometheus - } // (cfg.prometheus or {}); - # Just an example for metrics compatibility mapping. - # An entry means the first entry has the second entry as alias. - # The Metrics is then avalable, both with the original and the mapped name. - # Only one mapping per message is supported. - # metricsComp = { - # "Mempool.TxsInMempool" = "Mempool.TxsInMempool.Mapped"; - # "ChainDB.SlotNum" = "ChainDB.SlotNum.Mapped"; - # }; - } // pkgs.lib.optionalAttrs ((cfg.RTView or {}) != {}) - { - hasRTView = cfg.RTView; - }; -in pkgs.commonLib.defServiceModule - (lib: with lib; - { svcName = "cardano-tracer"; - svcDesc = "Cardano trace processor"; - - svcPackageSelector = - pkgs: ## Local: - pkgs.cardanoNodePackages.cardano-tracer - ## Imported by another repo, that adds an overlay: - or pkgs.cardano-tracer; - ## TODO: that's actually a bit ugly and could be improved. - ## This exe has to be available in the selected package. - exeName = "cardano-tracer"; - - extraOptionDecls = { - ### You can actually change those! - networkMagic = opt int 764824073 "Network magic (764824073 for Cardano mainnet)."; - acceptingSocket = mayOpt str "Socket path: as acceptor."; - connectToSocket = mayOpt str "Socket path: connect to."; - logRoot = opt str null "Log storage root directory."; - rotation = opt attrs {} "Log rotation overrides: see cardano-tracer documentation."; - RTView = opt attrs {} "RTView config overrides: see cardano-tracer documentation."; - ekgPortBase = opt int 3100 "EKG port base."; - ekgRequestFreq = opt int 1 "EKG request frequency"; - prometheus = opt attrs {} "Prometheus overrides: see cardano-tracer documentation."; - resourceFreq = mayOpt int "Frequency (1/ms) for tracing resource usage."; - metricsHelp = mayOpt str "JSON file containing metrics help annotations for Prometheus"; - - ### Here be dragons, on the other hand.. - configFile = mayOpt str - "Config file path override -- only set if you know what you're doing. Shudder. Your 'eminence'.."; - configJSONfn = opt (functionTo attrs) serviceConfigToJSON - "This is NOT meant to be overridden, at all -- we only expose it so it's externally accessible."; - }; - - configExeArgsFn = cfg: [ - "--config" (if cfg.configFile != null then cfg.configFile - else "${pkgs.writeText "cardano-tracer-config.json" - (__toJSON (serviceConfigToJSON cfg))}") +{ + config, + lib, + pkgs, + ... +}: +with lib; +with builtins; let + inherit (types) ints nullOr str; + + cfg = config.services.cardano-tracer; + + configFile = + if !isNull cfg.configFile + then cfg.configFile + else toFile "cardano-tracer-config.json" (toJSON tracerConfig); + + tracerConfig = + { + ekgRequestFreq = 1; + + logging = [ + { + logFormat = "ForHuman"; + logMode = "JournalMode"; + logRoot = "/tmp/cardano-node-logs"; + } + ]; + + network = { + contents = "/tmp/forwarder.sock"; + tag = "AcceptAt"; + }; + + networkMagic = cfg.networkMagic; + + resourceFreq = null; + + rotation = { + rpFrequencySecs = 15; + rpKeepFilesNum = 10; + rpLogLimitBytes = 1000000000; + rpMaxAgeHours = 24; + }; + } + // optionalAttrs cfg.ekgEnable { + hasEKG = { + epHost = cfg.ekgHost; + epPort = cfg.ekgPort; + }; + } + // optionalAttrs cfg.prometheusEnable { + hasPrometheus = { + epHost = cfg.prometheusHost; + epPort = cfg.prometheusPort; + }; + } + // optionalAttrs cfg.rtviewEnable { + hasRTView = { + epHost = cfg.rtviewHost; + epPort = cfg.rtviewPort; + }; + }; + + mkScript = let + cmd = + filter (x: x != "") + [ + "${cfg.executable} run" + "--config ${configFile}" + ] + ++ cfg.extraArgs + ++ cfg.rtsArgs; + in '' + echo "Starting: ${concatStringsSep "\"\n echo \"" cmd}" + echo "..or, once again, in a single line:" + echo "${toString cmd}" + ${toString cmd} + ''; + # runtimeDir = i : if cfg.runtimeDir i == null then cfg.stateDir i else "${cfg.runDirBase}${removePrefix cfg.runDirBase (cfg.runtimeDir i)}"; + # suffixDir = base: i: "${base}${optionalString (i != 0) "-${toString i}"}"; +in { + options = { + services.cardano-tracer = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Enable cardano-tracer, a service for logging and monitoring of + Cardano nodes. After it is connected to the node(s), it periodically + asks for different information, receives it, and handles it. + ''; + }; + + ##################################### + # # + # Alphabetical nixos module options # + # # + ##################################### + + asserts = mkOption { + type = types.bool; + default = false; + description = '' + Whether to use an executable with asserts enabled. + ''; + }; + + cardanoNodePackages = mkOption { + type = types.attrs; + default = pkgs.cardanoNodePackages or (import ../. {inherit (pkgs) system;}).cardanoNodePackages; + defaultText = "cardano-node packages"; + description = '' + The cardano-node packages and library that should be used. The main + use case is for a sharing optimization which reduces eval time when + cardano node packages are instantiated multiple times. + ''; + }; + + configFile = mkOption { + type = nullOr str; + default = null; + description = '' + The actual cardano-tracer configuration file. If this option is set + to null, a default configuration file will be built based on the nix + options. + ''; + }; + + ekgEnable = mkOption { + type = types.bool; + default = true; + description = '' + Whether to enable an EKG http interface for process monitoring. + ''; + }; + + ekgHost = mkOption { + type = types.str; + default = "127.0.0.1"; + description = '' + The host to bind if EKG is enabled. + ''; + }; + + ekgPort = mkOption { + type = types.port; + default = 12788; + description = '' + The port to listen on if EKG is enabled. + ''; + }; + + environment = mkOption { + type = types.enum (attrNames cfg.environments); + default = "preview"; + description = '' + The environment cardano-tracer will connect to. + ''; + }; + + environments = mkOption { + type = types.attrs; + default = cfg.cardanoNodePackages.cardanoLib.environments; + description = '' + The environments cardano-tracer will possibly utilize. + ''; + }; + + eventlog = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable eventlog profiling. + ''; + }; + + executable = mkOption { + type = types.str; + default = "exec ${cfg.package}/bin/cardano-tracer"; + defaultText = "cardano-node"; + description = '' + The cardano-tracer executable invocation to use. + ''; + }; + + extraArgs = mkOption { + type = types.listOf types.str; + default = []; + description = '' + Extra CLI args for cardano-tracer. + ''; + }; + + networkMagic = mkOption { + type = ints.positive; + default = (fromJSON (readFile cfg.environments.${cfg.environment}.nodeConfig.ShelleyGenesisFile)).networkMagic; + description = '' + The network magic of the cardano environment which will be connected + with cardano-tracer. + ''; + }; + + package = mkOption { + type = types.package; + default = + if (cfg.profiling != "none") + then cfg.cardanoNodePackages.cardano-tracer.passthru.profiled + else if cfg.eventlog + then cfg.cardanoNodePackages.cardano-tracer.passthru.eventlogged + else if cfg.asserts + then cfg.cardanoNodePackages.cardano-tracer.passthru.asserted + else cfg.cardanoNodePackages.cardano-tracer; + defaultText = "cardano-tracer"; + description = '' + The cardano-tracer package that should be used. + ''; + }; + + profiling = mkOption { + type = types.enum [ + "none" + "space" + "space-bio" + "space-closure" + "space-cost" + "space-heap" + "space-module" + "space-retainer" + "space-type" + "time" + "time-detail" ]; + default = "none"; + description = '' + Haskell profiling types which are available and will be applied to + the cardano-tracer binary if declared. + ''; + }; + + profilingArgs = mkOption { + type = types.listOf types.str; + default = let + commonProfilingArgs = + ["--machine-readable" "-tcardano-tracer.stats" "-pocardano-tracer"] + ++ optional (cfg.eventlog) "-l"; + in + if cfg.profiling == "time" + then ["-p"] ++ commonProfilingArgs + else if cfg.profiling == "time-detail" + then ["-P"] ++ commonProfilingArgs + else if cfg.profiling == "space" + then ["-h"] ++ commonProfilingArgs + else if cfg.profiling == "space-cost" + then ["-hc"] ++ commonProfilingArgs + else if cfg.profiling == "space-module" + then ["-hm"] ++ commonProfilingArgs + else if cfg.profiling == "space-closure" + then ["-hd"] ++ commonProfilingArgs + else if cfg.profiling == "space-type" + then ["-hy"] ++ commonProfilingArgs + else if cfg.profiling == "space-retainer" + then ["-hr"] ++ commonProfilingArgs + else if cfg.profiling == "space-bio" + then ["-hb"] ++ commonProfilingArgs + else if cfg.profiling == "space-heap" + then ["-hT"] ++ commonProfilingArgs + else []; + description = '' + RTS profiling options. + ''; + }; + + prometheusEnable = mkOption { + type = types.bool; + default = true; + description = '' + Whether to enable a prometheus export of EKG metrics. + ''; + }; + + prometheusHost = mkOption { + type = types.str; + default = "127.0.0.1"; + description = '' + The host to bind if prometheus is enabled. + ''; + }; + + prometheusPort = mkOption { + type = types.port; + default = 12798; + description = '' + The port to listen on if prometheus is enabled. + ''; + }; + + rts_flags_override = mkOption { + type = types.listOf types.str; + default = []; + description = '' + RTS flags override from profile content. + ''; + }; + + rtsArgs = mkOption { + type = types.listOf types.str; + default = []; + apply = args: + if (args != [] || cfg.profilingArgs != [] || cfg.rts_flags_override != []) + then ["+RTS"] ++ cfg.profilingArgs ++ args ++ cfg.rts_flags_override ++ ["-RTS"] + else []; + description = '' + Extra CLI args for cardano-node, to be surrounded by "+RTS"/"-RTS" + ''; + }; + + rtviewEnable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable an RTView client. + + As of node release 9.1 this option has no effect unless node was + built with `-f +rtview`. + + Ref: + https://github.com/IntersectMBO/cardano-node/pull/5846 + ''; + }; + + rtviewHost = mkOption { + type = types.str; + default = "127.0.0.1"; + description = '' + The host to bind if RTView is enabled. + ''; + }; + + rtviewPort = mkOption { + type = types.port; + default = 3300; + description = '' + The port to listen on if RTView is enabled. + ''; + }; + + # hostAddr = mkOption { + # type = types.str; + # default = "127.0.0.1"; + # description = '' + # The host address to bind to + # ''; + # }; + + # stateDirBase = mkOption { + # type = types.str; + # default = "/var/lib/"; + # description = '' + # Base directory to store blockchain data, for each instance. + # ''; + # }; + + # stateDir = mkOption { + # type = funcToOr types.str; + # default = "${cfg.stateDirBase}cardano-node"; + # apply = x : if (isFunction x) then x else i: x; + # description = '' + # Directory to store blockchain data, for each instance. + # ''; + # }; + + # runDirBase = mkOption { + # type = types.str; + # default = "/run/"; + # description = '' + # Base runtime directory, for each instance. + # ''; + # }; + + # runtimeDir = mkOption { + # type = funcToOr nullOrStr; + # default = i: ''${cfg.runDirBase}${suffixDir "cardano-node" i}''; + # apply = x : if isFunction x then x else if x == null then _: null else "${cfg.runDirBase}${suffixDir "cardano-node" x}"; + # description = '' + # Runtime directory relative to ${cfg.runDirBase}, for each instance + # ''; + # }; + + # databasePath = mkOption { + # type = funcToOr types.str; + # default = i : "${cfg.stateDir i}/${cfg.dbPrefix i}"; + # apply = x : if isFunction x then x else _ : x; + # description = ''Node database path, for each instance.''; + # }; + + # socketPath = mkOption { + # type = funcToOr types.str; + # default = i : "${runtimeDir i}/node.socket"; + # apply = x : if isFunction x then x else _ : x; + # description = ''Local communication socket path, for each instance.''; + # }; + + # tracerSocketPathAccept = mkOption { + # type = funcToOr nullOrStr; + # default = null; + # apply = x : if isFunction x then x else _ : x; + # description = '' + # Listen for incoming cardano-tracer connection on a local socket, + # for each instance. + # ''; + # }; + + # tracerSocketPathConnect = mkOption { + # type = funcToOr nullOrStr; + # default = null; + # apply = x : if isFunction x then x else _ : x; + # description = '' + # Connect to cardano-tracer listening on a local socket, + # for each instance. + # ''; + # }; + + # socketGroup = mkOption { + # type = types.str; + # default = "cardano-node"; + # description = '' + # systemd socket group owner. + # Note: only applies to sockets created by systemd + # (ie. when `systemdSocketActivation` is turned on). + # ''; + # }; + + # systemdSocketActivation = mkOption { + # type = types.bool; + # default = false; + # description = ''Use systemd socket activation''; + # }; + }; + }; + + config = mkIf cfg.enable { + systemd.services.cardano-tracer = { + description = "cardano-tracer service"; + wantedBy = ["multi-user.target"]; + + environment.HOME = "/var/lib/cardano-tracer"; + + path = [cfg.package]; + + # Allow up to 10 failures with 30 second restarts in a 15 minute window + # before entering failure state and alerting + startLimitBurst = 10; + startLimitIntervalSec = 900; + + serviceConfig = { + LimitNOFILE = "65535"; + + StateDirectory = "cardano-tracer"; + WorkingDirectory = "/var/lib/cardano-tracer"; + + # Ensure quick restarts on any condition + Restart = "always"; + RestartSec = 30; + + ExecStart = getExe (pkgs.writeShellApplication { + name = "cardano-tracer"; + text = mkScript; + }); + }; + }; + }; + + # systemd.sockets = genInstanceConf (n: i: mkIf cfg.systemdSocketActivation (recursiveUpdate { + # description = "Socket of the ${n} service."; + # wantedBy = [ "sockets.target" ]; + # partOf = [ "${n}.service" ]; + # socketConfig = { + # ListenStream = [ "${cfg.hostAddr}:${toString (if cfg.shareIpv4port then cfg.port else cfg.port + i)}" ] + # ++ optional (cfg.ipv6HostAddr i != null) "[${cfg.ipv6HostAddr i}]:${toString (if cfg.shareIpv6port then cfg.port else cfg.port + i)}" + # ++ (cfg.additionalListenStream i) + # ++ [(cfg.socketPath i)]; + # RuntimeDirectory = removePrefix cfg.runDirBase (cfg.runtimeDir i); + # NoDelay = "yes"; + # ReusePort = "yes"; + # SocketMode = "0660"; + # SocketUser = "cardano-node"; + # SocketGroup = cfg.socketGroup; + # FreeBind = "yes"; + # }; + # } (cfg.extraSocketConfig i))); + # } +} +# pkgs: +# let serviceConfigToJSON = +# cfg: +# { +# inherit (cfg) networkMagic resourceFreq metricsHelp; +# # loRequestNum = 100; +# network = +# if cfg.acceptingSocket != null +# then { +# tag = "AcceptAt"; +# contents = cfg.acceptingSocket; +# } else if cfg.connectToSocket != null +# then { +# tag = "ConnectTo"; +# contents = cfg.connectToSocket; +# } else +# throw "cardano-tracer-service: either acceptingSocket or connectToSocket must be provided."; +# logging = [{ +# inherit (cfg) logRoot; +# +# logMode = "FileMode"; +# logFormat = "ForMachine"; +# }]; +# rotation = { +# rpFrequencySecs = 15; +# rpKeepFilesNum = 10; +# rpLogLimitBytes = 1000000000; +# rpMaxAgeHours = 24; +# } // (cfg.rotation or {}); +# +# hasEKG = { +# epHost = "127.0.0.1"; +# epPort = cfg.ekgPortBase; +# }; +# ekgRequestFreq = 1; +# hasPrometheus = { +# epHost = "127.0.0.1"; +# epPort = 3200; ## supervisord.portShiftPrometheus +# } // (cfg.prometheus or {}); +# # Just an example for metrics compatibility mapping. +# # An entry means the first entry has the second entry as alias. +# # The Metrics is then avalable, both with the original and the mapped name. +# # Only one mapping per message is supported. +# # metricsComp = { +# # "Mempool.TxsInMempool" = "Mempool.TxsInMempool.Mapped"; +# # "ChainDB.SlotNum" = "ChainDB.SlotNum.Mapped"; +# # }; +# } // pkgs.optionalAttrs ((cfg.RTView or {}) != {}) +# { +# hasRTView = cfg.RTView; +# }; +# in pkgs.commondefServiceModule +# (lib: with lib; +# { svcName = "cardano-tracer"; +# svcDesc = "Cardano trace processor"; +# +# svcPackageSelector = +# pkgs: ## Local: +# pkgs.cardanoNodePackages.cardano-tracer +# ## Imported by another repo, that adds an overlay: +# or pkgs.cardano-tracer; +# ## TODO: that's actually a bit ugly and could be improved. +# ## This exe has to be available in the selected package. +# exeName = "cardano-tracer"; +# +# extraOptionDecls = { +# ### You can actually change those! +# networkMagic = opt int 764824073 "Network magic (764824073 for Cardano mainnet)."; +# acceptingSocket = mayOpt str "Socket path: as acceptor."; +# connectToSocket = mayOpt str "Socket path: connect to."; +# logRoot = opt str null "Log storage root directory."; +# rotation = opt attrs {} "Log rotation overrides: see cardano-tracer documentation."; +# RTView = opt attrs {} "RTView config overrides: see cardano-tracer documentation."; +# ekgPortBase = opt int 3100 "EKG port base."; +# ekgRequestFreq = opt int 1 "EKG request frequency"; +# prometheus = opt attrs {} "Prometheus overrides: see cardano-tracer documentation."; +# resourceFreq = mayOpt int "Frequency (1/ms) for tracing resource usage."; +# metricsHelp = mayOpt str "JSON file containing metrics help annotations for Prometheus"; +# +# ### Here be dragons, on the other hand.. +# configFile = mayOpt str +# "Config file path override -- only set if you know what you're doing. Shudder. Your 'eminence'.."; +# configJSONfn = opt (functionTo attrs) serviceConfigToJSON +# "This is NOT meant to be overridden, at all -- we only expose it so it's externally accessible."; +# }; +# +# configExeArgsFn = cfg: [ +# "--config" (if cfg.configFile != null then cfg.configFile +# else "${pkgs.writeText "cardano-tracer-config.json" +# (__toJSON (serviceConfigToJSON cfg))}") +# ]; +# +# configSystemdExtraConfig = _: {}; +# +# configSystemdExtraServiceConfig = +# cfg: with cfg; { +# Type = "exec"; +# User = "cardano-node"; +# Group = "cardano-node"; +# Restart = "always"; +# # RuntimeDirectory = localNodeConf.runtimeDir; +# # WorkingDirectory = localNodeConf.stateDir; +# }; +# }) - configSystemdExtraConfig = _: {}; - - configSystemdExtraServiceConfig = - cfg: with cfg; { - Type = "exec"; - User = "cardano-node"; - Group = "cardano-node"; - Restart = "always"; - # RuntimeDirectory = localNodeConf.runtimeDir; - # WorkingDirectory = localNodeConf.stateDir; - }; - }) diff --git a/nix/nixos/module-list.nix b/nix/nixos/module-list.nix index 4fd14193844..ff7b385401f 100644 --- a/nix/nixos/module-list.nix +++ b/nix/nixos/module-list.nix @@ -1,4 +1,5 @@ [ ./cardano-node-service.nix ./cardano-submit-api-service.nix + ./cardano-tracer-service.nix ] diff --git a/nix/workbench/profile/profile.nix b/nix/workbench/profile/profile.nix index a6703e82349..e4da07dee19 100644 --- a/nix/workbench/profile/profile.nix +++ b/nix/workbench/profile/profile.nix @@ -30,6 +30,18 @@ let --argjson x '${x}' '' "$x"; + ## This ports the (very minimal) config of the deprecated iohk-nix testnet environment to workbench, removing the dependency on it. + baseNodeConfigTestnet = + { + Protocol = "Cardano"; + RequiresNetworkMagic = "RequiresMagic"; + + LastKnownBlockVersion-Major = 3; + LastKnownBlockVersion-Minor = 0; + LastKnownBlockVersion-Alt = 0; + } + // workbenchNix.cardanoNodePackages.cardanoLib.defaultLogConfig; + mkServices = { profile, nodeSpecs, backend }: rec { inherit @@ -40,7 +52,7 @@ let inherit topologyFiles profiling; inherit workbenchNix; inherit jsonFilePretty; - baseNodeConfig = workbenchNix.cardanoNodePackages.cardanoLib.environments.testnet.nodeConfig; + baseNodeConfig = baseNodeConfigTestnet; }) node-services; diff --git a/scripts/byron-to-alonzo/burn.sh b/scripts/byron-to-alonzo/burn.sh index f6dd115e2a7..4051c59c01b 100755 --- a/scripts/byron-to-alonzo/burn.sh +++ b/scripts/byron-to-alonzo/burn.sh @@ -1,44 +1,61 @@ #!/usr/bin/env bash - -set -e -# set -x +set -euo pipefail # This script creates, signs, and submits a transaction that burns the tokens # that were created with mint.sh. +[ -n "${DEBUG:-}" ] && set -x + ROOT=example -COINS_IN_INPUT=1000000000 pushd ${ROOT} export CARDANO_NODE_SOCKET_PATH=node-bft1/node.sock - -KEYHASH=$(cardano-cli address key-hash --payment-verification-key-file ma/policy.vkey) +export CARDANO_NODE_NETWORK_ID=42 SCRIPT=ma/policy.script -TXID4=$(cardano-cli transaction txid --tx-body-file tx4.txbody) +POLICYID=$(cardano-cli mary transaction policyid --script-file ma/policy.script) +TOKEN_NAME="couttscoin" +TOKEN_NAME_HEX=$(printf "%s" "$TOKEN_NAME" | od -A n -t x1 | tr -d ' \n') -POLICYID=$(cardano-cli transaction policyid --script-file ma/policy.script) +# Obtain the input lovelace dynamically to reduce change calc complexity +NT_UTXO=$( + cardano-cli query utxo --whole-utxo --output-json \ + | jq -er '[to_entries[] | select(.value.value | length != 1)][0] + | {"txin": .key, "address": .value.address, "amount": .value.value.lovelace}') -cardano-cli transaction build-raw \ - --mary-era \ - --fee 0 \ - --tx-in $TXID4#0 \ - --tx-out $(cat addresses/user1.addr)+$((${COINS_IN_INPUT} / 2)) \ - --mint="-5 $POLICYID.couttscoin" \ - --out-file tx5.txbody +NT_TXIN=$(jq -er '.txin' <<< "$NT_UTXO") -cardano-cli transaction sign \ - --signing-key-file addresses/user1.skey \ - --signing-key-file ma/policy.skey \ - --script-file $SCRIPT \ - --testnet-magic 42 \ - --tx-body-file tx5.txbody \ - --out-file tx5.tx - -cardano-cli transaction submit --tx-file tx5.tx --testnet-magic 42 +# Match the fee to the min utxo set in mint.sh +FEE=$(jq -er '.amount' <<< "$NT_UTXO") +# For simplicity and to enable use of update-5.sh as a follow up script, we'll +# burn the min utxo lovelace in the native token utxo. +cardano-cli mary transaction build-raw \ + --tx-in "$NT_TXIN" \ + --mint="-5 $POLICYID.$TOKEN_NAME_HEX" \ + --mint-script-file $SCRIPT \ + --fee "$FEE" \ + --out-file tx-burn.txbody +cardano-cli mary transaction sign \ + --signing-key-file addresses/user1.skey \ + --signing-key-file ma/policy.skey \ + --tx-body-file tx-burn.txbody \ + --out-file tx-burn.tx + +echo +echo "The whole utxo prior to burning is:" +echo +cardano-cli query utxo --whole-utxo --output-json +echo + +cardano-cli mary transaction submit --tx-file tx-burn.tx +sleep 2 +echo +echo "The whole utxo after burning is:" +echo +cardano-cli query utxo --whole-utxo --output-json +echo popd - diff --git a/scripts/byron-to-alonzo/mint.sh b/scripts/byron-to-alonzo/mint.sh index 4d5f6122f9d..fa179137d08 100755 --- a/scripts/byron-to-alonzo/mint.sh +++ b/scripts/byron-to-alonzo/mint.sh @@ -1,16 +1,17 @@ #!/usr/bin/env bash - -set -e -# set -x +set -euo pipefail # This script creates, signs, and submits a transaction that creates some new tokens. # It uses the output of the transaction from update-4.sh. +[ -n "${DEBUG:-}" ] && set -x + ROOT=example -COINS_IN_INPUT=1000000000 +SPLIT_OUTPUT_ALLOC=1000000000 pushd ${ROOT} export CARDANO_NODE_SOCKET_PATH=node-bft1/node.sock +export CARDANO_NODE_NETWORK_ID=42 mkdir -p ma cardano-cli address key-gen \ @@ -21,34 +22,66 @@ KEYHASH=$(cardano-cli address key-hash --payment-verification-key-file ma/policy SCRIPT=ma/policy.script rm -f $SCRIPT -echo "{" >> $SCRIPT -echo " \"keyHash\": \"${KEYHASH}\"," >> $SCRIPT -echo " \"type\": \"sig\"" >> $SCRIPT -echo "}" >> $SCRIPT - -TXID3=$(cardano-cli transaction txid --tx-body-file tx3.txbody) - -POLICYID=$(cardano-cli transaction policyid --script-file ma/policy.script) - -cardano-cli transaction build-raw \ - --mary-era \ - --fee 0 \ - --tx-in $TXID3#0 \ - --tx-out="$(cat addresses/user1.addr)+$((${COINS_IN_INPUT} / 2))+5 $POLICYID.couttscoin" \ - --mint="5 $POLICYID.couttscoin" \ - --out-file tx4.txbody - -cardano-cli transaction sign \ +{ + echo "{" + echo " \"keyHash\": \"${KEYHASH}\"," + echo " \"type\": \"sig\"" + echo "}" +} >> $SCRIPT + +TXID3=$(cardano-cli mary transaction txid --tx-file tx3.tx) + +POLICYID=$(cardano-cli mary transaction policyid --script-file ma/policy.script) +TOKEN_NAME="couttscoin" +TOKEN_NAME_HEX=$(printf "%s" "$TOKEN_NAME" | od -A n -t x1 | tr -d ' \n') + +# Obtain the input lovelace dynamically to reduce change calc complexity +TOTAL_INPUT_LOVELACE=$( + cardano-cli query utxo --whole-utxo --output-json \ + | jq -er '[to_entries[] | select(.value.value | length == 1) | .value.value.lovelace] | add') + +# Slight over-estimate on the fee +FEE=200000 +MIN_UTXO=1000000 +CHANGE=$(( + + TOTAL_INPUT_LOVELACE + - SPLIT_OUTPUT_ALLOC + - MIN_UTXO + - FEE +)) + +# Overwrite the prior tx3 tx out file so update-5.sh still obtains the correct utxo after mint/burn +cardano-cli mary transaction build-raw \ + --tx-in "$TXID3#0" \ + --tx-in "$TXID3#1" \ + --tx-in "$TXID3#2" \ + --tx-out "$(cat addresses/user1.addr)+$((SPLIT_OUTPUT_ALLOC / 2))" \ + --tx-out "$(cat addresses/user1.addr)+$((SPLIT_OUTPUT_ALLOC / 2))" \ + --tx-out "$(cat addresses/user1.addr)+$CHANGE" \ + --tx-out="$(cat addresses/user1.addr)+$MIN_UTXO+5 $POLICYID.$TOKEN_NAME_HEX" \ + --mint="5 $POLICYID.$TOKEN_NAME_HEX" \ + --mint-script-file $SCRIPT \ + --fee "$FEE" \ + --out-file tx3.txbody + +cardano-cli mary transaction sign \ --signing-key-file addresses/user1.skey \ --signing-key-file ma/policy.skey \ - --script-file $SCRIPT \ - --testnet-magic 42 \ - --tx-body-file tx4.txbody \ - --out-file tx4.tx - -cardano-cli transaction submit --tx-file tx4.tx --testnet-magic 42 - - + --tx-body-file tx3.txbody \ + --out-file tx3.tx + +echo +echo "The whole utxo prior to minting is:" +echo +cardano-cli query utxo --whole-utxo --output-json +echo + +cardano-cli mary transaction submit --tx-file tx3.tx +sleep 2 +echo +echo "The whole utxo after minting is:" +echo +cardano-cli query utxo --whole-utxo --output-json +echo popd - diff --git a/scripts/byron-to-alonzo/mkfiles.sh b/scripts/byron-to-alonzo/mkfiles.sh index b47e940163e..9dbbe07096e 100755 --- a/scripts/byron-to-alonzo/mkfiles.sh +++ b/scripts/byron-to-alonzo/mkfiles.sh @@ -6,39 +6,53 @@ set -e set -u set -o pipefail - # This script sets up a cluster that starts out in Byron, and can transition to Mary. # # The script generates all the files needed for the setup, and prints commands # to be run manually (to start the nodes, post transactions, etc.). # +# One option to ensure you are running with repo matched cardano-cli and cardano-node +# versions is to enter a nix shell: `nix shell .#cardano-cli .#cardano-node` +# # There are three ways of triggering the transition to Shelley: -# 1. Trigger transition at protocol version 2.0.0 (as on mainnet) +# 1. Trigger transition at protocol version 2.0.0 (as on mainnet). # The system starts at 0.0.0, and we can only increase it by 1 in the major -# version, so this does require to -# a) post an update proposal and votes to transition to 1.0.0 +# version, so this does require to: +# +# a) post an update proposal and votes to transition to 1.0.0, +# # b) wait for the protocol to change (end of the epoch, or end of the last -# epoch if it's posted near the end of the epoch) +# epoch if it's posted near the end of the epoch), +# # c) change configuration.yaml to have 'LastKnownBlockVersion-Major: 2', -# and restart the nodes +# and restart the nodes +# # d) post an update proposal and votes to transition to 2.0.0 +# # This is what will happen on the mainnet, so it's vital to test this, but # it does contain some manual steps. -# 2. Trigger transition at protocol version 2.0.0 +# +# 2. Trigger transition at protocol version 2.0.0. # For testing purposes, we can also modify the system to do the transition to # Shelley at protocol version 1.0.0, by uncommenting the line containing # 'TestShelleyHardForkAtVersion' below. Then, we just need to execute step a) # above in order to trigger the transition. +# # This is still close to the procedure on the mainnet, and requires less # manual steps. -# 3. Schedule transition in the configuration +# +# 3. Schedule the transition in the configuration. # To do this, uncomment the line containing 'TestShelleyHardForkAtEpoch' # below. It's good for a quick test, and does not rely on posting update # proposals to the chain. +# # This is quite convenient, but it does not test that we can do the -# transition by posting update proposals to the network. For even more convenience -# if you want to start a node in Shelley, Allegra or Mary from epoch 0, supply the script -# with a shelley, allegra or mary string argument. E.g mkfiles.sh mary. +# transition by posting update proposals to the network. For even more +# convenience if you want to start a node in Shelley, Allegra or Mary from +# epoch 0, supply the script with a shelley, allegra or mary string +# argument. E.g mkfiles.sh mary. + +[ -n "${DEBUG:-}" ] && set -x ROOT=example @@ -51,10 +65,11 @@ POOL_NODES="node-pool1" ALL_NODES="${BFT_NODES} ${POOL_NODES}" INIT_SUPPLY=10020000000 -FUNDS_PER_GENESIS_ADDRESS=$((${INIT_SUPPLY} / ${NUM_BFT_NODES})) -FUNDS_PER_BYRON_ADDRESS=$((${FUNDS_PER_GENESIS_ADDRESS} - 1000000)) +FUNDS_PER_GENESIS_ADDRESS=$((INIT_SUPPLY / NUM_BFT_NODES)) + # We need to allow for a fee to transfer the funds out of the genesis. # We don't care too much, 1 ada is more than enough. +FUNDS_PER_BYRON_ADDRESS=$((FUNDS_PER_GENESIS_ADDRESS - 1000000)) NETWORK_MAGIC=42 SECURITY_PARAM=10 @@ -77,8 +92,9 @@ sprocket() { if [ "$UNAME" == "Windows_NT" ]; then # Named pipes names on Windows must have the structure: "\\.\pipe\PipeName" # See https://docs.microsoft.com/en-us/windows/win32/ipc/pipe-names - echo -n '\\.\pipe\' - echo "$1" | sed 's|/|\\|g' + # shellcheck disable=SC1003 + printf "%s" '\\.\pipe\' + echo "${1//\//\\}" else echo "$1" fi @@ -91,11 +107,11 @@ if ! mkdir "${ROOT}"; then exit fi -# copy and tweak the configuration +# Copy and tweak the configuration cp configuration/defaults/byron-mainnet/configuration.yaml ${ROOT}/ $SED -i "${ROOT}/configuration.yaml" \ -e 's/Protocol: RealPBFT/Protocol: Cardano/' \ - -e '/Protocol/ aPBftSignatureThreshold: 0.6' \ + -e '/^Protocol:/ aPBftSignatureThreshold: 0.6' \ -e 's/minSeverity: Info/minSeverity: Debug/' \ -e 's|GenesisFile: genesis.json|ByronGenesisFile: byron/genesis.json|' \ -e '/ByronGenesisFile/ aShelleyGenesisFile: shelley/genesis.json' \ @@ -104,17 +120,19 @@ $SED -i "${ROOT}/configuration.yaml" \ -e 's/RequiresNoMagic/RequiresMagic/' \ -e 's/LastKnownBlockVersion-Major: 0/LastKnownBlockVersion-Major: 1/' \ -e 's/LastKnownBlockVersion-Minor: 2/LastKnownBlockVersion-Minor: 0/' -# Options for making it easier to trigger the transition to Shelley + +# Options for making it easier to trigger the transition to Shelley: # If neither of those are used, we have to # - post an update proposal + votes to go to protocol version 1 # - after that's activated, change the configuration to have # 'LastKnownBlockVersion-Major: 2', and restart the nodes # - post another proposal + vote to go to protocol version 2 -#uncomment this for an automatic transition after the first epoch +# Uncomment the next line for an automatic transition after the first epoch: # echo "TestShelleyHardForkAtEpoch: 1" >> ${ROOT}/configuration.yaml -#uncomment this to trigger the hardfork with protocol version 1 -#echo "TestShelleyHardForkAtVersion: 1" >> ${ROOT}/configuration.yaml + +# Uncomment the next line to trigger the hardfork with protocol version 1: +# echo "TestShelleyHardForkAtVersion: 1" >> ${ROOT}/configuration.yaml # Create the node directories for NODE in ${ALL_NODES}; do @@ -122,7 +140,7 @@ for NODE in ${ALL_NODES}; do done # Make topology files -#TODO generalise this over the N BFT nodes and pool nodes +# TODO: generalise this over the N BFT nodes and pool nodes cat > "${ROOT}/node-bft1/topology.json" < "${ROOT}/byron/address-00$((${N} - 1))" + --secret "${ROOT}/byron/payment-keys.00$((N - 1)).key" > "${ROOT}/byron/address-00$((N - 1))" cardano-cli byron key signing-key-address \ --testnet-magic ${NETWORK_MAGIC} \ - --secret "${ROOT}/byron/genesis-keys.00$((${N} - 1)).key" > "${ROOT}/byron/genesis-address-00$((${N} - 1))" + --secret "${ROOT}/byron/genesis-keys.00$((N - 1)).key" > "${ROOT}/byron/genesis-address-00$((N - 1))" cardano-cli byron transaction issue-genesis-utxo-expenditure \ --genesis-json "${ROOT}/byron/genesis.json" \ --testnet-magic ${NETWORK_MAGIC} \ - --tx "${ROOT}/tx$((${N} - 1)).tx" \ - --wallet-key "${ROOT}/byron/delegate-keys.00$((${N} - 1)).key" \ - --rich-addr-from "$(head -n 1 "${ROOT}/byron/genesis-address-00$((${N} - 1))")" \ - --txout "(\"$(head -n 1 "${ROOT}/byron/address-00$((${N} - 1))")\", $FUNDS_PER_BYRON_ADDRESS)" + --tx "${ROOT}/tx$((N - 1)).tx" \ + --wallet-key "${ROOT}/byron/delegate-keys.00$((N - 1)).key" \ + --rich-addr-from "$(head -n 1 "${ROOT}/byron/genesis-address-00$((N - 1))")" \ + --txout "(\"$(head -n 1 "${ROOT}/byron/address-00$((N - 1))")\", $FUNDS_PER_BYRON_ADDRESS)" done # Update Proposal and votes @@ -267,9 +285,9 @@ for N in ${BFT_NODES_N}; do cardano-cli byron governance create-proposal-vote \ --proposal-filepath "${ROOT}/update-proposal" \ --testnet-magic ${NETWORK_MAGIC} \ - --signing-key "${ROOT}/byron/delegate-keys.00$((${N} - 1)).key" \ + --signing-key "${ROOT}/byron/delegate-keys.00$((N - 1)).key" \ --vote-yes \ - --output-filepath "${ROOT}/update-vote.00$((${N} - 1))" + --output-filepath "${ROOT}/update-vote.00$((N - 1))" done cardano-cli byron governance create-update-proposal \ @@ -288,9 +306,9 @@ for N in ${BFT_NODES_N}; do cardano-cli byron governance create-proposal-vote \ --proposal-filepath "${ROOT}/update-proposal-1" \ --testnet-magic ${NETWORK_MAGIC} \ - --signing-key "${ROOT}/byron/delegate-keys.00$((${N} - 1)).key" \ + --signing-key "${ROOT}/byron/delegate-keys.00$((N - 1)).key" \ --vote-yes \ - --output-filepath "${ROOT}/update-vote-1.00$((${N} - 1))" + --output-filepath "${ROOT}/update-vote-1.00$((N - 1))" done echo "=====================================================================" @@ -303,32 +321,27 @@ echo "=====================================================================" # Set up our template mkdir "${ROOT}/shelley" -# Copy the QA testnet alonzo and conway genesis files which is equivalent to the mainnet - -cp configuration/cardano/shelley_qa-alonzo-genesis.json "${ROOT}/shelley/genesis.alonzo.spec.json" -cp configuration/cardano/shelley_qa-conway-genesis.json "${ROOT}/shelley/genesis.conway.spec.json" - -cardano-cli genesis create --testnet-magic ${NETWORK_MAGIC} --genesis-dir "${ROOT}/shelley" +# Copy the alonzo and conway testnet template genesis files +cp configuration/cardano/testnet-template-alonzo.json "${ROOT}/shelley/genesis.alonzo.spec.json" +cp configuration/cardano/testnet-template-conway.json "${ROOT}/shelley/genesis.conway.spec.json" +cardano-cli shelley genesis create --testnet-magic ${NETWORK_MAGIC} --genesis-dir "${ROOT}/shelley" # Now generate for real: - -cardano-cli genesis create \ +cardano-cli shelley genesis create \ --testnet-magic ${NETWORK_MAGIC} \ --genesis-dir "${ROOT}/shelley/" \ --gen-genesis-keys ${NUM_BFT_NODES} \ --gen-utxo-keys 1 echo "What is in shelley" -echo "$(ls ${ROOT}/shelley)" +ls ${ROOT}/shelley cp "${ROOT}/shelley/genesis.json" "${ROOT}/shelley/copy-genesis.json" # We're going to use really quick epochs (300 seconds), by using short slots 0.2s # and K=10, but we'll keep long KES periods so we don't have to bother # cycling KES keys - - jq -M '. + { slotLength:0.1 , securityParam:10 @@ -352,7 +365,7 @@ jq --raw-output ' rm "${ROOT}/shelley/copy2-genesis.json" rm "${ROOT}/shelley/copy-genesis.json" -cardano-cli stake-address key-gen \ +cardano-cli shelley stake-address key-gen \ --verification-key-file "${ROOT}/shelley/utxo-keys/utxo-stake.vkey" \ --signing-key-file "${ROOT}/shelley/utxo-keys/utxo-stake.skey" @@ -360,22 +373,22 @@ cardano-cli address key-gen \ --verification-key-file "${ROOT}/shelley/utxo-keys/utxo2.vkey" \ --signing-key-file "${ROOT}/shelley/utxo-keys/utxo2.skey" -cardano-cli stake-address key-gen \ +cardano-cli shelley stake-address key-gen \ --verification-key-file "${ROOT}/shelley/utxo-keys/utxo2-stake.vkey" \ --signing-key-file "${ROOT}/shelley/utxo-keys/utxo2-stake.skey" # Create a symlink to all the payment keys in utxo-keys directory mkdir -p "${ROOT}/utxo-keys" -for x in $(find "${ROOT}/shelley/utxo-keys" -type f); do - if cat "$x" | jq -e 'select( +find "${ROOT}/shelley/utxo-keys" -type f | while IFS= read -r FILE; do + if jq -e 'select( false or .type == "GenesisUTxOVerificationKey_ed25519" or .type == "GenesisUTxOSigningKey_ed25519" or .type == "PaymentSigningKeyShelley_ed25519" or .type == "PaymentVerificationKeyShelley_ed25519" - )' > /dev/null; then - ln -sf "../$x" "${ROOT}/utxo-keys/$(basename "$x")" + )' < "$FILE" > /dev/null; then + ln -srf "$FILE" "${ROOT}/utxo-keys/$(basename "$FILE")" fi done @@ -393,7 +406,6 @@ echo "=====================================================================" # Make the pool operator cold keys # This was done already for the BFT nodes as part of the genesis creation - for NODE in ${POOL_NODES}; do cardano-cli node key-gen \ --cold-verification-key-file "${ROOT}/${NODE}/shelley/operator.vkey" \ @@ -406,18 +418,15 @@ for NODE in ${POOL_NODES}; do done # Symlink the BFT operator keys from the genesis delegates, for uniformity - for N in ${BFT_NODES_N}; do - ln -s ../../shelley/delegate-keys/delegate${N}.skey "${ROOT}/node-bft${N}/shelley/operator.skey" - ln -s ../../shelley/delegate-keys/delegate${N}.vkey "${ROOT}/node-bft${N}/shelley/operator.vkey" - ln -s ../../shelley/delegate-keys/delegate${N}.counter "${ROOT}/node-bft${N}/shelley/operator.counter" - ln -s ../../shelley/delegate-keys/delegate${N}.vrf.vkey "${ROOT}/node-bft${N}/shelley/vrf.vkey" - ln -s ../../shelley/delegate-keys/delegate${N}.vrf.skey "${ROOT}/node-bft${N}/shelley/vrf.skey" + ln -s "../../shelley/delegate-keys/delegate${N}.skey" "${ROOT}/node-bft${N}/shelley/operator.skey" + ln -s "../../shelley/delegate-keys/delegate${N}.vkey" "${ROOT}/node-bft${N}/shelley/operator.vkey" + ln -s "../../shelley/delegate-keys/delegate${N}.counter" "${ROOT}/node-bft${N}/shelley/operator.counter" + ln -s "../../shelley/delegate-keys/delegate${N}.vrf.vkey" "${ROOT}/node-bft${N}/shelley/vrf.vkey" + ln -s "../../shelley/delegate-keys/delegate${N}.vrf.skey" "${ROOT}/node-bft${N}/shelley/vrf.skey" done - # Make hot keys and for all nodes - for NODE in ${ALL_NODES}; do cardano-cli node key-gen-KES \ --verification-key-file "${ROOT}/${NODE}/shelley/kes.vkey" \ @@ -438,13 +447,11 @@ for NODE in ${ALL_NODES}; do done echo "=====================================================================" - # Make some payment and stake addresses # user1..n: will own all the funds in the system, we'll set this up from # initial utxo the # pool-owner1..n: will be the owner of the pools and we'll use their reward # account for pool rewards - USER_ADDRS="user1" POOL_ADDRS="pool-owner1" @@ -460,7 +467,7 @@ for ADDR in ${ADDRS}; do --signing-key-file "${ROOT}/addresses/${ADDR}.skey" # Stake address keys - cardano-cli stake-address key-gen \ + cardano-cli shelley stake-address key-gen \ --verification-key-file "${ROOT}/addresses/${ADDR}-stake.vkey" \ --signing-key-file "${ROOT}/addresses/${ADDR}-stake.skey" @@ -472,13 +479,13 @@ for ADDR in ${ADDRS}; do --out-file "${ROOT}/addresses/${ADDR}.addr" # Stake addresses - cardano-cli stake-address build \ + cardano-cli shelley stake-address build \ --stake-verification-key-file "${ROOT}/addresses/${ADDR}-stake.vkey" \ --testnet-magic ${NETWORK_MAGIC} \ --out-file "${ROOT}/addresses/${ADDR}-stake.addr" # Stake addresses registration certs - cardano-cli stake-address registration-certificate \ + cardano-cli shelley stake-address registration-certificate \ --stake-verification-key-file "${ROOT}/addresses/${ADDR}-stake.vkey" \ --out-file "${ROOT}/addresses/${ADDR}-stake.reg.cert" @@ -488,9 +495,8 @@ done USER_POOL_N="1" for N in ${USER_POOL_N}; do - # Stake address delegation certs - cardano-cli stake-address delegation-certificate \ + cardano-cli shelley stake-address stake-delegation-certificate \ --stake-verification-key-file "${ROOT}/addresses/user${N}-stake.vkey" \ --cold-verification-key-file "${ROOT}/node-pool${N}/shelley/operator.vkey" \ --out-file "${ROOT}/addresses/user${N}-stake.deleg.cert" @@ -506,12 +512,10 @@ echo ls -1 "${ROOT}/addresses/" echo "=====================================================================" - # Next is to make the stake pool registration cert - for NODE in ${POOL_NODES}; do - cardano-cli stake-pool registration-certificate \ + cardano-cli shelley stake-pool registration-certificate \ --testnet-magic ${NETWORK_MAGIC} \ --pool-pledge 0 --pool-cost 0 --pool-margin 0 \ --cold-verification-key-file "${ROOT}/${NODE}/shelley/operator.vkey" \ @@ -601,76 +605,85 @@ echo echo "Alternatively, you can run all the nodes in one go:" echo echo "$ROOT/run/all.sh" - +echo +echo "One option to ensure you are running with repo matched" +echo "cardano-cli and cardano-node versions is to enter a nix shell" +echo "before starting the nodes:" +echo " nix shell .#cardano-cli .#cardano-node" echo echo "In order to do the protocol updates, proceed as follows:" echo -echo " 0. invoke ./scripts/cardano/mkfiles.sh" -echo " 1. wait for the nodes to start producing blocks" -echo " 2. invoke ./scripts/cardano/update-1.sh " -echo " if you are early enough in the epoch N = current epoch" -echo " if not N = current epoch + 1. This applies for all update proposals" -echo " wait for the next epoch for the update to take effect" +echo " 0. Invoke ./scripts/byron-to-alonzo/mkfiles.sh and" +echo " start one or all nodes per above command examples." +echo +echo " 1. Wait for the nodes to start producing blocks." +echo +echo " 2. Invoke ./scripts/byron-to-alonzo/update-1.sh." +echo " Wait for the next epoch for the update to take effect." echo -echo " 3. invoke ./scripts/cardano/update-2.sh" -echo " 4. restart the nodes" -echo " wait for the next epoch for the update to take effect" -echo " you should be in the Shelley era if the update was successful" +echo " 3. Invoke ./scripts/byron-to-alonzo/update-2.sh." echo -echo " 5. invoke ./scripts/cardano/update-3.sh " +echo " 4. Restart the nodes." +echo " Wait for the next epoch for the update to take effect." +echo " You should be in the Shelley era if the update was successful." +echo +echo " 5. Invoke ./scripts/byron-to-alonzo/update-3.sh ." echo " Here, the current epoch (2 if you're quick)." echo " If you provide the wrong epoch, you will see an error" echo " that will tell you the current epoch, and can run" echo " the script again." -echo " 6. restart the nodes" -echo " wait for the next epoch for the update to take effect" -echo " you should be in the Allegra era if the update was successful" -echo " 7. invoke ./scripts/cardano/update-4.sh " -echo " 8. restart the nodes" -echo " wait for the next epoch for the update to take effect" -echo " you should be in the Mary era if the update was successful" -echo " 9. invoke ./scripts/cardano/update-5.sh " -echo " wait for the next epoch for the update to take effect" -echo " you should be in the Alonzo era if the update was successful" echo -echo "You can observe the status of the updates by grepping the logs, via" +echo " 6. Restart the nodes." +echo " Wait for the next epoch for the update to take effect." +echo " You should be in the Allegra era if the update was successful." echo -echo " grep LedgerUpdate ${ROOT}/node-pool1/node.log" +echo " 7. Invoke ./scripts/byron-to-alonzo/update-4.sh ." echo -echo "When in Shelley (after 3, and before 4), you should be able " -echo "to look at the protocol parameters, or the ledger state, " -echo "using commands like" +echo " 8. Restart the nodes." +echo " Wait for the next epoch for the update to take effect." +echo " You should be in the Mary era if the update was successful." echo -echo "CARDANO_NODE_SOCKET_PATH=${ROOT}/node-bft1/node.sock \\" -echo " cardano-cli query protocol-parameters \\" -echo " --cardano-mode --testnet-magic 42" +echo " a. Optionally, invoke ./scripts/byron-to-alonzo/mint.sh" +echo " and then ./scripts/byron-to-alonzo/burn.sh for a native token" +echo " minting and burning example in Mary." +echo +echo " 9. Invoke ./scripts/byron-to-alonzo/update-5.sh ." +echo " Wait for the next epoch for the update to take effect." +echo " You should be in the Alonzo era if the update was successful." +echo +echo "You can observe the status of the updates by grepping the logs, via" +echo +echo " grep LedgerUpdate ${ROOT}/node-pool1/node.log" echo -echo "This will fail outside of the Shelley era. In particular, " -echo "after step 3, you will get an error message that tells you " -echo "that you are in the Allegra era. You must then use the --allegra-era flag:" +echo "When in Shelley (after step 3), you should be able" +echo "to look at the protocol parameters, or the ledger state," +echo "using commands like:" echo echo "CARDANO_NODE_SOCKET_PATH=${ROOT}/node-bft1/node.sock \\" -echo " cardano-cli query protocol-parameters \\" -echo " --cardano-mode --allegra-era --testnet-magic 42" +echo " cardano-cli query protocol-parameters --testnet-magic 42" echo -echo "Similarly, use --mary-era in the Mary era." +echo "Occassionally on startup, the bft forgers in byron may encounter a" +echo "\"TraceNodeCannotForge\" error due to \"PBftCannotForgeThresholdExceeded\"" +echo "during the first several blocks. If this occurs, simply wipe state and retry." # For an automatic transition at epoch 0, specifying mary, allegra or shelley -# will start the node in the appropriate era. -echo "" +# as a cli arg will start the node in the appropriate era. +echo # These are needed for cardano-submit-api echo "EnableLogMetrics: False" >> "${ROOT}/configuration.yaml" echo "EnableLogging: True" >> "${ROOT}/configuration.yaml" -if [ "$1" = "babbage" ]; then - echo "TestShelleyHardForkAtEpoch: 0" >> "${ROOT}/configuration.yaml" - echo "TestAllegraHardForkAtEpoch: 0" >> "${ROOT}/configuration.yaml" - echo "TestMaryHardForkAtEpoch: 0" >> "${ROOT}/configuration.yaml" - echo "TestAlonzoHardForkAtEpoch: 0" >> "${ROOT}/configuration.yaml" - echo "TestBabbageHardForkAtEpoch: 0" >> "${ROOT}/configuration.yaml" - echo "ExperimentalHardForksEnabled: True" >> "${ROOT}/configuration.yaml" - echo "ExperimentalProtocolsEnabled: True" >> "${ROOT}/configuration.yaml" +if [ "${1:-}" = "babbage" ]; then + { + echo "TestShelleyHardForkAtEpoch: 0" + echo "TestAllegraHardForkAtEpoch: 0" + echo "TestMaryHardForkAtEpoch: 0" + echo "TestAlonzoHardForkAtEpoch: 0" + echo "TestBabbageHardForkAtEpoch: 0" + echo "ExperimentalHardForksEnabled: True" + echo "ExperimentalProtocolsEnabled: True" + } >> "${ROOT}/configuration.yaml" $SED -i "${ROOT}/configuration.yaml" \ -e 's/LastKnownBlockVersion-Major: 1/LastKnownBlockVersion-Major: 7/' @@ -678,13 +691,15 @@ if [ "$1" = "babbage" ]; then # Copy the cost model echo "Nodes will start in Alonzo era from epoch 0" -elif [ "$1" = "alonzo" ]; then - echo "TestShelleyHardForkAtEpoch: 0" >> "${ROOT}/configuration.yaml" - echo "TestAllegraHardForkAtEpoch: 0" >> "${ROOT}/configuration.yaml" - echo "TestMaryHardForkAtEpoch: 0" >> "${ROOT}/configuration.yaml" - echo "TestAlonzoHardForkAtEpoch: 0" >> "${ROOT}/configuration.yaml" - echo "ExperimentalHardForksEnabled: True" >> "${ROOT}/configuration.yaml" - echo "ExperimentalProtocolsEnabled: True" >> "${ROOT}/configuration.yaml" +elif [ "${1:-}" = "alonzo" ]; then + { + echo "TestShelleyHardForkAtEpoch: 0" + echo "TestAllegraHardForkAtEpoch: 0" + echo "TestMaryHardForkAtEpoch: 0" + echo "TestAlonzoHardForkAtEpoch: 0" + echo "ExperimentalHardForksEnabled: True" + echo "ExperimentalProtocolsEnabled: True" + } >> "${ROOT}/configuration.yaml" $SED -i "${ROOT}/configuration.yaml" \ -e 's/LastKnownBlockVersion-Major: 1/LastKnownBlockVersion-Major: 5/' @@ -692,23 +707,28 @@ elif [ "$1" = "alonzo" ]; then # Copy the cost model echo "Nodes will start in Alonzo era from epoch 0" -elif [ "$1" = "mary" ]; then - echo "TestShelleyHardForkAtEpoch: 0" >> "${ROOT}/configuration.yaml" - echo "TestAllegraHardForkAtEpoch: 0" >> "${ROOT}/configuration.yaml" - echo "TestMaryHardForkAtEpoch: 0" >> "${ROOT}/configuration.yaml" +elif [ "${1:-}" = "mary" ]; then + { + echo "TestShelleyHardForkAtEpoch: 0" + echo "TestAllegraHardForkAtEpoch: 0" + echo "TestMaryHardForkAtEpoch: 0" + } >> "${ROOT}/configuration.yaml" + $SED -i "${ROOT}/configuration.yaml" \ -e 's/LastKnownBlockVersion-Major: 1/LastKnownBlockVersion-Major: 4/' echo "Nodes will start in Mary era from epoch 0" -elif [ "$1" = "allegra" ]; then +elif [ "${1:-}" = "allegra" ]; then echo "TestShelleyHardForkAtEpoch: 0" >> "${ROOT}/configuration.yaml" echo "TestAllegraHardForkAtEpoch: 0" >> "${ROOT}/configuration.yaml" + $SED -i "${ROOT}/configuration.yaml" \ -e 's/LastKnownBlockVersion-Major: 1/LastKnownBlockVersion-Major: 3/' echo "Nodes will start in Allegra era from epoch 0" -elif [ "$1" = "shelley" ]; then +elif [ "${1:-}" = "shelley" ]; then echo "TestShelleyHardForkAtEpoch: 0" >> "${ROOT}/configuration.yaml" + $SED -i "${ROOT}/configuration.yaml" \ -e 's/LastKnownBlockVersion-Major: 1/LastKnownBlockVersion-Major: 2/' echo "Nodes will start in Shelley era from epoch 0" diff --git a/scripts/byron-to-alonzo/update-1.sh b/scripts/byron-to-alonzo/update-1.sh index 16dfaf58ccd..38742a177ca 100755 --- a/scripts/byron-to-alonzo/update-1.sh +++ b/scripts/byron-to-alonzo/update-1.sh @@ -1,38 +1,37 @@ #!/usr/bin/env bash +set -euo pipefail -set -e -# set -x - -# This script will +# This script will: # - move funds out of the Byron genesis address, so that we can use them later in Shelley # - initiate the transition to protocol version 1 (Byron, OBFT) +[ -n "${DEBUG:-}" ] && set -x + ROOT=example pushd ${ROOT} export CARDANO_NODE_SOCKET_PATH=node-bft1/node.sock +export CARDANO_NODE_NETWORK_ID=42 # move funds out of Byron genesis cardano-cli submit-tx \ - --testnet-magic 42 \ --tx tx0.tx + cardano-cli submit-tx \ - --testnet-magic 42 \ --tx tx1.tx # submit update proposal cardano-cli byron submit-update-proposal \ - --testnet-magic 42 \ --filepath update-proposal + sleep 2 # vote on proposal cardano-cli byron submit-proposal-vote \ - --testnet-magic 42 \ --filepath update-vote.000 + cardano-cli byron submit-proposal-vote \ - --testnet-magic 42 \ --filepath update-vote.001 popd diff --git a/scripts/byron-to-alonzo/update-2.sh b/scripts/byron-to-alonzo/update-2.sh index 4771b5e807f..d468a429f72 100755 --- a/scripts/byron-to-alonzo/update-2.sh +++ b/scripts/byron-to-alonzo/update-2.sh @@ -1,7 +1,5 @@ #!/usr/bin/env bash - -set -e -# set -x +set -euo pipefail # This script will initiate the transition to protocol version 2 (Shelley). @@ -10,22 +8,24 @@ set -e # Also, you need to restart the nodes after running this script in order for the # update to be endorsed by the nodes. +[ -n "${DEBUG:-}" ] && set -x + ROOT=example pushd ${ROOT} export CARDANO_NODE_SOCKET_PATH=node-bft1/node.sock +export CARDANO_NODE_NETWORK_ID=42 cardano-cli byron submit-update-proposal \ - --testnet-magic 42 \ --filepath update-proposal-1 sleep 2 + cardano-cli byron submit-proposal-vote \ - --testnet-magic 42 \ --filepath update-vote-1.000 + cardano-cli byron submit-proposal-vote \ - --testnet-magic 42 \ --filepath update-vote-1.001 sed -i configuration.yaml \ diff --git a/scripts/byron-to-alonzo/update-3.sh b/scripts/byron-to-alonzo/update-3.sh index 5c29b896ebe..8c9e0e5ef64 100755 --- a/scripts/byron-to-alonzo/update-3.sh +++ b/scripts/byron-to-alonzo/update-3.sh @@ -1,7 +1,5 @@ #!/usr/bin/env bash - -set -e -# set -x +set -euo pipefail # This script will initiate the transition to protocol version 3 (Allegra). @@ -16,24 +14,27 @@ set -e # Also, you need to restart the nodes after running this script in order for the # update to be endorsed by the nodes. -if [ ! "$1" ]; then echo "update-3.sh: expects an epoch argument"; exit; fi +[ -n "${DEBUG:-}" ] && set -x + +[ ! "${1:-}" ] && { echo "update-3.sh: expects an epoch argument"; exit; } EPOCH=$1 VERSION=3 ROOT=example -COINS_IN_INPUT=1000000000 +SPLIT_OUTPUT_ALLOC=1000000000 pushd ${ROOT} export CARDANO_NODE_SOCKET_PATH=node-bft1/node.sock +export CARDANO_NODE_NETWORK_ID=42 TXID0=$(cardano-cli byron transaction txid --tx tx0.tx) TXID1=$(cardano-cli byron transaction txid --tx tx1.tx) -cardano-cli governance create-update-proposal \ +cardano-cli shelley governance action create-protocol-parameters-update \ --out-file update-proposal-allegra \ - --epoch ${EPOCH} \ + --epoch "${EPOCH}" \ --genesis-verification-key-file shelley/genesis-keys/genesis1.vkey \ --genesis-verification-key-file shelley/genesis-keys/genesis2.vkey \ --protocol-major-version ${VERSION} \ @@ -60,15 +61,31 @@ cardano-cli key convert-byron-key \ # 4. delegate from the user1 stake address to the stake pool # We'll include the update proposal -cardano-cli transaction build-raw \ - --shelley-era \ +# Obtain the input lovelace dynamically to reduce change calc complexity +TOTAL_INPUT_LOVELACE=$( + cardano-cli query utxo --whole-utxo --output-json \ + | jq -er '[to_entries[] | select(.value.value | length == 1) | .value.value.lovelace] | add') + +# Slight over-estimate on the fee +FEE=300000 +STAKE_KEY_DEPOSIT=400000 +STAKEPOOL_DEPOSIT=0 +CHANGE=$(( + + TOTAL_INPUT_LOVELACE + - SPLIT_OUTPUT_ALLOC + - STAKEPOOL_DEPOSIT + - 2 * STAKE_KEY_DEPOSIT + - FEE +)) + +cardano-cli shelley transaction build-raw \ --invalid-hereafter 100000 \ - --fee 231501 \ - --tx-in ${TXID0}#0\ - --tx-in ${TXID1}#0\ - --tx-out $(cat addresses/user1.addr)+$((${COINS_IN_INPUT} / 2)) \ - --tx-out $(cat addresses/user1.addr)+$((${COINS_IN_INPUT} / 2)) \ - --tx-out $(cat addresses/user1.addr)+9017768499 \ + --fee "$FEE" \ + --tx-in "${TXID0}#0" \ + --tx-in "${TXID1}#0" \ + --tx-out "$(cat addresses/user1.addr)+$((SPLIT_OUTPUT_ALLOC / 2))" \ + --tx-out "$(cat addresses/user1.addr)+$((SPLIT_OUTPUT_ALLOC / 2))" \ + --tx-out "$(cat addresses/user1.addr)+$CHANGE" \ --certificate-file addresses/pool-owner1-stake.reg.cert \ --certificate-file node-pool1/registration.cert \ --certificate-file addresses/user1-stake.reg.cert \ @@ -83,7 +100,7 @@ cardano-cli transaction build-raw \ # 4. the pool1 operator key, due to the pool registration cert # 5. the genesis delegate keys, due to the update proposal -cardano-cli transaction sign \ +cardano-cli shelley transaction sign \ --signing-key-file shelley/utxo-keys/utxo1.skey \ --signing-key-file addresses/user1-stake.skey \ --signing-key-file node-pool1/owner.skey \ @@ -94,17 +111,15 @@ cardano-cli transaction sign \ --signing-key-file shelley/delegate-keys/delegate2.skey \ --signing-key-file byron/payment-keys.000-converted.key \ --signing-key-file byron/payment-keys.001-converted.key \ - --testnet-magic 42 \ --tx-body-file tx2.txbody \ --out-file tx2.tx -cardano-cli transaction submit --tx-file tx2.tx --testnet-magic 42 +cardano-cli shelley transaction submit --tx-file tx2.tx sed -i configuration.yaml \ -e 's/LastKnownBlockVersion-Major: 2/LastKnownBlockVersion-Major: 3/' \ - popd echo "Restart the nodes now to endorse the update." diff --git a/scripts/byron-to-alonzo/update-4.sh b/scripts/byron-to-alonzo/update-4.sh index 17fab553861..ef17a188bca 100755 --- a/scripts/byron-to-alonzo/update-4.sh +++ b/scripts/byron-to-alonzo/update-4.sh @@ -1,12 +1,10 @@ #!/usr/bin/env bash - -set -e -# set -x +set -euo pipefail # This script will initiate the transition to protocol version 4 (Mary). # You need to provide the current epoch as a positional argument (the Shelley -# update system requires this to be includded in the update proposal). +# update system requires this to be included in the update proposal). # In order for this to be successful, you need to already be in protocol version @@ -14,63 +12,76 @@ set -e # Also, you need to restart the nodes after running this script in order for the # update to be endorsed by the nodes. -if [ ! "$1" ]; then echo "update-4.sh: expects an epoch argument"; exit; fi +[ -n "${DEBUG:-}" ] && set -x + +[ ! "${1:-}" ] && { echo "update-4.sh: expects an epoch argument"; exit; } EPOCH=$1 VERSION=4 ROOT=example -COINS_IN_INPUT=1000000000 +SPLIT_OUTPUT_ALLOC=1000000000 pushd ${ROOT} export CARDANO_NODE_SOCKET_PATH=node-bft1/node.sock +export CARDANO_NODE_NETWORK_ID=42 -TXID2=$(cardano-cli transaction txid --tx-file tx2.tx) +TXID2=$(cardano-cli allegra transaction txid --tx-file tx2.tx) # Create the update proposal to change the protocol version to 4 -cardano-cli governance create-update-proposal \ +cardano-cli allegra governance action create-protocol-parameters-update \ --out-file update-proposal-mary \ - --epoch ${EPOCH} \ + --epoch "${EPOCH}" \ --genesis-verification-key-file shelley/genesis-keys/genesis1.vkey \ --genesis-verification-key-file shelley/genesis-keys/genesis2.vkey \ - --protocol-major-version ${VERSION} \ + --protocol-major-version "${VERSION}" \ --protocol-minor-version 0 # Create a transaction body containing the update proposal. -cardano-cli transaction build-raw \ - --allegra-era \ - --fee 186181 \ - --tx-in $TXID2#0\ - --tx-in $TXID2#1\ - --tx-in $TXID2#2\ - --tx-out $(cat addresses/user1.addr)+$((${COINS_IN_INPUT} / 2)) \ - --tx-out $(cat addresses/user1.addr)+$((${COINS_IN_INPUT} / 2)) \ - --tx-out $(cat addresses/user1.addr)+9017582318 \ +# Obtain the input lovelace dynamically to reduce change calc complexity +TOTAL_INPUT_LOVELACE=$( + cardano-cli query utxo --whole-utxo --output-json \ + | jq -er '[to_entries[] | select(.value.value | length == 1) | .value.value.lovelace] | add') + +# Slight over-estimate on the fee +FEE=200000 +CHANGE=$(( + + TOTAL_INPUT_LOVELACE + - SPLIT_OUTPUT_ALLOC + - FEE +)) + +cardano-cli allegra transaction build-raw \ + --fee "$FEE" \ + --tx-in "$TXID2#0" \ + --tx-in "$TXID2#1" \ + --tx-in "$TXID2#2" \ + --tx-out "$(cat addresses/user1.addr)+$((SPLIT_OUTPUT_ALLOC / 2))" \ + --tx-out "$(cat addresses/user1.addr)+$((SPLIT_OUTPUT_ALLOC / 2))" \ + --tx-out "$(cat addresses/user1.addr)+$CHANGE" \ --update-proposal-file update-proposal-mary \ --out-file tx3.txbody # Sign the transaction body with the two genesis delegate keys, # and the the uxto spending key. -cardano-cli transaction sign \ +cardano-cli allegra transaction sign \ --signing-key-file addresses/user1.skey \ --signing-key-file shelley/delegate-keys/delegate1.skey \ --signing-key-file shelley/delegate-keys/delegate2.skey \ - --testnet-magic 42 \ --tx-body-file tx3.txbody \ --out-file tx3.tx -cardano-cli transaction submit --tx-file tx3.tx --testnet-magic 42 +cardano-cli allegra transaction submit --tx-file tx3.tx sed -i configuration.yaml \ -e 's/LastKnownBlockVersion-Major: 3/LastKnownBlockVersion-Major: 4/' \ - popd echo "Restart the nodes now to endorse the update." diff --git a/scripts/byron-to-alonzo/update-5.sh b/scripts/byron-to-alonzo/update-5.sh index b7a9690c16a..ed86e7430a0 100755 --- a/scripts/byron-to-alonzo/update-5.sh +++ b/scripts/byron-to-alonzo/update-5.sh @@ -1,7 +1,5 @@ #!/usr/bin/env bash - -set -e -# set -x +set -euo pipefail # This script will initiate the transition to protocol version 5 (Alonzo). @@ -14,64 +12,76 @@ set -e # Also, you need to restart the nodes after running this script in order for the # update to be endorsed by the nodes. -if [ ! "$1" ]; then echo "update-5.sh: expects an epoch argument"; exit; fi +[ -n "${DEBUG:-}" ] && set -x + +[ ! "${1:-}" ] && { echo "update-5.sh: expects an epoch argument"; exit; } EPOCH=$1 VERSION=5 ROOT=example -COINS_IN_INPUT=1000000000 +SPLIT_OUTPUT_ALLOC=1000000000 pushd ${ROOT} export CARDANO_NODE_SOCKET_PATH=node-pool1/node.sock +export CARDANO_NODE_NETWORK_ID=42 -TXID2=$(cardano-cli transaction txid --tx-file tx3.tx) +TXID3=$(cardano-cli mary transaction txid --tx-file tx3.tx) # Create the update proposal to change the protocol version to 5 -cardano-cli governance create-update-proposal \ +cardano-cli mary governance action create-protocol-parameters-update \ --out-file update-proposal-alonzo \ - --epoch ${EPOCH} \ + --epoch "${EPOCH}" \ --genesis-verification-key-file shelley/genesis-keys/genesis1.vkey \ --genesis-verification-key-file shelley/genesis-keys/genesis2.vkey \ - --protocol-major-version ${VERSION} \ + --protocol-major-version "${VERSION}" \ --protocol-minor-version 0 # Create a transaction body containing the update proposal. -cardano-cli transaction build-raw \ - --mary-era \ - --fee 186181 \ - --tx-in $TXID2#0\ - --tx-in $TXID2#1\ - --tx-in $TXID2#2\ - --tx-out $(cat addresses/user1.addr)+$((${COINS_IN_INPUT} / 2)) \ - --tx-out $(cat addresses/user1.addr)+$((${COINS_IN_INPUT} / 2)) \ - --tx-out $(cat addresses/user1.addr)+9017396137 \ +# Obtain the input lovelace dynamically to reduce change calc complexity +TOTAL_INPUT_LOVELACE=$( + cardano-cli query utxo --whole-utxo --output-json \ + | jq -er '[to_entries[] | select(.value.value | length == 1) | .value.value.lovelace] | add') + +# Slight over-estimate on the fee +FEE=200000 +CHANGE=$(( + + TOTAL_INPUT_LOVELACE + - SPLIT_OUTPUT_ALLOC + - FEE +)) + +cardano-cli mary transaction build-raw \ + --fee "$FEE" \ + --tx-in "$TXID3#0" \ + --tx-in "$TXID3#1" \ + --tx-in "$TXID3#2" \ + --tx-out "$(cat addresses/user1.addr)+$((SPLIT_OUTPUT_ALLOC / 2))" \ + --tx-out "$(cat addresses/user1.addr)+$((SPLIT_OUTPUT_ALLOC / 2))" \ + --tx-out "$(cat addresses/user1.addr)+$CHANGE" \ --update-proposal-file update-proposal-alonzo \ --out-file tx4.txbody # Sign the transaction body with the two genesis delegate keys, # and the the uxto spending key. -cardano-cli transaction sign \ +cardano-cli mary transaction sign \ --signing-key-file addresses/user1.skey \ --signing-key-file shelley/delegate-keys/delegate1.skey \ --signing-key-file shelley/delegate-keys/delegate2.skey \ - --testnet-magic 42 \ --tx-body-file tx4.txbody \ --out-file tx4.tx -cardano-cli transaction submit --tx-file tx4.tx --testnet-magic 42 +cardano-cli mary transaction submit --tx-file tx4.tx sed -i configuration.yaml \ -e 's/LastKnownBlockVersion-Major: 4/LastKnownBlockVersion-Major: 5/' \ - popd echo "Restart the nodes now to endorse the update." -