Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 76 additions & 37 deletions scripts/gen_shadow_yaml.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
# -x QLEAN_PATH Path to qlean executable (default: <repo_root>/build/src/executable/qlean)
# -m MODULES_DIR Path to modules dir (default: <repo_root>/build/src/modules)
# -r PROJECT_ROOT Project root to use for defaults (default: parent dir of this script)
# -G GRAPH_FILE Path to GML graph file (default: atlas_v201801.shadow_v2.gml.xz)
# -b MAX_BOOTNODES Max bootnodes to pass to each node (short for --max-bootnodes)
# --use-inline-graph Use inline graph instead of external GML file (default: use external graph)
# --max-bootnodes Max bootnodes to pass to each node (supported: --max-bootnodes=5 or --max-bootnodes 5)
#
# Notes:
# - Node count is inferred from node_*.key files in GENESIS_DIR.
Expand Down Expand Up @@ -40,14 +44,17 @@ MODULES_DIR_DEFAULT="$PROJECT_ROOT/build/src/modules"
QLEAN_PATH="$QLEAN_PATH_DEFAULT"
MODULES_DIR="$MODULES_DIR_DEFAULT"
GENESIS_DIR=""
GRAPH_FILE="atlas_v201801.shadow_v2.gml.xz"
USE_INLINE_GRAPH=false
MAX_BOOTNODES=""

# Network/graph defaults (host/switched bandwidth, latency, packet loss)
BANDWIDTH_HOST="100 Mbit"
BANDWIDTH_SWITCH="1 Gbit"
LINK_LATENCY="1 ms"
PACKET_LOSS="0.0"

while getopts ":g:o:t:u:p:i:x:m:r:h" opt; do
while getopts ":g:o:t:u:p:i:x:m:r:G:b:h-:" opt; do
case $opt in
g) GENESIS_DIR="$OPTARG" ;;
o) OUTPUT_YAML="$OPTARG" ;;
Expand All @@ -58,7 +65,20 @@ while getopts ":g:o:t:u:p:i:x:m:r:h" opt; do
x) QLEAN_PATH="$OPTARG" ;;
m) MODULES_DIR="$OPTARG" ;;
r) PROJECT_ROOT="$OPTARG" ; QLEAN_PATH_DEFAULT="$PROJECT_ROOT/build/src/executable/qlean"; MODULES_DIR_DEFAULT="$PROJECT_ROOT/build/src/modules" ;;
G) GRAPH_FILE="$OPTARG" ;;
b) MAX_BOOTNODES="$OPTARG" ;;
h) print_usage; exit 0 ;;
-) case "${OPTARG}" in
use-inline-graph) USE_INLINE_GRAPH=true ;;
max-bootnodes)
# support: --max-bootnodes 5
MAX_BOOTNODES="${!OPTIND}"
OPTIND=$((OPTIND + 1)) ;;
max-bootnodes=*)
# support: --max-bootnodes=5
MAX_BOOTNODES="${OPTARG#*=}" ;;
*) echo "Error: Invalid option --${OPTARG}" >&2; print_usage; exit 2 ;;
esac ;;
:) echo "Error: Option -$OPTARG requires an argument" >&2; print_usage; exit 2 ;;
\?) echo "Error: Invalid option -$OPTARG" >&2; print_usage; exit 2 ;;
esac
Expand Down Expand Up @@ -96,9 +116,11 @@ GENESIS_DIR_ABS="$(py_abspath "$GENESIS_DIR")"
QLEAN_PATH_ABS="$(py_abspath "$QLEAN_PATH")"
MODULES_DIR_ABS="$(py_abspath "$MODULES_DIR")"
OUTPUT_YAML_ABS="$(py_abspath "$(dirname "$OUTPUT_YAML")")/$(basename "$OUTPUT_YAML")"
GRAPH_FILE_ABS="$(py_abspath "$GRAPH_FILE")"

CONFIG_YAML="$GENESIS_DIR_ABS/config.yaml"
VALIDATORS_YAML="$GENESIS_DIR_ABS/validators.yaml"
VALIDATOR_KEYS_MANIFEST_YAML="$GENESIS_DIR_ABS/hash-sig-keys/validator-keys-manifest.yaml"
VALIDATOR_CONFIG_YAML="$GENESIS_DIR_ABS/validator-config.yaml"
NODES_YAML="$GENESIS_DIR_ABS/nodes.yaml"

