Skip to content

Commit

Permalink
Expand reply / metadata functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
brianp committed Sep 12, 2023
1 parent 06465de commit ef28fd1
Show file tree
Hide file tree
Showing 10 changed files with 372 additions and 55 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

49 changes: 44 additions & 5 deletions base_layer/chat_ffi/chat.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ struct ChatClientFFI;

struct ChatMessages;

struct Message;

struct TariAddress;

struct TransportConfig;
Expand Down Expand Up @@ -116,20 +118,57 @@ void destroy_chat_config(struct ApplicationConfig *config);
*
* ## Arguments
* `client` - The Client pointer
* `message` - Pointer to a Message struct
* `error_out` - Pointer to an int which will be modified
*
* ## Returns
* `()` - Does not return a value, equivalent to void in C
*
* # Safety
* The ```receiver``` should be destroyed after use
*/
void send_chat_message(struct ChatClientFFI *client, struct Message *message, int *error_out);

/**
* Creates a message and returns a ptr to it
*
* ## Arguments
* `receiver` - A string containing a tari address
* `message` - The peer seeds config for the node
* `error_out` - Pointer to an int which will be modified
*
* ## Returns
* `()` - Does not return a value, equivalent to void in C
* `*mut Message` - Does not return a value, equivalent to void in C
*
* # Safety
* The ```receiver``` should be destroyed after use
*/
void send_chat_message(struct ChatClientFFI *client,
struct TariAddress *receiver,
const char *message_c_char,
int *error_out);
struct Message *create_chat_message(struct TariAddress *receiver,
const char *message,
int *error_out);

/**
* Creates message metadata
*
* ## Arguments
* `message` - A pointer to a message *IMPORTANT: This pointer will be consumed, and dropped during this function call.
* A new pointer for a new message will be returned*
* `metadata_type` - An int8 that maps to MessageMetadataType enum
* '0' -> Reply
* '1' -> TokenRequest
* `data` - contents for the metadata
* `error_out` - Pointer to an int which will be modified
*
* ## Returns
* `*mut Message` - a new pointer to the extended message
*
* ## Safety
* `message` Argument is dropped during this function.
*/
struct Message *add_chat_message_metadata(struct Message *message,
int *metadata_type,
const char *data_char,
int *error_out);

