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

Commit

Permalink
Returning detailed validation status
Browse files Browse the repository at this point in the history
  • Loading branch information
dr-orlovsky committed Mar 19, 2021
1 parent 3412d52 commit 7601092
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 20 deletions.
15 changes: 8 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "libcitadel"
version = "0.1.0-rc"
version = "0.1.0"
description = "C-language bindings for Citadel runtime"
authors = ["Dr Maxim Orlovsky <[email protected]>"]
license = "MIT"
Expand All @@ -19,7 +19,7 @@ openssl = { version = "^0.10", features = ["vendored"] }
libc = "0.2"
amplify = "3"
amplify_derive = "2.4"
citadel = { git = "https://github.com/mycitadel/citadel-runtime" }
citadel-runtime = "0.1"
# slip132 = "0.3.2"
lnpbp = "0.4"
lnpbp-invoice = { version = "0.1.0", features = ["serde", "rgb"] }
Expand Down
21 changes: 19 additions & 2 deletions citadel.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,13 @@ typedef enum invoice_type {
INVOICE_TYPE_PSBT,
} invoice_type;

typedef enum validity_t {
VALIDITY_T_UNABLE_TO_VALIDATE,
VALIDITY_T_VALID,
VALIDITY_T_UNRESOLVED_TX,
VALIDITY_T_INVALID,
} validity_t;

typedef struct bech32_info_t {
int status;
int category;
Expand Down Expand Up @@ -186,6 +193,16 @@ typedef struct prepared_transfer_t {
const char *psbt_base64;
} prepared_transfer_t;

typedef struct validation_status_t {
enum validity_t validity;
uint32_t info_len;
const char *const *info;
uint32_t warn_len;
const char *const *warn;
uint32_t failures_len;
const char *const *failures;
} validation_status_t;

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
Expand Down Expand Up @@ -262,8 +279,8 @@ struct prepared_transfer_t citadel_invoice_pay(struct citadel_client_t *client,
const char *citadel_psbt_publish(struct citadel_client_t *client,
const char *psbt);

const char *citadel_invoice_accept(struct citadel_client_t *client,
const char *consignment);
struct validation_status_t citadel_invoice_accept(struct citadel_client_t *client,
const char *consignment);

const char *citadel_asset_list(struct citadel_client_t *client);

Expand Down
14 changes: 7 additions & 7 deletions src/capi/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use wallet::bip32::PubkeyChain;
use wallet::Psbt;

use super::{descriptor_type, invoice_type};
use crate::capi::{prepared_transfer_t, AddressInfo};
use crate::capi::{prepared_transfer_t, AddressInfo, validation_status_t};
use crate::citadel_client_t;
use crate::error::*;
use crate::helpers::{TryAsStr, TryIntoRaw};
Expand Down Expand Up @@ -454,18 +454,18 @@ pub extern "C" fn citadel_psbt_publish(
pub extern "C" fn citadel_invoice_accept(
client: *mut citadel_client_t,
consignment: *const c_char,
) -> *const c_char {
) -> validation_status_t {
let client = citadel_client_t::from_raw(client);

let consignment = match client.parse_string(consignment, "consignment").ok()
{
None => return ptr::null(),
None => return validation_status_t::failure(),
Some(v) => v,
};
let consignment = match Consignment::from_str(&consignment) {
Err(err) => {
client.set_error_details(ERRNO_PARSE, err);
return ptr::null();
return validation_status_t::failure();
}
Ok(v) => v,
};
Expand All @@ -477,13 +477,13 @@ pub extern "C" fn citadel_invoice_accept(
.map_err(|_| ())
.and_then(|res| res.ok_or(()))
.ok()
.and_then(|status| status.to_string().try_into_raw())
.map(validation_status_t::from)
{
client.set_success();
return status;
return status
}

return ptr::null();
return validation_status_t::failure();
}

#[no_mangle]
Expand Down
94 changes: 92 additions & 2 deletions src/capi/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,18 @@
// the public domain worldwide. This software is distributed without
// any warranty.

use libc::c_char;
use libc::{c_char};
use std::ptr;

use bitcoin::consensus::serialize;
use citadel::client::InvoiceType;
use citadel::rpc::message;
use lnpbp::bech32::ToBech32String;
use rgb::Consignment;
use rgb::{Consignment, validation::{self, Validity}};
use wallet::descriptor;

use crate::TryIntoRaw;
use rgb::validation::{Info, Warning, Failure};

#[allow(non_camel_case_types)]
#[derive(Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Hash)]
Expand Down Expand Up @@ -94,3 +95,92 @@ impl From<message::PreparedTransfer> for prepared_transfer_t {
}
}
}

#[allow(non_camel_case_types)]
#[derive(Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Hash)]
#[repr(C)]
pub enum validity_t {
UNABLE_TO_VALIDATE,
VALID,
UNRESOLVED_TX,
INVALID,
}

impl From<Validity> for validity_t {
fn from(validity: Validity) -> Self {
match validity {
Validity::Valid => Self::VALID,
Validity::UnresolvedTransactions => Self::UNRESOLVED_TX,
Validity::Invalid => Self::INVALID,
}
}
}

// TODO: Provide memory release function for `prepared_transfer_t`
#[allow(non_camel_case_types)]
#[repr(C)]
pub struct validation_status_t {
pub validity: validity_t,
pub info_len: u32,
pub info: *const *const c_char,
pub warn_len: u32,
pub warn: *const *const c_char,
pub failures_len: u32,
pub failures: *const *const c_char,
}

impl validation_status_t {
pub fn failure() -> Self {
validation_status_t {
validity: validity_t::UNABLE_TO_VALIDATE,
info_len: 0,
info: ptr::null(),
warn_len: 0,
warn: ptr::null(),
failures_len: 0,
failures: ptr::null()
}
}
}

impl From<validation::Status> for validation_status_t {
fn from(status: validation::Status) -> Self {

let mut info = status.info
.iter()
.map(Info::to_string)
.map(String::try_into_raw)
.map(Option::unwrap)
.collect::<Vec<_>>();
info.shrink_to_fit();
let (info, info_len, _) = info.into_raw_parts();

let mut warn = status.warnings
.iter()
.map(Warning::to_string)
.map(String::try_into_raw)
.map(Option::unwrap)
.collect::<Vec<_>>();
warn.shrink_to_fit();
let (warn, warn_len, _) = warn.into_raw_parts();

let mut failures = status.failures
.iter()
.map(Failure::to_string)
.map(String::try_into_raw)
.map(Option::unwrap)
.collect::<Vec<_>>();
failures.shrink_to_fit();
let (failures, failures_len, _) = failures.into_raw_parts();

validation_status_t {
validity: status.validity().into(),
info_len: info_len as u32,
info,
warn_len: warn_len as u32,
warn,
failures_len: failures_len as u32,
failures
}
}
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#![recursion_limit = "256"]
#![feature(try_trait)]
#![feature(vec_into_raw_parts)]
// Coding conventions
#![deny(
non_upper_case_globals,
Expand Down

0 comments on commit 7601092

Please sign in to comment.