Skip to content

Commit

Permalink
feat: add favourite flag to contact (#5217)
Browse files Browse the repository at this point in the history
Description
---
Adds a favourite tag to contacts

Motivation and Context
---
Mobile applications have favorite tags on contacts. For data integrity, we link the two. 

How Has This Been Tested?
---
Unit tests
and manual
  • Loading branch information
SWvheerden authored Mar 6, 2023
1 parent 8962909 commit 0371b60
Show file tree
Hide file tree
Showing 13 changed files with 93 additions and 11 deletions.
2 changes: 1 addition & 1 deletion applications/tari_console_wallet/src/ui/state/app_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ impl AppState {
.map_err(|_| UiError::PublicKeyParseError)?,
};

let contact = Contact::new(alias, address, None, None);
let contact = Contact::new(alias, address, None, None, false);
inner.wallet.contacts_service.upsert_contact(contact).await?;

inner.refresh_contacts_state().await?;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE contacts drop favourite;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE contacts ADD favourite INTEGER DEFAULT 0 NOT NULL;
10 changes: 9 additions & 1 deletion base_layer/wallet/src/contacts_service/storage/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,24 @@ pub struct Contact {
pub node_id: NodeId,
pub last_seen: Option<NaiveDateTime>,
pub latency: Option<u32>,
pub favourite: bool,
}

impl Contact {
pub fn new(alias: String, address: TariAddress, last_seen: Option<NaiveDateTime>, latency: Option<u32>) -> Self {
pub fn new(
alias: String,
address: TariAddress,
last_seen: Option<NaiveDateTime>,
latency: Option<u32>,
favourite: bool,
) -> Self {
Self {
alias,
node_id: NodeId::from_key(address.public_key()),
address,
last_seen,
latency,
favourite,
}
}
}
Expand Down
14 changes: 13 additions & 1 deletion base_layer/wallet/src/contacts_service/storage/sqlite_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ impl ContactsBackend for ContactsServiceSqliteDatabase {
alias: Some(c.clone().alias),
last_seen: None,
latency: None,
favourite: Some(i32::from(c.favourite)),
})
.is_err()
{
Expand All @@ -100,6 +101,7 @@ impl ContactsBackend for ContactsServiceSqliteDatabase {
alias: None,
last_seen: Some(Some(date_time)),
latency: Some(latency),
favourite: None,
})?;
return Ok(Some(DbValue::TariAddress(Box::new(
TariAddress::from_bytes(&contact.address)
Expand Down Expand Up @@ -140,6 +142,7 @@ struct ContactSql {
alias: String,
last_seen: Option<NaiveDateTime>,
latency: Option<i32>,
favourite: i32,
}

impl ContactSql {
Expand Down Expand Up @@ -245,6 +248,11 @@ impl TryFrom<ContactSql> for Contact {
alias: o.alias,
last_seen: o.last_seen,
latency: o.latency.map(|val| val as u32),
favourite: match o.favourite {
0 => false,
1 => true,
_ => return Err(ContactsServiceStorageError::ConversionError),
},
})
}
}
Expand All @@ -260,6 +268,7 @@ impl From<Contact> for ContactSql {
alias: o.alias,
last_seen: o.last_seen,
latency: o.latency.map(|val| val as i32),
favourite: i32::from(o.favourite),
}
}
}
Expand All @@ -270,6 +279,7 @@ pub struct UpdateContact {
alias: Option<String>,
last_seen: Option<Option<NaiveDateTime>>,
latency: Option<Option<i32>>,
favourite: Option<i32>,
}

#[cfg(test)]
Expand Down Expand Up @@ -324,7 +334,7 @@ mod test {
for i in 0..names.len() {
let pub_key = PublicKey::from_secret_key(&PrivateKey::random(&mut OsRng));
let address = TariAddress::new(pub_key, Network::default());
contacts.push(Contact::new(names[i].clone(), address, None, None));
contacts.push(Contact::new(names[i].clone(), address, None, None, false));
ContactSql::from(contacts[i].clone()).commit(&mut conn).unwrap();
}

Expand Down Expand Up @@ -354,11 +364,13 @@ mod test {
alias: Some("Fred".to_string()),
last_seen: None,
latency: None,
favourite: Some(i32::from(true)),
})
.unwrap();

let c_updated = ContactSql::find_by_address(&contacts[1].address.to_bytes(), &mut conn).unwrap();
assert_eq!(c_updated.alias, "Fred".to_string());
assert_eq!(c_updated.favourite, i32::from(true));
});
}
}
1 change: 1 addition & 0 deletions base_layer/wallet/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ diesel::table! {
alias -> Text,
last_seen -> Nullable<Timestamp>,
latency -> Nullable<Integer>,
favourite -> Integer,
}
}

