Skip to content

Commit 6a0902b

Browse files
refactor: split big files in dash-spv (#160)
* refactor: split big files * small fixes
1 parent 7a0ee48 commit 6a0902b

36 files changed

+12600
-11857
lines changed

dash-spv/ARCHITECTURE.md

Lines changed: 306 additions & 316 deletions
Large diffs are not rendered by default.

dash-spv/CODE_ANALYSIS_SUMMARY.md

Lines changed: 214 additions & 224 deletions
Large diffs are not rendered by default.

dash-spv/src/client/chainlock.rs

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
//! ChainLock processing and validation.
2+
//!
3+
//! This module contains:
4+
//! - ChainLock processing
5+
//! - InstantSendLock processing
6+
//! - ChainLock validation updates
7+
//! - Pending ChainLock validation
8+
9+
use std::sync::Arc;
10+
11+
use crate::error::{Result, SpvError};
12+
use crate::network::NetworkManager;
13+
use crate::storage::StorageManager;
14+
use crate::types::SpvEvent;
15+
use key_wallet_manager::wallet_interface::WalletInterface;
16+
17+
use super::DashSpvClient;
18+
19+
impl<
20+
W: WalletInterface + Send + Sync + 'static,
21+
N: NetworkManager + Send + Sync + 'static,
22+
S: StorageManager + Send + Sync + 'static,
23+
> DashSpvClient<W, N, S>
24+
{
25+
/// Process and validate a ChainLock.
26+
pub async fn process_chainlock(
27+
&mut self,
28+
chainlock: dashcore::ephemerealdata::chain_lock::ChainLock,
29+
) -> Result<()> {
30+
tracing::info!(
31+
"Processing ChainLock for block {} at height {}",
32+
chainlock.block_hash,
33+
chainlock.block_height
34+
);
35+
36+
// First perform basic validation and storage through ChainLockManager
37+
let chain_state = self.state.read().await;
38+
{
39+
let mut storage = self.storage.lock().await;
40+
self.chainlock_manager
41+
.process_chain_lock(chainlock.clone(), &chain_state, &mut *storage)
42+
.await
43+
.map_err(SpvError::Validation)?;
44+
}
45+
drop(chain_state);
46+
47+
// Sequential sync handles masternode validation internally
48+
tracing::info!(
49+
"ChainLock stored, sequential sync will handle masternode validation internally"
50+
);
51+
52+
// Update chain state with the new ChainLock
53+
let mut state = self.state.write().await;
54+
if let Some(current_chainlock_height) = state.last_chainlock_height {
55+
if chainlock.block_height <= current_chainlock_height {
56+
tracing::debug!(
57+
"ChainLock for height {} does not supersede current ChainLock at height {}",
58+
chainlock.block_height,
59+
current_chainlock_height
60+
);
61+
return Ok(());
62+
}
63+
}
64+
65+
// Update our confirmed chain tip
66+
state.last_chainlock_height = Some(chainlock.block_height);
67+
state.last_chainlock_hash = Some(chainlock.block_hash);
68+
69+
tracing::info!(
70+
"🔒 Updated confirmed chain tip to ChainLock at height {} ({})",
71+
chainlock.block_height,
72+
chainlock.block_hash
73+
);
74+
75+
// Emit ChainLock event
76+
self.emit_event(SpvEvent::ChainLockReceived {
77+
height: chainlock.block_height,
78+
hash: chainlock.block_hash,
79+
});
80+
81+
// No need for additional storage - ChainLockManager already handles it
82+
Ok(())
83+
}
84+
85+
/// Process and validate an InstantSendLock.
86+
pub(super) async fn process_instantsendlock(
87+
&mut self,
88+
islock: dashcore::ephemerealdata::instant_lock::InstantLock,
89+
) -> Result<()> {
90+
tracing::info!("Processing InstantSendLock for tx {}", islock.txid);
91+
92+
// TODO: Implement InstantSendLock validation
93+
// - Verify BLS signature against known quorum
94+
// - Check if all inputs are locked
95+
// - Mark transaction as instantly confirmed
96+
// - Store InstantSendLock for future reference
97+
98+
// For now, just log the InstantSendLock details
99+
tracing::info!(
100+
"InstantSendLock validated: txid={}, inputs={}, signature={:?}",
101+
islock.txid,
102+
islock.inputs.len(),
103+
islock.signature.to_string().chars().take(20).collect::<String>()
104+
);
105+
106+
Ok(())
107+
}
108+
109+
/// Update ChainLock validation with masternode engine after sync completes.
110+
/// This should be called when masternode sync finishes to enable full validation.
111+
/// Returns true if the engine was successfully set.
112+
pub fn update_chainlock_validation(&self) -> Result<bool> {
113+
// Check if masternode sync has an engine available
114+
if let Some(engine) = self.sync_manager.get_masternode_engine() {
115+
// Clone the engine for the ChainLockManager
116+
let engine_arc = Arc::new(engine.clone());
117+
self.chainlock_manager.set_masternode_engine(engine_arc);
118+
119+
tracing::info!("Updated ChainLockManager with masternode engine for full validation");
120+
121+
// Note: Pending ChainLocks will be validated when they are next processed
122+
// or can be triggered by calling validate_pending_chainlocks separately
123+
// when mutable access to storage is available
124+
125+
Ok(true)
126+
} else {
127+
tracing::warn!("Masternode engine not available for ChainLock validation update");
128+
Ok(false)
129+
}
130+
}
131+
132+
/// Validate all pending ChainLocks after masternode engine is available.
133+
/// This requires mutable access to self for storage access.
134+
pub async fn validate_pending_chainlocks(&mut self) -> Result<()> {
135+
let chain_state = self.state.read().await;
136+
137+
let mut storage = self.storage.lock().await;
138+
match self.chainlock_manager.validate_pending_chainlocks(&chain_state, &mut *storage).await
139+
{
140+
Ok(_) => {
141+
tracing::info!("Successfully validated pending ChainLocks");
142+
Ok(())
143+
}
144+
Err(e) => {
145+
tracing::error!("Failed to validate pending ChainLocks: {}", e);
146+
Err(SpvError::Validation(e))
147+
}
148+
}
149+
}
150+
}

0 commit comments

Comments
 (0)