Skip to content

Commit

Permalink
lifetimes
Browse files Browse the repository at this point in the history
  • Loading branch information
insipx committed Nov 15, 2023
1 parent add1b9b commit 56279c0
Show file tree
Hide file tree
Showing 11 changed files with 298 additions and 245 deletions.
4 changes: 2 additions & 2 deletions xmtp_mls/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,14 @@ pub enum IdentityStrategy<Owner> {
ExternalIdentity(Identity),
}

impl<Owner> IdentityStrategy<Owner>
impl<'a, Owner> IdentityStrategy<Owner>
where
Owner: InboxOwner,
{
fn initialize_identity(
self,
store: &EncryptedMessageStore,
provider: &XmtpOpenMlsProvider,
provider: &'a XmtpOpenMlsProvider,
) -> Result<Identity, ClientBuilderError> {
let identity_option: Option<Identity> =
store.conn()?.fetch(&())?.map(|i: StoredIdentity| i.into());
Expand Down
44 changes: 31 additions & 13 deletions xmtp_mls/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use xmtp_proto::api_client::{XmtpApiClient, XmtpMlsClient};

use crate::{
api_client_wrapper::{ApiClientWrapper, IdentityUpdate},
builder::{ClientBuilder, IdentityStrategy},
configuration::KEY_PACKAGE_TOP_UP_AMOUNT,
groups::MlsGroup,
identity::Identity,
Expand Down Expand Up @@ -64,7 +65,7 @@ pub struct Client<ApiClient> {
pub store: EncryptedMessageStore, // Temporarily exposed outside crate for CLI client
}

impl<ApiClient> Client<ApiClient>
impl<'a, ApiClient> Client<ApiClient>
where
ApiClient: XmtpMlsClient + XmtpApiClient,
{
Expand All @@ -82,15 +83,28 @@ where
}
}

/// Build this struct
/// # Arguments
/// * `strat`: the [`IdentityStrategy`] for this client
///
/// # Example
///
/// TODO: Fix this example
/// ```no_run
/// Client::builder()
/// .api_client(api_client)
/// .network(Network::Dev)
/// .build()
/// ```
pub fn builder<Owner: crate::InboxOwner>(
strat: IdentityStrategy<Owner>,
) -> ClientBuilder<ApiClient, Owner> {
ClientBuilder::new(strat)
}

// TODO: Remove this and figure out the correct lifetimes to allow long lived provider
pub fn with_provider<'a, R, F, E>(&'a self, fun: F) -> Result<R, ClientError>
where
F: FnOnce(XmtpOpenMlsProvider) -> Result<R, E>,
ClientError: From<E>,
{
let mut connection = self.store.conn()?;
let provider = XmtpOpenMlsProvider::new(&mut connection);
fun(provider).map_err(ClientError::from)
pub fn mls_provider(&self, conn: &'a mut DbConnection) -> XmtpOpenMlsProvider<'a> {
XmtpOpenMlsProvider::new(conn)
}

pub fn create_group(&self) -> Result<MlsGroup<ApiClient>, ClientError> {
Expand Down Expand Up @@ -121,7 +135,9 @@ where

pub async fn register_identity(&self) -> Result<(), ClientError> {
// TODO: Mark key package as last_resort in creation
let last_resort_kp = self.identity.new_key_package(&self.mls_provider())?;
let mut connection = self.store.conn()?;
let mls_provider = XmtpOpenMlsProvider::new(&mut connection);
let last_resort_kp = self.identity.new_key_package(&mls_provider)?;
let last_resort_kp_bytes = last_resort_kp.tls_serialize_detached()?;

self.api_client
Expand All @@ -132,9 +148,11 @@ where
}

pub async fn top_up_key_packages(&self) -> Result<(), ClientError> {
let mut connection = self.store.conn()?;
let mls_provider = XmtpOpenMlsProvider::new(&mut connection);
let key_packages: Result<Vec<Vec<u8>>, ClientError> = (0..KEY_PACKAGE_TOP_UP_AMOUNT)
.map(|_| -> Result<Vec<u8>, ClientError> {
let kp = self.identity.new_key_package(&self.mls_provider())?;
let kp = self.identity.new_key_package(&mls_provider)?;
let kp_bytes = kp.tls_serialize_detached()?;

Ok(kp_bytes)
Expand Down Expand Up @@ -199,8 +217,8 @@ where
.api_client
.consume_key_packages(installation_ids)
.await?;

let mls_provider = self.mls_provider();
let mut conn = self.store.conn()?;
let mls_provider = XmtpOpenMlsProvider::new(&mut conn);

Ok(key_package_results
.values()
Expand Down
9 changes: 4 additions & 5 deletions xmtp_mls/src/groups/intents.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,16 +260,15 @@ mod tests {
let wallet = generate_local_wallet();
let wallet_address = wallet.get_address();
let client = ClientBuilder::new_test_client(wallet.into()).await;
let key_package = client
.identity
.new_key_package(&client.mls_provider())
.unwrap();
let mut conn = client.store.conn().unwrap();
let mls_provider = XmtpOpenMlsProvider::new(&mut conn);
let key_package = client.identity.new_key_package(&mls_provider).unwrap();
let verified_key_package = VerifiedKeyPackage::new(key_package, wallet_address.clone());

let intent = AddMembersIntentData::new(vec![verified_key_package.clone()]);
let as_bytes: Vec<u8> = intent.clone().try_into().unwrap();
let restored_intent =
AddMembersIntentData::from_bytes(as_bytes.as_slice(), &client.mls_provider()).unwrap();
AddMembersIntentData::from_bytes(as_bytes.as_slice(), &mls_provider).unwrap();

assert!(intent.key_packages[0]
.inner
Expand Down
71 changes: 37 additions & 34 deletions xmtp_mls/src/groups/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ pub enum GroupError {
Client(#[from] ClientError),
#[error("generic: {0}")]
Generic(String),
#[error("diesel error {0}")]
Diesel(#[from] diesel::result::Error),
}

pub struct MlsGroup<'c, ApiClient> {
Expand Down Expand Up @@ -107,7 +109,7 @@ where
mls_group.save(provider.key_store())?;
let group_id = mls_group.group_id().to_vec();
let stored_group = StoredGroup::new(group_id.clone(), now_ns(), membership_state);
stored_group.store(provider.conn())?;
stored_group.store(*provider.conn().borrow_mut())?;

Ok(Self::new(client, group_id, stored_group.created_at_ns))
}
Expand Down Expand Up @@ -193,43 +195,43 @@ where
}

pub(crate) async fn publish_intents(&self, conn: &mut DbConnection) -> Result<(), GroupError> {
let provider = self.client.mls_provider();
let mut openmls_group = self.load_mls_group(&provider)?;
let mut openmls_group = self.load_mls_group(&self.client.mls_provider(conn))?;

let intents = EncryptedMessageStore::find_group_intents(
conn,
self.group_id.clone(),
Some(vec![IntentState::ToPublish]),
None,
)?;

for intent in intents {
// TODO: Wrap in a transaction once we can synchronize with the MLS Keystore
let result = self.get_publish_intent_data(&provider, &mut openmls_group, &intent);
let result = XmtpOpenMlsProvider::transaction(conn, |provider| {
let (payload, post_commit_data) =
self.get_publish_intent_data(&provider, &mut openmls_group, &intent)?;

let payload_slice = payload.as_slice();

self.client
.api_client
.publish_to_group(vec![payload_slice])
.await?;

EncryptedMessageStore::set_group_intent_published(
&mut provider.conn().borrow_mut(),
intent.id,
sha256(payload_slice),
post_commit_data,
)?;
Ok::<_, GroupError>(())
});

if let Err(e) = result {
log::error!("error getting publish intent data {:?}", e);
// TODO: Figure out which types of errors we should abort completely on and which
// ones are safe to continue with
continue;
}

let (payload, post_commit_data) = result.expect("result already checked");
let payload_slice = payload.as_slice();

self.client
.api_client
.publish_to_group(vec![payload_slice])
.await?;

EncryptedMessageStore::set_group_intent_published(
conn,
intent.id,
sha256(payload_slice),
post_commit_data,
)?;
}

openmls_group.save(provider.key_store())?;
openmls_group.save(self.client.mls_provider(conn).key_store())?;

Ok(())
}
Expand Down Expand Up @@ -377,7 +379,9 @@ mod tests {
use openmls_traits::OpenMlsProvider;
use xmtp_cryptography::utils::generate_local_wallet;

use crate::{builder::ClientBuilder, utils::topic::get_welcome_topic};
use crate::{
builder::ClientBuilder, storage::EncryptedMessageStore, utils::topic::get_welcome_topic,
};

#[tokio::test]
async fn test_send_message() {
Expand Down Expand Up @@ -442,7 +446,8 @@ mod tests {
let client_2 = ClientBuilder::new_test_client(generate_local_wallet().into()).await;
client_2.register_identity().await.unwrap();

let provider = client_1.mls_provider();
let mut conn = client_1.store.conn().unwrap();
let provider = super::XmtpOpenMlsProvider::new(&mut conn);
let group = client_1.create_group().expect("create group");
group
.add_members_by_installation_id(vec![client_2
Expand Down Expand Up @@ -504,7 +509,9 @@ mod tests {
.unwrap();
assert_eq!(messages.len(), 1);

let mls_group = group.load_mls_group(&client.mls_provider()).unwrap();
let mut conn = client.store.conn().unwrap();
let provider = super::XmtpOpenMlsProvider::new(&mut conn);
let mls_group = group.load_mls_group(&provider).unwrap();
let pending_commit = mls_group.pending_commit();
assert!(pending_commit.is_some());
}
Expand All @@ -525,16 +532,12 @@ mod tests {
.await
.unwrap();

let intents = client
.store
.find_group_intents(conn, group.group_id.clone(), None, None)
.unwrap();
let intents =
EncryptedMessageStore::find_group_intents(conn, group.group_id.clone(), None, None)
.unwrap();
let intent = intents.first().unwrap();
// Set the intent to committed manually
client
.store
.set_group_intent_committed(conn, intent.id)
.unwrap();
EncryptedMessageStore::set_group_intent_committed(conn, intent.id).unwrap();
group.post_commit(conn).await.unwrap();

// Check if the welcome was actually sent
Expand Down
12 changes: 5 additions & 7 deletions xmtp_mls/src/identity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ pub struct Identity {
pub(crate) credential: Credential,
}

impl Identity {
impl<'a> Identity {
pub(crate) fn new(
store: &EncryptedMessageStore,
provider: &XmtpOpenMlsProvider,
Expand Down Expand Up @@ -72,6 +72,7 @@ impl Identity {
installation_keys: signature_keys,
credential,
};

StoredIdentity::from(&identity).store(&mut store.conn()?)?;

// TODO: upload credential_with_key and last_resort_key_package
Expand Down Expand Up @@ -129,11 +130,8 @@ mod tests {
#[test]
fn does_not_error() {
let store = EncryptedMessageStore::new_test();
Identity::new(
&store,
&XmtpOpenMlsProvider::new(&store),
&generate_local_wallet(),
)
.unwrap();
let mut conn = store.conn().unwrap();
let provider = XmtpOpenMlsProvider::new(&mut conn);
Identity::new(&provider, &generate_local_wallet()).unwrap();
}
}
Loading

0 comments on commit 56279c0

Please sign in to comment.