|
5 | 5 | import argparse |
6 | 6 | import sys |
7 | 7 |
|
8 | | -from adaup.commands.cardano_cli import CardanoCLI |
| 8 | +from adaup.commands.cardano_cli import CardanoCLI, WalletStore |
9 | 9 | from adaup.download.hydra import ( |
10 | | - generate_protocol_parameters, |
11 | | - create_hydra_credentials, |
12 | 10 | fetch_network_json, |
13 | | - download_and_setup_hydra, |
14 | | - generate_and_save_hydra_run_script |
| 11 | + download_and_setup_hydra |
15 | 12 | ) |
16 | | -from adaup.download.exec import exec |
| 13 | +from adaup.download.exec import executor, exec |
17 | 14 |
|
18 | 15 | HOME = os.environ.get("HOME", "/root") |
19 | 16 | HYDRA_VERSION="0.22.4" |
20 | 17 |
|
| 18 | +def create_hydra_credentials(cli:CardanoCLI,credentials_dir): |
| 19 | + """ |
| 20 | + Create the necessary credentials for a Hydra node. |
| 21 | +
|
| 22 | + Args: |
| 23 | + credentials_dir (str): The directory where the credentials will be stored. |
| 24 | + """ |
| 25 | + print(f"Creating hydra credentials in {credentials_dir}...") |
| 26 | + |
| 27 | + cardano_home = os.environ.get("CARDANO_HOME", os.path.expanduser("~/.cardano")) |
| 28 | + cardano_cli_path = os.path.join(cardano_home, "bin", "cardano-cli") |
| 29 | + |
| 30 | + if not os.path.isfile(cardano_cli_path) or not os.access(cardano_cli_path, os.X_OK): |
| 31 | + print(f"Error: cardano-cli executable not found at {cardano_cli_path}") |
| 32 | + sys.exit(1) |
| 33 | + |
| 34 | + store = WalletStore(credentials_dir) |
| 35 | + if store.gen_enterprise_wallet(cli,"node",skip_if_present=True) ==False: |
| 36 | + print("[Hydra] Node keys are already present") |
| 37 | + |
| 38 | + if store.gen_enterprise_wallet(cli,"funds",skip_if_present=True) == False: |
| 39 | + print("[Hydra] funds keys are already present") |
| 40 | + |
| 41 | + hydr_output_file=os.path.join(credentials_dir, "hydra") |
| 42 | + files=[hydr_output_file+".sk",hydr_output_file+".vk"] |
| 43 | + |
| 44 | + present =False |
| 45 | + for file in files: |
| 46 | + if os.path.isfile(file) and os.access(file, os.X_OK): |
| 47 | + present=True |
| 48 | + if present: |
| 49 | + print("[Hydra] Node keys are already present") |
| 50 | + return |
| 51 | + |
| 52 | + hydra_node_path = os.path.join(cardano_home, "bin", "hydra-node") |
| 53 | + if not os.path.isfile(hydra_node_path) or not os.access(hydra_node_path, os.X_OK): |
| 54 | + print(f"Error: hydra-node executable not found at {hydra_node_path}") |
| 55 | + sys.exit(1) |
| 56 | + |
| 57 | + executor([ |
| 58 | + hydra_node_path, "gen-hydra-key", |
| 59 | + "--output-file", hydr_output_file |
| 60 | + ], show_command=True, throw_error=True) |
| 61 | + print("Hydra credentials created successfully.") |
| 62 | + |
| 63 | +def generate_protocol_parameters(cli:CardanoCLI,filePath:str): |
| 64 | + """ |
| 65 | + Generate protocol parameters for the hydra node. |
| 66 | +
|
| 67 | + Args: |
| 68 | + node_bin_dir (str): The directory where cardano-cli is located. |
| 69 | +
|
| 70 | + Returns: |
| 71 | + str: Path to the generated protocol parameters file. |
| 72 | + """ |
| 73 | + print("Generating ledger protocol parameters...") |
| 74 | + |
| 75 | + result = cli.cardano_cli("query","protocol-parameters",[],include_network=True,include_socket=True) |
| 76 | + params = json.loads(result) |
| 77 | + |
| 78 | + params['txFeeFixed'] = 0 |
| 79 | + params['txFeePerByte'] = 0 |
| 80 | + params['executionUnitPrices']['priceMemory'] = 0 |
| 81 | + params['executionUnitPrices']['priceSteps'] = 0 |
| 82 | + |
| 83 | + with open(filePath, 'w') as f: |
| 84 | + json.dump(params, f, indent=2) |
| 85 | + return filePath |
| 86 | + |
| 87 | +def generate_and_save_hydra_run_script( |
| 88 | + node_index: int, |
| 89 | + network: str, |
| 90 | + cardano_home: str, |
| 91 | + node_bin_dir: str, |
| 92 | + tx_id: str, |
| 93 | + testnet_magic: int, |
| 94 | + hydra_node_path: str, |
| 95 | + node_configs: list = None |
| 96 | + ): |
| 97 | + """ |
| 98 | + Generates the run.sh script for a specific Hydra node. |
| 99 | +
|
| 100 | + Args: |
| 101 | + node_index (int): The index of the current hydra node. |
| 102 | + network (str): The Cardano network. |
| 103 | + cardano_home (str): Path to the .cardano home directory. |
| 104 | + node_bin_dir (str): Path to the directory containing hydra-node executable. |
| 105 | + tx_id (str): Hydra scripts transaction ID. |
| 106 | + testnet_magic (int): Testnet magic number. |
| 107 | + hydra_node_path (str): Path to the hydra-node executable. |
| 108 | + node_configs (list): A list of dictionaries, where each dictionary contains |
| 109 | + configuration details (including paths to verification keys) |
| 110 | + for all hydra nodes in the network. Used for peer discovery. |
| 111 | + """ |
| 112 | + print(f"Generating run.sh script for hydra node {node_index} on network {network}...") |
| 113 | + |
| 114 | + hydra_dir = os.path.join(cardano_home, network, f"hydra-{node_index}") |
| 115 | + credentials_dir = os.path.join(hydra_dir, "credentials") |
| 116 | + data_dir = os.path.join(hydra_dir, "data") |
| 117 | + |
| 118 | + os.makedirs(credentials_dir, exist_ok=True) |
| 119 | + os.makedirs(data_dir, exist_ok=True) |
| 120 | + |
| 121 | + cardano_signing_key = os.path.join(credentials_dir, "node.sk") |
| 122 | + hydra_signing_key = os.path.join(credentials_dir, "hydra.sk") |
| 123 | + protocol_params_path = os.path.join(credentials_dir, "protocol-params.json") |
| 124 | + |
| 125 | + if not os.path.exists(cardano_signing_key): |
| 126 | + print(f"Error: Cardano signing key not found at {cardano_signing_key}") |
| 127 | + return False |
| 128 | + if not os.path.exists(hydra_signing_key): |
| 129 | + print(f"Error: Hydra signing key not found at {hydra_signing_key}") |
| 130 | + return False |
| 131 | + if not os.path.exists(protocol_params_path): |
| 132 | + print(f"Error: Protocol parameters not found at {protocol_params_path}") |
| 133 | + return False |
| 134 | + |
| 135 | + run_command = [ |
| 136 | + hydra_node_path, |
| 137 | + "--node-id", f"node-{network}-{node_index}", |
| 138 | + "--persistence-dir", data_dir, |
| 139 | + "--cardano-signing-key", cardano_signing_key, |
| 140 | + "--hydra-signing-key", hydra_signing_key, |
| 141 | + "--hydra-scripts-tx-id", tx_id, |
| 142 | + "--ledger-protocol-parameters", protocol_params_path, |
| 143 | + "--testnet-magic", str(testnet_magic), |
| 144 | + "--node-socket", os.path.join(cardano_home, network, "node.socket"), |
| 145 | + "--api-port", str(4001 + node_index), |
| 146 | + "--listen", f"127.0.0.1:{5001 + node_index}", |
| 147 | + "--api-host", "0.0.0.0", |
| 148 | + ] |
| 149 | + |
| 150 | + peers = [] |
| 151 | + if node_configs: |
| 152 | + for other_config in node_configs: |
| 153 | + if other_config['index'] != node_index: |
| 154 | + peer_vk_path = other_config['cardano_verification_key'] |
| 155 | + hydra_vk_path = other_config['hydra_verification_key'] |
| 156 | + if os.path.exists(peer_vk_path) and os.path.exists(hydra_vk_path): |
| 157 | + peers.append(f"--peer=127.0.0.1:{5001 + other_config['index']}") |
| 158 | + peers.append(f"--cardano-verification-key={peer_vk_path}") |
| 159 | + peers.append(f"--hydra-verification-key={hydra_vk_path}") |
| 160 | + else: |
| 161 | + print(f"Warning: Missing keys for potential peer {other_config['index']}. Skipping peer configuration for node {node_index}.") |
| 162 | + run_command.extend(peers) |
| 163 | + |
| 164 | + formatted_command_parts = [] |
| 165 | + cmd_idx = 1 |
| 166 | + while cmd_idx < len(run_command): |
| 167 | + part = str(run_command[cmd_idx]) |
| 168 | + if part.startswith("--"): |
| 169 | + if cmd_idx + 1 < len(run_command) and not str(run_command[cmd_idx+1]).startswith("--"): |
| 170 | + formatted_command_parts.append(f" {part} {str(run_command[cmd_idx+1])}") |
| 171 | + cmd_idx += 2 |
| 172 | + else: |
| 173 | + formatted_command_parts.append(f" {part}") |
| 174 | + cmd_idx += 1 |
| 175 | + else: |
| 176 | + formatted_command_parts.append(f" {part}") |
| 177 | + cmd_idx += 1 |
| 178 | + |
| 179 | + run_script_content = f"#!/bin/bash\n\n{run_command[0]}" |
| 180 | + if len(formatted_command_parts) > 0: |
| 181 | + run_script_content += " \\\n" + " \\\n".join(formatted_command_parts) |
| 182 | + run_script_content += "\n" |
| 183 | + |
| 184 | + run_script_path = os.path.join(hydra_dir, "run.sh") |
| 185 | + |
| 186 | + with open(run_script_path, 'w') as f: |
| 187 | + f.write(run_script_content) |
| 188 | + os.chmod(run_script_path, 0o755) |
| 189 | + |
| 190 | + print(f"Created run.sh for node {node_index} at {run_script_path}") |
| 191 | + return True |
| 192 | + |
21 | 193 | def reset_hydra_data(args): |
22 | 194 | """ |
23 | 195 | Deletes all contents of hydra-{n}/data/** and re-queries protocol parameters. |
|
0 commit comments