Skip to content

Commit 476ea06

Browse files
committed
fix: storage sync, bootstrap consensus, 5MB SDK buffer, batch flush
- Bootstrap validator ignores delta sync from non-bootstrap peers - Non-bootstrap peers always accept bootstrap validator data - SDK response buffer increased from 64KB to 5MB for large blobs - WASM sync consensus: local write-through + P2P broadcast - Batch flush every 5s instead of per-write - Bootstrap end block set to 7,800,000 - Default emission_weight=0.0, max_cpu_secs=1800 - P2P channel capacity 256->4096
1 parent c211432 commit 476ea06

File tree

4 files changed

+49
-30
lines changed

4 files changed

+49
-30
lines changed

bins/validator-node/src/challenge_storage.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,11 +145,19 @@ impl StorageBackend for ChallengeStorageBackend {
145145
signature,
146146
});
147147

148-
// DO NOT write locally before consensus - this causes state divergence.
149-
// The proposer's get_weights would read uncommitted data that other validators
150-
// don't have yet. All nodes (including proposer) write only after P2P consensus.
148+
// Write locally first so WASM can read-your-own-writes during sync
149+
let storage_key = build_challenge_storage_key(challenge_id, key);
150+
if let Err(e) = tokio::task::block_in_place(|| {
151+
tokio::runtime::Handle::current().block_on(self.storage.put(
152+
storage_key,
153+
value.to_vec(),
154+
DPutOptions::default(),
155+
))
156+
}) {
157+
tracing::warn!(error = %e, "Failed to write locally before P2P broadcast");
158+
}
151159

152-
// Broadcast via P2P so all validators apply the write after consensus
160+
// Broadcast via P2P so other validators also apply the write
153161
tracing::debug!(
154162
proposal_id = %hex::encode(&proposal_id[..8]),
155163
challenge_id = %challenge_id,

bins/validator-node/src/main.rs

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -389,10 +389,7 @@ async fn main() -> Result<()> {
389389
enable_indexing: false,
390390
..Default::default()
391391
};
392-
let tracked_storage = TrackedStorage::new(
393-
Arc::clone(&local_storage) as Arc<dyn platform_distributed_storage::DistributedStore>,
394-
tracked_config,
395-
);
392+
let tracked_storage = TrackedStorage::new(Arc::clone(&local_storage) as Arc<dyn platform_distributed_storage::DistributedStore>, tracked_config);
396393
let storage = Arc::new(tracked_storage);
397394
info!("Distributed storage initialized with compression (audit/indexing disabled)");
398395

@@ -3922,7 +3919,14 @@ async fn handle_network_event(
39223919
}
39233920
}
39243921

