main.rs
Overview
This file implements the command-line interface (CLI) entry point for managing and configuring an AckiNacki node. It provides subcommands for setting up node configurations, generating BLS (Boneh–Lynn–Shacham) key pairs, and producing cryptographic keys compatible with the TVM client. The CLI parses arguments, loads or creates node configurations, manages cryptographic keys, and persists configurations or keys to files. The file extensively interacts with the node's configuration system, cryptographic libraries, and networking utilities.
Command-Line Argument Parsing
The CLI uses the clap crate to define argument parsing structures:
Args Struct
Root parser holding the main subcommand under
Commands.Fields:
command: Commands- The subcommand to execute.
Commands Enum
Defines the available subcommands:
Config(Config) - Manage node configuration files.
Bls(Bls)- Generate BLS key pairs.GenKeys(GenKeys)- Generate cryptographic keys for the TVM client.
Config Struct
Contains numerous options for configuring node parameters, network settings, keys, and blockchain-related files.
Key fields:
config_file_path: PathBuf(required) - Path to the node config file.Flags for creating default configs, specifying node IDs, blockchain config paths, key paths, network addresses, gossip settings, API settings, TLS certificates, thread load parameters, and more.
Several fields accept environment variables or comma-separated values.
Uses custom parsers for socket addresses (parse_node_addr, parse_gossip_addr) and durations (parse_duration::parse).
Bls Struct
Options for generating BLS key pairs:
path: Option<PathBuf>- File path to store keys.remove_old: bool- Flag to remove old keys before generating new ones.quiet: bool- Suppress public key printing.
GenKeys Struct
Option for generating random signing keys for the TVM client:
path: Option<PathBuf>- Optional output file path.
Functions and Methods
fn main() -> anyhow::Result<()>
Parses CLI arguments.
Dispatches subcommands:
ConfigSubcommand WorkflowLoads existing node config from file using load_config_from_file.
If the file is invalid or missing and
--defaultis set, a default configuration is created using provided parameters (e.g., node_id, chitchat_cluster_id).Updates configuration fields based on CLI options, including network addresses, keys, gossip seeds, API endpoints, TLS certificates, thread load parameters, and blockchain contract hashes.
Reads the BlockKeeper epoch and pre-epoch contract code hashes from default files if not provided.
Saves the final config back to the file via save_config_to_file.
BlsSubcommand WorkflowGenerates a new BLS key pair using gosh_blst::gen_bls_key_pair.
Converts to BLSKeyPair and RNG seed from secret key bytes.
If a path is specified:
Optionally prints the public key in JSON format unless
quietis set.Loads existing keys from file unless
remove_oldis true, in which case the file is deleted.Inserts the new key pair into a HashMap keyed by public key.
Saves the updated keys map back to file via
save_keys_map_to_file.
Otherwise, prints the key pair to stdout.
GenKeysSubcommand WorkflowCreates a TVM client context.
Generates a random signing key pair using tvm_client::crypto::generate_random_sign_keys.
Serializes the key pair to JSON.
Writes keys to file if a path is provided, else prints to stdout.
fn save_keys_map_to_file(path: PathBuf, keys_map: HashMap<PubKey, (Secret, RndSeed)>) -> anyhow::Result<()>
Saves a map of BLS public keys to their corresponding secret keys and random seeds.
Serializes each key tuple into a JSON object with fields:
"public": hex-encoded public key bytes."secret": hex-encoded secret seed."rnd": hex-encoded random seed bytes.
Writes the JSON array to the specified file path.
fn parse_node_addr(s: &str) -> Result<SocketAddr, String>
Parses a string into a
SocketAddrwith a default port of8500.Delegates to try_parse_socket_addr with the default port.
fn parse_gossip_addr(s: &str) -> Result<SocketAddr, String>
Parses a string into a
SocketAddrwith a default port of10000.Delegates to try_parse_socket_addr with the default port.
Important Implementation Details
The configuration loading logic supports fallback to default configurations if the config file is missing or invalid, enforcing required fields for default creation.
The system supports flexible configuration via command-line, environment variables, and files.
BLS key management supports appending or overwriting existing keys.
Uses serde JSON serialization for configuration and key storage.
The CLI exits with specific error codes for missing mandatory fields when creating a default config.
Network addresses are parsed with defaults to simplify user input.
The file paths for contract code hashes are constants and used for default configuration when not overridden.
The cryptographic key generation uses external crates and libraries like gosh_blst and tvm_client.
Interactions with other System Components
Node Configuration Modules: Loads and saves node config structs (GlobalConfig, NetworkConfig, NodeConfig) from node::config.
Network Utilities: Parses and validates socket addresses using
networkcrate functions.BLS Cryptography: Utilizes gosh_blst crate for BLS key pair generation and key handling types (PubKey, Secret,
GoshBLS).TVM Client: Uses tvm_client for generating signing keys and client context management.
File I/O: Reads and writes JSON config and key files to disk.
Command-Line Parsing:
clapcrate is used to parse CLI arguments and subcommands to configure node or generate keys.
Usage Examples
Generate BLS Key Pair with File Output and Remove Old Keys
ackinacki bls --path ./bls_keys.json --remove_old
This generates a new BLS key pair, removes the old key file if it exists, and appends the new key pair to the file.
Create or Update Node Configuration
ackinacki config --config-file-path ./node_config.json --default --node-id <64-char-hex> --chitchat-cluster-id mycluster --node-advertise-addr 192.168.1.2:8500 --api-addr 127.0.0.1:5000 --api-advertise-addr http://localhost:5000
Creates a default configuration if none exists, setting the required fields for node ID and network addresses.
Generate TVM Signing Keys and Print to Stdout
ackinacki genkeys
Generates a random TVM signing key pair and prints the JSON representation to the console.
Visual Diagram
flowchart TD
A["main()"] --> B{Commands}
B --> C[Config]
B --> D[Bls]
B --> E[GenKeys]
C --> F[Load config file]
F --> G{File valid?}
G -- Yes --> H[Update config with CLI params]
G -- No & default flag --> I[Create default config]
I --> H
H --> J[Save config to file]
D --> K[Generate BLS key pair]
K --> L{Has path?}
L -- Yes --> M{Remove old file?}
M -- Yes --> N[Delete old file]
M -- No --> O[Load existing keys]
O --> P[Insert new key]
N --> P
P --> Q[Save keys map to file]
L -- No --> R[Print key pair]
E --> S[Create TVM Client]
S --> T[Generate random signing keys]
T --> U{Has path?}
U -- Yes --> V[Write keys to file]
U -- No --> W[Print keys JSON]
References
For detailed configuration options and node setup, see Node Configuration.
For cryptographic key handling and BLS keys, refer to BLS Cryptography.
For networking address parsing and gossip configuration, see Network Configuration.
For TVM client key generation and context handling, see TVM Client.