use anyhow::Result;
use clap::*;
use mysten_metrics::start_prometheus_server;
use std::env;
use std::net::IpAddr;
use std::net::{Ipv4Addr, SocketAddr};
use std::path::PathBuf;
use std::sync::Arc;
use sui_config::Config;
use sui_data_ingestion_core::DataIngestionMetrics;
use sui_deepbook_indexer::config::IndexerConfig;
use sui_deepbook_indexer::metrics::DeepBookIndexerMetrics;
use sui_deepbook_indexer::postgres_manager::get_connection_pool;
use sui_deepbook_indexer::server::run_server;
use sui_deepbook_indexer::sui_deepbook_indexer::PgDeepbookPersistent;
use sui_deepbook_indexer::sui_deepbook_indexer::SuiDeepBookDataMapper;
use sui_indexer_builder::indexer_builder::IndexerBuilder;
use sui_indexer_builder::progress::{OutOfOrderSaveAfterDurationPolicy, ProgressSavingPolicy};
use sui_indexer_builder::sui_datasource::SuiCheckpointDatasource;
use sui_sdk::SuiClientBuilder;
use sui_types::base_types::ObjectID;
use tracing::info;
#[derive(Parser, Clone, Debug)]
struct Args {
#[clap(long, short)]
config_path: Option<PathBuf>,
}
#[tokio::main]
async fn main() -> Result<()> {
let _guard = telemetry_subscribers::TelemetryConfig::new()
.with_env()
.init();
let args = Args::parse();
let config_path = if let Some(path) = args.config_path {
path
} else {
env::current_dir()
.expect("Couldn't get current directory")
.join("config.yaml")
};
let config = IndexerConfig::load(&config_path)?;
let metrics_address =
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), config.metric_port);
let registry_service = start_prometheus_server(metrics_address);
let registry = registry_service.default_registry();
mysten_metrics::init_metrics(®istry);
info!("Metrics server started at port {}", config.metric_port);
let indexer_meterics = DeepBookIndexerMetrics::new(®istry);
let ingestion_metrics = DataIngestionMetrics::new(®istry);
let db_url = config.db_url.clone();
let datastore = PgDeepbookPersistent::new(
get_connection_pool(db_url.clone()).await,
ProgressSavingPolicy::OutOfOrderSaveAfterDuration(OutOfOrderSaveAfterDurationPolicy::new(
tokio::time::Duration::from_secs(30),
)),
);
let sui_client = Arc::new(
SuiClientBuilder::default()
.build(config.sui_rpc_url.clone())
.await?,
);
let sui_checkpoint_datasource = SuiCheckpointDatasource::new(
config.remote_store_url,
sui_client,
config.concurrency as usize,
config
.checkpoints_path
.map(|p| p.into())
.unwrap_or(tempfile::tempdir()?.into_path()),
config.deepbook_genesis_checkpoint,
ingestion_metrics.clone(),
Box::new(indexer_meterics.clone()),
);
let service_address =
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), config.service_port);
run_server(service_address, datastore.clone());
let indexer = IndexerBuilder::new(
"SuiDeepBookIndexer",
sui_checkpoint_datasource,
SuiDeepBookDataMapper {
metrics: indexer_meterics.clone(),
package_id: ObjectID::from_hex_literal(&config.deepbook_package_id.clone())
.unwrap_or_else(|err| panic!("Failed to parse deepbook package ID: {}", err)),
},
datastore,
)
.build();
indexer.start().await?;
Ok(())
}