Skip to content
This repository was archived by the owner on Feb 8, 2024. It is now read-only.

Commit 7601092

Browse files
committed
Returning detailed validation status
1 parent 3412d52 commit 7601092

File tree

6 files changed

+129
-20
lines changed

6 files changed

+129
-20
lines changed

Cargo.lock

+8-7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "libcitadel"
3-
version = "0.1.0-rc"
3+
version = "0.1.0"
44
description = "C-language bindings for Citadel runtime"
55
authors = ["Dr Maxim Orlovsky <[email protected]>"]
66
license = "MIT"
@@ -19,7 +19,7 @@ openssl = { version = "^0.10", features = ["vendored"] }
1919
libc = "0.2"
2020
amplify = "3"
2121
amplify_derive = "2.4"
22-
citadel = { git = "https://github.com/mycitadel/citadel-runtime" }
22+
citadel-runtime = "0.1"
2323
# slip132 = "0.3.2"
2424
lnpbp = "0.4"
2525
lnpbp-invoice = { version = "0.1.0", features = ["serde", "rgb"] }

citadel.h

+19-2
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,13 @@ typedef enum invoice_type {
157157
INVOICE_TYPE_PSBT,
158158
} invoice_type;
159159

160+
typedef enum validity_t {
161+
VALIDITY_T_UNABLE_TO_VALIDATE,
162+
VALIDITY_T_VALID,
163+
VALIDITY_T_UNRESOLVED_TX,
164+
VALIDITY_T_INVALID,
165+
} validity_t;
166+
160167
typedef struct bech32_info_t {
161168
int status;
162169
int category;
@@ -186,6 +193,16 @@ typedef struct prepared_transfer_t {
186193
const char *psbt_base64;
187194
} prepared_transfer_t;
188195

196+
typedef struct validation_status_t {
197+
enum validity_t validity;
198+
uint32_t info_len;
199+
const char *const *info;
200+
uint32_t warn_len;
201+
const char *const *warn;
202+
uint32_t failures_len;
203+
const char *const *failures;
204+
} validation_status_t;
205+
189206
#ifdef __cplusplus
190207
extern "C" {
191208
#endif // __cplusplus
@@ -262,8 +279,8 @@ struct prepared_transfer_t citadel_invoice_pay(struct citadel_client_t *client,
262279
const char *citadel_psbt_publish(struct citadel_client_t *client,
263280
const char *psbt);
264281

265-
const char *citadel_invoice_accept(struct citadel_client_t *client,
266-
const char *consignment);
282+
struct validation_status_t citadel_invoice_accept(struct citadel_client_t *client,
283+
const char *consignment);
267284

268285
const char *citadel_asset_list(struct citadel_client_t *client);
269286

src/capi/rpc.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use wallet::bip32::PubkeyChain;
2626
use wallet::Psbt;
2727

2828
use super::{descriptor_type, invoice_type};
29-
use crate::capi::{prepared_transfer_t, AddressInfo};
29+
use crate::capi::{prepared_transfer_t, AddressInfo, validation_status_t};
3030
use crate::citadel_client_t;
3131
use crate::error::*;
3232
use crate::helpers::{TryAsStr, TryIntoRaw};
@@ -454,18 +454,18 @@ pub extern "C" fn citadel_psbt_publish(
454454
pub extern "C" fn citadel_invoice_accept(
455455
client: *mut citadel_client_t,
456456
consignment: *const c_char,
457-
) -> *const c_char {
457+
) -> validation_status_t {
458458
let client = citadel_client_t::from_raw(client);
459459

460460
let consignment = match client.parse_string(consignment, "consignment").ok()
461461
{
462-
None => return ptr::null(),
462+
None => return validation_status_t::failure(),
463463
Some(v) => v,
464464
};
465465
let consignment = match Consignment::from_str(&consignment) {
466466
Err(err) => {
467467
client.set_error_details(ERRNO_PARSE, err);
468-
return ptr::null();
468+
return validation_status_t::failure();
469469
}
470470
Ok(v) => v,
471471
};
@@ -477,13 +477,13 @@ pub extern "C" fn citadel_invoice_accept(
477477
.map_err(|_| ())
478478
.and_then(|res| res.ok_or(()))
479479
.ok()
480-
.and_then(|status| status.to_string().try_into_raw())
480+
.map(validation_status_t::from)
481481
{
482482
client.set_success();
483-
return status;
483+
return status
484484
}
485485

486-
return ptr::null();
486+
return validation_status_t::failure();
487487
}
488488

489489
#[no_mangle]

src/capi/types.rs

+92-2
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,18 @@
77
// the public domain worldwide. This software is distributed without
88
// any warranty.
99

10-
use libc::c_char;
10+
use libc::{c_char};
1111
use std::ptr;
1212

1313
use bitcoin::consensus::serialize;
1414
use citadel::client::InvoiceType;
1515
use citadel::rpc::message;
1616
use lnpbp::bech32::ToBech32String;
17-
use rgb::Consignment;
17+
use rgb::{Consignment, validation::{self, Validity}};
1818
use wallet::descriptor;
1919

2020
use crate::TryIntoRaw;
21+
use rgb::validation::{Info, Warning, Failure};
2122

2223
#[allow(non_camel_case_types)]
2324
#[derive(Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Hash)]
@@ -94,3 +95,92 @@ impl From<message::PreparedTransfer> for prepared_transfer_t {
9495
}
9596
}
9697
}
98+
99+
#[allow(non_camel_case_types)]
100+
#[derive(Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Hash)]
101+
#[repr(C)]
102+
pub enum validity_t {
103+
UNABLE_TO_VALIDATE,
104+
VALID,
105+
UNRESOLVED_TX,
106+
INVALID,
107+
}
108+
109+
impl From<Validity> for validity_t {
110+
fn from(validity: Validity) -> Self {
111+
match validity {
112+
Validity::Valid => Self::VALID,
113+
Validity::UnresolvedTransactions => Self::UNRESOLVED_TX,
114+
Validity::Invalid => Self::INVALID,
115+
}
116+
}
117+
}
118+
119+
// TODO: Provide memory release function for `prepared_transfer_t`
120+
#[allow(non_camel_case_types)]
121+
#[repr(C)]
122+
pub struct validation_status_t {
123+
pub validity: validity_t,
124+
pub info_len: u32,
125+
pub info: *const *const c_char,
126+
pub warn_len: u32,
127+
pub warn: *const *const c_char,
128+
pub failures_len: u32,
129+
pub failures: *const *const c_char,
130+
}
131+
132+
impl validation_status_t {
133+
pub fn failure() -> Self {
134+
validation_status_t {
135+
validity: validity_t::UNABLE_TO_VALIDATE,
136+
info_len: 0,
137+
info: ptr::null(),
138+
warn_len: 0,
139+
warn: ptr::null(),
140+
failures_len: 0,
141+
failures: ptr::null()
142+
}
143+
}
144+
}
145+
146+
impl From<validation::Status> for validation_status_t {
147+
fn from(status: validation::Status) -> Self {
148+
149+
let mut info = status.info
150+
.iter()
151+
.map(Info::to_string)
152+
.map(String::try_into_raw)
153+
.map(Option::unwrap)
154+
.collect::<Vec<_>>();
155+
info.shrink_to_fit();
156+
let (info, info_len, _) = info.into_raw_parts();
157+
158+
let mut warn = status.warnings
159+
.iter()
160+
.map(Warning::to_string)
161+
.map(String::try_into_raw)
162+
.map(Option::unwrap)
163+
.collect::<Vec<_>>();
164+
warn.shrink_to_fit();
165+
let (warn, warn_len, _) = warn.into_raw_parts();
166+
167+
let mut failures = status.failures
168+
.iter()
169+
.map(Failure::to_string)
170+
.map(String::try_into_raw)
171+
.map(Option::unwrap)
172+
.collect::<Vec<_>>();
173+
failures.shrink_to_fit();
174+
let (failures, failures_len, _) = failures.into_raw_parts();
175+
176+
validation_status_t {
177+
validity: status.validity().into(),
178+
info_len: info_len as u32,
179+
info,
180+
warn_len: warn_len as u32,
181+
warn,
182+
failures_len: failures_len as u32,
183+
failures
184+
}
185+
}
186+
}

src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#![recursion_limit = "256"]
1111
#![feature(try_trait)]
12+
#![feature(vec_into_raw_parts)]
1213
// Coding conventions
1314
#![deny(
1415
non_upper_case_globals,

0 commit comments

Comments
 (0)