1use std::net::SocketAddr;
3
4use crate::{
5 generate_devnet::GenerateDevnet, generate_genesis::GenerateGenesis,
6 generate_localnet::GenerateLocalnet, generate_state_bloat::GenerateStateBloat,
7 get_dkg_outcome::GetDkgOutcome,
8};
9
10use alloy::signers::{local::MnemonicBuilder, utils::secret_key_to_address};
11use clap::Parser as _;
12use commonware_codec::DecodeExt;
13use eyre::Context;
14
15mod generate_devnet;
16mod generate_genesis;
17mod generate_localnet;
18mod generate_state_bloat;
19mod genesis_args;
20mod get_dkg_outcome;
21
22#[tokio::main]
23async fn main() -> eyre::Result<()> {
24 let args = Args::parse();
25 match args.action {
26 Action::GetDkgOutcome(args) => args.run().await.wrap_err("failed to get DKG outcome"),
27 Action::GenerateGenesis(args) => args.run().await.wrap_err("failed generating genesis"),
28 Action::GenerateDevnet(args) => args
29 .run()
30 .await
31 .wrap_err("failed to generate devnet configs"),
32 Action::GenerateLocalnet(args) => args
33 .run()
34 .await
35 .wrap_err("failed to generate localnet configs"),
36 Action::GenerateAddPeer(cfg) => generate_config_to_add_peer(cfg),
37 Action::GenerateStateBloat(args) => args
38 .run()
39 .await
40 .wrap_err("failed to generate state bloat file"),
41 }
42}
43
44#[derive(Debug, clap::Parser)]
45#[command(author)]
46#[command(version)]
47#[command(about)]
48#[command(long_about = None)]
49struct Args {
50 #[command(subcommand)]
51 action: Action,
52}
53
54#[derive(Debug, clap::Subcommand)]
55enum Action {
56 GetDkgOutcome(GetDkgOutcome),
57 GenerateGenesis(GenerateGenesis),
58 GenerateDevnet(GenerateDevnet),
59 GenerateLocalnet(GenerateLocalnet),
60 GenerateAddPeer(GenerateAddPeer),
61 GenerateStateBloat(GenerateStateBloat),
62}
63
64#[derive(Debug, clap::Args)]
65struct GenerateAddPeer {
66 #[arg(long)]
67 public_key: String,
68
69 #[arg(long)]
70 inbound_address: SocketAddr,
71
72 #[arg(long)]
73 rpc_endpoint: String,
74
75 #[arg(long, default_value_t = 0)]
76 admin_index: u32,
77
78 #[arg(long, default_value_t = 20)]
79 validator_index: u32,
80
81 #[arg(
82 short,
83 long,
84 default_value = "test test test test test test test test test test test junk"
85 )]
86 pub mnemonic: String,
87}
88
89fn generate_config_to_add_peer(
90 GenerateAddPeer {
91 public_key,
92 inbound_address,
93 admin_index,
94 validator_index,
95 rpc_endpoint,
96 mnemonic,
97 }: GenerateAddPeer,
98) -> eyre::Result<()> {
99 use tempo_precompiles::VALIDATOR_CONFIG_ADDRESS;
100 let public_key_bytes = const_hex::decode(&public_key)?;
101 let public_key = commonware_cryptography::ed25519::PublicKey::decode(&public_key_bytes[..])?;
102
103 let admin_key = const_hex::encode(
104 MnemonicBuilder::from_phrase_nth(&mnemonic, admin_index)
105 .credential()
106 .to_bytes(),
107 );
108
109 let validator_address = {
110 secret_key_to_address(
111 MnemonicBuilder::from_phrase_nth(mnemonic, validator_index).credential(),
112 )
113 };
114 let inbound = inbound_address.to_string();
115 let outbound = inbound_address.to_string();
116 println!(
117 "\
118 cast send {VALIDATOR_CONFIG_ADDRESS} \
119 \\\n\"addValidator(address newValidatorAddress, bytes32 publicKey, bool active, string calldata inboundAddress, string calldata outboundAddress)\" \
120 \\\n\"{validator_address}\" \
121 \\\n\"{public_key}\" \
122 \\\n\"true\" \
123 \\\n\"{inbound}\" \
124 \\\n\"{outbound}\" \
125 \\\n--private-key {admin_key} \
126 \\\n-r {rpc_endpoint}"
127 );
128 Ok(())
129}