Skip to content

Commit fd1e6b6

Browse files
committed
Add sc-proof-of-time dependency and integrate synthetic PoT slot handling in development mode for enhanced block production. Update configurations and structures in manual_seal.rs and lib.rs to support new functionality.
1 parent 46e41ff commit fd1e6b6

File tree

4 files changed

+60
-18
lines changed

4 files changed

+60
-18
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/sc-consensus-subspace-dev/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ sc-consensus.workspace = true
2121
sc-telemetry.workspace = true
2222
sc-transaction-pool-api.workspace = true
2323
sc-utils.workspace = true
24+
sc-proof-of-time.workspace = true
2425
sp-api.workspace = true
2526
sp-block-builder = { workspace = true, features = ["std"] }
2627
sp-blockchain.workspace = true

crates/sc-consensus-subspace-dev/src/manual_seal.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use crate::mock_digest::{MockSlotCalculator, create_genesis_solution, create_moc
88
use sc_client_api::BlockBackend;
99
use sc_consensus::{BlockImport, BlockImportParams, ForkChoiceStrategy, ImportResult, StateAction};
1010
use sc_transaction_pool_api::TransactionPool;
11+
use sc_proof_of_time::source::PotSlotInfo;
1112
use sp_api::ProvideRuntimeApi;
1213
use sp_blockchain::{HeaderBackend, HeaderMetadata};
1314
use sp_consensus::{BlockOrigin, Environment, Proposer};
@@ -17,7 +18,9 @@ use std::marker::PhantomData;
1718
use std::sync::Arc;
1819
use std::time::Duration;
1920
use subspace_core_primitives::PublicKey;
21+
use subspace_core_primitives::pot::PotCheckpoints;
2022
use tokio::time::sleep;
23+
use tokio::sync::broadcast::Sender as BroadcastSender;
2124
use tracing::{debug, info, warn};
2225

2326
/// Parameters for dev consensus
@@ -39,6 +42,8 @@ pub struct DevConsensusParams<Block, Client, E, TP, CIDP> {
3942
pub farmer_public_key: PublicKey,
4043
/// Whether to finalize blocks immediately
4144
pub finalize: bool,
45+
/// Sender for synthetic PoT slot notifications (dev mode only)
46+
pub pot_slot_sender: Option<BroadcastSender<PotSlotInfo>>,
4247
/// Marker
4348
pub _phantom: PhantomData<Block>,
4449
}
@@ -55,6 +60,7 @@ pub struct DevConsensus<Block, Client, E, TP, CIDP> {
5560
farmer_public_key: PublicKey,
5661
finalize: bool,
5762
slot_calculator: MockSlotCalculator,
63+
pot_slot_sender: Option<BroadcastSender<PotSlotInfo>>,
5864
_phantom: PhantomData<Block>,
5965
}
6066

@@ -91,6 +97,7 @@ where
9197
farmer_public_key: params.farmer_public_key,
9298
finalize: params.finalize,
9399
slot_calculator: MockSlotCalculator::new(slot_duration_ms),
100+
pot_slot_sender: params.pot_slot_sender,
94101
_phantom: PhantomData,
95102
}
96103
}
@@ -152,6 +159,15 @@ where
152159
next_block_number, *slot, parent_hash
153160
);
154161

162+
// Emit synthetic PoT slot info (dev mode)
163+
if let Some(sender) = &self.pot_slot_sender {
164+
// Use empty checkpoints; PoT verification is bypassed in dev mode
165+
let _ = sender.send(PotSlotInfo {
166+
slot,
167+
checkpoints: PotCheckpoints::default(),
168+
});
169+
}
170+
155171
// Create mock solution and pre-digest
156172
let solution = create_genesis_solution(self.farmer_public_key, self.farmer_public_key);
157173
let pre_digest = create_mock_pre_digest(slot, solution);

crates/subspace-service/src/lib.rs

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,26 +1222,43 @@ where
12221222
let object_mapping_notification_stream = subspace_link.object_mapping_notification_stream();
12231223
let archived_segment_notification_stream = subspace_link.archived_segment_notification_stream();
12241224