/**
* Add a contact
Expand Down
137 changes: 123 additions & 14 deletions base_layer/chat_ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ use tari_common_types::tari_address::TariAddress;
use tari_comms::multiaddr::Multiaddr;
use tari_contacts::contacts_service::{
handle::{DEFAULT_MESSAGE_LIMIT, DEFAULT_MESSAGE_PAGE},
types::Message,
types::{Message, MessageBuilder, MessageMetadata, MessageMetadataType},
};
use tari_p2p::{SocksAuthentication, TorControlAuthentication, TorTransportConfig, TransportConfig, TransportType};
use tari_utilities::hex;
Expand Down Expand Up @@ -485,8 +485,7 @@ unsafe fn init_logging(log_path: PathBuf, error_out: *mut c_int) {
///
/// ## Arguments
/// `client` - The Client pointer
/// `receiver` - A string containing a tari address
/// `message` - The peer seeds config for the node
/// `message` - Pointer to a Message struct
/// `error_out` - Pointer to an int which will be modified
///
/// ## Returns
Expand All @@ -495,12 +494,7 @@ unsafe fn init_logging(log_path: PathBuf, error_out: *mut c_int) {
/// # Safety
/// The ```receiver``` should be destroyed after use
#[no_mangle]
pub unsafe extern "C" fn send_chat_message(
client: *mut ChatClientFFI,
receiver: *mut TariAddress,
message_c_char: *const c_char,
error_out: *mut c_int,
) {
pub unsafe extern "C" fn send_chat_message(client: *mut ChatClientFFI, message: *mut Message, error_out: *mut c_int) {
let mut error = 0;
ptr::swap(error_out, &mut error as *mut c_int);

Expand All @@ -509,23 +503,138 @@ pub unsafe extern "C" fn send_chat_message(
ptr::swap(error_out, &mut error as *mut c_int);
}

if message.is_null() {
error = LibChatError::from(InterfaceError::NullError("message".to_string())).code;
ptr::swap(error_out, &mut error as *mut c_int);
}

(*client)
.runtime
.block_on((*client).client.send_message((*message).clone()));
}

/// Creates a message and returns a ptr to it
///
/// ## Arguments
/// `receiver` - A string containing a tari address
/// `message` - The peer seeds config for the node
/// `error_out` - Pointer to an int which will be modified
///
/// ## Returns
/// `*mut Message` - Does not return a value, equivalent to void in C
///
/// # Safety
/// The ```receiver``` should be destroyed after use
#[no_mangle]
pub unsafe extern "C" fn create_chat_message(
receiver: *mut TariAddress,
message: *const c_char,
error_out: *mut c_int,
) -> *mut Message {
let mut error = 0;
ptr::swap(error_out, &mut error as *mut c_int);

if receiver.is_null() {
error = LibChatError::from(InterfaceError::NullError("receiver".to_string())).code;
ptr::swap(error_out, &mut error as *mut c_int);
}

let message = match CStr::from_ptr(message_c_char).to_str() {
let message_str = match CStr::from_ptr(message).to_str() {
Ok(str) => str.to_string(),
Err(e) => {
error = LibChatError::from(InterfaceError::InvalidArgument(e.to_string())).code;
ptr::swap(error_out, &mut error as *mut c_int);
return;
return ptr::null_mut();
},
};

(*client)
.runtime
.block_on((*client).client.send_message((*receiver).clone(), message));
let message_out = MessageBuilder::new()
.address((*receiver).clone())
.message(message_str)
.build();

Box::into_raw(Box::new(message_out))
}

/// Creates message metadata
///
/// ## Arguments
/// `message` - A pointer to a message *IMPORTANT: This pointer will be consumed, and dropped during this function call.
/// A new pointer for a new message will be returned*
/// `metadata_type` - An int8 that maps to MessageMetadataType enum
/// '0' -> Reply
/// '1' -> TokenRequest
/// `data` - contents for the metadata
/// `error_out` - Pointer to an int which will be modified
///
/// ## Returns
/// `*mut Message` - a new pointer to the extended message
///
/// ## Safety
/// `message` Argument is dropped during this function.
#[no_mangle]
pub unsafe extern "C" fn add_chat_message_metadata(
message: *mut Message,
metadata_type: *mut c_int,
data_char: *const c_char,
error_out: *mut c_int,
) -> *mut Message {
let mut error = 0;
ptr::swap(error_out, &mut error as *mut c_int);

if message.is_null() {
error = LibChatError::from(InterfaceError::NullError("message".to_string())).code;
ptr::swap(error_out, &mut error as *mut c_int);
return ptr::null_mut();
}

if metadata_type.is_null() {
error = LibChatError::from(InterfaceError::NullError("metadata type".to_string())).code;
ptr::swap(error_out, &mut error as *mut c_int);
return ptr::null_mut();
}

let metadata_type = match u8::try_from(*metadata_type) {
Ok(n) => match MessageMetadataType::from_byte(n) {
Some(t) => t,
None => {
error = LibChatError::from(InterfaceError::InvalidArgument(
"Couldn't convert byte to Metadata type".to_string(),
))
.code;
ptr::swap(error_out, &mut error as *mut c_int);
return ptr::null_mut();
},
},
Err(e) => {
error = LibChatError::from(InterfaceError::InvalidArgument(e.to_string())).code;
ptr::swap(error_out, &mut error as *mut c_int);
return ptr::null_mut();
},
};

if data_char.is_null() {
error = LibChatError::from(InterfaceError::NullError("data".to_string())).code;
ptr::swap(error_out, &mut error as *mut c_int);
return ptr::null_mut();
}

let data = match CStr::from_ptr(data_char).to_str() {
Ok(str) => str.as_bytes().into(),
Err(e) => {
error = LibChatError::from(InterfaceError::InvalidArgument(e.to_string())).code;
ptr::swap(error_out, &mut error as *mut c_int);
return ptr::null_mut();
},
};

let metadata = MessageMetadata { metadata_type, data };
let new_message = Box::into_raw(Box::new(
MessageBuilder::from((*message).clone()).metadata(metadata).build(),
));
drop(Box::from_raw(message));

new_message
}

/// Add a contact
Expand Down
23 changes: 19 additions & 4 deletions base_layer/contacts/examples/chat_client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use tari_comms::{CommsNode, NodeIdentity};
use tari_contacts::contacts_service::{
handle::ContactsServiceHandle,
service::ContactOnlineStatus,
types::{Message, MessageBuilder},
types::{Message, MessageBuilder, MessageMetadata, MessageMetadataType},
};
use tari_shutdown::Shutdown;

Expand All @@ -44,9 +44,11 @@ const LOG_TARGET: &str = "contacts::chat_client";
#[async_trait]
pub trait ChatClient {
async fn add_contact(&self, address: &TariAddress);
fn add_metadata(&self, message: Message, metadata_type: MessageMetadataType, data: String) -> Message;
async fn check_online_status(&self, address: &TariAddress) -> ContactOnlineStatus;
async fn send_message(&self, receiver: TariAddress, message: String);
fn create_message(&self, receiver: &TariAddress, message: String) -> Message;
async fn get_messages(&self, sender: &TariAddress, limit: u64, page: u64) -> Vec<Message>;
async fn send_message(&self, message: Message);
fn identity(&self) -> &NodeIdentity;
fn shutdown(&mut self);
}
Expand Down Expand Up @@ -148,10 +150,10 @@ impl ChatClient for Client {
ContactOnlineStatus::Offline
}

async fn send_message(&self, receiver: TariAddress, message: String) {
async fn send_message(&self, message: Message) {
if let Some(mut contacts_service) = self.contacts.clone() {
contacts_service
.send_message(MessageBuilder::new().message(message).address(receiver).build())
.send_message(message)
.await
.expect("Message wasn't sent");
}
Expand All @@ -168,6 +170,19 @@ impl ChatClient for Client {

messages
}

fn create_message(&self, receiver: &TariAddress, message: String) -> Message {
MessageBuilder::new().address(receiver.clone()).message(message).build()
}

fn add_metadata(&self, message: Message, metadata_type: MessageMetadataType, data: String) -> Message {
let metadata = MessageMetadata {
metadata_type,
data: data.into_bytes(),
};

MessageBuilder::from(message).metadata(metadata).build()
}
}

pub async fn wait_for_connectivity(comms: CommsNode) -> anyhow::Result<()> {
Expand Down
7 changes: 4 additions & 3 deletions base_layer/contacts/src/contacts_service/types/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pub struct Message {
}

#[repr(u8)]
#[derive(FromPrimitive, Debug, Copy, Clone, Default)]
#[derive(FromPrimitive, Debug, Copy, Clone, Default, PartialEq)]
pub enum Direction {
Inbound = 0,
#[default]
Expand All @@ -67,10 +67,11 @@ pub struct MessageMetadata {
}

#[repr(u8)]
#[derive(FromPrimitive, Debug, Copy, Clone, Default, Deserialize, Serialize)]
#[derive(FromPrimitive, Debug, Copy, Clone, Default, Deserialize, Serialize, PartialEq)]
pub enum MessageMetadataType {
Reply = 0,
#[default]
TokenRequest = 0,
TokenRequest = 1,
}

impl MessageMetadataType {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

use tari_common_types::tari_address::TariAddress;
use tari_utilities::ByteArray;
use uuid::Uuid;

use crate::contacts_service::types::{message::MessageMetadata, Message};
Expand All @@ -33,7 +32,7 @@ pub struct MessageBuilder {

impl MessageBuilder {
pub fn new() -> Self {
let message_id = Uuid::new_v4().into_bytes().to_vec();
let message_id = Uuid::new_v4().to_string().into_bytes();

Self {
inner: Message {
Expand Down Expand Up @@ -78,3 +77,11 @@ impl MessageBuilder {
self.inner.clone()
}
}

impl From<Message> for MessageBuilder {
fn from(message: Message) -> Self {
Self {
inner: Message { ..message },
}
}
}
1 change: 1 addition & 0 deletions integration_tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ thiserror = "^1.0.20"
time = "0.3.15"
tokio = { version = "1.10", features = ["macros", "time", "sync", "rt-multi-thread"] }
tonic = "0.6.2"
uuid = { version = "1.3", features = ["v4"] }

[package.metadata.cargo-machete]
ignored = ["minotari_wallet_ffi", "minotari_chat_ffi"]
Expand Down
Loading

0 comments on commit ef28fd1

Please sign in to comment.