diff --git a/deployment/config/indexer/cardano_node_docker.mainnet.yml b/deployment/config/indexer/cardano_node_docker.mainnet.yml index f0f45eec..b58884d3 100644 --- a/deployment/config/indexer/cardano_node_docker.mainnet.yml +++ b/deployment/config/indexer/cardano_node_docker.mainnet.yml @@ -15,6 +15,6 @@ sink: db: type: postgres database_url: postgresql://carp:1234@postgres:5432/carp_mainnet - network: mainnet # preview / preprod / testnet + network: mainnet # preview / preprod / testnet / custom start_block: diff --git a/deployment/config/indexer/oura_docker.mainnet.yml b/deployment/config/indexer/oura_docker.mainnet.yml index 6f7ce7fb..5a87b8e0 100644 --- a/deployment/config/indexer/oura_docker.mainnet.yml +++ b/deployment/config/indexer/oura_docker.mainnet.yml @@ -8,6 +8,6 @@ sink: db: type: postgres database_url: postgresql://carp:1234@postgres:5432/carp_mainnet - network: mainnet # preview / preprod / testnet + network: mainnet # preview / preprod / testnet / custom start_block: diff --git a/docs/docs/indexer/run.md b/docs/docs/indexer/run.md index 30f0cb49..bfa3793a 100644 --- a/docs/docs/indexer/run.md +++ b/docs/docs/indexer/run.md @@ -22,7 +22,7 @@ sink: db: type: postgres database_url: postgresql://carp:1234@localhost:5432/carp_mainnet - network: mainnet # preview / preprod / testnet + network: mainnet # preview / preprod / testnet / custom start_block: ``` diff --git a/indexer/configs/cardano_node.yml b/indexer/configs/cardano_node.yml index e83d5e3a..413d6f12 100644 --- a/indexer/configs/cardano_node.yml +++ b/indexer/configs/cardano_node.yml @@ -13,6 +13,6 @@ sink: db: type: postgres database_url: postgresql://carp:1234@localhost:5432/carp_mainnet - network: mainnet # preview / preprod / testnet + network: mainnet # preview / preprod / testnet / custom start_block: diff --git a/indexer/configs/default.yml b/indexer/configs/default.yml index 4990df99..272c7321 100644 --- a/indexer/configs/default.yml +++ b/indexer/configs/default.yml @@ -8,6 +8,6 @@ sink: db: type: postgres database_url: postgresql://carp:1234@localhost:5432/carp_mainnet - network: mainnet # preview / preprod / testnet + network: mainnet # preview / preprod / testnet / custom start_block: diff --git a/indexer/configs/oura.yml b/indexer/configs/oura.yml index 4990df99..272c7321 100644 --- a/indexer/configs/oura.yml +++ b/indexer/configs/oura.yml @@ -8,6 +8,6 @@ sink: db: type: postgres database_url: postgresql://carp:1234@localhost:5432/carp_mainnet - network: mainnet # preview / preprod / testnet + network: mainnet # preview / preprod / testnet / custom start_block: diff --git a/indexer/src/genesis.rs b/indexer/src/genesis.rs index 8d5ed3cc..feb442ce 100644 --- a/indexer/src/genesis.rs +++ b/indexer/src/genesis.rs @@ -13,36 +13,19 @@ use migration::DbErr; use tasks::utils::TaskPerfAggregator; use tasks::{execution_plan::ExecutionPlan, genesis::genesis_executor::process_genesis_block}; -const GENESIS_MAINNET: &str = "./genesis/mainnet-byron-genesis.json"; -const GENESIS_PREVIEW: &str = "./genesis/preview-byron-genesis.json"; -const GENESIS_PREPROD: &str = "./genesis/preprod-byron-genesis.json"; -const GENESIS_TESTNET: &str = "./genesis/testnet-byron-genesis.json"; - pub async fn process_genesis( conn: &DatabaseConnection, network: &str, + genesis_folder: &str, exec_plan: Arc, ) -> anyhow::Result<()> { - // https://github.com/txpipe/oura/blob/67b01e8739ed2927ced270e08daea74b03bcc7f7/src/sources/common.rs#L91 - let genesis_path = match dbg!(network) { - "mainnet" => GENESIS_MAINNET, - "testnet" => GENESIS_TESTNET, - "preview" => GENESIS_PREVIEW, - "preprod" => GENESIS_PREPROD, - rest => { - return Err(anyhow!( - "{} is invalid. NETWORK must be either mainnet/preview/preprod/testnet", - rest - )) - } - }; - let task_perf_aggregator = Arc::new(Mutex::new(TaskPerfAggregator::default())); tracing::info!("Parsing genesis file..."); let mut time_counter = std::time::Instant::now(); - let file = fs::File::open(genesis_path).expect("Failed to open genesis file"); + let file = fs::File::open(format!("{}/{}-byron-genesis.json", genesis_folder, network)) + .expect("Failed to open genesis file"); let genesis_file: Box = Box::new( parse_genesis_data(file).map_err(|err| anyhow!("can't parse genesis data: {:?}", err))?, ); diff --git a/indexer/src/main.rs b/indexer/src/main.rs index 05bc965d..a9b12f2f 100644 --- a/indexer/src/main.rs +++ b/indexer/src/main.rs @@ -52,7 +52,11 @@ pub enum DbConfig { #[serde(tag = "type", rename_all = "snake_case")] #[serde(deny_unknown_fields)] pub enum SinkConfig { - Cardano { db: DbConfig, network: String }, + Cardano { + db: DbConfig, + network: String, + genesis_folder: Option, + }, } pub enum Network {} @@ -184,6 +188,33 @@ async fn main() -> anyhow::Result<()> { "mainnet" => dcspark_blockchain_source::cardano::NetworkConfiguration::mainnet(), "preprod" => dcspark_blockchain_source::cardano::NetworkConfiguration::preprod(), "preview" => dcspark_blockchain_source::cardano::NetworkConfiguration::preview(), + "custom" => dcspark_blockchain_source::cardano::NetworkConfiguration { + // TODO: dynamically fill in all of this + chain_info: dcspark_blockchain_source::cardano::ChainInfo::Custom { + protocol_magic: 0, + network_id: 0, + }, + relay: (Cow::Borrowed("preprod-node.world.dev.cardano.org."), 30000), + from: dcspark_blockchain_source::cardano::Point::BlockHeader { + slot_nb: dcspark_core::SlotNumber::new(86400), + hash: dcspark_core::BlockId::new( + "c4a1595c5cc7a31eda9e544986fe9387af4e3491afe0ca9a80714f01951bbd5c", + ), + }, + genesis_parent: dcspark_core::BlockId::new( + "d4b8de7a11d929a323373cbab6c1a9bdc931beffff11db111cf9d57356ee1937", + ), + genesis: dcspark_core::BlockId::new( + "9ad7ff320c9cf74e0f5ee78d22a85ce42bb0a487d0506bf60cfb5a91ea4497d2", + ), + shelley_era_config: dcspark_blockchain_source::cardano::time::Era { + first_slot: 4492800, + start_epoch: 208, + known_time: 1596059091, + slot_length: 1, + epoch_length_seconds: 432000, + }, + }, _ => return Err(anyhow::anyhow!("network not supported by source")), }; diff --git a/indexer/src/sinks/cardano.rs b/indexer/src/sinks/cardano.rs index 7b45cc64..31689c0a 100644 --- a/indexer/src/sinks/cardano.rs +++ b/indexer/src/sinks/cardano.rs @@ -3,6 +3,7 @@ use crate::perf_aggregator::PerfAggregator; use crate::sink::Sink; use crate::types::{MultiEraBlock, StoppableService}; use crate::{genesis, DbConfig, SinkConfig}; +use anyhow::anyhow; use async_trait::async_trait; use dcspark_blockchain_source::cardano::Point; @@ -28,6 +29,7 @@ use tasks::utils::TaskPerfAggregator; pub struct CardanoSink { db: DatabaseConnection, network: String, + genesis_folder: Option, exec_plan: Arc, last_epoch: i128, @@ -38,8 +40,12 @@ pub struct CardanoSink { impl CardanoSink { #[allow(unreachable_patterns)] pub async fn new(config: SinkConfig, exec_plan: Arc) -> anyhow::Result { - let (db_config, network) = match config { - SinkConfig::Cardano { db, network } => (db, network), + let (db_config, network, genesis_folder) = match config { + SinkConfig::Cardano { + db, + network, + genesis_folder, + } => (db, network, genesis_folder), _ => todo!("Invalid sink config provided"), }; match db_config { @@ -49,6 +55,7 @@ impl CardanoSink { Ok(Self { db: conn, network, + genesis_folder, exec_plan, last_epoch: -1, epoch_start_time: std::time::Instant::now(), @@ -118,6 +125,8 @@ impl CardanoSink { } } +const KNOWN_GENESIS_FOLDER: &str = "./genesis"; + #[async_trait] impl Sink for CardanoSink { type From = Point; @@ -130,7 +139,27 @@ impl Sink for CardanoSink { }; if start.is_empty() { - genesis::process_genesis(&self.db, &self.network, self.exec_plan.clone()).await?; + // https://github.com/txpipe/oura/blob/67b01e8739ed2927ced270e08daea74b03bcc7f7/src/sources/common.rs#L91 + let genesis_folder: &str = match dbg!(&self.network[..]) { + "mainnet" | "testnet" | "preview" | "preprod" => KNOWN_GENESIS_FOLDER, + "custom" => &self + .genesis_folder + .as_ref() + .expect("genesis_folder should be specified for custom networks")[..], + rest => { + return Err(anyhow!( + "{} is invalid. NETWORK must be either mainnet/preview/preprod/testnet or a 'custom' network", + rest + )) + } + }; + genesis::process_genesis( + &self.db, + &self.network, + genesis_folder, + self.exec_plan.clone(), + ) + .await?; return self.get_latest_point().await; }