Skip to content

Commit 833114f

Browse files
committed
bad rebase fixed
1 parent e3621de commit 833114f

8 files changed

Lines changed: 116 additions & 242 deletions

File tree

dash-spv/peer_reputation.json

Lines changed: 0 additions & 90 deletions
This file was deleted.

dash-spv/src/client/chainlock.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@ impl<W: WalletInterface, N: NetworkManager, S: StorageManager> DashSpvClient<W,
4141
.await
4242
{
4343
// Penalize the peer that relayed the invalid ChainLock
44-
let reason = format!("Invalid ChainLock: {}", e);
45-
self.network.penalize_peer_invalid_chainlock(peer_address, &reason).await;
44+
self.network.penalize_peer_invalid_chainlock(peer_address).await;
4645
return Err(SpvError::Validation(e));
4746
}
4847
}
@@ -110,7 +109,7 @@ impl<W: WalletInterface, N: NetworkManager, S: StorageManager> DashSpvClient<W,
110109
tracing::warn!("{}", reason);
111110

112111
// Ban the peer using the reputation system
113-
self.network.penalize_peer_invalid_instantlock(peer_address, &reason).await;
112+
self.network.penalize_peer_invalid_instantlock(peer_address).await;
114113

115114
return Err(SpvError::Validation(e));
116115
}

dash-spv/src/client/queries.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,20 @@ impl<W: WalletInterface, N: NetworkManager, S: StorageManager> DashSpvClient<W,
3232
self.network.peer_count()
3333
}
3434

35+
/// Disconnect a specific peer.
36+
pub async fn disconnect_peer(&self, addr: &std::net::SocketAddr, reason: &str) -> Result<()> {
37+
// Cast network manager to PeerNetworkManager to access disconnect_peer
38+
let network = self
39+
.network
40+
.as_any()
41+
.downcast_ref::<crate::network::manager::PeerNetworkManager>()
42+
.ok_or_else(|| {
43+
SpvError::Config("Network manager does not support peer disconnection".to_string())
44+
})?;
45+
46+
network.disconnect_peer(addr, reason).await
47+
}
48+
3549
// ============ Masternode Queries ============
3650

3751
/// Get a reference to the masternode list engine.

dash-spv/src/network/manager.rs

Lines changed: 55 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Peer network manager for SPV client
22
3-
use std::collections::HashSet;
3+
use std::collections::{HashMap, HashSet};
44
use std::net::SocketAddr;
55
use std::path::PathBuf;
66
use std::sync::atomic::{AtomicUsize, Ordering};
@@ -17,9 +17,7 @@ use crate::network::addrv2::AddrV2Handler;
1717
use crate::network::constants::*;
1818
use crate::network::discovery::DnsDiscovery;
1919
use crate::network::pool::PeerPool;
20-
use crate::network::reputation::{
21-
misbehavior_scores, positive_scores, PeerReputationManager, ReputationAware,
22-
};
20+
use crate::network::reputation::{ChangeReason, PeerReputationManager};
2321
use crate::network::{
2422
HandshakeManager, Message, MessageDispatcher, MessageType, NetworkManager, Peer,
2523
};
@@ -446,11 +444,9 @@ impl PeerNetworkManager {
446444
headers2_disabled.lock().await.insert(addr);
447445
// Apply reputation penalty
448446
reputation_manager
449-
.update_reputation(
450-
addr,
451-
misbehavior_scores::INVALID_MESSAGE,
452-
"Headers2 decompression failed",
453-
)
447+
.lock()
448+
.await
449+
.update_reputation(addr, ChangeReason::InvalidHeaders2)
454450
.await;
455451
continue; // Don't forward corrupted message
456452
}
@@ -759,7 +755,7 @@ impl PeerNetworkManager {
759755
}
760756

761757
// Save reputation data periodically
762-
if let Err(e) = reputation_manager.save_to_storage(&*peer_store).await {
758+
if let Err(e) = reputation_manager.lock().await.save_to_storage(&*peer_store).await {
763759
log::warn!("Failed to save reputation data: {}", e);
764760
}
765761
}
@@ -972,16 +968,37 @@ impl PeerNetworkManager {
972968
}
973969

