Skip to content

Commit a54d48d

Browse files
committed
fix logging of states and ask only one peer for mnlist diffs
1 parent 0fa2837 commit a54d48d

5 files changed

Lines changed: 102 additions & 35 deletions

File tree

dash-spv/src/client/mod.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2029,10 +2029,6 @@ impl DashSpvClient {
20292029
);
20302030
None
20312031
} else {
2032-
tracing::debug!(
2033-
"MasternodeListEngine has {} masternode lists",
2034-
engine.masternode_lists.len()
2035-
);
20362032
Some(engine)
20372033
}
20382034
}

dash-spv/src/network/multi_peer.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1123,7 +1123,8 @@ impl NetworkManager for MultiPeerNetworkManager {
11231123
NetworkMessage::GetHeaders(_)
11241124
| NetworkMessage::GetCFHeaders(_)
11251125
| NetworkMessage::GetCFilters(_)
1126-
| NetworkMessage::GetData(_) => self.send_to_single_peer(message).await,
1126+
| NetworkMessage::GetData(_)
1127+
| NetworkMessage::GetMnListD(_) => self.send_to_single_peer(message).await,
11271128
_ => {
11281129
// For other messages, broadcast to all peers
11291130
let results = self.broadcast(message).await;

dash-spv/src/storage/disk.rs

Lines changed: 85 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1444,27 +1444,99 @@ impl StorageManager for DiskStorageManager {
14441444
}
14451445

14461446
async fn store_masternode_state(&mut self, state: &MasternodeState) -> StorageResult<()> {
1447-
let path = self.base_path.join("state/masternode.json");
1448-
let json = serde_json::to_string_pretty(state).map_err(|e| {
1447+
// Store the main state info as JSON (without the large engine_state)
1448+
let json_path = self.base_path.join("state/masternode.json");
1449+
let engine_path = self.base_path.join("state/masternode_engine.bin");
1450+
1451+
// Create a version without the engine state for JSON storage
1452+
let json_state = serde_json::json!({
1453+
"last_height": state.last_height,
1454+
"last_update": state.last_update,
1455+
"terminal_block_hash": state.terminal_block_hash,
1456+
"engine_state_size": state.engine_state.len()
1457+
});
1458+
1459+
let json = serde_json::to_string_pretty(&json_state).map_err(|e| {
14491460
StorageError::Serialization(format!("Failed to serialize masternode state: {}", e))
14501461
})?;
1451-
1452-
tokio::fs::write(path, json).await?;
1462+
tokio::fs::write(json_path, json).await?;
1463+
1464+
// Store the engine state as binary
1465+
if !state.engine_state.is_empty() {
1466+
tokio::fs::write(engine_path, &state.engine_state).await?;
1467+
}
1468+
14531469
Ok(())
14541470
}
14551471

14561472
async fn load_masternode_state(&self) -> StorageResult<Option<MasternodeState>> {
1457-
let path = self.base_path.join("state/masternode.json");
1458-
if !path.exists() {
1473+
let json_path = self.base_path.join("state/masternode.json");
1474+
let engine_path = self.base_path.join("state/masternode_engine.bin");
1475+
1476+
if !json_path.exists() {
14591477
return Ok(None);
14601478
}
1461-
1462-
let content = tokio::fs::read_to_string(path).await?;
1463-
let state = serde_json::from_str(&content).map_err(|e| {
1464-
StorageError::Serialization(format!("Failed to deserialize masternode state: {}", e))
1465-
})?;
1466-
1467-
Ok(Some(state))
1479+
1480+
// Try to read the file with size limit check
1481+
let metadata = tokio::fs::metadata(&json_path).await?;
1482+
if metadata.len() > 10_000_000 { // 10MB limit for JSON file
1483+
tracing::error!("Masternode state JSON file is too large: {} bytes. Likely corrupted.", metadata.len());
1484+
// Delete the corrupted file and return None to start fresh
1485+
let _ = tokio::fs::remove_file(&json_path).await;
1486+
let _ = tokio::fs::remove_file(&engine_path).await;
1487+
return Ok(None);
1488+
}
1489+
1490+
let content = tokio::fs::read_to_string(&json_path).await?;
1491+
1492+
// First try to parse as the new format (without engine_state in JSON)
1493+
if let Ok(json_state) = serde_json::from_str::<serde_json::Value>(&content) {
1494+
if !json_state.get("engine_state").is_some() {
1495+
// New format - load from separate files
1496+
let last_height = json_state["last_height"].as_u64()
1497+
.ok_or_else(|| StorageError::Serialization("Missing last_height".to_string()))? as u32;
1498+
let last_update = json_state["last_update"].as_u64()
1499+
.ok_or_else(|| StorageError::Serialization("Missing last_update".to_string()))?;
1500+
let terminal_block_hash = json_state["terminal_block_hash"].as_array()
1501+
.and_then(|arr| {
1502+
if arr.len() == 32 {
1503+
let mut hash = [0u8; 32];
1504+
for (i, v) in arr.iter().enumerate() {
1505+
hash[i] = v.as_u64()? as u8;
1506+
}
1507+
Some(hash)
1508+
} else {
1509+
None
1510+
}
1511+
});
1512+
1513+
// Load the engine state binary if it exists
1514+
let engine_state = if engine_path.exists() {
1515+
tokio::fs::read(engine_path).await?
1516+
} else {
1517+
Vec::new()
1518+
};
1519+
1520+
return Ok(Some(MasternodeState {
1521+
last_height,
1522+
engine_state,
1523+
last_update,
1524+
terminal_block_hash,
1525+
}));
1526+
}
1527+
}
1528+
1529+
// Fall back to old format (with engine_state in JSON) - but with size protection
1530+
match serde_json::from_str::<MasternodeState>(&content) {
1531+
Ok(state) => Ok(Some(state)),
1532+
Err(e) => {
1533+
tracing::error!("Failed to deserialize masternode state: {}. Deleting corrupted file.", e);
1534+
// Delete the corrupted file
1535+
let _ = tokio::fs::remove_file(&json_path).await;
1536+
let _ = tokio::fs::remove_file(&engine_path).await;
1537+
Ok(None)
1538+
}
1539+
}
14681540
}
14691541

14701542
async fn store_chain_state(&mut self, state: &ChainState) -> StorageResult<()> {

dash-spv/src/storage/service.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,21 @@ impl StorageService {
216216
tracing::info!("Storage service started");
217217

218218
while let Some(command) = self.command_rx.recv().await {
219-
tracing::debug!("StorageService: received command {:?}", command);
219+
// Log command details, but avoid logging large data fields
220+
match &command {
221+
StorageCommand::SaveMasternodeState { .. } => {
222+
tracing::debug!("StorageService: received command SaveMasternodeState (details omitted due to large data)");
223+
}
224+
StorageCommand::StoreChainState { .. } => {
225+
tracing::debug!("StorageService: received command StoreChainState (details omitted due to large data)");
226+
}
227+
StorageCommand::StoreFilter { .. } => {
228+
tracing::debug!("StorageService: received command StoreFilter (details omitted due to large data)");
229+
}
230+
_ => {
231+
tracing::debug!("StorageService: received command {:?}", command);
232+
}
233+
}
220234
self.process_command(command).await;
221235
}
222236

dash-spv/src/sync/masternodes.rs

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,6 @@ impl MasternodeSyncManager {
9797
// Deserialize the engine state
9898
match bincode::deserialize::<MasternodeListEngine>(&state.engine_state) {
9999
Ok(engine) => {
100-
tracing::info!(
101-
"Restored masternode engine state from storage (last_height: {}, {} masternode lists)",
102-
state.last_height,
103-
engine.masternode_lists.len()
104-
);
105100
self.engine = Some(engine);
106101
}
107102
Err(e) => {
@@ -1644,17 +1639,6 @@ impl MasternodeSyncManager {
16441639

16451640
tracing::info!("Successfully applied masternode list diff");
16461641

1647-
// Log the current masternode engine state after applying diff
1648-
if let Some(engine) = &self.engine {
1649-
let current_ml_height = engine.masternode_lists.keys().max().copied().unwrap_or(0);
1650-
tracing::info!(
1651-
"Masternode engine state after diff: highest ML height = {}, total MLs = {}, known snapshots = {}",
1652-
current_ml_height,
1653-
engine.masternode_lists.len(),
1654-
engine.known_snapshots.len()
1655-
);
1656-
}
1657-
16581642
// Find the height of the target block
16591643
let target_height = if let Some(height) =
16601644
storage.get_header_height_by_hash(&target_block_hash).await.map_err(|e| {

0 commit comments

Comments
 (0)