mod.rs
1 // Copyright (C) 2019-2025 Alpha-Delta Network Inc. 2 // This file is part of the ADL library. 3 4 // The ADL library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 9 // The ADL library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 14 // You should have received a copy of the GNU General Public License 15 // along with the ADL library. If not, see <https://www.gnu.org/licenses/>. 16 17 use adl_ast::NetworkName; 18 use adl_errors::UtilError; 19 use adl_package::{fetch_from_network, verify_valid_program}; 20 21 use super::*; 22 23 mod block; 24 pub use block::AdlBlock; 25 26 mod program; 27 pub use program::AdlProgram; 28 29 mod state_root; 30 pub use state_root::StateRoot; 31 32 mod committee; 33 pub use committee::AdlCommittee; 34 35 mod mempool; 36 pub use mempool::AdlMempool; 37 38 mod peers; 39 pub use peers::AdlPeers; 40 41 mod transaction; 42 pub use transaction::AdlTransaction; 43 44 mod utils; 45 use utils::*; 46 47 /// Query live data from the Alpha network. 48 #[derive(Parser, Debug)] 49 pub struct AdlQuery { 50 #[clap(flatten)] 51 pub(crate) env_override: EnvOptions, 52 #[clap(subcommand)] 53 pub command: QueryCommands, 54 } 55 56 impl Command for AdlQuery { 57 type Input = (); 58 type Output = String; 59 60 fn log_span(&self) -> Span { 61 tracing::span!(tracing::Level::INFO, "Adl") 62 } 63 64 fn prelude(&self, _context: Context) -> Result<Self::Input> { 65 Ok(()) 66 } 67 68 fn apply(self, context: Context, _: Self::Input) -> Result<Self::Output> { 69 // Parse the network. 70 let network: NetworkName = get_network(&self.env_override.network)?; 71 let endpoint = get_endpoint(&self.env_override.endpoint)?; 72 handle_query(self, context, network, &endpoint) 73 } 74 } 75 76 // A helper function to handle the `query` command. 77 fn handle_query( 78 query: AdlQuery, 79 context: Context, 80 network: NetworkName, 81 endpoint: &str, 82 ) -> Result<<AdlQuery as Command>::Output> { 83 let recursive = context.recursive; 84 let (program, output) = match query.command { 85 QueryCommands::Block { command } => (None, command.apply(context, ())?), 86 QueryCommands::Transaction { command } => (None, command.apply(context, ())?), 87 QueryCommands::Program { command } => { 88 // Check if querying for program source code. 89 let program = 90 if command.mappings || command.mapping_value.is_some() { None } else { Some(command.name.clone()) }; 91 (program, command.apply(context, ())?) 92 } 93 QueryCommands::Stateroot { command } => (None, command.apply(context, ())?), 94 QueryCommands::Committee { command } => (None, command.apply(context, ())?), 95 QueryCommands::Mempool { command } => { 96 if endpoint == "https://api.explorer.provable.com/v1" { 97 tracing::warn!( 98 "⚠️ `adl query mempool` is only valid when using a custom endpoint. Specify one using `--endpoint`." 99 ); 100 } 101 (None, command.apply(context, ())?) 102 } 103 QueryCommands::Peers { command } => { 104 if endpoint == "https://api.explorer.provable.com/v1" { 105 tracing::warn!( 106 "⚠️ `adl query peers` is only valid when using a custom endpoint. Specify one using `--endpoint`." 107 ); 108 } 109 (None, command.apply(context, ())?) 110 } 111 }; 112 113 // Make GET request to retrieve on-chain state. 114 let url = format!("{endpoint}/{network}/{output}"); 115 let result = fetch_from_network(&url)?; 116 if !recursive { 117 tracing::info!("✅ Successfully retrieved data from '{url}'.\n"); 118 println!("{result}\n"); 119 } 120 121 // Verify that the source file parses into a valid Alpha program. 122 if let Some(name) = program { 123 verify_valid_program(&name, &result)?; 124 } 125 126 Ok(result) 127 } 128 129 #[derive(Parser, Debug)] 130 pub enum QueryCommands { 131 #[clap(about = "Query block information")] 132 Block { 133 #[clap(flatten)] 134 command: AdlBlock, 135 }, 136 #[clap(about = "Query transaction information")] 137 Transaction { 138 #[clap(flatten)] 139 command: AdlTransaction, 140 }, 141 #[clap(about = "Query program source code and live mapping values")] 142 Program { 143 #[clap(flatten)] 144 command: AdlProgram, 145 }, 146 #[clap(about = "Query the latest stateroot")] 147 Stateroot { 148 #[clap(flatten)] 149 command: StateRoot, 150 }, 151 #[clap(about = "Query the current committee")] 152 Committee { 153 #[clap(flatten)] 154 command: AdlCommittee, 155 }, 156 #[clap(about = "Query transactions and transmissions from the memory pool")] 157 Mempool { 158 #[clap(flatten)] 159 command: AdlMempool, 160 }, 161 #[clap(about = "Query peer information")] 162 Peers { 163 #[clap(flatten)] 164 command: AdlPeers, 165 }, 166 }