cln-grpc: Add the connect method

This commit is contained in:
Christian Decker 2022-01-26 18:42:49 +01:00 committed by Rusty Russell
parent f5147bbf1e
commit 6098386182
6 changed files with 169 additions and 2 deletions

View file

@ -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;
}

View file

@ -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),
}
}
}

View file

@ -266,4 +266,34 @@ async fn close(
}
async fn connect_peer(
&self,
request: tonic::Request<pb::ConnectRequest>,
) -> Result<tonic::Response<pb::ConnectResponse>, 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
)
)),
}
}
}

View file

@ -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<bool>,
}
#[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<String>,
#[serde(alias = "port", skip_serializing_if = "Option::is_none")]
pub port: Option<u16>,
}
}
@ -731,5 +743,48 @@ pub mod responses {
pub txid: Option<String>,
}
/// 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<String>,
#[serde(alias = "address", skip_serializing_if = "Option::is_none")]
pub address: Option<String>,
#[serde(alias = "port", skip_serializing_if = "Option::is_none")]
pub port: Option<u16>,
}
#[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,
}
}

View file

@ -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",

View file

@ -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"
}
}
}