-
Notifications
You must be signed in to change notification settings - Fork 188
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(torii): configutation file for all torii cli options #2646
Changes from 3 commits
d6c77c0
3108039
aa985f7
7c19061
cf20035
f671543
8b41cf2
a2c064e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -11,15 +11,15 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||
//! for more info. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
use std::cmp; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
use std::collections::VecDeque; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
use std::net::SocketAddr; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
use std::path::PathBuf; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
use std::str::FromStr; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
use std::sync::Arc; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
use std::time::Duration; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
use anyhow::Context; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
use clap::{ArgAction, Parser}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
use clap::{ArgAction, CommandFactory, FromArgMatches, Parser}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
use clap_config::ClapConfig; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
use dojo_metrics::exporters::prometheus::PrometheusRecorder; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
use dojo_utils::parse::{parse_socket_address, parse_url}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
use dojo_world::contracts::world::WorldContractReader; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -39,7 +39,7 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||
use torii_core::processors::store_transaction::StoreTransactionProcessor; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
use torii_core::simple_broker::SimpleBroker; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
use torii_core::sql::Sql; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
use torii_core::types::{Contract, ContractType, Model, ToriiConfig}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
use torii_core::types::{Contract, ContractType, Model}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
use torii_server::proxy::Proxy; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
use tracing::{error, info}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
use tracing_subscriber::{fmt, EnvFilter}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -48,12 +48,12 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||
pub(crate) const LOG_TARGET: &str = "torii::cli"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
/// Dojo World Indexer | ||||||||||||||||||||||||||||||||||||||||||||||||||||
#[derive(Parser, Debug)] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
#[derive(ClapConfig, Parser, Debug)] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
#[command(name = "torii", author, version, about, long_about = None)] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
struct Args { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
/// The world to index | ||||||||||||||||||||||||||||||||||||||||||||||||||||
#[arg(short, long = "world", env = "DOJO_WORLD_ADDRESS")] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
world_address: Option<Felt>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
world_address: Felt, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
/// The sequencer rpc endpoint to index. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
#[arg(long, value_name = "URL", default_value = ":5050", value_parser = parse_url)] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -139,33 +139,25 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||
index_raw_events: bool, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
/// ERC contract addresses to index | ||||||||||||||||||||||||||||||||||||||||||||||||||||
#[arg(long, value_parser = parse_erc_contracts)] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
#[arg(conflicts_with = "config")] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
contracts: Option<std::vec::Vec<Contract>>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
#[arg(long, value_parser = parse_erc_contracts, default_value = "")] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
contracts: Vec<Contract>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
/// Configuration file | ||||||||||||||||||||||||||||||||||||||||||||||||||||
#[arg(long)] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
#[clap_config(skip)] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
config: Option<PathBuf>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
#[tokio::main] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
async fn main() -> anyhow::Result<()> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
let args = Args::parse(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
let mut config = if let Some(path) = args.config { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
ToriiConfig::load_from_path(&path)? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
let matches = <Args as CommandFactory>::command().get_matches(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
let args = if let Some(path) = matches.get_one::<PathBuf>("config") { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
let config: ArgsConfig = toml::from_str(&std::fs::read_to_string(path)?)?; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Args::from_merged(matches, Some(config)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
let mut config = ToriiConfig::default(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
if let Some(contracts) = args.contracts { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
config.contracts = VecDeque::from(contracts); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
config | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Args::from_arg_matches(&matches)? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Ohayo sensei! Let's enhance the config file handling! The config file handling could be more robust:
Consider this improvement: - let args = if let Some(path) = matches.get_one::<PathBuf>("config") {
- let config: ArgsConfig = toml::from_str(&std::fs::read_to_string(path)?)?;
- Args::from_merged(matches, Some(config))
+ let args = if let Some(path) = matches.get_one::<PathBuf>("config") {
+ if !path.exists() {
+ anyhow::bail!("Config file not found: {}", path.display());
+ }
+ let content = std::fs::read_to_string(path)
+ .with_context(|| format!("Failed to read config file: {}", path.display()))?;
+ let config: ArgsConfig = toml::from_str(&content)
+ .with_context(|| format!("Failed to parse TOML config at: {}", path.display()))?;
+ Args::from_merged(matches, Some(config)) 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
let world_address = verify_single_world_address(args.world_address, &mut config)?; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
let filter_layer = EnvFilter::try_from_default_env() | ||||||||||||||||||||||||||||||||||||||||||||||||||||
.unwrap_or_else(|_| EnvFilter::new("info,hyper_reverse_proxy=off")); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -208,10 +200,9 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||
let provider: Arc<_> = JsonRpcClient::new(HttpTransport::new(args.rpc)).into(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
// Get world address | ||||||||||||||||||||||||||||||||||||||||||||||||||||
let world = WorldContractReader::new(world_address, provider.clone()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
let world = WorldContractReader::new(args.world_address, provider.clone()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
let contracts = | ||||||||||||||||||||||||||||||||||||||||||||||||||||
config.contracts.iter().map(|contract| (contract.address, contract.r#type)).collect(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
let contracts = args.contracts.iter().map(|contract| (contract.address, contract.r#type)).collect(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
let (mut executor, sender) = Executor::new(pool.clone(), shutdown_tx.clone()).await?; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
tokio::spawn(async move { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -256,7 +247,7 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
let shutdown_rx = shutdown_tx.subscribe(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
let (grpc_addr, grpc_server) = | ||||||||||||||||||||||||||||||||||||||||||||||||||||
torii_grpc::server::new(shutdown_rx, &pool, block_rx, world_address, Arc::clone(&provider)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
torii_grpc::server::new(shutdown_rx, &pool, block_rx, args.world_address, Arc::clone(&provider)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
.await?; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
let mut libp2p_relay_server = torii_relay::server::Relay::new( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -321,26 +312,6 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||
Ok(()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
// Verifies that the world address is defined at most once | ||||||||||||||||||||||||||||||||||||||||||||||||||||
// and returns the world address | ||||||||||||||||||||||||||||||||||||||||||||||||||||
fn verify_single_world_address( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
world_address: Option<Felt>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
config: &mut ToriiConfig, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
) -> anyhow::Result<Felt> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
let world_from_config = | ||||||||||||||||||||||||||||||||||||||||||||||||||||
config.contracts.iter().find(|c| c.r#type == ContractType::WORLD).map(|c| c.address); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
match (world_address, world_from_config) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
(Some(_), Some(_)) => Err(anyhow::anyhow!("World address specified multiple times")), | ||||||||||||||||||||||||||||||||||||||||||||||||||||
(Some(addr), _) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
config.contracts.push_front(Contract { address: addr, r#type: ContractType::WORLD }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Ok(addr) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
(_, Some(addr)) => Ok(addr), | ||||||||||||||||||||||||||||||||||||||||||||||||||||
(None, None) => Err(anyhow::anyhow!("World address not specified")), | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
async fn spawn_rebuilding_graphql_server( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
shutdown_tx: Sender<()>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
pool: Arc<SqlitePool>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -369,18 +340,20 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||
// - erc_type:address:start_block | ||||||||||||||||||||||||||||||||||||||||||||||||||||
// - address:start_block (erc_type defaults to ERC20) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
fn parse_erc_contracts(s: &str) -> anyhow::Result<Vec<Contract>> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
if s.is_empty() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
return Ok(Vec::new()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
let parts: Vec<&str> = s.split(',').collect(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
let mut contracts = Vec::new(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
for part in parts { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
match part.split(':').collect::<Vec<&str>>().as_slice() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
[r#type, address] => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
let r#type = r#type.parse::<ContractType>()?; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
let address = Felt::from_str(address) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
.with_context(|| format!("Expected address, found {}", address))?; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
contracts.push(Contract { address, r#type }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
[address] => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
let r#type = ContractType::WORLD; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
if r#type == ContractType::WORLD { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
return Err(anyhow::anyhow!("World address cannot be specified as an ERC contract")); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
let address = Felt::from_str(address) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
.with_context(|| format!("Expected address, found {}", address))?; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
contracts.push(Contract { address, r#type }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
🛠️ Refactor suggestion
Consider using clap directly instead of clap_config, sensei!
The verification reveals:
clap_config
is only used in one place (bin/torii/src/main.rs
) for a simpleskip
attributeclap
directly, as seen in multiple filesThe functionality can be replaced with clap's built-in attributes, making the dependency unnecessary:
#[clap_config(skip)]
with#[arg(skip)]
🔗 Analysis chain
Consider workspace version management and package stability, sensei!
The
clap_config
dependency has a few concerns:.workspace = true
) like other dependenciesLet's check the package's health:
Consider:
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
Length of output: 257
Script:
Length of output: 15413