Expand Down Expand Up @@ -209,51 +231,60 @@ mkdir -p "$(dirname "$OUTPUT_YAML_ABS")"
printf "experimental:\n"
printf " native_preemption_enabled: true\n"
printf "network:\n"
# Emit an inline GML graph: create one node per host with 100 Mbit and a central switch with 1 Gbit
printf " graph:\n"
printf " type: gml\n"
printf " inline: |\n"
printf " graph [\n"
printf " directed 0\n"

if [[ "$USE_INLINE_GRAPH" == "true" ]]; then
# Emit inline GML graph
printf " inline: |\n"
printf " graph [\n"
printf " directed 0\n"

# Print node entries for each host
for ((i=0; i<NODE_COUNT; i++)); do
# Print node entries for each host
for ((i=0; i<NODE_COUNT; i++)); do
printf " node [\n"
printf " id %d\n" "$i"
printf " host_bandwidth_up \"%s\"\n" "$BANDWIDTH_HOST"
printf " host_bandwidth_down \"%s\"\n" "$BANDWIDTH_HOST"
printf " ]\n"
done

# Central switch node (id = NODE_COUNT)
central_id=$NODE_COUNT
printf " node [\n"
printf " id %d\n" "$i"
printf " host_bandwidth_up \"%s\"\n" "$BANDWIDTH_HOST"
printf " host_bandwidth_down \"%s\"\n" "$BANDWIDTH_HOST"
printf " id %d\n" "$central_id"
printf " host_bandwidth_up \"%s\"\n" "$BANDWIDTH_SWITCH"
printf " host_bandwidth_down \"%s\"\n" "$BANDWIDTH_SWITCH"
printf " ]\n"
done

# Central switch node (id = NODE_COUNT)
central_id=$NODE_COUNT
printf " node [\n"
printf " id %d\n" "$central_id"
printf " host_bandwidth_up \"%s\"\n" "$BANDWIDTH_SWITCH"
printf " host_bandwidth_down \"%s\"\n" "$BANDWIDTH_SWITCH"
printf " ]\n"
# Self-loop edges for hosts and switch
for ((i=0; i<=NODE_COUNT; i++)); do
printf " edge [\n"
printf " source %d\n" "$i"
printf " target %d\n" "$i"
printf " latency \"%s\"\n" "$LINK_LATENCY"
printf " packet_loss %s\n" "$PACKET_LOSS"
printf " ]\n"
done

# Self-loop edges for hosts and switch
for ((i=0; i<=NODE_COUNT; i++)); do
printf " edge [\n"
printf " source %d\n" "$i"
printf " target %d\n" "$i"
printf " latency \"%s\"\n" "$LINK_LATENCY"
printf " packet_loss %s\n" "$PACKET_LOSS"
printf " ]\n"
done
# Edges from each host to central switch
for ((i=0; i<NODE_COUNT; i++)); do
printf " edge [\n"
printf " source %d\n" "$i"
printf " target %d\n" "$central_id"
printf " latency \"%s\"\n" "$LINK_LATENCY"
printf " packet_loss %s\n" "$PACKET_LOSS"
printf " ]\n"
done

# Edges from each host to central switch
for ((i=0; i<NODE_COUNT; i++)); do
printf " edge [\n"
printf " source %d\n" "$i"
printf " target %d\n" "$central_id"
printf " latency \"%s\"\n" "$LINK_LATENCY"
printf " packet_loss %s\n" "$PACKET_LOSS"
printf " ]\n"
done
printf " ]\n"
else
# Use external GML file (absolute path)
printf " file:\n"
printf " path: \"%s\"\n" "$GRAPH_FILE_ABS"
fi

printf " ]\n"
printf " use_shortest_path: true\n"

printf "hosts:\n"

