diff --git a/examples/cli/cli-client.rs b/examples/cli/cli-client.rs index d5573339d..15557f0be 100644 --- a/examples/cli/cli-client.rs +++ b/examples/cli/cli-client.rs @@ -6,23 +6,26 @@ extern crate ethers; extern crate log; extern crate xmtp; +use std::{fs, path::PathBuf, time::Duration}; + use clap::{Parser, Subcommand}; use log::{error, info}; -use std::fs; -use std::path::PathBuf; -use std::time::Duration; use thiserror::Error; -use xmtp::builder::{AccountStrategy, ClientBuilderError}; -use xmtp::client::ClientError; -use xmtp::conversation::{Conversation, ConversationError, ListMessagesOptions}; -use xmtp::conversations::Conversations; -use xmtp::storage::{ - now, EncryptedMessageStore, EncryptionKey, MessageState, StorageError, StorageOption, +use xmtp::{ + builder::{AccountStrategy, ClientBuilderError}, + client::ClientError, + conversation::{Conversation, ConversationError, ListMessagesOptions}, + conversations::Conversations, + storage::{ + now, EncryptedMessageStore, EncryptionKey, MessageState, StorageError, StorageOption, + }, + InboxOwner, }; -use xmtp::InboxOwner; use xmtp_api_grpc::grpc_api_helper::Client as ApiClient; -use xmtp_cryptography::signature::{RecoverableSignature, SignatureError}; -use xmtp_cryptography::utils::{rng, seeded_rng, LocalWallet}; +use xmtp_cryptography::{ + signature::{RecoverableSignature, SignatureError}, + utils::{rng, seeded_rng, LocalWallet}, +}; use xmtp_proto::api_client::XmtpApiClient; type Client = xmtp::client::Client; type ClientBuilder = xmtp::builder::ClientBuilder; diff --git a/mls_validation_service/src/handlers.rs b/mls_validation_service/src/handlers.rs index 1e73cb904..15efac046 100644 --- a/mls_validation_service/src/handlers.rs +++ b/mls_validation_service/src/handlers.rs @@ -1,11 +1,10 @@ -use openmls_rust_crypto::OpenMlsRustCrypto; -use openmls_traits::OpenMlsProvider; -use tonic::{Request, Response, Status}; - use openmls::{ prelude::{KeyPackageIn, MlsMessageIn, ProtocolMessage, TlsDeserializeTrait}, versions::ProtocolVersion, }; +use openmls_rust_crypto::OpenMlsRustCrypto; +use openmls_traits::OpenMlsProvider; +use tonic::{Request, Response, Status}; use xmtp_proto::xmtp::mls_validation::v1::{ validate_group_messages_response::ValidationResponse as ValidateGroupMessageValidationResponse, validate_key_packages_response::ValidationResponse as ValidateKeyPackageValidationResponse, @@ -97,7 +96,8 @@ fn validate_group_message(message: Vec) -> Result) -> Result (Vec, SignatureKeyPair, String) { diff --git a/mls_validation_service/src/main.rs b/mls_validation_service/src/main.rs index a64bdefce..dd193760e 100644 --- a/mls_validation_service/src/main.rs +++ b/mls_validation_service/src/main.rs @@ -6,8 +6,8 @@ use clap::Parser; use config::Args; use env_logger::Env; use handlers::ValidationService; -use tokio::signal::unix::{signal, SignalKind}; use tokio::{ + signal::unix::{signal, SignalKind}, spawn, sync::oneshot::{self, Sender}, }; diff --git a/mls_validation_service/src/validation_helpers.rs b/mls_validation_service/src/validation_helpers.rs index 6cef87e50..6f44e7446 100644 --- a/mls_validation_service/src/validation_helpers.rs +++ b/mls_validation_service/src/validation_helpers.rs @@ -1,6 +1,5 @@ -use xmtp_mls::association::Eip191Association; - use prost::Message; +use xmtp_mls::association::Eip191Association; use xmtp_proto::xmtp::v3::message_contents::Eip191Association as Eip191AssociationProto; pub fn hex_encode(key: &[u8]) -> String { diff --git a/xmtp/src/account.rs b/xmtp/src/account.rs index cb24ed14c..36a564fa5 100644 --- a/xmtp/src/account.rs +++ b/xmtp/src/account.rs @@ -1,20 +1,18 @@ -use std::fmt; -use std::sync::{Mutex, MutexGuard}; - -use crate::{ - association::{AssociationError, Eip191Association}, - contact::Contact, - types::Address, - vmac_protos::ProtoWrapper, - Signable, +use std::{ + fmt, + sync::{Mutex, MutexGuard}, }; + use serde::{Deserialize, Serialize}; use thiserror::Error; -use vodozemac::olm::{ - Account as OlmAccount, AccountPickle as OlmAccountPickle, IdentityKeys, InboundCreationResult, - PreKeyMessage, Session as OlmSession, SessionConfig, SessionCreationError, +use vodozemac::{ + olm::{ + Account as OlmAccount, AccountPickle as OlmAccountPickle, IdentityKeys, + InboundCreationResult, PreKeyMessage, Session as OlmSession, SessionConfig, + SessionCreationError, + }, + Ed25519Signature, }; -use vodozemac::Ed25519Signature; use xmtp_cryptography::signature::SignatureError; use xmtp_proto::xmtp::v3::message_contents::{ installation_contact_bundle::Version, vmac_account_linked_key::Association as AssociationProto, @@ -22,6 +20,14 @@ use xmtp_proto::xmtp::v3::message_contents::{ VmacInstallationPublicKeyBundleV1, VmacUnsignedPublicKey, }; +use crate::{ + association::{AssociationError, Eip191Association}, + contact::Contact, + types::Address, + vmac_protos::ProtoWrapper, + Signable, +}; + #[derive(Debug, Error)] pub enum AccountError { #[error("session creation")] @@ -200,14 +206,18 @@ impl Account { #[cfg(test)] pub(crate) mod tests { - use crate::association::AssociationError; + use ethers::{ + core::rand::thread_rng, + signers::{LocalWallet, Signer}, + }; + use ethers_core::{ + types::{Address as EthAddress, Signature}, + utils::hex, + }; + use serde_json::json; use super::{Account, Eip191Association}; - use ethers::core::rand::thread_rng; - use ethers::signers::{LocalWallet, Signer}; - use ethers_core::types::{Address as EthAddress, Signature}; - use ethers_core::utils::hex; - use serde_json::json; + use crate::association::AssociationError; pub fn test_wallet_signer(pub_key: Vec) -> Result { Eip191Association::test(pub_key) diff --git a/xmtp/src/association.rs b/xmtp/src/association.rs index 2ad171593..fd2d6c391 100644 --- a/xmtp/src/association.rs +++ b/xmtp/src/association.rs @@ -1,11 +1,15 @@ -use crate::types::Address; -use crate::InboxOwner; use serde::{Deserialize, Serialize}; use thiserror::Error; -use xmtp_cryptography::signature::{RecoverableSignature, SignatureError}; -use xmtp_cryptography::utils::generate_local_wallet; -use xmtp_proto::xmtp::v3::message_contents::Eip191Association as Eip191AssociationProto; -use xmtp_proto::xmtp::v3::message_contents::RecoverableEcdsaSignature as RecoverableEcdsaSignatureProto; +use xmtp_cryptography::{ + signature::{RecoverableSignature, SignatureError}, + utils::generate_local_wallet, +}; +use xmtp_proto::xmtp::v3::message_contents::{ + Eip191Association as Eip191AssociationProto, + RecoverableEcdsaSignature as RecoverableEcdsaSignatureProto, +}; + +use crate::{types::Address, InboxOwner}; #[derive(Debug, Error)] pub enum AssociationError { @@ -103,9 +107,10 @@ impl From for Eip191AssociationProto { } } -/// AssociationText represents the string which was signed by the authorizing blockchain account. A valid AssociationText must -/// contain the address of the blockchain account and a representation of the XMTP installation public key. Different standards may -/// choose how this information is encoded, as well as adding extra requirements for increased security. +/// AssociationText represents the string which was signed by the authorizing blockchain account. A +/// valid AssociationText must contain the address of the blockchain account and a representation of +/// the XMTP installation public key. Different standards may choose how this information is +/// encoded, as well as adding extra requirements for increased security. #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] pub enum AssociationText { Static { diff --git a/xmtp/src/bin/update-schema.rs b/xmtp/src/bin/update-schema.rs index 96d7a6851..694d02d43 100644 --- a/xmtp/src/bin/update-schema.rs +++ b/xmtp/src/bin/update-schema.rs @@ -1,12 +1,13 @@ extern crate toml; extern crate xmtp; -use rand::distributions::{Alphanumeric, DistString}; use std::{ env, fs::{self, File}, io::{Read, Write}, process::Command, }; + +use rand::distributions::{Alphanumeric, DistString}; use toml::Table; use xmtp::storage::{EncryptedMessageStore, StorageOption}; diff --git a/xmtp/src/builder.rs b/xmtp/src/builder.rs index e1cb0c626..57c245fe6 100644 --- a/xmtp/src/builder.rs +++ b/xmtp/src/builder.rs @@ -1,15 +1,15 @@ +use log::info; +use thiserror::Error; +use xmtp_proto::api_client::XmtpApiClient; + use crate::{ account::{Account, AccountError}, association::{AssociationError, AssociationText, Eip191Association}, client::{Client, Network}, storage::{now, EncryptedMessageStore, StoredUser}, types::Address, - InboxOwner, Store, + Fetch, InboxOwner, StorageError, Store, }; -use crate::{Fetch, StorageError}; -use log::info; -use thiserror::Error; -use xmtp_proto::api_client::XmtpApiClient; #[derive(Error, Debug)] pub enum ClientBuilderError { @@ -191,13 +191,12 @@ mod tests { use tempfile::TempPath; use xmtp_cryptography::utils::generate_local_wallet; + use super::ClientBuilder; use crate::{ mock_xmtp_api_client::MockXmtpApiClient, storage::{EncryptedMessageStore, StorageOption}, }; - use super::ClientBuilder; - impl ClientBuilder { pub fn new_test() -> Self { let wallet = generate_local_wallet(); diff --git a/xmtp/src/client.rs b/xmtp/src/client.rs index ed8ed4656..e5ea2da6b 100644 --- a/xmtp/src/client.rs +++ b/xmtp/src/client.rs @@ -1,10 +1,14 @@ use core::fmt; -use std::fmt::Formatter; +use std::{collections::HashMap, fmt::Formatter}; use diesel::Connection; use log::{debug, info}; use thiserror::Error; use vodozemac::olm::PreKeyMessage; +use xmtp_proto::{ + api_client::XmtpApiClient, + xmtp::message_api::v1::{Envelope, PublishRequest, QueryRequest}, +}; use crate::{ account::Account, @@ -19,9 +23,6 @@ use crate::{ utils::{build_envelope, build_user_contact_topic, key_fingerprint}, Store, }; -use std::collections::HashMap; -use xmtp_proto::api_client::XmtpApiClient; -use xmtp_proto::xmtp::message_api::v1::{Envelope, PublishRequest, QueryRequest}; const INSTALLATION_REFRESH_INTERVAL_NS: i64 = 0; @@ -170,7 +171,7 @@ impl Client { if let Err(e) = session.store(conn) { match e { - StorageError::DieselResult(_) => log::warn!("Session Already exists"), // TODO: Some thought is needed here, is this a critical error which should unroll? + StorageError::DieselResult(_) => log::warn!("Session Already exists"), /* TODO: Some thought is needed here, is this a critical error which should unroll? */ other_error => return Err(other_error.into()), } } @@ -307,7 +308,8 @@ where Ok(()) } - /// Fetch Installations from the Network and create uninitialized sessions for newly discovered contacts + /// Fetch Installations from the Network and create uninitialized sessions for newly discovered + /// contacts // TODO: Reduce Visibility pub async fn refresh_user_installations(&self, user_address: &str) -> Result<(), ClientError> { // Store the timestamp of when the refresh process begins @@ -372,12 +374,12 @@ where #[cfg(test)] mod tests { - use xmtp_proto::xmtp::v3::message_contents::installation_contact_bundle::Version; - use xmtp_proto::xmtp::v3::message_contents::vmac_unsigned_public_key::Union::Curve25519; - use xmtp_proto::xmtp::v3::message_contents::vmac_unsigned_public_key::VodozemacCurve25519; + use xmtp_proto::xmtp::v3::message_contents::{ + installation_contact_bundle::Version, + vmac_unsigned_public_key::{Union::Curve25519, VodozemacCurve25519}, + }; - use crate::test_utils::test_utils::gen_test_client; - use crate::ClientBuilder; + use crate::{test_utils::test_utils::gen_test_client, ClientBuilder}; #[tokio::test] async fn registration() { diff --git a/xmtp/src/codecs/text.rs b/xmtp/src/codecs/text.rs index 56650e727..31052acf6 100644 --- a/xmtp/src/codecs/text.rs +++ b/xmtp/src/codecs/text.rs @@ -1,7 +1,9 @@ -use super::{CodecError, ContentCodec}; use std::collections::HashMap; + use xmtp_proto::xmtp::message_contents::{ContentTypeId, EncodedContent}; +use super::{CodecError, ContentCodec}; + pub struct TextCodec {} impl TextCodec { const AUTHORITY_ID: &str = "xmtp.org"; diff --git a/xmtp/src/contact.rs b/xmtp/src/contact.rs index 43f2cd263..c89ba6320 100644 --- a/xmtp/src/contact.rs +++ b/xmtp/src/contact.rs @@ -1,6 +1,5 @@ use prost::{DecodeError, EncodeError, Message}; use thiserror::Error; - use vodozemac::Curve25519PublicKey; use xmtp_proto::xmtp::v3::message_contents::{ installation_contact_bundle::Version as ContactBundleVersionProto, @@ -42,7 +41,8 @@ impl Contact { wallet_address, }; // .association() will return an error if it fails to validate - // If you try and create with a wallet address that doesn't match the signature, this will fail + // If you try and create with a wallet address that doesn't match the signature, this will + // fail contact.association()?; Ok(contact) @@ -170,9 +170,8 @@ fn extract_proto_association( #[cfg(test)] mod tests { - use crate::account::{tests::test_wallet_signer, Account}; - use super::Contact; + use crate::account::{tests::test_wallet_signer, Account}; #[test] fn serialize_round_trip() { diff --git a/xmtp/src/conversation.rs b/xmtp/src/conversation.rs index 8c3413689..9278f61a9 100644 --- a/xmtp/src/conversation.rs +++ b/xmtp/src/conversation.rs @@ -1,3 +1,8 @@ +use prost::{DecodeError, Message}; +// use async_trait::async_trait; +use thiserror::Error; +use xmtp_proto::api_client::XmtpApiClient; + use crate::{ client::ClientError, codecs::{text::TextCodec, CodecError, ContentCodec}, @@ -11,11 +16,6 @@ use crate::{ types::Address, Client, Store, }; -use xmtp_proto::api_client::XmtpApiClient; - -use prost::{DecodeError, Message}; -// use async_trait::async_trait; -use thiserror::Error; #[derive(Debug, Error)] pub enum ConversationError { diff --git a/xmtp/src/conversations.rs b/xmtp/src/conversations.rs index 5f1fe6d05..417128f78 100644 --- a/xmtp/src/conversations.rs +++ b/xmtp/src/conversations.rs @@ -5,12 +5,14 @@ use futures::executor::block_on; use log::info; use prost::Message; use vodozemac::olm::{self, OlmMessage}; -use xmtp_proto::api_client::XmtpApiClient; -use xmtp_proto::xmtp::{ - message_api::v1::{Envelope, PublishRequest}, - v3::message_contents::{ - EdDsaSignature, PadlockMessageEnvelope, PadlockMessageHeader, PadlockMessagePayload, - PadlockMessagePayloadVersion, PadlockMessageSealedMetadata, +use xmtp_proto::{ + api_client::XmtpApiClient, + xmtp::{ + message_api::v1::{Envelope, PublishRequest}, + v3::message_contents::{ + EdDsaSignature, PadlockMessageEnvelope, PadlockMessageHeader, PadlockMessagePayload, + PadlockMessagePayloadVersion, PadlockMessageSealedMetadata, + }, }, }; @@ -351,7 +353,8 @@ impl Conversations { message.id, e ); - // TODO update message status to failed on non-retryable errors so that we don't retry it next time + // TODO update message status to failed on non-retryable errors so that we don't + // retry it next time } } @@ -401,8 +404,7 @@ impl Conversations { #[cfg(test)] mod tests { use prost::Message; - use xmtp_proto::api_client::XmtpApiClient; - use xmtp_proto::xmtp::message_api::v1::QueryRequest; + use xmtp_proto::{api_client::XmtpApiClient, xmtp::message_api::v1::QueryRequest}; use crate::{ codecs::{text::TextCodec, ContentCodec}, diff --git a/xmtp/src/lib.rs b/xmtp/src/lib.rs index 04a0e516a..b76e7f046 100644 --- a/xmtp/src/lib.rs +++ b/xmtp/src/lib.rs @@ -20,11 +20,10 @@ pub mod vmac_protos; pub use builder::ClientBuilder; pub use client::{Client, Network}; +pub use codecs::{text::TextCodec, ContentCodec}; use storage::StorageError; use xmtp_cryptography::signature::{RecoverableSignature, SignatureError}; -pub use codecs::{text::TextCodec, ContentCodec}; - pub trait Signable { fn bytes_to_sign(&self) -> Vec; } @@ -56,11 +55,15 @@ pub trait InboxOwner { #[cfg(test)] mod tests { - use crate::builder::ClientBuilder; use std::time::{SystemTime, UNIX_EPOCH}; + use uuid::Uuid; - use xmtp_proto::api_client::XmtpApiClient; - use xmtp_proto::xmtp::message_api::v1::{Envelope, PublishRequest, QueryRequest}; + use xmtp_proto::{ + api_client::XmtpApiClient, + xmtp::message_api::v1::{Envelope, PublishRequest, QueryRequest}, + }; + + use crate::builder::ClientBuilder; fn gen_test_envelope(topic: String) -> Envelope { let time_since_epoch = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); diff --git a/xmtp/src/message.rs b/xmtp/src/message.rs index 0356f2e9a..c63680c7e 100644 --- a/xmtp/src/message.rs +++ b/xmtp/src/message.rs @@ -1,7 +1,3 @@ -use crate::{ - storage::InboundMessage, - types::{Address, InstallationId}, -}; use prost::DecodeError as ProstDecodeError; use thiserror::Error; use vodozemac::{olm, DecodeError as VmacDecodeError}; @@ -9,6 +5,11 @@ use xmtp_proto::xmtp::v3::message_contents::{ PadlockMessageEnvelope, PadlockMessageHeader, PadlockMessageSealedMetadata, }; +use crate::{ + storage::InboundMessage, + types::{Address, InstallationId}, +}; + #[derive(Debug, Error)] pub enum PayloadError { #[error("prostdecode:{0}")] diff --git a/xmtp/src/mock_xmtp_api_client.rs b/xmtp/src/mock_xmtp_api_client.rs index 2d49b630e..f0b4d72fc 100644 --- a/xmtp/src/mock_xmtp_api_client.rs +++ b/xmtp/src/mock_xmtp_api_client.rs @@ -1,8 +1,9 @@ -use async_trait::async_trait; use std::{ collections::HashMap, sync::{Arc, Mutex}, }; + +use async_trait::async_trait; use xmtp_proto::api_client::*; pub struct MockXmtpApiSubscription {} diff --git a/xmtp/src/owner/evm_owner.rs b/xmtp/src/owner/evm_owner.rs index 42692bbfc..2dda10e92 100644 --- a/xmtp/src/owner/evm_owner.rs +++ b/xmtp/src/owner/evm_owner.rs @@ -1,9 +1,9 @@ -use crate::InboxOwner; - pub use ethers::signers::{LocalWallet, Signer}; use futures::executor; use xmtp_cryptography::signature::{h160addr_to_string, RecoverableSignature, SignatureError}; +use crate::InboxOwner; + impl InboxOwner for LocalWallet { fn get_address(&self) -> String { h160addr_to_string(self.address()) diff --git a/xmtp/src/session.rs b/xmtp/src/session.rs index be3320944..426c99c77 100644 --- a/xmtp/src/session.rs +++ b/xmtp/src/session.rs @@ -1,10 +1,11 @@ +use thiserror::Error; +use vodozemac::olm::{DecryptionError, OlmMessage, Session as OlmSession}; + use crate::{ contact::Contact, storage::{DbConnection, StorageError, StoredSession}, Save, Store, }; -use thiserror::Error; -use vodozemac::olm::{DecryptionError, OlmMessage, Session as OlmSession}; #[derive(Debug, Error)] pub enum SessionError { @@ -114,7 +115,8 @@ impl TryFrom<&SessionManager> for StoredSession { Ok(StoredSession::new( value.session.session_id(), value.peer_installation_id.clone(), - // TODO: Better error handling approach. StoreError and SessionError end up being dependent on eachother + // TODO: Better error handling approach. StoreError and SessionError end up being + // dependent on eachother value .session_bytes() .map_err(|_| StorageError::Serialization)?, diff --git a/xmtp/src/storage/encrypted_store/mod.rs b/xmtp/src/storage/encrypted_store/mod.rs index 0a010b4df..002550d6e 100644 --- a/xmtp/src/storage/encrypted_store/mod.rs +++ b/xmtp/src/storage/encrypted_store/mod.rs @@ -1,31 +1,23 @@ //! A durable object store powered by Sqlite and Diesel. //! -//! Provides mechanism to store objects between sessions. The behavior of the store can be tailored by -//! choosing an appropriate `StoreOption`. +//! Provides mechanism to store objects between sessions. The behavior of the store can be tailored +//! by choosing an appropriate `StoreOption`. //! //! ## Migrations //! -//! Table definitions are located `/migrations/`. On initialization the store will see if -//! there are any outstanding database migrations and perform them as needed. When updating the table -//! definitions `schema.rs` must also be updated. To generate the correct schemas you can run -//! `diesel print-schema` or use `cargo run update-schema` which will update the files for you. -//! +//! Table definitions are located `/migrations/`. On initialization the store will see +//! if there are any outstanding database migrations and perform them as needed. When updating the +//! table definitions `schema.rs` must also be updated. To generate the correct schemas you can run +//! `diesel print-schema` or use `cargo run update-schema` which will update the files for you. pub mod models; pub mod schema; -use self::{ - models::*, - schema::{accounts, conversations, installations, messages, refresh_jobs, sessions, users}, -}; -use super::{now, StorageError}; -use crate::{account::Account, utils::is_wallet_address, Fetch, Store}; use diesel::{ connection::SimpleConnection, prelude::*, r2d2::{ConnectionManager, Pool, PooledConnection}, - result::DatabaseErrorKind, - result::Error, + result::{DatabaseErrorKind, Error}, sql_query, sql_types::Text, }; @@ -34,6 +26,13 @@ use log::warn; use rand::RngCore; use xmtp_cryptography::utils as crypto_utils; +use self::{ + models::*, + schema::{accounts, conversations, installations, messages, refresh_jobs, sessions, users}, +}; +use super::{now, StorageError}; +use crate::{account::Account, utils::is_wallet_address, Fetch, Store}; + pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!("./migrations/"); pub type DbConnection = PooledConnection>; @@ -102,8 +101,8 @@ impl EncryptedMessageStore { Self::set_sqlcipher_key(pool.clone(), &key)?; } - // TODO: Validate that sqlite is correctly configured. Bad EncKey is not detected until the migrations run which returns an - // unhelpful error. + // TODO: Validate that sqlite is correctly configured. Bad EncKey is not detected until the + // migrations run which returns an unhelpful error. let mut obj = Self { connect_opt: opts, @@ -757,15 +756,15 @@ fn warn_length(list: &Vec, str_id: &str, max_length: usize) { #[cfg(test)] mod tests { - use super::{models::*, EncryptedMessageStore, StorageError, StorageOption}; - use crate::{Fetch, Store}; + use std::{boxed::Box, fs, thread::sleep, time::Duration}; + use rand::{ distributions::{Alphanumeric, DistString}, Rng, }; - use std::boxed::Box; - use std::fs; - use std::{thread::sleep, time::Duration}; + + use super::{models::*, EncryptedMessageStore, StorageError, StorageOption}; + use crate::{Fetch, Store}; fn rand_string() -> String { Alphanumeric.sample_string(&mut rand::thread_rng(), 16) diff --git a/xmtp/src/storage/encrypted_store/models.rs b/xmtp/src/storage/encrypted_store/models.rs index 73e818782..bff3c9402 100644 --- a/xmtp/src/storage/encrypted_store/models.rs +++ b/xmtp/src/storage/encrypted_store/models.rs @@ -1,3 +1,13 @@ +use std::{ + fmt, + time::{SystemTime, UNIX_EPOCH}, +}; + +use diesel::prelude::*; +use prost::{DecodeError, Message}; +use xmtp_cryptography::hash::sha256_bytes; +use xmtp_proto::xmtp::{message_api::v1::Envelope, message_contents::EncodedContent}; + use super::{schema::*, DbConnection}; use crate::{ account::Account, @@ -5,12 +15,6 @@ use crate::{ storage::StorageError, ContentCodec, Save, TextCodec, }; -use diesel::prelude::*; -use prost::{DecodeError, Message}; -use std::fmt; -use std::time::{SystemTime, UNIX_EPOCH}; -use xmtp_cryptography::hash::sha256_bytes; -use xmtp_proto::xmtp::{message_api::v1::Envelope, message_contents::EncodedContent}; #[derive(Insertable, Selectable, Identifiable, Queryable, PartialEq, Debug, Clone)] #[diesel(table_name = users)] diff --git a/xmtp/src/test_utils.rs b/xmtp/src/test_utils.rs index 170e44c13..f00bf9c2c 100644 --- a/xmtp/src/test_utils.rs +++ b/xmtp/src/test_utils.rs @@ -1,9 +1,10 @@ #[cfg(test)] pub mod test_utils { + use xmtp_proto::api_client::XmtpApiClient; + use crate::{ conversation::Conversation, mock_xmtp_api_client::MockXmtpApiClient, Client, ClientBuilder, }; - use xmtp_proto::api_client::XmtpApiClient; async fn gen_test_client_internal(api_client: MockXmtpApiClient) -> Client { let mut client = ClientBuilder::new_test() diff --git a/xmtp/src/utils.rs b/xmtp/src/utils.rs index ea7b1d093..f792fc4a9 100644 --- a/xmtp/src/utils.rs +++ b/xmtp/src/utils.rs @@ -1,8 +1,8 @@ -use base64::{engine::general_purpose, Engine as _}; use std::time::{SystemTime, UNIX_EPOCH}; + +use base64::{engine::general_purpose, Engine as _}; use vodozemac::Curve25519PublicKey; use xmtp_cryptography::hash::keccak256; - use xmtp_proto::xmtp::message_api::v1::Envelope; pub fn get_current_time_ns() -> u64 { diff --git a/xmtp/src/vmac_protos.rs b/xmtp/src/vmac_protos.rs index 839a47b1e..ab047397f 100644 --- a/xmtp/src/vmac_protos.rs +++ b/xmtp/src/vmac_protos.rs @@ -1,8 +1,6 @@ use vodozemac::Curve25519PublicKey; -use xmtp_proto::xmtp::v3::message_contents::vmac_unsigned_public_key::{ - Union, VodozemacCurve25519, -}; use xmtp_proto::xmtp::v3::message_contents::{ + vmac_unsigned_public_key::{Union, VodozemacCurve25519}, VmacAccountLinkedKey, VmacInstallationLinkedKey, VmacUnsignedPublicKey, }; @@ -57,13 +55,14 @@ impl From> for Curve25519PublicKey { #[cfg(test)] mod test { - use super::*; use vodozemac::olm::{Account, SessionConfig}; use xmtp_proto::xmtp::v3::message_contents::{ VmacAccountLinkedKey, VmacInstallationLinkedKey, VmacInstallationPublicKeyBundleV1, VmacUnsignedPublicKey, }; + use super::*; + // Generate a VmacContactBundle fn generate_test_contact_bundle() -> VmacInstallationPublicKeyBundleV1 { let mut account = Account::new(); diff --git a/xmtp_api_grpc/src/grpc_api_helper.rs b/xmtp_api_grpc/src/grpc_api_helper.rs index 1459313fd..320217052 100644 --- a/xmtp_api_grpc/src/grpc_api_helper.rs +++ b/xmtp_api_grpc/src/grpc_api_helper.rs @@ -1,24 +1,29 @@ +use std::sync::{Arc, Mutex}; // TODO switch to async mutexes +use std::{ + str::FromStr, + sync::atomic::{AtomicBool, Ordering}, +}; + use http_body::combinators::UnsyncBoxBody; use hyper::{client::HttpConnector, Uri}; use hyper_rustls::HttpsConnector; -use std::str::FromStr; -use std::sync::atomic::{AtomicBool, Ordering}; -use std::sync::{Arc, Mutex}; // TODO switch to async mutexes use tokio::sync::oneshot; use tokio_rustls::rustls::{ClientConfig, OwnedTrustAnchor, RootCertStore}; -use tonic::async_trait; -use tonic::Status; -use tonic::{metadata::MetadataValue, transport::Channel, Request, Streaming}; -use xmtp_proto::api_client::{Error, ErrorKind, XmtpApiClient, XmtpApiSubscription, XmtpMlsClient}; -use xmtp_proto::xmtp::message_api::v1::{ - message_api_client::MessageApiClient, BatchQueryRequest, BatchQueryResponse, Envelope, - PublishRequest, PublishResponse, QueryRequest, QueryResponse, SubscribeRequest, -}; -use xmtp_proto::xmtp::message_api::v3::mls_api_client::MlsApiClient as ProtoMlsApiClient; -use xmtp_proto::xmtp::message_api::v3::{ - ConsumeKeyPackagesRequest, ConsumeKeyPackagesResponse, GetIdentityUpdatesRequest, - GetIdentityUpdatesResponse, PublishToGroupRequest, PublishWelcomesRequest, - RegisterInstallationRequest, RegisterInstallationResponse, UploadKeyPackagesRequest, +use tonic::{async_trait, metadata::MetadataValue, transport::Channel, Request, Status, Streaming}; +use xmtp_proto::{ + api_client::{Error, ErrorKind, XmtpApiClient, XmtpApiSubscription, XmtpMlsClient}, + xmtp::message_api::{ + v1::{ + message_api_client::MessageApiClient, BatchQueryRequest, BatchQueryResponse, Envelope, + PublishRequest, PublishResponse, QueryRequest, QueryResponse, SubscribeRequest, + }, + v3::{ + mls_api_client::MlsApiClient as ProtoMlsApiClient, ConsumeKeyPackagesRequest, + ConsumeKeyPackagesResponse, GetIdentityUpdatesRequest, GetIdentityUpdatesResponse, + PublishToGroupRequest, PublishWelcomesRequest, RegisterInstallationRequest, + RegisterInstallationResponse, UploadKeyPackagesRequest, + }, + }, }; fn tls_config() -> ClientConfig { diff --git a/xmtp_api_grpc/src/lib.rs b/xmtp_api_grpc/src/lib.rs index 1ae3b43d2..15d24466a 100644 --- a/xmtp_api_grpc/src/lib.rs +++ b/xmtp_api_grpc/src/lib.rs @@ -9,12 +9,15 @@ pub use grpc_api_helper::Client; mod tests { use std::time::{SystemTime, UNIX_EPOCH}; - use super::*; - use xmtp_proto::api_client::{XmtpApiClient, XmtpApiSubscription}; - use xmtp_proto::xmtp::message_api::v1::{ - BatchQueryRequest, Envelope, PublishRequest, QueryRequest, SubscribeRequest, + use xmtp_proto::{ + api_client::{XmtpApiClient, XmtpApiSubscription}, + xmtp::message_api::v1::{ + BatchQueryRequest, Envelope, PublishRequest, QueryRequest, SubscribeRequest, + }, }; + use super::*; + // Return the json serialization of an Envelope with bytes pub fn test_envelope(topic: String) -> Envelope { let time_since_epoch = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); diff --git a/xmtp_cryptography/src/hash.rs b/xmtp_cryptography/src/hash.rs index 57c1afe7b..b7aad3ff0 100644 --- a/xmtp_cryptography/src/hash.rs +++ b/xmtp_cryptography/src/hash.rs @@ -7,7 +7,8 @@ pub fn keccak256(msg: &str) -> Vec { k.as_slice().to_vec() } -/// Sha256 is used in places where cryptographic security is not required, as sha256 has a significant speed improvement over Keccak. +/// Sha256 is used in places where cryptographic security is not required, as sha256 has a +/// significant speed improvement over Keccak. pub fn sha256_bytes(bytes: &[u8]) -> Vec { let k = Sha256::digest(bytes); diff --git a/xmtp_cryptography/src/signature.rs b/xmtp_cryptography/src/signature.rs index 296db13b3..971e7a4ab 100644 --- a/xmtp_cryptography/src/signature.rs +++ b/xmtp_cryptography/src/signature.rs @@ -26,8 +26,9 @@ pub enum SignatureError { #[derive(Debug, Serialize, Deserialize, PartialEq, Clone)] pub enum RecoverableSignature { - // This Signature is primary used by EVM compatible accounts. It assumes that the recoveryid is included in the signature and - // that all messages passed in have not been prefixed with '\0x19Ethereum....' + // This Signature is primary used by EVM compatible accounts. It assumes that the recoveryid + // is included in the signature and that all messages passed in have not been prefixed + // with '\0x19Ethereum....' Eip191Signature(Vec), } @@ -112,9 +113,12 @@ pub fn h160addr_to_string(bytes: H160) -> String { #[cfg(test)] pub mod tests { + use ethers::{ + core::rand::thread_rng, + signers::{LocalWallet, Signer}, + }; + use crate::signature::RecoverableSignature; - use ethers::core::rand::thread_rng; - use ethers::signers::{LocalWallet, Signer}; pub async fn generate_random_signature(msg: &str) -> (String, Vec) { let wallet = LocalWallet::new(&mut thread_rng()); diff --git a/xmtp_mls/src/api_client_wrapper.rs b/xmtp_mls/src/api_client_wrapper.rs index 49f0c5511..7e057e49c 100644 --- a/xmtp_mls/src/api_client_wrapper.rs +++ b/xmtp_mls/src/api_client_wrapper.rs @@ -5,25 +5,21 @@ use xmtp_proto::{ Envelope, Error as ApiError, ErrorKind, PagingInfo, QueryRequest, XmtpApiClient, XmtpMlsClient, }, - xmtp::{ - message_api::{v1::Cursor, v3::GetIdentityUpdatesRequest}, - mls::message_contents::{ - group_message::{Version as GroupMessageVersion, V1 as GroupMessageV1}, - welcome_message::{Version as WelcomeMessageVersion, V1 as WelcomeMessageV1}, - WelcomeMessage as WelcomeMessageProto, - }, - }, xmtp::{ message_api::{ - v1::SortDirection, + v1::{Cursor, SortDirection}, v3::{ get_identity_updates_response::update::Kind as UpdateKind, publish_welcomes_request::WelcomeMessageRequest, ConsumeKeyPackagesRequest, - KeyPackageUpload, PublishToGroupRequest, PublishWelcomesRequest, - RegisterInstallationRequest, UploadKeyPackagesRequest, + GetIdentityUpdatesRequest, KeyPackageUpload, PublishToGroupRequest, + PublishWelcomesRequest, RegisterInstallationRequest, UploadKeyPackagesRequest, }, }, - mls::message_contents::GroupMessage, + mls::message_contents::{ + group_message::{Version as GroupMessageVersion, V1 as GroupMessageV1}, + welcome_message::{Version as WelcomeMessageVersion, V1 as WelcomeMessageV1}, + GroupMessage, WelcomeMessage as WelcomeMessageProto, + }, }, }; @@ -272,29 +268,30 @@ type IdentityUpdatesMap = HashMap>; #[cfg(test)] mod tests { - use super::ApiClientWrapper; + use async_trait::async_trait; use mockall::mock; - use xmtp_proto::api_client::{ - Error, PagingInfo, XmtpApiClient, XmtpApiSubscription, XmtpMlsClient, - }; - use xmtp_proto::xmtp::message_api::v1::IndexCursor; - use xmtp_proto::xmtp::message_api::v3::consume_key_packages_response::KeyPackage; - use xmtp_proto::xmtp::message_api::v3::get_identity_updates_response::update::Kind as UpdateKind; - use xmtp_proto::xmtp::message_api::v3::get_identity_updates_response::{ - NewInstallationUpdate, Update, WalletUpdates, - }; - use xmtp_proto::xmtp::message_api::v3::{ - ConsumeKeyPackagesRequest, ConsumeKeyPackagesResponse, GetIdentityUpdatesRequest, - GetIdentityUpdatesResponse, PublishToGroupRequest, PublishWelcomesRequest, - RegisterInstallationRequest, RegisterInstallationResponse, UploadKeyPackagesRequest, - }; - - use xmtp_proto::xmtp::message_api::v1::{ - cursor::Cursor as InnerCursor, BatchQueryRequest, BatchQueryResponse, Cursor, Envelope, - PublishRequest, PublishResponse, QueryRequest, QueryResponse, SubscribeRequest, + use xmtp_proto::{ + api_client::{Error, PagingInfo, XmtpApiClient, XmtpApiSubscription, XmtpMlsClient}, + xmtp::message_api::{ + v1::{ + cursor::Cursor as InnerCursor, BatchQueryRequest, BatchQueryResponse, Cursor, + Envelope, IndexCursor, PublishRequest, PublishResponse, QueryRequest, + QueryResponse, SubscribeRequest, + }, + v3::{ + consume_key_packages_response::KeyPackage, + get_identity_updates_response::{ + update::Kind as UpdateKind, NewInstallationUpdate, Update, WalletUpdates, + }, + ConsumeKeyPackagesRequest, ConsumeKeyPackagesResponse, GetIdentityUpdatesRequest, + GetIdentityUpdatesResponse, PublishToGroupRequest, PublishWelcomesRequest, + RegisterInstallationRequest, RegisterInstallationResponse, + UploadKeyPackagesRequest, + }, + }, }; - use async_trait::async_trait; + use super::ApiClientWrapper; fn build_envelopes(num_envelopes: usize, topic: &str) -> Vec { let mut out: Vec = vec![]; diff --git a/xmtp_mls/src/association.rs b/xmtp_mls/src/association.rs index fa587384b..630f9dcab 100644 --- a/xmtp_mls/src/association.rs +++ b/xmtp_mls/src/association.rs @@ -1,11 +1,15 @@ -use crate::types::Address; -use crate::InboxOwner; use serde::{Deserialize, Serialize}; use thiserror::Error; -use xmtp_cryptography::signature::{RecoverableSignature, SignatureError}; -use xmtp_cryptography::utils::generate_local_wallet; -use xmtp_proto::xmtp::v3::message_contents::Eip191Association as Eip191AssociationProto; -use xmtp_proto::xmtp::v3::message_contents::RecoverableEcdsaSignature as RecoverableEcdsaSignatureProto; +use xmtp_cryptography::{ + signature::{RecoverableSignature, SignatureError}, + utils::generate_local_wallet, +}; +use xmtp_proto::xmtp::v3::message_contents::{ + Eip191Association as Eip191AssociationProto, + RecoverableEcdsaSignature as RecoverableEcdsaSignatureProto, +}; + +use crate::{types::Address, InboxOwner}; #[derive(Debug, Error)] pub enum AssociationError { @@ -101,9 +105,10 @@ impl From for Eip191AssociationProto { } } -/// AssociationText represents the string which was signed by the authorizing blockchain account. A valid AssociationText must -/// contain the address of the blockchain account and a representation of the XMTP installation public key. Different standards may -/// choose how this information is encoded, as well as adding extra requirements for increased security. +/// AssociationText represents the string which was signed by the authorizing blockchain account. A +/// valid AssociationText must contain the address of the blockchain account and a representation of +/// the XMTP installation public key. Different standards may choose how this information is +/// encoded, as well as adding extra requirements for increased security. #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] pub enum AssociationText { Static { diff --git a/xmtp_mls/src/bin/update-schema.rs b/xmtp_mls/src/bin/update-schema.rs index 3cec21ed1..7beb4a2c6 100644 --- a/xmtp_mls/src/bin/update-schema.rs +++ b/xmtp_mls/src/bin/update-schema.rs @@ -1,12 +1,13 @@ extern crate toml; extern crate xmtp_mls; -use rand::distributions::{Alphanumeric, DistString}; use std::{ env, fs::{self, File}, io::{Read, Write}, process::Command, }; + +use rand::distributions::{Alphanumeric, DistString}; use toml::Table; use xmtp_mls::storage::{EncryptedMessageStore, StorageOption}; diff --git a/xmtp_mls/src/builder.rs b/xmtp_mls/src/builder.rs index 415520a9e..3470b9c6c 100644 --- a/xmtp_mls/src/builder.rs +++ b/xmtp_mls/src/builder.rs @@ -1,20 +1,20 @@ -use crate::configuration::CIPHERSUITE; -use crate::storage::identity::StoredIdentity; -use crate::xmtp_openmls_provider::XmtpOpenMlsProvider; -use crate::{ - client::{Client, Network}, - identity::{Identity, IdentityError}, - storage::EncryptedMessageStore, - InboxOwner, -}; -use crate::{Fetch, StorageError}; -#[cfg(not(test))] -use log::debug; #[cfg(test)] use std::println as debug; + +#[cfg(not(test))] +use log::debug; use thiserror::Error; use xmtp_proto::api_client::{XmtpApiClient, XmtpMlsClient}; +use crate::{ + client::{Client, Network}, + configuration::CIPHERSUITE, + identity::{Identity, IdentityError}, + storage::{identity::StoredIdentity, EncryptedMessageStore}, + xmtp_openmls_provider::XmtpOpenMlsProvider, + Fetch, InboxOwner, StorageError, +}; + #[derive(Error, Debug)] pub enum ClientBuilderError { #[error("Missing parameter: {parameter}")] @@ -155,13 +155,12 @@ mod tests { use xmtp_api_grpc::grpc_api_helper::Client as GrpcClient; use xmtp_cryptography::utils::generate_local_wallet; + use super::{ClientBuilder, IdentityStrategy}; use crate::{ storage::{EncryptedMessageStore, StorageOption}, Client, }; - use super::{ClientBuilder, IdentityStrategy}; - async fn get_local_grpc_client() -> GrpcClient { GrpcClient::create("http://localhost:5556".to_string(), false) .await diff --git a/xmtp_mls/src/client.rs b/xmtp_mls/src/client.rs index ebf81c04c..f3d895e4e 100644 --- a/xmtp_mls/src/client.rs +++ b/xmtp_mls/src/client.rs @@ -211,7 +211,7 @@ mod tests { let wallet = generate_local_wallet(); let wallet_address = wallet.get_address(); let client = ClientBuilder::new_test_client(wallet.clone().into()).await; - + client.register_identity().await.unwrap(); client.top_up_key_packages().await.unwrap(); diff --git a/xmtp_mls/src/identity.rs b/xmtp_mls/src/identity.rs index a9723a091..fb460ba06 100644 --- a/xmtp_mls/src/identity.rs +++ b/xmtp_mls/src/identity.rs @@ -9,6 +9,7 @@ use openmls_traits::{types::CryptoError, OpenMlsProvider}; use prost::Message; use thiserror::Error; use xmtp_cryptography::signature::SignatureError; +use xmtp_proto::xmtp::v3::message_contents::Eip191Association as Eip191AssociationProto; use crate::{ association::{AssociationError, AssociationText, Eip191Association}, @@ -18,7 +19,6 @@ use crate::{ xmtp_openmls_provider::XmtpOpenMlsProvider, InboxOwner, Store, }; -use xmtp_proto::xmtp::v3::message_contents::Eip191Association as Eip191AssociationProto; #[derive(Debug, Error)] pub enum IdentityError { @@ -123,9 +123,8 @@ impl Identity { mod tests { use xmtp_cryptography::utils::generate_local_wallet; - use crate::{storage::EncryptedMessageStore, xmtp_openmls_provider::XmtpOpenMlsProvider}; - use super::Identity; + use crate::{storage::EncryptedMessageStore, xmtp_openmls_provider::XmtpOpenMlsProvider}; #[test] fn does_not_error() { diff --git a/xmtp_mls/src/mock_xmtp_api_client.rs b/xmtp_mls/src/mock_xmtp_api_client.rs index b70be389d..f150fabcb 100644 --- a/xmtp_mls/src/mock_xmtp_api_client.rs +++ b/xmtp_mls/src/mock_xmtp_api_client.rs @@ -1,8 +1,9 @@ -use async_trait::async_trait; use std::{ collections::HashMap, sync::{Arc, Mutex}, }; + +use async_trait::async_trait; use xmtp_proto::api_client::*; pub struct MockXmtpApiSubscription {} diff --git a/xmtp_mls/src/owner/evm_owner.rs b/xmtp_mls/src/owner/evm_owner.rs index 42692bbfc..2dda10e92 100644 --- a/xmtp_mls/src/owner/evm_owner.rs +++ b/xmtp_mls/src/owner/evm_owner.rs @@ -1,9 +1,9 @@ -use crate::InboxOwner; - pub use ethers::signers::{LocalWallet, Signer}; use futures::executor; use xmtp_cryptography::signature::{h160addr_to_string, RecoverableSignature, SignatureError}; +use crate::InboxOwner; + impl InboxOwner for LocalWallet { fn get_address(&self) -> String { h160addr_to_string(self.address()) diff --git a/xmtp_mls/src/proto_wrapper.rs b/xmtp_mls/src/proto_wrapper.rs index f4df6761d..4f2ec0232 100644 --- a/xmtp_mls/src/proto_wrapper.rs +++ b/xmtp_mls/src/proto_wrapper.rs @@ -1,7 +1,5 @@ -use xmtp_proto::xmtp::v3::message_contents::vmac_unsigned_public_key::{ - Union, VodozemacCurve25519, -}; use xmtp_proto::xmtp::v3::message_contents::{ + vmac_unsigned_public_key::{Union, VodozemacCurve25519}, VmacAccountLinkedKey, VmacInstallationLinkedKey, VmacUnsignedPublicKey, }; diff --git a/xmtp_mls/src/storage/encrypted_store/group.rs b/xmtp_mls/src/storage/encrypted_store/group.rs index 6cbf5941e..7eba6ce3e 100644 --- a/xmtp_mls/src/storage/encrypted_store/group.rs +++ b/xmtp_mls/src/storage/encrypted_store/group.rs @@ -1,6 +1,7 @@ -use super::schema::groups; use diesel::prelude::*; +use super::schema::groups; + #[derive(Insertable, Identifiable, Queryable, Debug, Clone)] #[diesel(table_name = groups)] #[diesel(primary_key(id))] diff --git a/xmtp_mls/src/storage/encrypted_store/group_intent.rs b/xmtp_mls/src/storage/encrypted_store/group_intent.rs index 7da2954d9..021bae983 100644 --- a/xmtp_mls/src/storage/encrypted_store/group_intent.rs +++ b/xmtp_mls/src/storage/encrypted_store/group_intent.rs @@ -1,6 +1,7 @@ -use super::schema::group_intents; use diesel::prelude::*; +use super::schema::group_intents; + #[derive(Queryable, Identifiable, Debug, Clone)] #[diesel(table_name = group_intents)] #[diesel(primary_key(id))] diff --git a/xmtp_mls/src/storage/encrypted_store/group_message.rs b/xmtp_mls/src/storage/encrypted_store/group_message.rs index 0f109ac45..ffaea8bf2 100644 --- a/xmtp_mls/src/storage/encrypted_store/group_message.rs +++ b/xmtp_mls/src/storage/encrypted_store/group_message.rs @@ -1,6 +1,7 @@ -use super::schema::group_messages; use diesel::prelude::*; +use super::schema::group_messages; + #[derive(Insertable, Identifiable, Queryable, Debug, Clone)] #[diesel(table_name = group_messages)] #[diesel(primary_key(id))] diff --git a/xmtp_mls/src/storage/encrypted_store/identity.rs b/xmtp_mls/src/storage/encrypted_store/identity.rs index 50e8f8b23..eda965f6d 100644 --- a/xmtp_mls/src/storage/encrypted_store/identity.rs +++ b/xmtp_mls/src/storage/encrypted_store/identity.rs @@ -1,10 +1,11 @@ +use diesel::prelude::*; + use super::{schema::identity, DbConnection, StorageError}; use crate::{ identity::Identity, storage::serialization::{db_deserialize, db_serialize}, Fetch, Store, }; -use diesel::prelude::*; #[derive(Insertable, Queryable, Debug, Clone)] #[diesel(table_name = identity)] diff --git a/xmtp_mls/src/storage/encrypted_store/key_store_entry.rs b/xmtp_mls/src/storage/encrypted_store/key_store_entry.rs index f2cb87e7a..8dddbbeb8 100644 --- a/xmtp_mls/src/storage/encrypted_store/key_store_entry.rs +++ b/xmtp_mls/src/storage/encrypted_store/key_store_entry.rs @@ -1,8 +1,8 @@ -use super::DbConnection; -use super::{schema::openmls_key_store, StorageError}; -use crate::{Delete, Fetch, Store}; use diesel::prelude::*; +use super::{schema::openmls_key_store, DbConnection, StorageError}; +use crate::{Delete, Fetch, Store}; + #[derive(Insertable, Queryable, Debug, Clone)] #[diesel(table_name = openmls_key_store)] #[diesel(primary_key(key_bytes))] diff --git a/xmtp_mls/src/storage/encrypted_store/mod.rs b/xmtp_mls/src/storage/encrypted_store/mod.rs index 2dcf7163c..0da7c242e 100644 --- a/xmtp_mls/src/storage/encrypted_store/mod.rs +++ b/xmtp_mls/src/storage/encrypted_store/mod.rs @@ -1,15 +1,14 @@ //! A durable object store powered by Sqlite and Diesel. //! -//! Provides mechanism to store objects between sessions. The behavor of the store can be tailored by -//! choosing an appropriate `StoreOption`. +//! Provides mechanism to store objects between sessions. The behavor of the store can be tailored +//! by choosing an appropriate `StoreOption`. //! //! ## Migrations //! -//! Table definitions are located `/migrations/`. On intialization the store will see if -//! there are any outstanding database migrations and perform them as needed. When updating the table -//! definitions `schema.rs` must also be updated. To generate the correct schemas you can run -//! `diesel print-schema` or use `cargo run update-schema` which will update the files for you. -//! +//! Table definitions are located `/migrations/`. On intialization the store will see +//! if there are any outstanding database migrations and perform them as needed. When updating the +//! table definitions `schema.rs` must also be updated. To generate the correct schemas you can run +//! `diesel print-schema` or use `cargo run update-schema` which will update the files for you. pub mod group; pub mod group_intent; @@ -19,19 +18,19 @@ pub mod key_store_entry; pub mod schema; pub mod topic_refresh_state; -use super::StorageError; use diesel::{ connection::SimpleConnection, prelude::*, r2d2::{ConnectionManager, Pool, PooledConnection}, - result::DatabaseErrorKind, - result::Error, + result::{DatabaseErrorKind, Error}, }; use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness}; use log::warn; use rand::RngCore; use xmtp_cryptography::utils as crypto_utils; +use super::StorageError; + pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!("./migrations/"); pub type DbConnection = PooledConnection>; @@ -101,8 +100,8 @@ impl EncryptedMessageStore { Self::set_sqlcipher_key(pool.clone(), &key)?; } - // TODO: Validate that sqlite is correctly configured. Bad EncKey is not detected until the migrations run which returns an - // unhelpful error. + // TODO: Validate that sqlite is correctly configured. Bad EncKey is not detected until the + // migrations run which returns an unhelpful error. let mut obj = Self { connect_opt: opts, @@ -168,14 +167,15 @@ fn warn_length(list: &Vec, str_id: &str, max_length: usize) { #[cfg(test)] mod tests { - use super::{identity::StoredIdentity, EncryptedMessageStore, StorageError, StorageOption}; - use crate::{Fetch, Store}; + use std::{boxed::Box, fs}; + use rand::{ distributions::{Alphanumeric, DistString}, Rng, }; - use std::boxed::Box; - use std::fs; + + use super::{identity::StoredIdentity, EncryptedMessageStore, StorageError, StorageOption}; + use crate::{Fetch, Store}; pub(crate) fn rand_string() -> String { Alphanumeric.sample_string(&mut rand::thread_rng(), 16) diff --git a/xmtp_mls/src/storage/encrypted_store/topic_refresh_state.rs b/xmtp_mls/src/storage/encrypted_store/topic_refresh_state.rs index de04b3f5e..88111d460 100644 --- a/xmtp_mls/src/storage/encrypted_store/topic_refresh_state.rs +++ b/xmtp_mls/src/storage/encrypted_store/topic_refresh_state.rs @@ -1,6 +1,7 @@ -use super::schema::topic_refresh_state; use diesel::prelude::*; +use super::schema::topic_refresh_state; + #[derive(Insertable, Identifiable, Queryable, Debug, Clone)] #[diesel(table_name = topic_refresh_state)] #[diesel(primary_key(topic))] diff --git a/xmtp_mls/src/storage/sql_key_store.rs b/xmtp_mls/src/storage/sql_key_store.rs index f4654f31f..db5d89a1e 100644 --- a/xmtp_mls/src/storage/sql_key_store.rs +++ b/xmtp_mls/src/storage/sql_key_store.rs @@ -1,13 +1,12 @@ use log::{debug, error}; use openmls_traits::key_store::{MlsEntity, OpenMlsKeyStore}; -use crate::{Delete, Fetch, Store}; - use super::{ encrypted_store::key_store_entry::StoredKeyStoreEntry, serialization::{db_deserialize, db_serialize}, EncryptedMessageStore, StorageError, }; +use crate::{Delete, Fetch, Store}; #[derive(Debug)] pub struct SqlKeyStore<'a> { @@ -86,13 +85,12 @@ mod tests { use openmls_traits::key_store::OpenMlsKeyStore; use rand::distributions::{Alphanumeric, DistString}; + use super::SqlKeyStore; use crate::{ configuration::CIPHERSUITE, storage::{EncryptedMessageStore, StorageOption}, }; - use super::SqlKeyStore; - fn rand_string() -> String { Alphanumeric.sample_string(&mut rand::thread_rng(), 16) } diff --git a/xmtp_proto/src/api_client.rs b/xmtp_proto/src/api_client.rs index 0c045e058..2d30b33e6 100644 --- a/xmtp_proto/src/api_client.rs +++ b/xmtp_proto/src/api_client.rs @@ -1,16 +1,16 @@ -use async_trait::async_trait; use std::{error::Error as StdError, fmt}; -use crate::xmtp::message_api::v3::{ - ConsumeKeyPackagesRequest, ConsumeKeyPackagesResponse, GetIdentityUpdatesRequest, - GetIdentityUpdatesResponse, PublishToGroupRequest, PublishWelcomesRequest, - RegisterInstallationRequest, RegisterInstallationResponse, UploadKeyPackagesRequest, -}; +use async_trait::async_trait; pub use super::xmtp::message_api::v1::{ BatchQueryRequest, BatchQueryResponse, Envelope, PagingInfo, PublishRequest, PublishResponse, QueryRequest, QueryResponse, SubscribeRequest, }; +use crate::xmtp::message_api::v3::{ + ConsumeKeyPackagesRequest, ConsumeKeyPackagesResponse, GetIdentityUpdatesRequest, + GetIdentityUpdatesResponse, PublishToGroupRequest, PublishWelcomesRequest, + RegisterInstallationRequest, RegisterInstallationResponse, UploadKeyPackagesRequest, +}; #[derive(Debug)] pub enum ErrorKind { diff --git a/xmtp_v2/src/encryption.rs b/xmtp_v2/src/encryption.rs index 2926d291f..69d620863 100644 --- a/xmtp_v2/src/encryption.rs +++ b/xmtp_v2/src/encryption.rs @@ -1,13 +1,11 @@ -use hkdf::Hkdf; -use rand::Rng; -use sha2::Sha256; - -use generic_array::GenericArray; - use aes_gcm::{ aead::{Aead, KeyInit, Payload}, Aes256Gcm, Nonce, }; +use generic_array::GenericArray; +use hkdf::Hkdf; +use rand::Rng; +use sha2::Sha256; // Lightweight ciphertext holder pub struct Ciphertext { diff --git a/xmtp_v2/src/hashes.rs b/xmtp_v2/src/hashes.rs index a50155a6f..3672e04c8 100644 --- a/xmtp_v2/src/hashes.rs +++ b/xmtp_v2/src/hashes.rs @@ -1,5 +1,4 @@ -use sha2::Digest; -use sha2::Sha256; +use sha2::{Digest, Sha256}; use sha3::Keccak256; pub fn sha256(data: &[u8]) -> [u8; 32] { diff --git a/xmtp_v2/src/k256_helper.rs b/xmtp_v2/src/k256_helper.rs index 0d3f8f935..af9e41b73 100644 --- a/xmtp_v2/src/k256_helper.rs +++ b/xmtp_v2/src/k256_helper.rs @@ -1,6 +1,6 @@ -use k256::elliptic_curve::sec1::ToEncodedPoint; use k256::{ ecdsa::{signature::Verifier, RecoveryId, Signature, VerifyingKey}, + elliptic_curve::sec1::ToEncodedPoint, PublicKey, SecretKey, }; use sha2::{digest::Update, Digest, Sha256}; @@ -73,7 +73,8 @@ pub fn recover_public_key_predigest_sha256( Ok(recovered_key.to_encoded_point(false).as_bytes().to_vec()) } -/// Return recovered key from a compact signature, recovery_id, and message (does keccak256 internally) +/// Return recovered key from a compact signature, recovery_id, and message (does keccak256 +/// internally) pub fn recover_public_key_predigest_keccak256( message: &[u8], signature: &[u8], diff --git a/xmtp_v2/src/lib.rs b/xmtp_v2/src/lib.rs index 4c7bb3ab2..d65fd1145 100644 --- a/xmtp_v2/src/lib.rs +++ b/xmtp_v2/src/lib.rs @@ -72,7 +72,8 @@ mod tests { #[test] fn test_hardcoded_decryption() { - // Generated from xmtp-js with simple console.log statements around unit-tests that use the decrypt function + // Generated from xmtp-js with simple console.log statements around unit-tests that use the + // decrypt function let hkdf_salt: Vec = vec![ 139, 45, 107, 41, 87, 173, 15, 163, 250, 14, 194, 152, 200, 180, 226, 48, 140, 198, 1, 93, 80, 253, 64, 244, 41, 69, 15, 139, 197, 77, 189, 53, @@ -322,8 +323,10 @@ mod tests { #[test] fn test_public_key_recovery_sha256() { // message: 48656c6c6f20776f726c64 // "hello world" - // Signature: 8268b9c8d7629e9bbbd392004c337a5d7c99d1e59cf26a4a4f024935462cbf277f34e41be8fbcc9a5ffe69adcd0461e04b740df4180ce4864222236d735234a301 - // Expected public: 04fd927bcc71326a7a294f202133d94f4064f38ede547bc9449ed7307eecc23a845214a6c2880d64a352ec8410f90f5263fb00d6536aa27c7441d4fd6b97f4e518 + // Signature: + // 8268b9c8d7629e9bbbd392004c337a5d7c99d1e59cf26a4a4f024935462cbf277f34e41be8fbcc9a5ffe69adcd0461e04b740df4180ce4864222236d735234a301 + // Expected public: + // 04fd927bcc71326a7a294f202133d94f4064f38ede547bc9449ed7307eecc23a845214a6c2880d64a352ec8410f90f5263fb00d6536aa27c7441d4fd6b97f4e518 let message = hex::decode("48656c6c6f20776f726c64").unwrap(); let signature = hex::decode("8268b9c8d7629e9bbbd392004c337a5d7c99d1e59cf26a4a4f024935462cbf277f34e41be8fbcc9a5ffe69adcd0461e04b740df4180ce4864222236d735234a301").unwrap(); let expected_public_bytes = hex::decode("04fd927bcc71326a7a294f202133d94f4064f38ede547bc9449ed7307eecc23a845214a6c2880d64a352ec8410f90f5263fb00d6536aa27c7441d4fd6b97f4e518").unwrap(); @@ -335,12 +338,15 @@ mod tests { #[test] fn test_public_key_recovery_keccak256() { - // Best way to test recovery with keccak256 is to test our existing XMTP Create Identity Signature - // pre eth personal sign message: 584d5450203a20437265617465204964656e746974790a30383830633662626331663638396565616231373161343330613431303431653361663730396132666136633439336664623434653332396362656561303464303966316666653561643465303133623866656230313836633232613532646331313836643462353835626465393139313238323039396531366663366565643830303333346138626334353363366561303734363634616138656465630a0a466f72206d6f726520696e666f3a2068747470733a2f2f786d74702e6f72672f7369676e6174757265732f + // Best way to test recovery with keccak256 is to test our existing XMTP Create Identity + // Signature pre eth personal sign message: + // 584d5450203a20437265617465204964656e746974790a30383830633662626331663638396565616231373161343330613431303431653361663730396132666136633439336664623434653332396362656561303464303966316666653561643465303133623866656230313836633232613532646331313836643462353835626465393139313238323039396531366663366565643830303333346138626334353363366561303734363634616138656465630a0a466f72206d6f726520696e666f3a2068747470733a2f2f786d74702e6f72672f7369676e6174757265732f // wallet address: '0x13d0b11D0157F1740e139171C98FFF95b83AD107' - // identity key signature d5ea9e13675a39295d82b0ee9fe2782b0754f93666e280e75451e84306953aac5979d039126d5e516ebb4b5150b8d128b7e3b71f9dce1d4939a2456c52fbf3fc + // identity key signature + // d5ea9e13675a39295d82b0ee9fe2782b0754f93666e280e75451e84306953aac5979d039126d5e516ebb4b5150b8d128b7e3b71f9dce1d4939a2456c52fbf3fc // identity key recovery 0 - // expected public key bytes (64, no 0x04 prefix): 96fdd6c4e8c00e02642e800fe965808eb89e4f256fc913159950995a142289fad97bfd119e2afe5ee9de765e26f09e6f86e300616a8829228f57a6cc47e42381 + // expected public key bytes (64, no 0x04 prefix): + // 96fdd6c4e8c00e02642e800fe965808eb89e4f256fc913159950995a142289fad97bfd119e2afe5ee9de765e26f09e6f86e300616a8829228f57a6cc47e42381 let message = hex::decode("584d5450203a20437265617465204964656e746974790a30383830633662626331663638396565616231373161343330613431303431653361663730396132666136633439336664623434653332396362656561303464303966316666653561643465303133623866656230313836633232613532646331313836643462353835626465393139313238323039396531366663366565643830303333346138626334353363366561303734363634616138656465630a0a466f72206d6f726520696e666f3a2068747470733a2f2f786d74702e6f72672f7369676e6174757265732f").unwrap(); let signature = hex::decode("d5ea9e13675a39295d82b0ee9fe2782b0754f93666e280e75451e84306953aac5979d039126d5e516ebb4b5150b8d128b7e3b71f9dce1d4939a2456c52fbf3fc00").unwrap(); let expected_public_bytes = hex::decode("0496fdd6c4e8c00e02642e800fe965808eb89e4f256fc913159950995a142289fad97bfd119e2afe5ee9de765e26f09e6f86e300616a8829228f57a6cc47e42381").unwrap(); diff --git a/xmtp_v2/src/signature.rs b/xmtp_v2/src/signature.rs index 351a0f21c..9e30490b6 100644 --- a/xmtp_v2/src/signature.rs +++ b/xmtp_v2/src/signature.rs @@ -1,11 +1,10 @@ -use crate::traits; - -use k256::ecdsa::signature::DigestVerifier; pub use k256::ecdsa::{RecoveryId, SigningKey, VerifyingKey}; -use k256::PublicKey; +use k256::{ecdsa::signature::DigestVerifier, PublicKey}; use sha2::Sha256; use sha3::{Digest, Keccak256}; +use crate::traits; + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum EcdsaSignature { // Both carry signature bytes and a recovery id diff --git a/xmtp_v2/src/traits.rs b/xmtp_v2/src/traits.rs index 078d99888..3d38b1a08 100644 --- a/xmtp_v2/src/traits.rs +++ b/xmtp_v2/src/traits.rs @@ -1,4 +1,5 @@ -// This trait acts as a abstraction layer to allow "SignatureVerifiers" to be used with other types of Signature-like enums one day +// This trait acts as a abstraction layer to allow "SignatureVerifiers" to be used with other types +// of Signature-like enums one day pub trait SignatureVerifiable { fn get_signature(&self) -> Option; }