Skip to content

Commit fd05bce

Browse files
quakeCopilot
andcommitted
feat(rpc): support connect_peer by pubkey
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 8af04a8 commit fd05bce

File tree

5 files changed

+91
-55
lines changed

5 files changed

+91
-55
lines changed

crates/fiber-lib/src/fiber/network.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,8 @@ pub enum NetworkActorCommand {
288288
/// Network commands
289289
// Connect to a peer, and optionally also save the peer to the peer store.
290290
ConnectPeer(Multiaddr, bool),
291+
// Connect to a peer via pubkey, resolving address from local graph/saved state.
292+
ConnectPeerWithPubkey(Pubkey, RpcReplyPort<Result<(), String>>),
291293
DisconnectPeer(Pubkey, PeerDisconnectReason),
292294
// Save the address of a peer to the peer store, the address here must be a valid
293295
// multiaddr with the peer id.
@@ -1105,6 +1107,24 @@ where
11051107
// Tentacle sends an event by calling handle_error function instead, which
11061108
// may receive errors like DialerError.
11071109
}
1110+
NetworkActorCommand::ConnectPeerWithPubkey(pubkey, reply) => {
1111+
let address = state
1112+
.get_peer_addresses_by_pubkey(&pubkey)
1113+
.into_iter()
1114+
.choose(&mut rand::thread_rng());
1115+
let Some(addr) = address else {
1116+
let _ = reply.send(Err(Error::PeerNotFound(pubkey).to_string()));
1117+
return Ok(());
1118+
};
1119+
match state.control.dial(addr, TargetProtocol::All).await {
1120+
Ok(()) => {
1121+
let _ = reply.send(Ok(()));
1122+
}
1123+
Err(err) => {
1124+
let _ = reply.send(Err(err.to_string()));
1125+
}
1126+
}
1127+
}
11081128
NetworkActorCommand::DisconnectPeer(pubkey, reason) => {
11091129
if let Some(session) = state.peer_session_map.get(&pubkey).map(|p| p.session_id) {
11101130
debug!(

crates/fiber-lib/src/fiber/tests/rpc.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use crate::{
1818
graph::{GraphNodesParams, GraphNodesResult},
1919
invoice::{InvoiceParams, InvoiceResult, NewInvoiceParams},
2020
payment::{GetPaymentCommandParams, GetPaymentCommandResult},
21-
peer::ListPeersResult,
21+
peer::{ConnectPeerParams, ListPeersResult},
2222
},
2323
};
2424
use biscuit_auth::macros::biscuit;
@@ -209,7 +209,7 @@ async fn test_rpc_list_peers() {
209209
Some(gen_rpc_config()),
210210
)
211211
.await;
212-
let [mut node_0, mut node_1] = nodes.try_into().expect("2 nodes");
212+
let [mut node_0, node_1] = nodes.try_into().expect("2 nodes");
213213

214214
let list_peers: ListPeersResult = node_0.send_rpc_request("list_peers", ()).await.unwrap();
215215
assert_eq!(list_peers.peers.len(), 1);
@@ -231,6 +231,23 @@ async fn test_rpc_list_peers() {
231231
let list_peers: ListPeersResult = node_0.send_rpc_request("list_peers", ()).await.unwrap();
232232
assert_eq!(list_peers.peers.len(), 0);
233233

234+
let _res: () = node_0
235+
.send_rpc_request(
236+
"connect_peer",
237+
ConnectPeerParams {
238+
address: None,
239+
pubkey: Some(node_1_pubkey),
240+
save: Some(false),
241+
},
242+
)
243+
.await
244+
.unwrap();
245+
tokio::time::sleep(tokio::time::Duration::from_millis(1000)).await;
246+
247+
let list_peers: ListPeersResult = node_0.send_rpc_request("list_peers", ()).await.unwrap();
248+
assert_eq!(list_peers.peers.len(), 1);
249+
assert_eq!(list_peers.peers[0].pubkey, node_1.pubkey);
250+
234251
let mut node_3 = NetworkNode::new_with_config(
235252
NetworkNodeConfigBuilder::new()
236253
.node_name(Some(format!("node-{}", 3)))
@@ -248,7 +265,6 @@ async fn test_rpc_list_peers() {
248265
assert_eq!(list_peers.peers.len(), 1);
249266
assert_eq!(list_peers.peers[0].pubkey, node_0.pubkey);
250267

251-
node_0.connect_to(&mut node_1).await;
252268
let list_peers: ListPeersResult = node_0.send_rpc_request("list_peers", ()).await.unwrap();
253269
assert_eq!(list_peers.peers.len(), 2);
254270
dbg!("list_peers: {:?}", &list_peers);

crates/fiber-lib/src/rpc/README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -865,7 +865,10 @@ Connect to a peer.
865865

866866
##### Params
867867

868-
* `address` - <em>`MultiAddr`</em>, The address of the peer to connect to.
868+
* `address` - <em>`Option<MultiAddr>`</em>, The address of the peer to connect to.
869+
Either `address` or `pubkey` must be provided.
870+
* `pubkey` - <em>Option<[Pubkey](#type-pubkey)></em>, The public key of the peer to connect to.
871+
The node resolves the address from locally synced graph data.
869872
* `save` - <em>`Option<bool>`</em>, Whether to save the peer address to the peer store.
870873

871874
##### Returns

crates/fiber-lib/src/rpc/peer.rs

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@ pub use tentacle::multiaddr::MultiAddr;
1616
#[derive(Serialize, Deserialize, Debug, Clone)]
1717
pub struct ConnectPeerParams {
1818
/// The address of the peer to connect to.
19-
pub address: MultiAddr,
19+
/// Either `address` or `pubkey` must be provided.
20+
pub address: Option<MultiAddr>,
21+
/// The public key of the peer to connect to.
22+
/// The node resolves the address from locally synced graph data.
23+
pub pubkey: Option<Pubkey>,
2024
/// Whether to save the peer address to the peer store.
2125
pub save: Option<bool>,
2226
}
@@ -94,11 +98,27 @@ impl PeerRpcServer for PeerRpcServerImpl {
9498

9599
impl PeerRpcServerImpl {
96100
pub async fn connect_peer(&self, params: ConnectPeerParams) -> Result<(), ErrorObjectOwned> {
97-
let message = NetworkActorMessage::Command(NetworkActorCommand::ConnectPeer(
98-
params.address.clone(),
99-
params.save.unwrap_or(true),
100-
));
101-
crate::handle_actor_cast!(self.actor, message, params)
101+
if let Some(address) = params.address.clone() {
102+
let save = params.save.unwrap_or(true);
103+
let message =
104+
NetworkActorMessage::Command(NetworkActorCommand::ConnectPeer(address, save));
105+
return crate::handle_actor_cast!(self.actor, message, params);
106+
}
107+
108+
if let Some(pubkey) = params.pubkey.clone() {
109+
let message = |rpc_reply| {
110+
NetworkActorMessage::Command(NetworkActorCommand::ConnectPeerWithPubkey(
111+
pubkey, rpc_reply,
112+
))
113+
};
114+
return crate::handle_actor_call!(self.actor, message, params);
115+
}
116+
117+
Err(ErrorObjectOwned::owned(
118+
CALL_EXECUTION_FAILED_CODE,
119+
"either `address` or `pubkey` is required",
120+
Some(params),
121+
))
102122
}
103123

104124
pub async fn disconnect_peer(

docs/testnet-nodes.md

Lines changed: 22 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -72,58 +72,22 @@
7272

7373

7474

75-
76-
## Discover Public Nodes from `graph_nodes` (optional)
77-
78-
1. Query graph nodes
79-
80-
```bash
81-
curl -s --location 'http://127.0.0.1:8227' --header 'Content-Type: application/json' --data '{
82-
"id": 1,
83-
"jsonrpc": "2.0",
84-
"method": "graph_nodes",
85-
"params": [
86-
{}
87-
]
88-
}'
89-
```
90-
91-
2. Find node1 / node2 by pubkey and read addresses
92-
93-
- node1 pubkey: `02b6d4e3ab86a2ca2fad6fae0ecb2e1e559e0b911939872a90abdda6d20302be71`
94-
- node1 address (current): `"/ip4/18.162.235.225/tcp/8119/p2p/QmXen3eUHhywmutEzydCsW4hXBoeVmdET2FJvMX69XJ1Eo"`
95-
- node2 pubkey: `0291a6576bd5a94bd74b27080a48340875338fff9f6d6361fe6b8db8d0d1912fcc`
96-
- node2 address (current): `"/ip4/18.163.221.211/tcp/8119/p2p/QmbKyzq9qUmymW2Gi8Zq7kKVpPiNA1XUJ6uMvsUC4F3p89"`
97-
- use each node's `addresses` field in the `connect_peer` call below.
98-
99-
```bash
100-
curl -s --location 'http://127.0.0.1:8227' --header 'Content-Type: application/json' --data '{
101-
"id": 1,
102-
"jsonrpc": "2.0",
103-
"method": "graph_nodes",
104-
"params": [
105-
{}
106-
]
107-
}' | jq '.result.nodes[] | select(.pubkey=="02b6d4e3ab86a2ca2fad6fae0ecb2e1e559e0b911939872a90abdda6d20302be71" or .pubkey=="0291a6576bd5a94bd74b27080a48340875338fff9f6d6361fe6b8db8d0d1912fcc") | {pubkey, addresses}'
108-
```
109-
110-
11175
## Establishing a CKB Channel with Public Node 1
11276

11377

11478
1. Establish a network connection between nodeA and node1
11579

11680
```bash
11781
curl -s --location 'http://127.0.0.1:8227' --header 'Content-Type: application/json' --data '{
118-
"id": 1,
119-
"jsonrpc": "2.0",
120-
"method": "connect_peer",
121-
"params": [
122-
{
123-
"address": "/ip4/18.162.235.225/tcp/8119/p2p/QmXen3eUHhywmutEzydCsW4hXBoeVmdET2FJvMX69XJ1Eo"
124-
}
125-
]
126-
}'
82+
"id": 1,
83+
"jsonrpc": "2.0",
84+
"method": "connect_peer",
85+
"params": [
86+
{
87+
"pubkey": "02b6d4e3ab86a2ca2fad6fae0ecb2e1e559e0b911939872a90abdda6d20302be71"
88+
}
89+
]
90+
}'
12791
```
12892

12993
```json
@@ -376,6 +340,19 @@
376340

377341
1. Establish a network connection between nodeA and node1
378342

343+
```bash
344+
curl -s --location 'http://127.0.0.1:8227' --header 'Content-Type: application/json' --data '{
345+
"id": 1,
346+
"jsonrpc": "2.0",
347+
"method": "connect_peer",
348+
"params": [
349+
{
350+
"pubkey": "02b6d4e3ab86a2ca2fad6fae0ecb2e1e559e0b911939872a90abdda6d20302be71"
351+
}
352+
]
353+
}'
354+
```
355+
379356

380357

381358
2. Establish a channel with 20 RUSD: nodeA (20 RUSD) ⟺ node1 (0)

0 commit comments

Comments
 (0)