1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
// Copyright (c) 2021-2024 Espresso Systems (espressosys.com)
// This file is part of the HotShot repository.
// You should have received a copy of the MIT License
// along with the HotShot repository. If not, see <https://mit-license.org/>.
//! The whitelist is an adaptor that is able to update the allowed public keys for
//! all brokers. Right now, we do this by asking the orchestrator for the list of
//! allowed public keys. In the future, we will pull the stake table from the L1.
use std::{str::FromStr, sync::Arc};
use anyhow::{Context, Result};
use cdn_broker::reexports::discovery::{DiscoveryClient, Embedded, Redis};
use clap::Parser;
use hotshot_example_types::node_types::TestTypes;
use hotshot_orchestrator::client::OrchestratorClient;
use hotshot_types::{
network::NetworkConfig,
traits::{node_implementation::NodeType, signature_key::SignatureKey},
};
use surf_disco::Url;
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
/// The main component of the push CDN.
struct Args {
/// The discovery client endpoint (including scheme) to connect to.
/// With the local discovery feature, this is a file path.
/// With the remote (redis) discovery feature, this is a redis URL (e.g. `redis://127.0.0.1:6789`).
#[arg(short, long)]
discovery_endpoint: String,
/// The URL the orchestrator is running on. This should be something like `http://localhost:5555`
#[arg(short, long)]
orchestrator_url: String,
/// Whether or not to use the local discovery client
#[arg(short, long)]
local_discovery: bool,
}
#[tokio::main]
async fn main() -> Result<()> {
// Parse the command line arguments
let args = Args::parse();
// Initialize tracing
tracing_subscriber::fmt::init();
// Create a new `OrchestratorClient` from the supplied URL
let orchestrator_client = OrchestratorClient::new(
Url::from_str(&args.orchestrator_url).with_context(|| "Invalid URL")?,
);
// Attempt to get the config from the orchestrator.
// Loops internally until the config is received.
let config: NetworkConfig<<TestTypes as NodeType>::SignatureKey> =
orchestrator_client.get_config_after_collection().await;
tracing::info!("Received config from orchestrator");
// Extrapolate the state_ver_keys from the config and convert them to a compatible format
let whitelist = config
.config
.known_nodes_with_stake
.iter()
.map(|k| Arc::from(k.stake_table_entry.stake_key.to_bytes()))
.collect();
if args.local_discovery {
<Embedded as DiscoveryClient>::new(args.discovery_endpoint, None)
.await?
.set_whitelist(whitelist)
.await?;
} else {
<Redis as DiscoveryClient>::new(args.discovery_endpoint, None)
.await?
.set_whitelist(whitelist)
.await?;
}
tracing::info!("Posted config to discovery endpoint");
Ok(())
}