grpc: Add WaitBlockHeight method to grpc interface

This commit is contained in:
Christian Decker 2023-09-29 14:42:45 +02:00 committed by Rusty Russell
parent 76c5e6aa65
commit dfea5fbe6d
12 changed files with 255 additions and 21 deletions

View file

@ -1579,6 +1579,13 @@
"WaitAnyInvoice.status": 4,
"WaitAnyInvoice.updated_index": 14
},
"WaitblockheightRequest": {
"WaitBlockHeight.blockheight": 1,
"WaitBlockHeight.timeout": 2
},
"WaitblockheightResponse": {
"WaitBlockHeight.blockheight": 1
},
"WaitinvoiceRequest": {
"WaitInvoice.label": 1
},
@ -5518,6 +5525,18 @@
"added": "v23.08",
"deprecated": false
},
"WaitBlockHeight": {
"added": "pre-v0.10.1",
"deprecated": null
},
"WaitBlockHeight.blockheight": {
"added": "pre-v0.10.1",
"deprecated": false
},
"WaitBlockHeight.timeout": {
"added": "pre-v0.10.1",
"deprecated": false
},
"WaitInvoice": {
"added": "pre-v0.10.1",
"deprecated": null

View file

@ -61,6 +61,7 @@ service Node {
rpc SetChannel(SetchannelRequest) returns (SetchannelResponse) {}
rpc SignInvoice(SigninvoiceRequest) returns (SigninvoiceResponse) {}
rpc SignMessage(SignmessageRequest) returns (SignmessageResponse) {}
rpc WaitBlockHeight(WaitblockheightRequest) returns (WaitblockheightResponse) {}
rpc Stop(StopRequest) returns (StopResponse) {}
rpc PreApproveKeysend(PreapprovekeysendRequest) returns (PreapprovekeysendResponse) {}
rpc PreApproveInvoice(PreapproveinvoiceRequest) returns (PreapproveinvoiceResponse) {}
@ -1727,6 +1728,15 @@ message SignmessageResponse {
string zbase = 3;
}
message WaitblockheightRequest {
uint32 blockheight = 1;
optional uint32 timeout = 2;
}
message WaitblockheightResponse {
uint32 blockheight = 1;
}
message StopRequest {
}

View file

@ -1599,6 +1599,15 @@ impl From<responses::SignmessageResponse> for pb::SignmessageResponse {
}
}
#[allow(unused_variables)]
impl From<responses::WaitblockheightResponse> for pb::WaitblockheightResponse {
fn from(c: responses::WaitblockheightResponse) -> Self {
Self {
blockheight: c.blockheight, // Rule #2 for type u32
}
}
}
#[allow(unused_variables)]
impl From<responses::StopResponse> for pb::StopResponse {
fn from(c: responses::StopResponse) -> Self {
@ -2299,6 +2308,16 @@ impl From<requests::SignmessageRequest> for pb::SignmessageRequest {
}
}
#[allow(unused_variables)]
impl From<requests::WaitblockheightRequest> for pb::WaitblockheightRequest {
fn from(c: requests::WaitblockheightRequest) -> Self {
Self {
blockheight: c.blockheight, // Rule #2 for type u32
timeout: c.timeout, // Rule #2 for type u32?
}
}
}
#[allow(unused_variables)]
impl From<requests::StopRequest> for pb::StopRequest {
fn from(c: requests::StopRequest) -> Self {
@ -2986,6 +3005,16 @@ impl From<pb::SignmessageRequest> for requests::SignmessageRequest {
}
}
#[allow(unused_variables)]
impl From<pb::WaitblockheightRequest> for requests::WaitblockheightRequest {
fn from(c: pb::WaitblockheightRequest) -> Self {
Self {
blockheight: c.blockheight, // Rule #1 for type u32
timeout: c.timeout, // Rule #1 for type u32?
}
}
}
#[allow(unused_variables)]
impl From<pb::StopRequest> for requests::StopRequest {
fn from(c: pb::StopRequest) -> Self {

View file

@ -1722,6 +1722,38 @@ async fn sign_message(
}
async fn wait_block_height(
&self,
request: tonic::Request<pb::WaitblockheightRequest>,
) -> Result<tonic::Response<pb::WaitblockheightResponse>, tonic::Status> {
let req = request.into_inner();
let req: requests::WaitblockheightRequest = req.into();
debug!("Client asked for wait_block_height");
trace!("wait_block_height request: {:?}", req);
let mut rpc = ClnRpc::new(&self.rpc_path)
.await
.map_err(|e| Status::new(Code::Internal, e.to_string()))?;
let result = rpc.call(Request::WaitBlockHeight(req))
.await
.map_err(|e| Status::new(
Code::Unknown,
format!("Error calling method WaitBlockHeight: {:?}", e)))?;
match result {
Response::WaitBlockHeight(r) => {
trace!("wait_block_height response: {:?}", r);
Ok(tonic::Response::new(r.into()))
},
r => Err(Status::new(
Code::Internal,
format!(
"Unexpected result {:?} to method call WaitBlockHeight",
r
)
)),
}
}
async fn stop(
&self,
request: tonic::Request<pb::StopRequest>,

View file

@ -1,3 +1,4 @@
use crate::pb::*;
use serde_json::json;
#[test]
@ -246,7 +247,8 @@ fn test_getinfo() {
"network": "regtest",
"fees_collected_msat": "0msat", "lightning-dir": "/tmp/ltests-20irp76f/test_pay_variants_1/lightning-1/regtest",
"our_features": {"init": "8808226aa2", "node": "80008808226aa2", "channel": "", "invoice": "024200"}});
let _u: cln_rpc::model::responses::GetinfoResponse = serde_json::from_value(j.clone()).unwrap();
let u: cln_rpc::model::responses::GetinfoResponse = serde_json::from_value(j.clone()).unwrap();
let _g: GetinfoResponse = u.into();
//let u2: cln_rpc::model::GetinfoResponse = g.into();
//let j2 = serde_json::to_value(u2).unwrap();
//assert_eq!(j, j2);
@ -254,6 +256,48 @@ fn test_getinfo() {
#[test]
fn test_keysend() {
let g =
KeysendRequest {
destination: hex::decode(
"035d2b1192dfba134e10e540875d366ebc8bc353d5aa766b80c090b39c3a5d885d",
)
.unwrap(),
amount_msat: Some(Amount { msat: 10000 }),
label: Some("hello".to_string()),
exemptfee: None,
maxdelay: None,
retry_for: None,
maxfeepercent: None,
routehints: Some(RoutehintList {
hints: vec![Routehint {
hops: vec![RouteHop {
id: hex::decode(
"035d2b1192dfba134e10e540875d366ebc8bc353d5aa766b80c090b39c3a5d885d",
)
.unwrap(),
short_channel_id: "12345x678x90".to_string(),
feebase: Some(Amount { msat: 123 }),
feeprop: 1234,
expirydelta: 9,
},RouteHop {
id: hex::decode(
"035d2b1192dfba134e10e540875d366ebc8bc353d5aa766b80c090b39c3a5d885d",
)
.unwrap(),
short_channel_id: "12345x678x90".to_string(),
feebase: Some(Amount { msat: 123 }),
feeprop: 1234,
expirydelta: 9,
}],
}],
}),
extratlvs: None,
};
let u: cln_rpc::model::requests::KeysendRequest = g.into();
let _ser = serde_json::to_string(&u);
let j = r#"{
"destination": "035d2b1192dfba134e10e540875d366ebc8bc353d5aa766b80c090b39c3a5d885d",
"payment_hash": "e74b03a98453dcb5a7ed5406b97ec3566dde4be85ef71685110f4c0ebc600592",
@ -267,6 +311,8 @@ fn test_keysend() {
"status": "complete"
}"#;
let u: cln_rpc::model::responses::KeysendResponse = serde_json::from_str(j).unwrap();
let g: KeysendResponse = u.clone().into();
println!("{:?}", g);
let v: serde_json::Value = serde_json::to_value(u.clone()).unwrap();
let g: cln_rpc::model::responses::KeysendResponse = u.into();

35
cln-rpc/src/model.rs generated
View file

@ -67,6 +67,7 @@ pub enum Request {
SetChannel(requests::SetchannelRequest),
SignInvoice(requests::SigninvoiceRequest),
SignMessage(requests::SignmessageRequest),
WaitBlockHeight(requests::WaitblockheightRequest),
Stop(requests::StopRequest),
PreApproveKeysend(requests::PreapprovekeysendRequest),
PreApproveInvoice(requests::PreapproveinvoiceRequest),
@ -130,6 +131,7 @@ pub enum Response {
SetChannel(responses::SetchannelResponse),
SignInvoice(responses::SigninvoiceResponse),
SignMessage(responses::SignmessageResponse),
WaitBlockHeight(responses::WaitblockheightResponse),
Stop(responses::StopResponse),
PreApproveKeysend(responses::PreapprovekeysendResponse),
PreApproveInvoice(responses::PreapproveinvoiceResponse),
@ -1507,6 +1509,23 @@ pub mod requests {
type Response = super::responses::SignmessageResponse;
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct WaitblockheightRequest {
pub blockheight: u32,
#[serde(skip_serializing_if = "Option::is_none")]
pub timeout: Option<u32>,
}
impl From<WaitblockheightRequest> for Request {
fn from(r: WaitblockheightRequest) -> Self {
Request::WaitBlockHeight(r)
}
}
impl IntoRequest for WaitblockheightRequest {
type Response = super::responses::WaitblockheightResponse;
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct StopRequest {
}
@ -4879,6 +4898,22 @@ pub mod responses {
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct WaitblockheightResponse {
pub blockheight: u32,
}
impl TryFrom<Response> for WaitblockheightResponse {
type Error = super::TryFromResponseError;
fn try_from(response: Response) -> Result<Self, Self::Error> {
match response {
Response::WaitBlockHeight(response) => Ok(response),
_ => Err(TryFromResponseError)
}
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct StopResponse {
}

View file

@ -103,7 +103,7 @@ def load_jsonrpc_service(schema_dir: str):
"SignInvoice",
"SignMessage",
# "unreserveinputs",
# "waitblockheight",
"WaitBlockHeight",
# "ListConfigs",
# "check", # No point in mapping this one
"Stop",

File diff suppressed because one or more lines are too long

View file

@ -279,6 +279,11 @@ class NodeStub(object):
request_serializer=node__pb2.SignmessageRequest.SerializeToString,
response_deserializer=node__pb2.SignmessageResponse.FromString,
)
self.WaitBlockHeight = channel.unary_unary(
'/cln.Node/WaitBlockHeight',
request_serializer=node__pb2.WaitblockheightRequest.SerializeToString,
response_deserializer=node__pb2.WaitblockheightResponse.FromString,
)
self.Stop = channel.unary_unary(
'/cln.Node/Stop',
request_serializer=node__pb2.StopRequest.SerializeToString,
@ -622,6 +627,12 @@ class NodeServicer(object):
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def WaitBlockHeight(self, request, context):
"""Missing associated documentation comment in .proto file."""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def Stop(self, request, context):
"""Missing associated documentation comment in .proto file."""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
@ -914,6 +925,11 @@ def add_NodeServicer_to_server(servicer, server):
request_deserializer=node__pb2.SignmessageRequest.FromString,
response_serializer=node__pb2.SignmessageResponse.SerializeToString,
),
'WaitBlockHeight': grpc.unary_unary_rpc_method_handler(
servicer.WaitBlockHeight,
request_deserializer=node__pb2.WaitblockheightRequest.FromString,
response_serializer=node__pb2.WaitblockheightResponse.SerializeToString,
),
'Stop': grpc.unary_unary_rpc_method_handler(
servicer.Stop,
request_deserializer=node__pb2.StopRequest.FromString,
@ -1845,6 +1861,23 @@ class Node(object):
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def WaitBlockHeight(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/cln.Node/WaitBlockHeight',
node__pb2.WaitblockheightRequest.SerializeToString,
node__pb2.WaitblockheightResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def Stop(request,
target,

View file

@ -19,6 +19,7 @@ _globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'primitives_pb2', _globals)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
_globals['_CHANNELSIDE']._serialized_start=718
_globals['_CHANNELSIDE']._serialized_end=754

View file

@ -1358,6 +1358,12 @@ def signmessage2py(m):
})
def waitblockheight2py(m):
return remove_default({
"blockheight": m.blockheight, # PrimitiveField in generate_composite
})
def stop2py(m):
return remove_default({
})

View file

@ -0,0 +1,18 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"additionalProperties": false,
"required": [
"blockheight"
],
"properties": {
"blockheight": {
"type": "u32",
"description": "The current block height (>= blockheight parameter)"
},
"timeout": {
"type": "u32",
"description": "If timeout seconds is reached without the specified blockheight being reached, this command will fail with a code of 2000."
}
}
}