Expand Down Expand Up @@ -283,16 +314,24 @@ mkdir -p "$(dirname "$OUTPUT_YAML_ABS")"
"--bootnodes" "$NODES_YAML"
"--genesis" "$CONFIG_YAML"
"--validator-registry-path" "$VALIDATORS_YAML"
"--validator-keys-manifest" "$VALIDATOR_KEYS_MANIFEST_YAML"
"--node-id" "node_${i}"
"--node-key" "$key_file"
"--listen-addr" "/ip4/0.0.0.0/udp/${udp_port}/quic-v1"
"--prometheus-port" "$prom_port"
"--shadow"
)
# Append max bootnodes flag if requested
if [[ -n "$MAX_BOOTNODES" ]]; then
args_str+=("--max-bootnodes" "$MAX_BOOTNODES")
fi
# Join args preserving spaces
IFS=' ' read -r -a _dummy <<< "" # reset
joined="${args_str[*]}"

printf " %s:\n" "$node_name"
printf " bandwidth_up: \"%s\"\n" "$BANDWIDTH_HOST"
printf " bandwidth_down: \"%s\"\n" "$BANDWIDTH_HOST"
printf " network_node_id: %d\n" "$i"
printf " ip_addr: %s\n" "$ip"
printf " processes:\n"
Expand Down
4 changes: 4 additions & 0 deletions src/app/configuration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ namespace lean::app {
return validator_keys_manifest_path_;
}

bool Configuration::fakeXmss() const {
return fake_xmss_;
}

const Configuration::DatabaseConfig &Configuration::database() const {
return database_;
}
Expand Down
4 changes: 4 additions & 0 deletions src/app/configuration.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ namespace lean::app {
[[nodiscard]] virtual const std::filesystem::path &
validatorKeysManifestPath() const;

[[nodiscard]] virtual bool fakeXmss() const;

[[nodiscard]] virtual const DatabaseConfig &database() const;

[[nodiscard]] virtual const MetricsConfig &metrics() const;
Expand All @@ -82,6 +84,8 @@ namespace lean::app {

std::filesystem::path validator_keys_manifest_path_;

bool fake_xmss_ = false;

DatabaseConfig database_;
MetricsConfig metrics_;
};
Expand Down
99 changes: 57 additions & 42 deletions src/app/configurator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "app/configuration.hpp"
#include "app/default_logging_yaml.hpp"
#include "app/validator_keys_manifest.hpp"
#include "crypto/xmss/xmss_provider_fake.hpp"
#include "crypto/xmss/xmss_util.hpp"
#include "log/formatters/filepath.hpp"
#include "modules/networking/get_node_key.hpp"
Expand Down Expand Up @@ -133,6 +134,7 @@ namespace lean::app {
"Log levels: trace, debug, verbose, info, warn, error, critical, off.\n"
"Default: all targets log at `info`.\n"
"Global log level can be set with: -l<level>.")
("shadow", "Run with shadow compatibility (fake xmss provider)")
;

po::options_description storage_options("Storage options");
Expand Down Expand Up @@ -405,7 +407,8 @@ namespace lean::app {
auto value = validator_keys_manifest.as<std::string>();
config_->validator_keys_manifest_path_ = value;
} else {
file_errors_ << "E: Value 'general.validator-keys-manifest' must be scalar\n";
file_errors_ << "E: Value 'general.validator-keys-manifest' must "
"be scalar\n";
file_has_error_ = true;
}
}
Expand Down Expand Up @@ -504,10 +507,11 @@ namespace lean::app {
cli_values_map_, "xmss-sk", [&](const std::string &value) {
config_->xmss_secret_key_path_ = value;
});
find_argument<std::string>(
cli_values_map_, "validator-keys-manifest", [&](const std::string &value) {
config_->validator_keys_manifest_path_ = value;
});
find_argument<std::string>(cli_values_map_,
"validator-keys-manifest",
[&](const std::string &value) {
config_->validator_keys_manifest_path_ = value;
});
if (fail) {
return Error::CliArgsParseFailed;
}
Expand Down Expand Up @@ -608,55 +612,66 @@ namespace lean::app {
return Error::InvalidValue;
}

