diff --git a/cln-grpc/proto/node.proto b/cln-grpc/proto/node.proto index b834c9c34..d03b92427 100644 --- a/cln-grpc/proto/node.proto +++ b/cln-grpc/proto/node.proto @@ -16,6 +16,7 @@ service Node { rpc AutoCleanInvoice(AutocleaninvoiceRequest) returns (AutocleaninvoiceResponse) {} rpc CheckMessage(CheckmessageRequest) returns (CheckmessageResponse) {} rpc Close(CloseRequest) returns (CloseResponse) {} + rpc ConnectPeer(ConnectRequest) returns (ConnectResponse) {} } message GetinfoRequest { @@ -339,3 +340,35 @@ message CloseResponse { optional bytes tx = 8; optional bytes txid = 9; } + +message ConnectRequest { + bytes id = 1; + optional string host = 2; + optional uint32 port = 3; +} + +message ConnectResponse { + // Connect.direction + enum ConnectDirection { + IN = 0; + OUT = 1; + } + bytes id = 1; + bytes features = 2; + ConnectDirection direction = 3; +} + +message ConnectAddress { + // Connect.address.type + enum ConnectAddressType { + LOCAL_SOCKET = 0; + IPV4 = 1; + IPV6 = 2; + TORV2 = 3; + TORV3 = 4; + } + ConnectAddressType item_type = 1; + optional string socket = 2; + optional string address = 3; + optional uint32 port = 4; +} diff --git a/cln-grpc/src/convert.rs b/cln-grpc/src/convert.rs index 5dbfd54ee..0c2d78a26 100644 --- a/cln-grpc/src/convert.rs +++ b/cln-grpc/src/convert.rs @@ -289,6 +289,17 @@ impl From<&responses::CloseResponse> for pb::CloseResponse { } } +#[allow(unused_variables)] +impl From<&responses::ConnectResponse> for pb::ConnectResponse { + fn from(c: &responses::ConnectResponse) -> Self { + Self { + id: hex::decode(&c.id).unwrap(), + features: hex::decode(&c.features).unwrap(), + direction: c.direction as i32, + } + } +} + #[allow(unused_variables)] impl From<&pb::GetinfoRequest> for requests::GetinfoRequest { fn from(c: &pb::GetinfoRequest) -> Self { @@ -371,3 +382,14 @@ impl From<&pb::CloseRequest> for requests::CloseRequest { } } +#[allow(unused_variables)] +impl From<&pb::ConnectRequest> for requests::ConnectRequest { + fn from(c: &pb::ConnectRequest) -> Self { + Self { + id: hex::encode(&c.id), + host: c.host.clone(), + port: c.port.map(|i| i as u16), + } + } +} + diff --git a/cln-grpc/src/server.rs b/cln-grpc/src/server.rs index 3576bac86..f492ed660 100644 --- a/cln-grpc/src/server.rs +++ b/cln-grpc/src/server.rs @@ -266,4 +266,34 @@ async fn close( } +async fn connect_peer( + &self, + request: tonic::Request, +) -> Result, tonic::Status> { + let req = request.into_inner(); + let req: requests::ConnectRequest = (&req).into(); + debug!("Client asked for getinfo"); + let mut rpc = ClnRpc::new(&self.rpc_path) + .await + .map_err(|e| Status::new(Code::Internal, e.to_string()))?; + let result = rpc.call(Request::ConnectPeer(req)) + .await + .map_err(|e| Status::new( + Code::Unknown, + format!("Error calling method ConnectPeer: {:?}", e)))?; + match result { + Response::ConnectPeer(r) => Ok( + tonic::Response::new((&r).into()) + ), + r => Err(Status::new( + Code::Internal, + format!( + "Unexpected result {:?} to method call ConnectPeer", + r + ) + )), + } + +} + } diff --git a/cln-rpc/src/model.rs b/cln-rpc/src/model.rs index 3e6a0fc76..a9494af74 100644 --- a/cln-rpc/src/model.rs +++ b/cln-rpc/src/model.rs @@ -24,6 +24,7 @@ pub enum Request { AutoCleanInvoice(requests::AutocleaninvoiceRequest), CheckMessage(requests::CheckmessageRequest), Close(requests::CloseRequest), + ConnectPeer(requests::ConnectRequest), } #[derive(Clone, Debug, Serialize, Deserialize)] @@ -38,6 +39,7 @@ pub enum Response { AutoCleanInvoice(responses::AutocleaninvoiceResponse), CheckMessage(responses::CheckmessageResponse), Close(responses::CloseResponse), + ConnectPeer(responses::ConnectResponse), } pub mod requests { @@ -114,6 +116,16 @@ pub mod requests { pub force_lease_closed: Option, } + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct ConnectRequest { + #[serde(alias = "id")] + pub id: String, + #[serde(alias = "host", skip_serializing_if = "Option::is_none")] + pub host: Option, + #[serde(alias = "port", skip_serializing_if = "Option::is_none")] + pub port: Option, + } + } @@ -731,5 +743,48 @@ pub mod responses { pub txid: Option, } + /// Whether they initiated connection or we did + #[derive(Copy, Clone, Debug, Deserialize, Serialize)] + #[serde(rename_all = "lowercase")] + pub enum ConnectDirection { + IN, + OUT, + } + + /// Type of connection (*torv2*/*torv3* only if **direction** is *out*) + #[derive(Copy, Clone, Debug, Deserialize, Serialize)] + #[serde(rename_all = "lowercase")] + pub enum ConnectAddressType { + LOCAL_SOCKET, + IPV4, + IPV6, + TORV2, + TORV3, + } + + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct ConnectAddress { + // Path `Connect.address.type` + #[serde(rename = "type")] + pub item_type: ConnectAddressType, + #[serde(alias = "socket", skip_serializing_if = "Option::is_none")] + pub socket: Option, + #[serde(alias = "address", skip_serializing_if = "Option::is_none")] + pub address: Option, + #[serde(alias = "port", skip_serializing_if = "Option::is_none")] + pub port: Option, + } + + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct ConnectResponse { + #[serde(alias = "id")] + pub id: String, + #[serde(alias = "features")] + pub features: String, + // Path `Connect.direction` + #[serde(rename = "direction")] + pub direction: ConnectDirection, + } + } diff --git a/contrib/msggen/msggen/__main__.py b/contrib/msggen/msggen/__main__.py index 5700b9764..b98b27f83 100644 --- a/contrib/msggen/msggen/__main__.py +++ b/contrib/msggen/msggen/__main__.py @@ -6,6 +6,12 @@ import subprocess import json +# Sometimes we want to rename a method, due to a name clash +method_name_override = { + "Connect": "ConnectPeer", +} + + def repo_root(): path = subprocess.check_output(["git", "rev-parse", "--show-toplevel"]) return Path(path.strip().decode('UTF-8')) @@ -26,7 +32,7 @@ def load_jsonrpc_method(name): response.typename += "Response" return Method( - name=name, + name=method_name_override.get(name, name), request=request, response=response, ) @@ -44,7 +50,7 @@ def load_jsonrpc_service(): "CheckMessage", # "check", # No point in mapping this one "Close", - # "connect", + "Connect", # "createinvoice", # "createonion", # "datastore", diff --git a/doc/schemas/connect.request.json b/doc/schemas/connect.request.json new file mode 100644 index 000000000..97c401853 --- /dev/null +++ b/doc/schemas/connect.request.json @@ -0,0 +1,21 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "pubkey", + "description": "" + }, + "host": { + "type": "string", + "description": "The hostname of the node." + }, + "port": { + "type": "u16", + "description": "Port to try connecting to" + } + } +}