From 7bf8285df2e64f4d7e3c5f081ddd3710a14515e1 Mon Sep 17 00:00:00 2001 From: mrnaveira <47919901+mrnaveira@users.noreply.github.com> Date: Thu, 19 May 2022 10:17:24 +0100 Subject: [PATCH 1/2] new ffi method to crate a covenant from bytes --- base_layer/wallet_ffi/src/lib.rs | 101 ++++++++++++++++++++++++++++++- base_layer/wallet_ffi/wallet.h | 11 ++++ 2 files changed, 111 insertions(+), 1 deletion(-) diff --git a/base_layer/wallet_ffi/src/lib.rs b/base_layer/wallet_ffi/src/lib.rs index be59c721a4..64ca8140ac 100644 --- a/base_layer/wallet_ffi/src/lib.rs +++ b/base_layer/wallet_ffi/src/lib.rs @@ -979,6 +979,66 @@ 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 +/// `error_out` - Pointer to an int which will be modified to an error code should one occur, may not be null. Functions +/// as an out parameter. +/// +/// ## 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); + } +} + +/// -------------------------------------------------------------------------------------------- /// + /// ----------------------------------- Seed Words ----------------------------------------------/// /// Create an empty instance of TariSeedWords @@ -6441,7 +6501,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::{ @@ -6950,6 +7013,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_keys_dont_panic() { unsafe { diff --git a/base_layer/wallet_ffi/wallet.h b/base_layer/wallet_ffi/wallet.h index 660a25f7e2..28a6a78a36 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); + /// -------------------------------- Seed Words -------------------------------------------------- /// // Create an empty instance of TariSeedWords struct TariSeedWords *seed_words_create(); From 2a7b95b6fe34e3a69098400a5513d685002fc779 Mon Sep 17 00:00:00 2001 From: mrnaveira <47919901+mrnaveira@users.noreply.github.com> Date: Thu, 19 May 2022 11:09:05 +0100 Subject: [PATCH 2/2] fix whitespace --- base_layer/wallet_ffi/wallet.h | 1 + 1 file changed, 1 insertion(+) diff --git a/base_layer/wallet_ffi/wallet.h b/base_layer/wallet_ffi/wallet.h index ca83bb7070..abb4dabce1 100644 --- a/base_layer/wallet_ffi/wallet.h +++ b/base_layer/wallet_ffi/wallet.h @@ -199,6 +199,7 @@ struct TariCovenant *covenant_create_from_bytes( // Frees memory for a TariCovenant void covenant_destroy(struct TariCovenant *covenant); + /// -------------------------------- Output Features --------------------------------------------- /// // Creates a TariOutputFeatures from byte values