1225-
let (pot_source_worker, pot_gossip_worker, pot_slot_info_stream) = PotSourceWorker::new(
1226-
config.is_timekeeper,
1227-
config.timekeeper_cpu_cores,
1228-
client.clone(),
1229-
pot_verifier.clone(),
1230-
Arc::clone(&network_service),
1231-
pot_gossip_notification_service,
1232-
sync_service.clone(),
1233-
sync_oracle.clone(),
1234-
)
1235-
.map_err(|error| Error::Other(error.into()))?;
1225+
// Pot slot info stream used by domains and block production
1226+
// In dev mode, use synthetic stream; otherwise start real PoT workers
1227+
let (dev_pot_slot_sender_opt, pot_slot_info_stream_opt, additional_pot_slot_info_stream): (
1228+
Option<broadcast::Sender<PotSlotInfo>>,
1229+
Option<sc_proof_of_time::source::PotSlotInfoStream>,
1230+
broadcast::Receiver<PotSlotInfo>,
1231+
) = if config.dev_no_farming {
1232+
// Dev mode: create synthetic PoT slot stream (no real PoT workers needed)
1233+
let (dev_pot_slot_sender, dev_pot_slot_receiver) =
1234+
tokio::sync::broadcast::channel::<PotSlotInfo>(16);
1235+
// In dev mode, slot worker is not used, so pot_slot_info_stream_opt is None
1236+
(Some(dev_pot_slot_sender), None, dev_pot_slot_receiver)
1237+
} else {
1238+
// Production mode: start real PoT source workers (needed for domains and block production)
1239+
let (pot_source_worker, pot_gossip_worker, pot_slot_info_stream) = PotSourceWorker::new(
1240+
config.is_timekeeper,
1241+
config.timekeeper_cpu_cores,
1242+
client.clone(),
1243+
pot_verifier.clone(),
1244+
Arc::clone(&network_service),
1245+
pot_gossip_notification_service,
1246+
sync_service.clone(),
1247+
sync_oracle.clone(),
1248+
)
1249+
.map_err(|error| Error::Other(error.into()))?;
12361250

1237-
let additional_pot_slot_info_stream = pot_source_worker.subscribe_pot_slot_info_stream();
1251+
let additional_pot_slot_info_stream = pot_source_worker.subscribe_pot_slot_info_stream();
12381252

1239-
task_manager
1240-
.spawn_essential_handle()
1241-
.spawn("pot-source", Some("pot"), pot_source_worker.run());
1242-
task_manager
1243-
.spawn_essential_handle()
1244-
.spawn("pot-gossip", Some("pot"), pot_gossip_worker.run());
1253+
task_manager
1254+
.spawn_essential_handle()
1255+
.spawn("pot-source", Some("pot"), pot_source_worker.run());
1256+
task_manager
1257+
.spawn_essential_handle()
1258+
.spawn("pot-gossip", Some("pot"), pot_gossip_worker.run());
1259+
1260+
(None, Some(pot_slot_info_stream), additional_pot_slot_info_stream)
1261+
};
12451262

12461263
if config.base.role.is_authority() || config.force_new_slot_notifications {
12471264
// Check if dev-no-farming mode is enabled
@@ -1250,6 +1267,9 @@ where
12501267
warn!("⚠️ This mode bypasses consensus and is FOR DEVELOPMENT ONLY");
12511268
warn!("⚠️ DO NOT USE IN PRODUCTION");
12521269

1270+
// Use the synthetic PoT slot sender created above for dev mode block production
1271+
let dev_pot_slot_sender = dev_pot_slot_sender_opt.expect("dev_pot_slot_sender should be Some in dev mode; qed");
1272+
12531273
let proposer_factory = ProposerFactory::new(
12541274
task_manager.spawn_handle(),
12551275
client.clone(),
@@ -1316,6 +1336,7 @@ where
13161336
block_interval,
13171337
farmer_public_key,
13181338
finalize: false, // TODO: Add finalization support if needed
1339+
pot_slot_sender: Some(dev_pot_slot_sender),
13191340
_phantom: std::marker::PhantomData,
13201341
});
13211342

@@ -1335,6 +1356,9 @@ where
13351356
);
13361357
} else {
13371358
// Production consensus path
1359+
// PoT workers already started unconditionally above
1360+
let pot_slot_info_stream = pot_slot_info_stream_opt.expect("pot_slot_info_stream should be Some in production mode; qed");
1361+
13381362
let proposer_factory = ProposerFactory::new(
13391363
task_manager.spawn_handle(),
13401364
client.clone(),

0 commit comments

Comments
 (0)