1use std::process::exit;
2
3use agglayer_config::storage::backup::BackupConfig;
4use clap::Parser;
5use cli::Cli;
6use eyre::Context as _;
7use pessimistic_proof::ELF;
8use sp1_sdk::HashableKey as _;
9
10mod cli;
11
12fn main() -> eyre::Result<()> {
13 dotenvy::dotenv().ok();
14
15 let cli = Cli::parse();
16
17 match cli.cmd {
18 cli::Commands::Run { cfg } => agglayer_node::main(cfg, &version(), None)?,
19 cli::Commands::Config { base_dir } => println!(
20 "{}",
21 toml::to_string_pretty(&agglayer_config::Config::new(&base_dir))
22 .context("Failed to serialize Config to TOML")?
23 ),
24 cli::Commands::ValidateConfig { path } => {
25 match agglayer_config::Config::try_load(path.as_path()) {
26 Ok(config) => {
27 println!(
28 "{}",
29 toml::to_string_pretty(&config)
30 .context("Failed to serialize ValidateConfig to TOML")?
31 );
32 }
33 Err(error) => eprintln!("{error}"),
34 }
35 }
36 cli::Commands::Vkey => {
37 tokio::runtime::Builder::new_multi_thread()
38 .enable_all()
39 .build()?
40 .block_on(async move {
41 let vkey_hex = compute_program_vkey(ELF).await;
42 match vkey_hex {
43 Ok(vkey_hex) => println!("{vkey_hex}"),
44 Err(error) => eprintln!("{error:?}"),
45 }
46 });
47 }
48
49 cli::Commands::VkeySelector => {
50 let vkey_selector_hex =
51 hex::encode(pessimistic_proof::core::PESSIMISTIC_PROOF_PROGRAM_SELECTOR);
52 println!("0x{vkey_selector_hex}");
53 }
54
55 cli::Commands::Backup(cli::Backup::List { config_path: cfg }) => {
56 let cfg = agglayer_config::Config::try_load(&cfg)?;
57
58 if let BackupConfig::Enabled { path, .. } = cfg.storage.backup {
59 match agglayer_storage::backup::BackupEngine::list_backups(&path) {
60 Ok(result) => println!("{}", serde_json::to_string(&result).unwrap()),
61 Err(error) => eprintln!("{error}"),
62 }
63 }
64 }
65
66 cli::Commands::Backup(cli::Backup::Restore {
67 config_path: cfg,
68 db_versions,
69 }) => {
70 let cfg = agglayer_config::Config::try_load(&cfg)?;
71
72 if let BackupConfig::Enabled { ref path, .. } = cfg.storage.backup {
73 for (db_kind, version) in db_versions {
74 let (db_path, backup_path) = db_kind.create_paths(&cfg, path);
75
76 agglayer_storage::backup::BackupEngine::restore_at(
77 &backup_path,
78 &db_path,
79 version,
80 )?;
81 }
82 } else {
83 println!("Backups are not enabled in the configuration file.");
84 exit(1);
85 }
86 }
87 }
88
89 Ok(())
90}
91
92pub fn version() -> String {
94 let pkg_name = env!("CARGO_PKG_NAME");
95 let git_describe = env!("VERGEN_GIT_DESCRIBE");
96 let timestamp = env!("VERGEN_GIT_COMMIT_TIMESTAMP");
97 format!("{pkg_name} ({git_describe}) [git commit timestamp: {timestamp}]")
98}
99
100pub async fn compute_program_vkey(program: &'static [u8]) -> eyre::Result<String> {
101 let vkey = prover_executor::Executor::compute_program_vkey(program)
102 .await
103 .context("Failed to compute program vkey")?;
104 Ok(vkey.bytes32())
105}