@@ -5,19 +5,23 @@ use std::{
5
5
fmt:: Display ,
6
6
pin:: Pin ,
7
7
task:: { Context , Poll } ,
8
+ time:: Duration ,
8
9
} ;
9
10
10
11
use futures:: { FutureExt , Stream } ;
11
- use libp2p:: identity:: secp256k1:: Keypair ;
12
+ use libp2p:: { identity:: secp256k1:: Keypair , PeerId } ;
12
13
use thiserror:: Error ;
13
- use tokio:: sync:: {
14
- broadcast:: { self , error:: RecvError } ,
15
- mpsc,
14
+ use tokio:: {
15
+ sync:: {
16
+ broadcast:: { self , error:: RecvError } ,
17
+ mpsc, oneshot,
18
+ } ,
19
+ time:: timeout,
16
20
} ;
17
21
use tracing:: warn;
18
22
19
23
use crate :: {
20
- commands:: { Command , PublishMessage , UnsignedPublishMessage } ,
24
+ commands:: { Command , PublishMessage , QueryP2PStateCommand , UnsignedPublishMessage } ,
21
25
events:: Event ,
22
26
} ;
23
27
@@ -76,6 +80,59 @@ impl P2PHandle {
76
80
pub fn sign_message ( & self , msg : UnsignedPublishMessage ) -> PublishMessage {
77
81
msg. sign_secp256k1 ( & self . keypair )
78
82
}
83
+
84
+ /// Checks if the P2P node is connected to the specified peer.
85
+ /// Returns true if connected, false otherwise.
86
+ pub async fn is_connected ( & self , peer_id : PeerId ) -> bool {
87
+ let ( sender, receiver) = oneshot:: channel ( ) ;
88
+
89
+ // Send the command to check connection
90
+ let cmd = Command :: QueryP2PState ( QueryP2PStateCommand :: IsConnected {
91
+ peer_id,
92
+ response_sender : sender,
93
+ } ) ;
94
+
95
+ // Use a cloned sender to avoid borrow issues
96
+ let cmd_sender = self . commands . clone ( ) ;
97
+
98
+ // Send the command
99
+ if cmd_sender. send ( cmd) . await . is_err ( ) {
100
+ // If the command channel is closed, assume not connected
101
+ return false ;
102
+ }
103
+
104
+ // Wait for response with timeout
105
+ // TODO: make this configurable
106
+ match timeout ( Duration :: from_secs ( 1 ) , receiver) . await {
107
+ Ok ( Ok ( is_connected) ) => is_connected,
108
+ _ => false , // Timeout or channel closed
109
+ }
110
+ }
111
+
112
+ /// Gets the list of all currently connected peers.
113
+ pub async fn get_connected_peers ( & self ) -> Vec < PeerId > {
114
+ let ( sender, receiver) = oneshot:: channel ( ) ;
115
+
116
+ // Send the command
117
+ let cmd = Command :: QueryP2PState ( QueryP2PStateCommand :: GetConnectedPeers {
118
+ response_sender : sender,
119
+ } ) ;
120
+
121
+ // Use a cloned sender to avoid borrow issues
122
+ let cmd_sender = self . commands . clone ( ) ;
123
+
124
+ // If sending fails, return empty list
125
+ if cmd_sender. send ( cmd) . await . is_err ( ) {
126
+ return Vec :: new ( ) ;
127
+ }
128
+
129
+ // Wait for response with timeout
130
+ // TODO: make this configurable
131
+ match timeout ( Duration :: from_secs ( 1 ) , receiver) . await {
132
+ Ok ( Ok ( peers) ) => peers,
133
+ _ => Vec :: new ( ) , // Timeout or channel closed
134
+ }
135
+ }
79
136
}
80
137
81
138
impl Clone for P2PHandle {
0 commit comments