Skip to main content

tempo_xtask/
main.rs

1//! xtask is a Swiss army knife of tools that help with running and testing tempo.
2use 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}