974970
/// Disconnect a specific peer
975-
pub async fn disconnect_peer(&self, addr: &SocketAddr) -> Result<(), Error> {
971+
pub async fn disconnect_peer(&self, addr: &SocketAddr, reason: &str) -> Result<(), Error> {
972+
log::info!("Disconnecting peer {} - reason: {}", addr, reason);
973+
974+
// Remove the peer
976975
self.pool.remove_peer(addr).await;
977976

978977
Ok(())
979978
}
980979

981980
/// Get reputation information for all peers
982981
pub async fn get_peer_reputations(&self) -> HashMap<SocketAddr, (i32, bool)> {
983-
let reputations = self.reputation_manager.lock().await.get_all_reputations().await;
984-
reputations.into_iter().map(|(addr, rep)| (addr, (rep.score, rep.is_banned()))).collect()
982+
let mut lock = self.reputation_manager.lock().await;
983+
let reputations = lock.get_all_reputations().await;
984+
reputations.iter().map(|(addr, rep)| (*addr, (rep.score(), rep.is_banned()))).collect()
985+
}
986+
987+
/// Ban a specific peer manually
988+
pub async fn ban_peer(&self, addr: &SocketAddr, reason: &str) -> Result<(), Error> {
989+
log::info!("Manually banning peer {} - reason: {}", addr, reason);
990+
991+
// Disconnect the peer first
992+
self.disconnect_peer(addr, reason).await?;
993+
994+
// Update reputation to trigger ban
995+
self.reputation_manager
996+
.lock()
997+
.await
998+
.update_reputation(*addr, ChangeReason::ManuallyBanned)
999+
.await;
1000+
1001+
Ok(())
9851002
}
9861003

9871004
/// Unban a specific peer
@@ -1003,7 +1020,9 @@ impl PeerNetworkManager {
10031020
}
10041021

10051022
// Save reputation data before shutdown
1006-
if let Err(e) = self.reputation_manager.save_to_storage(&*self.peer_store).await {
1023+
if let Err(e) =
1024+
self.reputation_manager.lock().await.save_to_storage(&*self.peer_store).await
1025+
{
10071026
log::warn!("Failed to save reputation data on shutdown: {}", e);
10081027
}
10091028

@@ -1098,64 +1117,62 @@ impl NetworkManager for PeerNetworkManager {
10981117
} // end match
10991118
} // end send_message
11001119

1101-
async fn penalize_peer(&self, address: SocketAddr, score_change: i32, reason: &str) {
1102-
self.reputation_manager.update_reputation(address, score_change, reason).await;
1120+
async fn penalize_peer(&self, address: SocketAddr, reason: ChangeReason) {
1121+
self.reputation_manager.lock().await.update_reputation(address, reason).await;
11031122
}
11041123

1105-
async fn penalize_peer_invalid_chainlock(&self, address: SocketAddr, reason: &str) {
1106-
match self.disconnect_peer(&address, reason).await {
1124+
async fn penalize_peer_invalid_chainlock(&self, address: SocketAddr) {
1125+
match self.disconnect_peer(&address, &ChangeReason::InvalidChainLock.to_string()).await {
11071126
Ok(()) => {
1108-
log::warn!(
1109-
"Peer {} disconnected for invalid ChainLock enforcement: {}",
1110-
address,
1111-
reason
1112-
);
1127+
log::warn!("Peer {} disconnected for invalid ChainLock enforcement", address,);
11131128
}
11141129
Err(err) => {
11151130
log::error!(
1116-
"Failed to disconnect peer {} after invalid ChainLock enforcement ({}): {}",
1131+
"Failed to disconnect peer {} after invalid ChainLock enforcement: {}",
11171132
address,
1118-
reason,
11191133
err
11201134
);
11211135
}
11221136
}
11231137

11241138
// Apply misbehavior score and a short temporary ban
11251139
self.reputation_manager
1126-
.update_reputation(address, misbehavior_scores::INVALID_CHAINLOCK, reason)
1140+
.lock()
1141+
.await
1142+
.update_reputation(address, ChangeReason::InvalidChainLock)
11271143
.await;
11281144

11291145
// Short ban: 10 minutes for relaying invalid ChainLock
11301146
self.reputation_manager
1131-
.temporary_ban_peer(address, Duration::from_secs(10 * 60), reason)
1147+
.lock()
1148+
.await
1149+
.temporary_ban_peer(address, Duration::from_secs(10 * 60))
11321150
.await;
11331151
}
11341152

1135-
async fn penalize_peer_invalid_instantlock(&self, address: SocketAddr, reason: &str) {
1153+
async fn penalize_peer_invalid_instantlock(&self, address: SocketAddr) {
11361154
// Apply misbehavior score and a short temporary ban
11371155
self.reputation_manager
1138-
.update_reputation(address, misbehavior_scores::INVALID_INSTANTLOCK, reason)
1156+
.lock()
1157+
.await
1158+
.update_reputation(address, ChangeReason::InvalidInstantLock)
11391159
.await;
11401160

11411161
// Short ban: 10 minutes for relaying invalid InstantLock
11421162
self.reputation_manager
1143-
.temporary_ban_peer(address, Duration::from_secs(10 * 60), reason)
1163+
.lock()
1164+
.await
1165+
.temporary_ban_peer(address, Duration::from_secs(10 * 60))
11441166
.await;
11451167

1146-
match self.disconnect_peer(&address, reason).await {
1168+
match self.disconnect_peer(&address, &ChangeReason::InvalidInstantLock.to_string()).await {
11471169
Ok(()) => {
1148-
log::warn!(
1149-
"Peer {} disconnected for invalid InstantLock enforcement: {}",
1150-
address,
1151-
reason
1152-
);
1170+
log::warn!("Peer {} disconnected for invalid InstantLock enforcement", address,);
11531171
}
11541172
Err(err) => {
11551173
log::error!(
1156-
"Failed to disconnect peer {} after invalid InstantLock enforcement ({}): {}",
1174+
"Failed to disconnect peer {} after invalid InstantLock enforcement: {}",
11571175
address,
1158-
reason,
11591176
err
11601177
);
11611178
}

dash-spv/src/network/mod.rs

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ mod message_type;
1414
#[cfg(test)]
1515
mod tests;
1616

17-
use crate::error::NetworkResult;
17+
use crate::{error::NetworkResult, network::reputation::ChangeReason};
1818
use async_trait::async_trait;
1919
use dashcore::network::message::NetworkMessage;
2020
use dashcore::BlockHash;
@@ -23,6 +23,7 @@ pub use manager::PeerNetworkManager;
2323
pub use message_dispatcher::{Message, MessageDispatcher};
2424
pub use message_type::MessageType;
2525
pub use peer::Peer;
26+
pub(crate) use reputation::PeerReputation;
2627
use std::net::SocketAddr;
2728
use tokio::sync::mpsc::UnboundedReceiver;
2829

@@ -95,25 +96,15 @@ pub trait NetworkManager: Send + Sync + 'static {
9596

9697
/// Penalize a peer by address by adjusting reputation.
9798
/// Default implementation is a no-op for managers without reputation.
98-
async fn penalize_peer(&self, _address: SocketAddr, _score_change: i32, _reason: &str) {}
99+
async fn penalize_peer(&self, _address: SocketAddr, _reason: ChangeReason) {}
99100

100101
/// Penalize a peer by address for an invalid ChainLock.
101-
async fn penalize_peer_invalid_chainlock(&self, address: SocketAddr, reason: &str) {
102-
self.penalize_peer(
103-
address,
104-
crate::network::reputation::misbehavior_scores::INVALID_CHAINLOCK,
105-
reason,
106-
)
107-
.await;
102+
async fn penalize_peer_invalid_chainlock(&self, address: SocketAddr) {
103+
self.penalize_peer(address, ChangeReason::InvalidChainLock).await;
108104
}
109105

110106
/// Penalize a peer by address for an invalid InstantLock.
111-
async fn penalize_peer_invalid_instantlock(&self, peer_address: SocketAddr, reason: &str) {
112-
self.penalize_peer(
113-
peer_address,
114-
crate::network::reputation::misbehavior_scores::INVALID_INSTANTLOCK,
115-
reason,
116-
)
117-
.await;
107+
async fn penalize_peer_invalid_instantlock(&self, peer_address: SocketAddr) {
108+
self.penalize_peer(peer_address, ChangeReason::InvalidInstantLock).await;
118109
}
119110
}

0 commit comments

Comments
 (0)