From 360803dbafa42b2501fd7c1c4c99d450ab778414 Mon Sep 17 00:00:00 2001 From: Jay White Date: Mon, 10 Aug 2026 10:08:59 -0400 Subject: [PATCH] fix: default prover-db indexer to disabled unless explicitly enabled --- pallets/prover_db_indexer/README.md | 3 +- pallets/prover_db_indexer/src/lib.rs | 3 ++ pallets/prover_db_indexer/src/tests.rs | 23 +++++++++++++++- sxt-core/src/prover_db_indexer.rs | 38 ++++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 2 deletions(-) diff --git a/pallets/prover_db_indexer/README.md b/pallets/prover_db_indexer/README.md index d06611a6..e8df352d 100644 --- a/pallets/prover_db_indexer/README.md +++ b/pallets/prover_db_indexer/README.md @@ -13,7 +13,8 @@ events forward via HTTP+protobuf: - `pallet_tables::TableDropped` → `drop_table` - `pallet_indexing::QuorumReached` → `put_batches` -The consumer is configured via node-supplied config keys — see +Gated by `prover_db_indexer/enabled` (default `false`). Once enabled, +the consumer is configured via node-supplied config keys — see [`sxt_core::prover_db_indexer::ProverDbConsumerConfig`] for the indexer URL, include filters, block-per-invocation cap, and OCW lock deadline. \ No newline at end of file diff --git a/pallets/prover_db_indexer/src/lib.rs b/pallets/prover_db_indexer/src/lib.rs index 2a18b3ba..c791fc0d 100644 --- a/pallets/prover_db_indexer/src/lib.rs +++ b/pallets/prover_db_indexer/src/lib.rs @@ -151,6 +151,9 @@ pub mod pallet { EventRecord: TryInto>, { fn run_consumer() -> Result<(), ConsumerError> { + if !ProverDbConsumerConfig::enabled(native::config::config::get) { + return Ok(()); + } let config = ProverDbConsumerConfig::try_from_map(native::config::config::get)?; // Serialize concurrent OCW invocations. Substrate spawns // `offchain_worker` for every imported block, and rounds can diff --git a/pallets/prover_db_indexer/src/tests.rs b/pallets/prover_db_indexer/src/tests.rs index ff55540f..77fb14aa 100644 --- a/pallets/prover_db_indexer/src/tests.rs +++ b/pallets/prover_db_indexer/src/tests.rs @@ -14,7 +14,11 @@ use polkadot_sdk::sp_runtime::offchain::Duration; use proof_of_sql_commitment_map::CommitmentSchemeFlags; use prost::Message; use sxt_core::indexing::{BatchId, DataQuorum, SubmitterList}; -use sxt_core::prover_db_indexer::{PROVER_DB_CONFIG_INCLUDE_KEY, PROVER_DB_CONFIG_URL_KEY}; +use sxt_core::prover_db_indexer::{ + PROVER_DB_CONFIG_ENABLED_KEY, + PROVER_DB_CONFIG_INCLUDE_KEY, + PROVER_DB_CONFIG_URL_KEY, +}; use sxt_core::tables::{QuorumScope, Source, TableIdentifier, TableType}; use crate::mock::*; @@ -78,6 +82,7 @@ fn setup_with_config( } }); let mut config_store = std::collections::HashMap::new(); + config_store.insert(PROVER_DB_CONFIG_ENABLED_KEY.to_string(), "true".to_string()); config_store.insert(PROVER_DB_CONFIG_URL_KEY.to_string(), MOCK_URL.to_string()); config_store.insert( PROVER_DB_CONFIG_INCLUDE_KEY.to_string(), @@ -145,6 +150,22 @@ fn ocw_skips_when_not_configured() { }); } +/// Disabled by default, so a configured URL alone must not trigger a run. +#[test] +fn ocw_skips_when_disabled_even_with_url_configured() { + let mut ext = new_test_ext(); + let (offchain, _) = TestOffchainExt::new(); + ext.register_extension(OffchainWorkerExt::new(offchain.clone())); + ext.register_extension(OffchainDbExt::new(offchain)); + let mut config_store = std::collections::HashMap::new(); + config_store.insert(PROVER_DB_CONFIG_URL_KEY.to_string(), MOCK_URL.to_string()); + ext.register_extension(native::config::ConfigExt(std::sync::Arc::new(config_store))); + ext.execute_with(|| { + System::set_block_number(1); + ProverDbIndexer::offchain_worker(1); + }); +} + /// If another OCW round is in progress (lock held), this invocation /// must do nothing — no HTTP traffic, no state reads beyond the lock /// itself. `TestOffchainExt` would panic on an unexpected request, so diff --git a/sxt-core/src/prover_db_indexer.rs b/sxt-core/src/prover_db_indexer.rs index da586b51..6a565195 100644 --- a/sxt-core/src/prover_db_indexer.rs +++ b/sxt-core/src/prover_db_indexer.rs @@ -13,6 +13,9 @@ use url::Url; use crate::tables::TableIdentifier; use crate::IDENT_LENGTH; +/// Config key gating whether the prover-db OCW consumer runs at all; defaults to disabled. +pub const PROVER_DB_CONFIG_ENABLED_KEY: &str = "prover_db_indexer/enable"; + /// Config key holding the prover-db indexer's target URL. pub const PROVER_DB_CONFIG_URL_KEY: &str = "prover_db_indexer/url"; @@ -95,6 +98,14 @@ pub enum ProverDbConsumerConfigError { } impl ProverDbConsumerConfig { + /// Whether [`PROVER_DB_CONFIG_ENABLED_KEY`] is set to `true`; defaults to `false`. + pub fn enabled Option>>(get: F) -> bool { + get(PROVER_DB_CONFIG_ENABLED_KEY) + .flatten() + .and_then(|s| s.parse::().ok()) + .unwrap_or(false) + } + /// Builds a config by looking up each setting via `get`, where /// `get(key)` returns `None` if `key` isn't registered at all, or /// `Some(None)` if it's registered but unset. @@ -283,6 +294,33 @@ mod tests { TableIdentifier::from_str_unchecked(name, namespace) } + // ── ProverDbConsumerConfig::enabled ────────────────────────────── + + #[test] + fn enabled_defaults_to_false() { + assert!(!ProverDbConsumerConfig::enabled(make_get(&[]))); + assert!(!ProverDbConsumerConfig::enabled(make_get(&[( + PROVER_DB_CONFIG_ENABLED_KEY, + None, + )]))); + assert!(!ProverDbConsumerConfig::enabled(make_get(&[( + PROVER_DB_CONFIG_ENABLED_KEY, + Some("not-a-bool"), + )]))); + } + + #[test] + fn enabled_true_when_explicitly_set() { + assert!(ProverDbConsumerConfig::enabled(make_get(&[( + PROVER_DB_CONFIG_ENABLED_KEY, + Some("true"), + )]))); + assert!(!ProverDbConsumerConfig::enabled(make_get(&[( + PROVER_DB_CONFIG_ENABLED_KEY, + Some("false"), + )]))); + } + // ── ProverDbConsumerConfig::try_from_map ───────────────────────── /// Builds a `get` closure from an explicit key list. A key absent