// Validate and load XMSS keys (mandatory)
if (config_->xmss_public_key_path_.empty()) {
SL_ERROR(logger_, "The '--xmss-pk' (XMSS public key) path must be provided");
return Error::InvalidValue;
}
if (config_->xmss_secret_key_path_.empty()) {
SL_ERROR(logger_, "The '--xmss-sk' (XMSS secret key) path must be provided");
return Error::InvalidValue;
if (find_argument(cli_values_map_, "shadow")) {
config_->fake_xmss_ = true;
}
if (not config_->fakeXmss()) {
// Validate and load XMSS keys (mandatory)
if (config_->xmss_public_key_path_.empty()) {
SL_ERROR(logger_,
"The '--xmss-pk' (XMSS public key) path must be provided");
return Error::InvalidValue;
}
if (config_->xmss_secret_key_path_.empty()) {
SL_ERROR(logger_,
"The '--xmss-sk' (XMSS secret key) path must be provided");
return Error::InvalidValue;
}

config_->xmss_public_key_path_ =
resolve_relative(config_->xmss_public_key_path_, "xmss-pk");
if (not is_regular_file(config_->xmss_public_key_path_)) {
SL_ERROR(logger_,
"The 'xmss-pk' file does not exist or is not a file: {}",
config_->xmss_public_key_path_);
return Error::InvalidValue;
}
config_->xmss_public_key_path_ =
resolve_relative(config_->xmss_public_key_path_, "xmss-pk");
if (not is_regular_file(config_->xmss_public_key_path_)) {
SL_ERROR(logger_,
"The 'xmss-pk' file does not exist or is not a file: {}",
config_->xmss_public_key_path_);
return Error::InvalidValue;
}

config_->xmss_secret_key_path_ =
resolve_relative(config_->xmss_secret_key_path_, "xmss-sk");
if (not is_regular_file(config_->xmss_secret_key_path_)) {
SL_ERROR(logger_,
"The 'xmss-sk' file does not exist or is not a file: {}",
config_->xmss_secret_key_path_);
return Error::InvalidValue;
}
config_->xmss_secret_key_path_ =
resolve_relative(config_->xmss_secret_key_path_, "xmss-sk");
if (not is_regular_file(config_->xmss_secret_key_path_)) {
SL_ERROR(logger_,
"The 'xmss-sk' file does not exist or is not a file: {}",
config_->xmss_secret_key_path_);
return Error::InvalidValue;
}

// Load XMSS keypair from JSON files
OUTCOME_TRY(keypair, crypto::xmss::loadKeypairFromJson(
config_->xmss_secret_key_path_,
config_->xmss_public_key_path_
));
config_->xmss_keypair_ = std::move(keypair);
SL_INFO(logger_, "Loaded XMSS keypair from:");
SL_INFO(logger_, " Public key: {}", config_->xmss_public_key_path_);
SL_INFO(logger_, " Secret key: {}", config_->xmss_secret_key_path_);
// Load XMSS keypair from JSON files
BOOST_OUTCOME_TRY(
config_->xmss_keypair_,
crypto::xmss::loadKeypairFromJson(config_->xmss_secret_key_path_,
config_->xmss_public_key_path_));
SL_INFO(logger_, "Loaded XMSS keypair from:");
SL_INFO(logger_, " Public key: {}", config_->xmss_public_key_path_);
SL_INFO(logger_, " Secret key: {}", config_->xmss_secret_key_path_);
} else {
config_->xmss_keypair_ = crypto::xmss::XmssProviderFake::loadKeypair(
config_->xmss_secret_key_path_.string());
}

// Load validator keys manifest (mandatory)
if (config_->validator_keys_manifest_path_.empty()) {
SL_ERROR(logger_, "The '--validator-keys-manifest' path must be provided");
SL_ERROR(logger_,
"The '--validator-keys-manifest' path must be provided");
return Error::InvalidValue;
}

config_->validator_keys_manifest_path_ =
resolve_relative(config_->validator_keys_manifest_path_, "validator-keys-manifest");
config_->validator_keys_manifest_path_ = resolve_relative(
config_->validator_keys_manifest_path_, "validator-keys-manifest");
if (not is_regular_file(config_->validator_keys_manifest_path_)) {
SL_ERROR(logger_,
"The 'validator-keys-manifest' file does not exist or is not a file: {}",
"The 'validator-keys-manifest' file does not exist or is not a "
"file: {}",
config_->validator_keys_manifest_path_);
return Error::InvalidValue;
}
Expand Down
Loading
Loading