diff --git a/base_layer/wallet_ffi/src/lib.rs b/base_layer/wallet_ffi/src/lib.rs index dc79358318..07dd6b0e42 100644 --- a/base_layer/wallet_ffi/src/lib.rs +++ b/base_layer/wallet_ffi/src/lib.rs @@ -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 @@ -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::{ @@ -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 { diff --git a/base_layer/wallet_ffi/wallet.h b/base_layer/wallet_ffi/wallet.h index 70b6017767..abb4dabce1 100644 --- a/base_layer/wallet_ffi/wallet.h +++ b/base_layer/wallet_ffi/wallet.h @@ -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