3925-
if !validator_set.is_validator(&resp.responder) {
3922+
let in_bootstrap = state_manager.apply(|s| s.is_in_bootstrap_period());
3923+
let we_are_bootstrap = keypair.hotkey().to_ss58() == platform_core::constants::BOOTSTRAP_VALIDATOR_SS58;
3924+
if in_bootstrap && we_are_bootstrap && resp.responder.to_ss58() != platform_core::constants::BOOTSTRAP_VALIDATOR_SS58 {
3925+
debug!(
3926+
responder = %resp.responder.to_ss58(),
3927+
"Bootstrap validator ignoring delta sync from non-bootstrap peer"
3928+
);
3929+
} else if !validator_set.is_validator(&resp.responder) {
39263930
warn!(responder = %resp.responder.to_ss58(), "Storage sync response from non-validator");
39273931
} else if resp.entries.is_empty() {
39283932
debug!(
@@ -4017,6 +4021,7 @@ async fn handle_network_event(
40174021
let mut skipped = 0u64;
40184022
let mut max_block = 0u64;
40194023
let opts = put_options_with_block(state_manager);
4024+
let from_bootstrap = resp.responder.to_ss58() == platform_core::constants::BOOTSTRAP_VALIDATOR_SS58;
40204025

40214026
for entry in &resp.entries {
40224027
// Reject entries with unreasonable version numbers
@@ -4034,26 +4039,33 @@ async fn handle_network_event(
40344039

40354040
let key = StorageKey::new(&entry.namespace, hex::encode(&entry.key));
40364041

4037-
// Only apply if peer version is newer
4038-
match storage
4039-
.get(&key, platform_distributed_storage::GetOptions::default())
4040-
.await
4041-
{
4042-
Ok(Some(existing)) if existing.metadata.version >= entry.version => {
4043-
skipped += 1;
4042+
// During bootstrap, always accept data from the bootstrap validator
4043+
// (it is the source of truth). Otherwise, only apply if newer.
4044+
let should_apply = if in_bootstrap && from_bootstrap {
4045+
true
4046+
} else {
4047+
match storage
4048+
.get(&key, platform_distributed_storage::GetOptions::default())
4049+
.await
4050+
{
4051+
Ok(Some(existing)) if existing.metadata.version >= entry.version => false,
4052+
_ => true,
40444053
}
4045-
_ => {
4046-
if let Err(e) =
4047-
storage.put(key, entry.value.clone(), opts.clone()).await
4048-
{
4049-
warn!(error = %e, "Failed to apply synced entry");
4050-
} else {
4051-
applied += 1;
4052-
if entry.updated_block > max_block {
4053-
max_block = entry.updated_block;
4054-
}
4054+
};
4055+
4056+
if should_apply {
4057+
if let Err(e) =
4058+
storage.put(key, entry.value.clone(), opts.clone()).await
4059+
{
4060+
warn!(error = %e, "Failed to apply synced entry");
4061+
} else {
4062+
applied += 1;
4063+
if entry.updated_block > max_block {
4064+
max_block = entry.updated_block;
40554065
}
40564066
}
4067+
} else {
4068+
skipped += 1;
40574069
}
40584070
}
40594071

@@ -5072,8 +5084,7 @@ fn compact_storage_if_needed(db_path: &std::path::Path) -> anyhow::Result<()> {
50725084
if let Some(ns_end) = key.iter().position(|&b| b == b':') {
50735085
let ns = &key[..ns_end];
50745086
let key_part = &key[ns_end + 1..];
5075-
let index_key =
5076-
format!("{}:{}", String::from_utf8_lossy(ns), hex::encode(key_part));
5087+
let index_key = format!("{}:{}", String::from_utf8_lossy(ns), hex::encode(key_part));
50775088
index_tree.remove(index_key.as_bytes())?;
50785089
}
50795090
pruned_count += 1;

crates/challenge-sdk-wasm/src/host_functions.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use alloc::vec;
22
use alloc::vec::Vec;
33

44
const RESPONSE_BUF_SMALL: usize = 4096;
5-
const RESPONSE_BUF_MEDIUM: usize = 64 * 1024;
5+
const RESPONSE_BUF_MEDIUM: usize = 5 * 1024 * 1024;
66
const RESPONSE_BUF_LARGE: usize = 4 * 1024 * 1024;
77

88
#[link(wasm_import_module = "platform_network")]

crates/core/src/constants.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ pub const MIN_VALIDATOR_STAKE_TAO: u64 = 10_000;
8383
pub const BOOTSTRAP_PERIOD_EPOCHS: u64 = 100;
8484

8585
/// Bittensor block number until which the bootstrap validator dominates
86-
pub const BOOTSTRAP_END_BLOCK: u64 = 7_700_000;
86+
pub const BOOTSTRAP_END_BLOCK: u64 = 7_800_000;
8787

8888
/// The bootstrap validator hotkey (SS58) that is trusted during bootstrap
8989
pub const BOOTSTRAP_VALIDATOR_SS58: &str = "5GziQCcRpN8NCJktX343brnfuVe3w6gUYieeStXPD1Dag2At";

0 commit comments

Comments
 (0)