Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(wallet_ffi): new ffi method to create covenant #4115

Merged
merged 3 commits into from
May 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 96 additions & 1 deletion base_layer/wallet_ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -990,7 +990,63 @@ pub unsafe extern "C" fn commitment_signature_destroy(com_sig: *mut TariCommitme
}

/// -------------------------------------------------------------------------------------------- ///
/// --------------------------------------- Covenant --------------------------------------------///

/// Creates a TariCovenant from a ByteVector containing the covenant bytes
///
/// ## Arguments
/// `covenant_bytes` - The covenant bytes as a ByteVector
///
/// ## Returns
/// `TariCovenant` - Returns a commitment signature. Note that it will be ptr::null_mut() if any argument is
/// null or if there was an error with the contents of bytes
///
/// # Safety
/// The ```covenant_destroy``` function must be called when finished with a TariCovenant to prevent a memory leak
#[no_mangle]
pub unsafe extern "C" fn covenant_create_from_bytes(
covenant_bytes: *const ByteVector,
error_out: *mut c_int,
) -> *mut TariCovenant {
let mut error = 0;
ptr::swap(error_out, &mut error as *mut c_int);

if covenant_bytes.is_null() {
error = LibWalletError::from(InterfaceError::NullError("covenant_bytes".to_string())).code;
ptr::swap(error_out, &mut error as *mut c_int);
return ptr::null_mut();
}
let decoded_covenant_bytes = (*covenant_bytes).0.clone();

match TariCovenant::from_bytes(&decoded_covenant_bytes) {
Ok(covenant) => Box::into_raw(Box::new(covenant)),
Err(e) => {
error!(target: LOG_TARGET, "Error creating a Covenant: {:?}", e);
error = LibWalletError::from(InterfaceError::InvalidArgument("covenant_bytes".to_string())).code;
ptr::swap(error_out, &mut error as *mut c_int);
ptr::null_mut()
},
}
}

/// Frees memory for a TariCovenant
///
/// ## Arguments
/// `covenant` - The pointer to a TariCovenant
///
/// ## Returns
/// `()` - Does not return a value, equivalent to void in C
///
/// # Safety
/// None
#[no_mangle]
pub unsafe extern "C" fn covenant_destroy(covenant: *mut TariCovenant) {
if !covenant.is_null() {
Box::from_raw(covenant);
}
}

/// -------------------------------------------------------------------------------------------- ///
/// ---------------------------------- Output Features ------------------------------------------///

/// Creates a TariOutputFeatures from byte values
Expand Down Expand Up @@ -6585,7 +6641,10 @@ mod test {

use libc::{c_char, c_uchar, c_uint};
use tari_common_types::{emoji, transaction::TransactionStatus};
use tari_core::transactions::test_helpers::{create_unblinded_output, TestParams};
use tari_core::{
covenant,
transactions::test_helpers::{create_unblinded_output, TestParams},
};
use tari_key_manager::{mnemonic::MnemonicLanguage, mnemonic_wordlists};
use tari_test_utils::random;
use tari_wallet::{
Expand Down Expand Up @@ -7094,6 +7153,42 @@ mod test {
}
}

#[test]
fn test_covenant_create_empty() {
unsafe {
let mut error = 0;
let error_ptr = &mut error as *mut c_int;

let covenant_bytes = Box::into_raw(Box::new(ByteVector(Vec::new())));
let covenant = covenant_create_from_bytes(covenant_bytes, error_ptr);

assert_eq!(error, 0);
let empty_covenant = covenant!();
assert_eq!(*covenant, empty_covenant);

covenant_destroy(covenant);
byte_vector_destroy(covenant_bytes);
}
}

#[test]
fn test_covenant_create_filled() {
unsafe {
let mut error = 0;
let error_ptr = &mut error as *mut c_int;

let expected_covenant = covenant!(identity());
let covenant_bytes = Box::into_raw(Box::new(ByteVector(expected_covenant.to_bytes())));
let covenant = covenant_create_from_bytes(covenant_bytes, error_ptr);

assert_eq!(error, 0);
assert_eq!(*covenant, expected_covenant);

covenant_destroy(covenant);
byte_vector_destroy(covenant_bytes);
}
}

#[test]
fn test_output_features_create_empty() {
unsafe {
Expand Down
11 changes: 11 additions & 0 deletions base_layer/wallet_ffi/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,17 @@ struct TariCommitmentSignature *commitment_signature_create_from_bytes(
// Frees memory for a TariCommitmentSignature
void commitment_signature_destroy(struct TariCommitmentSignature *com_sig);

/// -------------------------------- Covenant --------------------------------------------- ///

// Creates a TariCovenant from a ByteVector containing the covenant bytes
struct TariCovenant *covenant_create_from_bytes(
struct ByteVector *covenant_bytes,
int *error_out
);

// Frees memory for a TariCovenant
void covenant_destroy(struct TariCovenant *covenant);

/// -------------------------------- Output Features --------------------------------------------- ///

// Creates a TariOutputFeatures from byte values
Expand Down