Expand Down
3 changes: 2 additions & 1 deletion base_layer/wallet/tests/contacts_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ pub fn test_contacts_service() {
let (_secret_key, public_key) = PublicKey::random_keypair(&mut OsRng);
let address = TariAddress::new(public_key, Network::default());

contacts.push(Contact::new(random::string(8), address, None, None));
contacts.push(Contact::new(random::string(8), address, None, None, false));

runtime
.block_on(contacts_service.upsert_contact(contacts[i].clone()))
Expand Down Expand Up @@ -189,6 +189,7 @@ pub fn test_contacts_service() {

let mut updated_contact = contacts[1].clone();
updated_contact.alias = "Fred".to_string();
updated_contact.favourite = true;

runtime
.block_on(contacts_service.upsert_contact(updated_contact.clone()))
Expand Down
6 changes: 3 additions & 3 deletions base_layer/wallet/tests/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ async fn test_wallet() {
let (_secret_key, public_key) = PublicKey::random_keypair(&mut OsRng);
let address = TariAddress::new(public_key, Network::LocalNet);

contacts.push(Contact::new(random::string(8), address, None, None));
contacts.push(Contact::new(random::string(8), address, None, None, false));

alice_wallet
.contacts_service
Expand Down Expand Up @@ -869,7 +869,7 @@ async fn test_contacts_service_liveness() {
.add_peer(bob_identity.to_peer())
.await
.unwrap();
let contact_bob = Contact::new(random::string(8), bob_address.clone(), None, None);
let contact_bob = Contact::new(random::string(8), bob_address.clone(), None, None, false);
alice_wallet.contacts_service.upsert_contact(contact_bob).await.unwrap();

bob_wallet
Expand All @@ -878,7 +878,7 @@ async fn test_contacts_service_liveness() {
.add_peer(alice_identity.to_peer())
.await
.unwrap();
let contact_alice = Contact::new(random::string(8), alice_address.clone(), None, None);
let contact_alice = Contact::new(random::string(8), alice_address.clone(), None, None, false);
bob_wallet.contacts_service.upsert_contact(contact_alice).await.unwrap();

alice_wallet
Expand Down
1 change: 1 addition & 0 deletions base_layer/wallet_ffi/src/callback_handler_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,7 @@ mod test {
faux_unconfirmed_tx.destination_address,
None,
None,
false,
);
let data = ContactsLivenessData::new(
contact.address.clone(),
Expand Down
44 changes: 40 additions & 4 deletions base_layer/wallet_ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2651,6 +2651,7 @@ pub unsafe extern "C" fn seed_words_destroy(seed_words: *mut TariSeedWords) {
pub unsafe extern "C" fn contact_create(
alias: *const c_char,
address: *mut TariWalletAddress,
favourite: bool,
error_out: *mut c_int,
) -> *mut TariContact {
let mut error = 0;
Expand Down Expand Up @@ -2679,7 +2680,7 @@ pub unsafe extern "C" fn contact_create(
return ptr::null_mut();
}

let contact = Contact::new(alias_string, (*address).clone(), None, None);
let contact = Contact::new(alias_string, (*address).clone(), None, None, favourite);
Box::into_raw(Box::new(contact))
}

Expand Down Expand Up @@ -2716,6 +2717,34 @@ pub unsafe extern "C" fn contact_get_alias(contact: *mut TariContact, error_out:
CString::into_raw(a)
}

/// Gets the favourite status of the TariContact
///
/// ## Arguments
/// `contact` - The pointer to a TariContact
/// `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
/// `bool` - Returns a bool indicating the favourite status of a contact. NOTE this will return false if the pointer is
/// null as well.
///
/// # Safety
/// The ```string_destroy``` method must be called when finished with a string from rust to prevent a memory leak
#[no_mangle]
pub unsafe extern "C" fn contact_get_favourite(contact: *mut TariContact, error_out: *mut c_int) -> bool {
let mut error = 0;
let mut favourite = false;
ptr::swap(error_out, &mut error as *mut c_int);
if contact.is_null() {
error = LibWalletError::from(InterfaceError::NullError("contact".to_string())).code;
ptr::swap(error_out, &mut error as *mut c_int);
} else {
favourite = (*contact).favourite;
}

favourite
}

/// Gets the TariWalletAddress of the TariContact
///
/// ## Arguments
Expand Down Expand Up @@ -9078,7 +9107,9 @@ mod test {
let test_str = "Test Contact";
let test_contact_str = CString::new(test_str).unwrap();
let test_contact_alias: *const c_char = CString::into_raw(test_contact_str) as *const c_char;
let test_contact = contact_create(test_contact_alias, test_address, error_ptr);
let test_contact = contact_create(test_contact_alias, test_address, true, error_ptr);
let favourite = contact_get_favourite(test_contact, error_ptr);
assert!(favourite);
let alias = contact_get_alias(test_contact, error_ptr);
let alias_string = CString::from_raw(alias).to_str().unwrap().to_owned();
assert_eq!(alias_string, test_str);
Expand All @@ -9104,12 +9135,12 @@ mod test {
let test_str = "Test Contact";
let test_contact_str = CString::new(test_str).unwrap();
let test_contact_alias: *const c_char = CString::into_raw(test_contact_str) as *const c_char;
let mut _test_contact = contact_create(ptr::null_mut(), test_contact_address, error_ptr);
let mut _test_contact = contact_create(ptr::null_mut(), test_contact_address, false, error_ptr);
assert_eq!(
error,
LibWalletError::from(InterfaceError::NullError("alias_ptr".to_string())).code
);
_test_contact = contact_create(test_contact_alias, ptr::null_mut(), error_ptr);
_test_contact = contact_create(test_contact_alias, ptr::null_mut(), false, error_ptr);
assert_eq!(
error,
LibWalletError::from(InterfaceError::NullError("public_key_ptr".to_string())).code
Expand All @@ -9124,6 +9155,11 @@ mod test {
error,
LibWalletError::from(InterfaceError::NullError("contact_ptr".to_string())).code
);
let _contact_address = contact_get_favourite(ptr::null_mut(), error_ptr);
assert_eq!(
error,
LibWalletError::from(InterfaceError::NullError("contact_ptr".to_string())).code
);
let contact_key_bytes = public_key_get_bytes(ptr::null_mut(), error_ptr);
assert_eq!(
error,
Expand Down
19 changes: 19 additions & 0 deletions base_layer/wallet_ffi/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -1368,6 +1368,7 @@ void seed_words_destroy(struct TariSeedWords *seed_words);
*/
TariContact *contact_create(const char *alias,
TariWalletAddress *address,
bool favourite,
int *error_out);

/**
Expand All @@ -1388,6 +1389,24 @@ TariContact *contact_create(const char *alias,
char *contact_get_alias(TariContact *contact,
int *error_out);

/**
* Gets the favourite status of the TariContact
*
* ## Arguments
* `contact` - The pointer to a TariContact
* `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
* `bool` - Returns a bool indicating the favourite status of a contact. NOTE this will return false if the pointer is
* null as well.
*
* # Safety
* The ```string_destroy``` method must be called when finished with a string from rust to prevent a memory leak
*/
bool contact_get_favourite(TariContact *contact,
int *error_out);

/**
* Gets the TariWalletAddress of the TariContact
*
Expand Down
1 change: 1 addition & 0 deletions integration_tests/tests/utils/ffi/contact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ impl Contact {
ptr = ffi_import::contact_create(
CString::new(alias).unwrap().into_raw(),
WalletAddress::from_hex(address).get_ptr(),
false,
&mut error,
);
if error > 0 {
Expand Down
1 change: 1 addition & 0 deletions integration_tests/tests/utils/ffi/ffi_import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ extern "C" {
pub fn contact_create(
alias: *const c_char,
address: *mut TariWalletAddress,
favourite: bool,
error_out: *mut c_int,
) -> *mut TariContact;
pub fn contact_get_alias(contact: *mut TariContact, error_out: *mut c_int) -> *mut c_char;
Expand Down

0 comments on commit 0371b60

Please sign in to comment.