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