From e234414502dc139345d3d3f9287ed29593bb0475 Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Tue, 5 Dec 2023 16:47:51 -0500 Subject: [PATCH 01/20] move add and remove members to use wallet addresses --- dev/gen_protos.sh | 2 +- xmtp_mls/src/api_client_wrapper.rs | 14 +- xmtp_mls/src/codecs/membership_change.rs | 17 +- xmtp_mls/src/groups/intents.rs | 46 ++-- xmtp_mls/src/groups/mod.rs | 70 ++--- xmtp_mls/src/retry.rs | 31 ++- xmtp_proto/src/gen/xmtp.message_api.v1.rs | 61 ++--- .../src/gen/xmtp.message_contents.serde.rs | 2 +- xmtp_proto/src/gen/xmtp.mls.database.rs | 246 +++++++++--------- xmtp_proto/src/gen/xmtp.mls.database.serde.rs | 26 +- .../src/gen/xmtp.mls.message_contents.rs | 213 ++++++++------- .../gen/xmtp.mls.message_contents.serde.rs | 76 +++--- 12 files changed, 430 insertions(+), 374 deletions(-) diff --git a/dev/gen_protos.sh b/dev/gen_protos.sh index dfc61150f..d15fe88ff 100755 --- a/dev/gen_protos.sh +++ b/dev/gen_protos.sh @@ -5,7 +5,7 @@ if ! cargo install --list | grep "protoc-gen-prost-crate" > /dev/null; then exit 1 fi fi -if ! buf generate https://github.com/xmtp/proto.git#branch=nmolnar/mls-verification-service,subdir=proto; then +if ! buf generate https://github.com/xmtp/proto.git#branch=insipx/remove-add-wallet-addresses,subdir=proto; then echo "Failed to generate protobuf definitions" exit 1 fi diff --git a/xmtp_mls/src/api_client_wrapper.rs b/xmtp_mls/src/api_client_wrapper.rs index 54c1e2250..f5795278f 100644 --- a/xmtp_mls/src/api_client_wrapper.rs +++ b/xmtp_mls/src/api_client_wrapper.rs @@ -52,7 +52,7 @@ where loop { let mut result = retry_async!( self.retry_strategy, - (|| async { + (async { self.api_client .query(QueryRequest { content_topics: vec![topic.to_string()], @@ -91,7 +91,7 @@ where ) -> Result, ApiError> { let res = retry_async!( self.retry_strategy, - (|| async { + (async { self.api_client .register_installation(RegisterInstallationRequest { last_resort_key_package: Some(KeyPackageUpload { @@ -108,7 +108,7 @@ where pub async fn upload_key_packages(&self, key_packages: Vec>) -> Result<(), ApiError> { retry_async!( self.retry_strategy, - (|| async { + (async { self.api_client .upload_key_packages(UploadKeyPackagesRequest { key_packages: key_packages @@ -132,7 +132,7 @@ where ) -> Result { let res = retry_async!( self.retry_strategy, - (|| async { + (async { self.api_client .consume_key_packages(ConsumeKeyPackagesRequest { installation_ids: installation_ids.clone(), @@ -179,7 +179,7 @@ where retry_async!( self.retry_strategy, - (|| async { + (async { self.api_client .publish_welcomes(PublishWelcomesRequest { welcome_messages: welcome_requests.clone(), @@ -198,7 +198,7 @@ where ) -> Result { let result = retry_async!( self.retry_strategy, - (|| async { + (async { self.api_client .get_identity_updates(GetIdentityUpdatesRequest { start_time_ns, @@ -262,7 +262,7 @@ where retry_async!( self.retry_strategy, - (|| async { + (async { self.api_client .publish_to_group(PublishToGroupRequest { messages: to_send.clone(), diff --git a/xmtp_mls/src/codecs/membership_change.rs b/xmtp_mls/src/codecs/membership_change.rs index b02e91192..a01e7c228 100644 --- a/xmtp_mls/src/codecs/membership_change.rs +++ b/xmtp_mls/src/codecs/membership_change.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use prost::Message; use xmtp_proto::xmtp::mls::message_contents::{ - ContentTypeId, EncodedContent, GroupMembershipChange, + ContentTypeId, EncodedContent, GroupMembershipChanges, }; use super::{CodecError, ContentCodec}; @@ -14,7 +14,7 @@ impl GroupMembershipChangeCodec { const TYPE_ID: &'static str = "group_membership_change"; } -impl ContentCodec for GroupMembershipChangeCodec { +impl ContentCodec for GroupMembershipChangeCodec { fn content_type() -> ContentTypeId { ContentTypeId { authority_id: GroupMembershipChangeCodec::AUTHORITY_ID.to_string(), @@ -24,7 +24,7 @@ impl ContentCodec for GroupMembershipChangeCodec { } } - fn encode(data: GroupMembershipChange) -> Result { + fn encode(data: GroupMembershipChanges) -> Result { let mut buf = Vec::new(); data.encode(&mut buf) .map_err(|e| CodecError::Encode(e.to_string()))?; @@ -38,8 +38,8 @@ impl ContentCodec for GroupMembershipChangeCodec { }) } - fn decode(content: EncodedContent) -> Result { - let decoded = GroupMembershipChange::decode(content.content.as_slice()) + fn decode(content: EncodedContent) -> Result { + let decoded = GroupMembershipChanges::decode(content.content.as_slice()) .map_err(|e| CodecError::Decode(e.to_string()))?; Ok(decoded) @@ -48,19 +48,19 @@ impl ContentCodec for GroupMembershipChangeCodec { #[cfg(test)] mod tests { - use xmtp_proto::xmtp::mls::message_contents::Member; + // use xmtp_proto::xmtp::mls::message_contents::Member; use crate::utils::test::{rand_string, rand_vec}; use super::*; - + /* TODO::INSIPX: FIX #[test] fn test_encode_decode() { let new_member = Member { installation_ids: vec![rand_vec()], wallet_address: rand_string(), }; - let data = GroupMembershipChange { + let data = GroupMembershipChanges { members_added: vec![new_member.clone()], members_removed: vec![], installations_added: vec![], @@ -77,4 +77,5 @@ mod tests { let decoded = GroupMembershipChangeCodec::decode(encoded).unwrap(); assert_eq!(decoded.members_added[0], new_member); } + */ } diff --git a/xmtp_mls/src/groups/intents.rs b/xmtp_mls/src/groups/intents.rs index 0cc8b04ad..a41f4a757 100644 --- a/xmtp_mls/src/groups/intents.rs +++ b/xmtp_mls/src/groups/intents.rs @@ -11,7 +11,7 @@ use xmtp_proto::xmtp::mls::database::{ }; use crate::{ - verified_key_package::{KeyPackageVerificationError, VerifiedKeyPackage}, + types::Address, verified_key_package::KeyPackageVerificationError, xmtp_openmls_provider::XmtpOpenMlsProvider, }; @@ -25,6 +25,8 @@ pub enum IntentError { TlsCodec(#[from] tls_codec::Error), #[error("generic: {0}")] Generic(String), + #[error(transparent)] + FromHex(#[from] hex::FromHexError), } #[derive(Debug, Clone)] @@ -69,26 +71,24 @@ impl From for Vec { #[derive(Debug, Clone)] pub struct AddMembersIntentData { - pub key_packages: Vec, + pub wallet_addresses: Vec
, } impl AddMembersIntentData { - pub fn new(key_packages: Vec) -> Self { - Self { key_packages } + pub fn new(wallet_addresses: Vec
) -> Self { + Self { wallet_addresses } } pub(crate) fn to_bytes(&self) -> Result, IntentError> { let mut buf = Vec::new(); - let key_package_bytes_result: Result>, tls_codec::Error> = self - .key_packages + let wallet_addresses = self + .wallet_addresses .iter() - .map(|kp| kp.inner.tls_serialize_detached()) - .collect(); + .map(|addr| hex::decode(&addr[2..])) + .collect::, _>>()?; AddMembersData { - version: Some(AddMembersVersion::V1(AddMembersV1 { - key_packages_bytes: key_package_bytes_result?, - })), + version: Some(AddMembersVersion::V1(AddMembersV1 { wallet_addresses })), } .encode(&mut buf) .expect("encode error"); @@ -96,23 +96,15 @@ impl AddMembersIntentData { Ok(buf) } - pub(crate) fn from_bytes( - data: &[u8], - provider: &XmtpOpenMlsProvider, - ) -> Result { + pub(crate) fn from_bytes(data: &[u8]) -> Result { let msg = AddMembersData::decode(data)?; - let key_package_bytes = match msg.version { - Some(AddMembersVersion::V1(v1)) => v1.key_packages_bytes, + let address_bytes = match msg.version { + Some(AddMembersVersion::V1(v1)) => v1.wallet_addresses, None => return Err(IntentError::Generic("missing payload".to_string())), }; - let key_packages: Result, KeyPackageVerificationError> = - key_package_bytes - .iter() - // TODO: Serialize VerifiedKeyPackages directly, so that we don't have to re-verify - .map(|kp| VerifiedKeyPackage::from_bytes(provider, kp)) - .collect(); - - Ok(Self::new(key_packages?)) + let addresses = address_bytes.iter().map(|addr| hex::encode(addr)).collect(); + + Ok(Self::new(addresses)) } } @@ -242,7 +234,7 @@ mod tests { use xmtp_cryptography::utils::generate_local_wallet; use super::*; - use crate::{builder::ClientBuilder, InboxOwner}; + use crate::{builder::ClientBuilder, verified_key_package::VerifiedKeyPackage, InboxOwner}; #[test] fn test_serialize_send_message() { @@ -254,6 +246,7 @@ mod tests { assert_eq!(restored_intent.message, message); } + /* TODO:INSIPX: FINISH #[tokio::test] async fn test_serialize_add_members() { let wallet = generate_local_wallet(); @@ -280,4 +273,5 @@ mod tests { restored_intent.key_packages[0].wallet_address ); } + */ } diff --git a/xmtp_mls/src/groups/mod.rs b/xmtp_mls/src/groups/mod.rs index a2d580833..2abd1243d 100644 --- a/xmtp_mls/src/groups/mod.rs +++ b/xmtp_mls/src/groups/mod.rs @@ -1,7 +1,6 @@ mod intents; mod members; use intents::SendMessageIntentData; -#[cfg(not(test))] use log::debug; use openmls::{ framing::ProtocolMessage, @@ -15,8 +14,6 @@ use openmls::{ }; use openmls_traits::OpenMlsProvider; use std::mem::discriminant; -#[cfg(test)] -use std::println as debug; use thiserror::Error; use tls_codec::{Deserialize, Serialize}; use xmtp_proto::api_client::{Envelope, XmtpApiClient, XmtpMlsClient}; @@ -30,7 +27,7 @@ use crate::{ identity::Identity, retry, retry::{Retry, RetryableError}, - retryable, + retry_async, retryable, storage::{ db_connection::DbConnection, group::{GroupMembershipState, StoredGroup}, @@ -429,11 +426,7 @@ where pub async fn add_members(&self, wallet_addresses: Vec) -> Result<(), GroupError> { let conn = &mut self.client.store.conn()?; - let key_packages = self - .client - .get_key_packages_for_wallet_addresses(wallet_addresses) - .await?; - let intent_data: Vec = AddMembersIntentData::new(key_packages).try_into()?; + let intent_data: Vec = AddMembersIntentData::new(wallet_addresses).try_into()?; let intent = NewGroupIntent::new(IntentKind::AddMembers, self.group_id.clone(), intent_data); intent.store(conn)?; @@ -443,19 +436,10 @@ where pub async fn add_members_by_installation_id( &self, - installation_ids: Vec>, + _installation_ids: Vec>, ) -> Result<(), GroupError> { - let conn = &mut self.client.store.conn()?; - let key_packages = self - .client - .get_key_packages_for_installation_ids(installation_ids) - .await?; - let intent_data: Vec = AddMembersIntentData::new(key_packages).try_into()?; - let intent = - NewGroupIntent::new(IntentKind::AddMembers, self.group_id.clone(), intent_data); - intent.store(conn)?; - - self.sync_with_conn(conn).await + // remove + unimplemented!() } pub(crate) async fn remove_members_by_installation_id( @@ -525,9 +509,12 @@ where )?; for intent in intents { - let result = retry!( + let result = retry_async!( Retry::default(), - (|| self.get_publish_intent_data(&provider, &mut openmls_group, &intent)) + (async { + self.get_publish_intent_data(&provider, &mut openmls_group, &intent) + .await + }) ); if let Err(e) = result { log::error!("error getting publish intent data {:?}", e); @@ -556,9 +543,9 @@ where } // Takes a StoredGroupIntent and returns the payload and post commit data as a tuple - fn get_publish_intent_data( + async fn get_publish_intent_data( &self, - provider: &XmtpOpenMlsProvider, + provider: &XmtpOpenMlsProvider<'_>, openmls_group: &mut OpenMlsGroup, intent: &StoredGroupIntent, ) -> Result<(Vec, Option>), GroupError> { @@ -577,30 +564,30 @@ where Ok((msg_bytes, None)) } IntentKind::AddMembers => { - let intent_data = - AddMembersIntentData::from_bytes(intent.data.as_slice(), provider)?; + let intent_data = AddMembersIntentData::from_bytes(intent.data.as_slice())?; - let key_packages: Vec = intent_data - .key_packages - .iter() - .map(|kp| kp.inner.clone()) - .collect(); + let key_packages = self + .client + .get_key_packages_for_wallet_addresses(intent_data.wallet_addresses) + .await?; + + log::debug!("KEY PACKAGES: {:?}", key_packages); + + let mls_key_packages: Vec = + key_packages.iter().map(|kp| kp.inner.clone()).collect(); let (commit, welcome, _group_info) = openmls_group.add_members( provider, &self.client.identity.installation_keys, - key_packages.as_slice(), + mls_key_packages.as_slice(), )?; let commit_bytes = commit.tls_serialize_detached()?; // If somehow another installation has made it into the commit, this will be missing // their installation ID - let installation_ids: Vec> = intent_data - .key_packages - .iter() - .map(|kp| kp.installation_id()) - .collect(); + let installation_ids: Vec> = + key_packages.iter().map(|kp| kp.installation_id()).collect(); let post_commit_data = Some(PostCommitAction::from_welcome(welcome, installation_ids)?.to_bytes()); @@ -811,16 +798,15 @@ mod tests { #[tokio::test] async fn test_add_members() { + crate::tests::setup(); + let client = ClientBuilder::new_test_client(generate_local_wallet().into()).await; let client_2 = ClientBuilder::new_test_client(generate_local_wallet().into()).await; client_2.register_identity().await.unwrap(); let group = client.create_group().expect("create group"); group - .add_members_by_installation_id(vec![client_2 - .identity - .installation_keys - .to_public_vec()]) + .add_members(vec![client_2.account_address()]) .await .unwrap(); diff --git a/xmtp_mls/src/retry.rs b/xmtp_mls/src/retry.rs index bb5293694..667a6fc9c 100644 --- a/xmtp_mls/src/retry.rs +++ b/xmtp_mls/src/retry.rs @@ -226,7 +226,7 @@ macro_rules! retry_async { let mut attempts = 0; loop { #[allow(clippy::redundant_closure_call)] - match $code().await { + match $code.await { Ok(v) => break Ok(v), Err(e) => { if (&e).is_retryable() && attempts < $retry.retries() { @@ -373,8 +373,33 @@ mod tests { for i in 0..3 { tx.send(i).unwrap(); } - let test_future = || async { retryable_async_fn(&rx.clone()).await }; - retry_async!(Retry::default(), test_future).unwrap(); + retry_async!( + Retry::default(), + (async { retryable_async_fn(&rx.clone()).await }) + ) + .unwrap(); assert!(rx.is_empty()); } + + #[tokio::test] + async fn it_works_async_mut() { + crate::tests::setup(); + + async fn retryable_async_fn(data: &mut usize) -> Result<(), SomeError> { + if *data == 2 { + return Ok(()); + } + *data += 1; + // do some work + tokio::time::sleep(std::time::Duration::from_nanos(100)).await; + Err(SomeError::ARetryableError) + } + + let mut data: usize = 0; + retry_async!( + Retry::default(), + (async { retryable_async_fn(&mut data).await }) + ) + .unwrap(); + } } diff --git a/xmtp_proto/src/gen/xmtp.message_api.v1.rs b/xmtp_proto/src/gen/xmtp.message_api.v1.rs index aede8f493..4cdbcba7a 100644 --- a/xmtp_proto/src/gen/xmtp.message_api.v1.rs +++ b/xmtp_proto/src/gen/xmtp.message_api.v1.rs @@ -5,13 +5,13 @@ #[derive(Clone, PartialEq, ::prost::Message)] pub struct Token { /// identity key signed by a wallet - #[prost(message, optional, tag = "1")] + #[prost(message, optional, tag="1")] pub identity_key: ::core::option::Option, /// encoded bytes of AuthData - #[prost(bytes = "vec", tag = "2")] + #[prost(bytes="vec", tag="2")] pub auth_data_bytes: ::prost::alloc::vec::Vec, /// identity key signature of AuthData bytes - #[prost(message, optional, tag = "3")] + #[prost(message, optional, tag="3")] pub auth_data_signature: ::core::option::Option, } /// AuthData carries token parameters that are authenticated @@ -23,10 +23,10 @@ pub struct Token { #[derive(Clone, PartialEq, ::prost::Message)] pub struct AuthData { /// address of the wallet - #[prost(string, tag = "1")] + #[prost(string, tag="1")] pub wallet_addr: ::prost::alloc::string::String, /// time when the token was generated/signed - #[prost(uint64, tag = "2")] + #[prost(uint64, tag="2")] pub created_ns: u64, } /// This is based off of the go-waku Index type, but with the @@ -35,9 +35,9 @@ pub struct AuthData { #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct IndexCursor { - #[prost(bytes = "vec", tag = "1")] + #[prost(bytes="vec", tag="1")] pub digest: ::prost::alloc::vec::Vec, - #[prost(uint64, tag = "2")] + #[prost(uint64, tag="2")] pub sender_time_ns: u64, } /// Wrapper for potentially multiple types of cursor @@ -47,7 +47,7 @@ pub struct Cursor { /// Making the cursor a one-of type, as I would like to change the way we /// handle pagination to use a precomputed sort field. /// This way we can handle both methods - #[prost(oneof = "cursor::Cursor", tags = "1")] + #[prost(oneof="cursor::Cursor", tags="1")] pub cursor: ::core::option::Option, } /// Nested message and enum types in `Cursor`. @@ -56,9 +56,9 @@ pub mod cursor { /// handle pagination to use a precomputed sort field. /// This way we can handle both methods #[allow(clippy::derive_partial_eq_without_eq)] - #[derive(Clone, PartialEq, ::prost::Oneof)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Cursor { - #[prost(message, tag = "1")] + #[prost(message, tag="1")] Index(super::IndexCursor), } } @@ -68,11 +68,11 @@ pub mod cursor { #[derive(Clone, PartialEq, ::prost::Message)] pub struct PagingInfo { /// Note: this is a uint32, while go-waku's pageSize is a uint64 - #[prost(uint32, tag = "1")] + #[prost(uint32, tag="1")] pub limit: u32, - #[prost(message, optional, tag = "2")] + #[prost(message, optional, tag="2")] pub cursor: ::core::option::Option, - #[prost(enumeration = "SortDirection", tag = "3")] + #[prost(enumeration="SortDirection", tag="3")] pub direction: i32, } /// Envelope encapsulates a message while in transit. @@ -82,72 +82,74 @@ pub struct Envelope { /// The topic the message belongs to, /// If the message includes the topic as well /// it MUST be the same as the topic in the envelope. - #[prost(string, tag = "1")] + #[prost(string, tag="1")] pub content_topic: ::prost::alloc::string::String, /// Message creation timestamp /// If the message includes the timestamp as well /// it MUST be equivalent to the timestamp in the envelope. - #[prost(uint64, tag = "2")] + #[prost(uint64, tag="2")] pub timestamp_ns: u64, - #[prost(bytes = "vec", tag = "3")] + #[prost(bytes="vec", tag="3")] pub message: ::prost::alloc::vec::Vec, } /// Publish #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct PublishRequest { - #[prost(message, repeated, tag = "1")] + #[prost(message, repeated, tag="1")] pub envelopes: ::prost::alloc::vec::Vec, } /// Empty message as a response for Publish #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] -pub struct PublishResponse {} +pub struct PublishResponse { +} /// Subscribe #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SubscribeRequest { - #[prost(string, repeated, tag = "1")] + #[prost(string, repeated, tag="1")] pub content_topics: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, } /// SubscribeAll #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] -pub struct SubscribeAllRequest {} +pub struct SubscribeAllRequest { +} /// Query #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct QueryRequest { - #[prost(string, repeated, tag = "1")] + #[prost(string, repeated, tag="1")] pub content_topics: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, - #[prost(uint64, tag = "2")] + #[prost(uint64, tag="2")] pub start_time_ns: u64, - #[prost(uint64, tag = "3")] + #[prost(uint64, tag="3")] pub end_time_ns: u64, - #[prost(message, optional, tag = "4")] + #[prost(message, optional, tag="4")] pub paging_info: ::core::option::Option, } /// The response, containing envelopes, for a query #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct QueryResponse { - #[prost(message, repeated, tag = "1")] + #[prost(message, repeated, tag="1")] pub envelopes: ::prost::alloc::vec::Vec, - #[prost(message, optional, tag = "2")] + #[prost(message, optional, tag="2")] pub paging_info: ::core::option::Option, } /// BatchQuery #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct BatchQueryRequest { - #[prost(message, repeated, tag = "1")] + #[prost(message, repeated, tag="1")] pub requests: ::prost::alloc::vec::Vec, } /// Response containing a list of QueryResponse messages #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct BatchQueryResponse { - #[prost(message, repeated, tag = "1")] + #[prost(message, repeated, tag="1")] pub responses: ::prost::alloc::vec::Vec, } /// Sort direction @@ -662,5 +664,4 @@ pub const FILE_DESCRIPTOR_SET: &[u8] = &[ ]; include!("xmtp.message_api.v1.serde.rs"); include!("xmtp.message_api.v1.tonic.rs"); -// @@protoc_insertion_point(module) - +// @@protoc_insertion_point(module) \ No newline at end of file diff --git a/xmtp_proto/src/gen/xmtp.message_contents.serde.rs b/xmtp_proto/src/gen/xmtp.message_contents.serde.rs index 7eb3d12f9..3042dc548 100644 --- a/xmtp_proto/src/gen/xmtp.message_contents.serde.rs +++ b/xmtp_proto/src/gen/xmtp.message_contents.serde.rs @@ -1326,7 +1326,7 @@ impl serde::Serialize for EciesMessage { if let Some(v) = self.version.as_ref() { match v { ecies_message::Version::V1(v) => { - struct_ser.serialize_field("v1", pbjson::private::base64::encode(v).as_str())?; + struct_ser.serialize_field("v1", pbjson::private::base64::encode(&v).as_str())?; } } } diff --git a/xmtp_proto/src/gen/xmtp.mls.database.rs b/xmtp_proto/src/gen/xmtp.mls.database.rs index 4dddd477c..d8a838f1b 100644 --- a/xmtp_proto/src/gen/xmtp.mls.database.rs +++ b/xmtp_proto/src/gen/xmtp.mls.database.rs @@ -36,7 +36,7 @@ pub mod add_members_data { #[derive(Clone, PartialEq, ::prost::Message)] pub struct V1 { #[prost(bytes="vec", repeated, tag="1")] - pub key_packages_bytes: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, + pub wallet_addresses: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Oneof)] @@ -95,7 +95,7 @@ pub mod post_commit_action { } /// Encoded file descriptor set for the `xmtp.mls.database` package pub const FILE_DESCRIPTOR_SET: &[u8] = &[ - 0x0a, 0xf3, 0x10, 0x0a, 0x1a, 0x6d, 0x6c, 0x73, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, + 0x0a, 0xf0, 0x10, 0x0a, 0x1a, 0x6d, 0x6c, 0x73, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x11, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x22, 0x80, 0x01, 0x0a, 0x0f, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, @@ -106,131 +106,131 @@ pub const FILE_DESCRIPTOR_SET: &[u8] = &[ 0x29, 0x0a, 0x02, 0x56, 0x31, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x42, 0x09, 0x0a, 0x07, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x87, 0x01, 0x0a, 0x0e, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x84, 0x01, 0x0a, 0x0e, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x44, 0x61, 0x74, 0x61, 0x12, 0x36, 0x0a, 0x02, 0x76, 0x31, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x31, 0x48, 0x00, 0x52, 0x02, 0x76, 0x31, - 0x1a, 0x32, 0x0a, 0x02, 0x56, 0x31, 0x12, 0x2c, 0x0a, 0x12, 0x6b, 0x65, 0x79, 0x5f, 0x70, 0x61, - 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0c, 0x52, 0x10, 0x6b, 0x65, 0x79, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x42, - 0x79, 0x74, 0x65, 0x73, 0x42, 0x09, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, - 0x8a, 0x01, 0x0a, 0x11, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x73, 0x44, 0x61, 0x74, 0x61, 0x12, 0x39, 0x0a, 0x02, 0x76, 0x31, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x27, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, 0x61, 0x74, - 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, - 0x65, 0x72, 0x73, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x31, 0x48, 0x00, 0x52, 0x02, 0x76, 0x31, - 0x1a, 0x2f, 0x0a, 0x02, 0x56, 0x31, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, - 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, - 0x52, 0x0f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, - 0x73, 0x42, 0x09, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xd7, 0x01, 0x0a, - 0x10, 0x50, 0x6f, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x57, 0x0a, 0x0d, 0x73, 0x65, 0x6e, 0x64, 0x5f, 0x77, 0x65, 0x6c, 0x63, 0x6f, 0x6d, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, - 0x6d, 0x6c, 0x73, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x50, 0x6f, 0x73, - 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x65, - 0x6e, 0x64, 0x57, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x73, 0x48, 0x00, 0x52, 0x0c, 0x73, 0x65, - 0x6e, 0x64, 0x57, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x73, 0x1a, 0x62, 0x0a, 0x0c, 0x53, 0x65, - 0x6e, 0x64, 0x57, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6e, - 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x77, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, - 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, - 0x77, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x06, - 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x42, 0xb5, 0x01, 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e, 0x78, - 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, - 0x42, 0x0c, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, - 0x5a, 0x28, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x6d, 0x74, - 0x70, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x33, 0x2f, 0x67, 0x6f, 0x2f, 0x6d, 0x6c, - 0x73, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0xa2, 0x02, 0x03, 0x58, 0x4d, 0x44, - 0xaa, 0x02, 0x11, 0x58, 0x6d, 0x74, 0x70, 0x2e, 0x4d, 0x6c, 0x73, 0x2e, 0x44, 0x61, 0x74, 0x61, - 0x62, 0x61, 0x73, 0x65, 0xca, 0x02, 0x11, 0x58, 0x6d, 0x74, 0x70, 0x5c, 0x4d, 0x6c, 0x73, 0x5c, - 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0xe2, 0x02, 0x1d, 0x58, 0x6d, 0x74, 0x70, 0x5c, - 0x4d, 0x6c, 0x73, 0x5c, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5c, 0x47, 0x50, 0x42, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13, 0x58, 0x6d, 0x74, 0x70, 0x3a, - 0x3a, 0x4d, 0x6c, 0x73, 0x3a, 0x3a, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x4a, 0x8d, - 0x0a, 0x0a, 0x06, 0x12, 0x04, 0x01, 0x00, 0x37, 0x01, 0x0a, 0x27, 0x0a, 0x01, 0x0c, 0x12, 0x03, - 0x01, 0x00, 0x12, 0x1a, 0x1d, 0x20, 0x56, 0x33, 0x20, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x20, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, - 0x65, 0x0a, 0x0a, 0x08, 0x0a, 0x01, 0x02, 0x12, 0x03, 0x03, 0x00, 0x1a, 0x0a, 0x08, 0x0a, 0x01, - 0x08, 0x12, 0x03, 0x05, 0x00, 0x3f, 0x0a, 0x09, 0x0a, 0x02, 0x08, 0x0b, 0x12, 0x03, 0x05, 0x00, - 0x3f, 0x0a, 0x34, 0x0a, 0x02, 0x04, 0x00, 0x12, 0x04, 0x09, 0x00, 0x12, 0x01, 0x1a, 0x28, 0x20, - 0x54, 0x68, 0x65, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, - 0x64, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x20, 0x61, 0x20, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x00, 0x01, 0x12, 0x03, - 0x09, 0x08, 0x17, 0x0a, 0x2c, 0x0a, 0x04, 0x04, 0x00, 0x03, 0x00, 0x12, 0x04, 0x0b, 0x02, 0x0d, - 0x03, 0x1a, 0x1e, 0x20, 0x56, 0x31, 0x20, 0x6f, 0x66, 0x20, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x44, 0x61, 0x74, 0x61, - 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x03, 0x00, 0x01, 0x12, 0x03, 0x0b, 0x0a, 0x0c, 0x0a, - 0x0d, 0x0a, 0x06, 0x04, 0x00, 0x03, 0x00, 0x02, 0x00, 0x12, 0x03, 0x0c, 0x04, 0x1c, 0x0a, 0x0e, - 0x0a, 0x07, 0x04, 0x00, 0x03, 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, 0x0c, 0x04, 0x09, 0x0a, 0x0e, - 0x0a, 0x07, 0x04, 0x00, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x0c, 0x0a, 0x17, 0x0a, 0x0e, - 0x0a, 0x07, 0x04, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x0c, 0x1a, 0x1b, 0x0a, 0x0c, - 0x0a, 0x04, 0x04, 0x00, 0x08, 0x00, 0x12, 0x04, 0x0f, 0x02, 0x11, 0x03, 0x0a, 0x0c, 0x0a, 0x05, - 0x04, 0x00, 0x08, 0x00, 0x01, 0x12, 0x03, 0x0f, 0x08, 0x0f, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, - 0x02, 0x00, 0x12, 0x03, 0x10, 0x04, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x06, - 0x12, 0x03, 0x10, 0x04, 0x06, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, - 0x10, 0x07, 0x09, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x10, 0x0c, - 0x0d, 0x0a, 0x39, 0x0a, 0x02, 0x04, 0x01, 0x12, 0x04, 0x15, 0x00, 0x1e, 0x01, 0x1a, 0x2d, 0x20, - 0x54, 0x68, 0x65, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, - 0x64, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x64, 0x64, 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, - 0x20, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, - 0x04, 0x01, 0x01, 0x12, 0x03, 0x15, 0x08, 0x16, 0x0a, 0x2b, 0x0a, 0x04, 0x04, 0x01, 0x03, 0x00, - 0x12, 0x04, 0x17, 0x02, 0x19, 0x03, 0x1a, 0x1d, 0x20, 0x56, 0x31, 0x20, 0x6f, 0x66, 0x20, 0x41, - 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, - 0x44, 0x61, 0x74, 0x61, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x03, 0x00, 0x01, 0x12, 0x03, - 0x17, 0x0a, 0x0c, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x01, 0x03, 0x00, 0x02, 0x00, 0x12, 0x03, 0x18, - 0x04, 0x2a, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x03, 0x00, 0x02, 0x00, 0x04, 0x12, 0x03, 0x18, - 0x04, 0x0c, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x03, 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, 0x18, - 0x0d, 0x12, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x18, - 0x13, 0x25, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x18, - 0x28, 0x29, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x01, 0x08, 0x00, 0x12, 0x04, 0x1b, 0x02, 0x1d, 0x03, - 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x08, 0x00, 0x01, 0x12, 0x03, 0x1b, 0x08, 0x0f, 0x0a, 0x0b, - 0x0a, 0x04, 0x04, 0x01, 0x02, 0x00, 0x12, 0x03, 0x1c, 0x04, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, - 0x01, 0x02, 0x00, 0x06, 0x12, 0x03, 0x1c, 0x04, 0x06, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, - 0x00, 0x01, 0x12, 0x03, 0x1c, 0x07, 0x09, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x03, - 0x12, 0x03, 0x1c, 0x0c, 0x0d, 0x0a, 0x3e, 0x0a, 0x02, 0x04, 0x02, 0x12, 0x04, 0x21, 0x00, 0x2a, - 0x01, 0x1a, 0x32, 0x20, 0x54, 0x68, 0x65, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x72, 0x65, 0x71, - 0x75, 0x69, 0x72, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x20, - 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x20, 0x67, - 0x72, 0x6f, 0x75, 0x70, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x02, 0x01, 0x12, 0x03, 0x21, 0x08, - 0x19, 0x0a, 0x2e, 0x0a, 0x04, 0x04, 0x02, 0x03, 0x00, 0x12, 0x04, 0x23, 0x02, 0x25, 0x03, 0x1a, - 0x20, 0x20, 0x56, 0x31, 0x20, 0x6f, 0x66, 0x20, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, - 0x6d, 0x62, 0x65, 0x72, 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x44, 0x61, 0x74, 0x61, - 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x03, 0x00, 0x01, 0x12, 0x03, 0x23, 0x0a, 0x0c, 0x0a, - 0x0d, 0x0a, 0x06, 0x04, 0x02, 0x03, 0x00, 0x02, 0x00, 0x12, 0x03, 0x24, 0x04, 0x28, 0x0a, 0x0e, - 0x0a, 0x07, 0x04, 0x02, 0x03, 0x00, 0x02, 0x00, 0x04, 0x12, 0x03, 0x24, 0x04, 0x0c, 0x0a, 0x0e, - 0x0a, 0x07, 0x04, 0x02, 0x03, 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, 0x24, 0x0d, 0x12, 0x0a, 0x0e, - 0x0a, 0x07, 0x04, 0x02, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x24, 0x13, 0x23, 0x0a, 0x0e, - 0x0a, 0x07, 0x04, 0x02, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x24, 0x26, 0x27, 0x0a, 0x0c, - 0x0a, 0x04, 0x04, 0x02, 0x08, 0x00, 0x12, 0x04, 0x27, 0x02, 0x29, 0x03, 0x0a, 0x0c, 0x0a, 0x05, - 0x04, 0x02, 0x08, 0x00, 0x01, 0x12, 0x03, 0x27, 0x08, 0x0f, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x02, - 0x02, 0x00, 0x12, 0x03, 0x28, 0x04, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x06, - 0x12, 0x03, 0x28, 0x04, 0x06, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x01, 0x12, 0x03, - 0x28, 0x07, 0x09, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x03, 0x12, 0x03, 0x28, 0x0c, - 0x0d, 0x0a, 0x3b, 0x0a, 0x02, 0x04, 0x03, 0x12, 0x04, 0x2d, 0x00, 0x37, 0x01, 0x1a, 0x2f, 0x20, - 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x74, 0x79, 0x70, - 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x70, 0x6f, 0x73, 0x74, 0x2d, 0x63, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x0a, 0x0a, 0x0a, - 0x0a, 0x03, 0x04, 0x03, 0x01, 0x12, 0x03, 0x2d, 0x08, 0x18, 0x0a, 0x23, 0x0a, 0x04, 0x04, 0x03, - 0x03, 0x00, 0x12, 0x04, 0x2f, 0x02, 0x32, 0x03, 0x1a, 0x15, 0x20, 0x53, 0x65, 0x6e, 0x64, 0x57, - 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x0a, 0x0a, - 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x03, 0x00, 0x01, 0x12, 0x03, 0x2f, 0x0a, 0x16, 0x0a, 0x0d, 0x0a, - 0x06, 0x04, 0x03, 0x03, 0x00, 0x02, 0x00, 0x12, 0x03, 0x30, 0x04, 0x28, 0x0a, 0x0e, 0x0a, 0x07, - 0x04, 0x03, 0x03, 0x00, 0x02, 0x00, 0x04, 0x12, 0x03, 0x30, 0x04, 0x0c, 0x0a, 0x0e, 0x0a, 0x07, - 0x04, 0x03, 0x03, 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, 0x30, 0x0d, 0x12, 0x0a, 0x0e, 0x0a, 0x07, - 0x04, 0x03, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x30, 0x13, 0x23, 0x0a, 0x0e, 0x0a, 0x07, - 0x04, 0x03, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x30, 0x26, 0x27, 0x0a, 0x0d, 0x0a, 0x06, - 0x04, 0x03, 0x03, 0x00, 0x02, 0x01, 0x12, 0x03, 0x31, 0x04, 0x1e, 0x0a, 0x0e, 0x0a, 0x07, 0x04, - 0x03, 0x03, 0x00, 0x02, 0x01, 0x05, 0x12, 0x03, 0x31, 0x04, 0x09, 0x0a, 0x0e, 0x0a, 0x07, 0x04, - 0x03, 0x03, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x31, 0x0a, 0x19, 0x0a, 0x0e, 0x0a, 0x07, 0x04, - 0x03, 0x03, 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, 0x31, 0x1c, 0x1d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, - 0x03, 0x08, 0x00, 0x12, 0x04, 0x34, 0x02, 0x36, 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x08, - 0x00, 0x01, 0x12, 0x03, 0x34, 0x08, 0x0c, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x03, 0x02, 0x00, 0x12, - 0x03, 0x35, 0x04, 0x23, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x06, 0x12, 0x03, 0x35, - 0x04, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x01, 0x12, 0x03, 0x35, 0x11, 0x1e, - 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x03, 0x12, 0x03, 0x35, 0x21, 0x22, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x1a, 0x2f, 0x0a, 0x02, 0x56, 0x31, 0x12, 0x29, 0x0a, 0x10, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, + 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, + 0x52, 0x0f, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, + 0x73, 0x42, 0x09, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x8a, 0x01, 0x0a, + 0x11, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x44, 0x61, + 0x74, 0x61, 0x12, 0x39, 0x0a, 0x02, 0x76, 0x31, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, + 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, + 0x73, 0x65, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, + 0x44, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x31, 0x48, 0x00, 0x52, 0x02, 0x76, 0x31, 0x1a, 0x2f, 0x0a, + 0x02, 0x56, 0x31, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0f, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x42, 0x09, + 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xd7, 0x01, 0x0a, 0x10, 0x50, 0x6f, + 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x57, + 0x0a, 0x0d, 0x73, 0x65, 0x6e, 0x64, 0x5f, 0x77, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, + 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x43, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x57, + 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x73, 0x48, 0x00, 0x52, 0x0c, 0x73, 0x65, 0x6e, 0x64, 0x57, + 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x73, 0x1a, 0x62, 0x0a, 0x0c, 0x53, 0x65, 0x6e, 0x64, 0x57, + 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0c, 0x52, 0x0f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, + 0x64, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x77, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x5f, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x77, 0x65, 0x6c, + 0x63, 0x6f, 0x6d, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x06, 0x0a, 0x04, 0x6b, + 0x69, 0x6e, 0x64, 0x42, 0xb5, 0x01, 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x6d, 0x74, 0x70, + 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x42, 0x0c, 0x49, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x28, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x6d, 0x74, 0x70, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x33, 0x2f, 0x67, 0x6f, 0x2f, 0x6d, 0x6c, 0x73, 0x2f, 0x64, + 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0xa2, 0x02, 0x03, 0x58, 0x4d, 0x44, 0xaa, 0x02, 0x11, + 0x58, 0x6d, 0x74, 0x70, 0x2e, 0x4d, 0x6c, 0x73, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, + 0x65, 0xca, 0x02, 0x11, 0x58, 0x6d, 0x74, 0x70, 0x5c, 0x4d, 0x6c, 0x73, 0x5c, 0x44, 0x61, 0x74, + 0x61, 0x62, 0x61, 0x73, 0x65, 0xe2, 0x02, 0x1d, 0x58, 0x6d, 0x74, 0x70, 0x5c, 0x4d, 0x6c, 0x73, + 0x5c, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13, 0x58, 0x6d, 0x74, 0x70, 0x3a, 0x3a, 0x4d, 0x6c, + 0x73, 0x3a, 0x3a, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x4a, 0x8d, 0x0a, 0x0a, 0x06, + 0x12, 0x04, 0x01, 0x00, 0x37, 0x01, 0x0a, 0x27, 0x0a, 0x01, 0x0c, 0x12, 0x03, 0x01, 0x00, 0x12, + 0x1a, 0x1d, 0x20, 0x56, 0x33, 0x20, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x20, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x20, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x0a, 0x0a, + 0x08, 0x0a, 0x01, 0x02, 0x12, 0x03, 0x03, 0x00, 0x1a, 0x0a, 0x08, 0x0a, 0x01, 0x08, 0x12, 0x03, + 0x05, 0x00, 0x3f, 0x0a, 0x09, 0x0a, 0x02, 0x08, 0x0b, 0x12, 0x03, 0x05, 0x00, 0x3f, 0x0a, 0x34, + 0x0a, 0x02, 0x04, 0x00, 0x12, 0x04, 0x09, 0x00, 0x12, 0x01, 0x1a, 0x28, 0x20, 0x54, 0x68, 0x65, + 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x20, 0x74, + 0x6f, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x20, 0x61, 0x20, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x00, 0x01, 0x12, 0x03, 0x09, 0x08, 0x17, + 0x0a, 0x2c, 0x0a, 0x04, 0x04, 0x00, 0x03, 0x00, 0x12, 0x04, 0x0b, 0x02, 0x0d, 0x03, 0x1a, 0x1e, + 0x20, 0x56, 0x31, 0x20, 0x6f, 0x66, 0x20, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x44, 0x61, 0x74, 0x61, 0x0a, 0x0a, 0x0c, + 0x0a, 0x05, 0x04, 0x00, 0x03, 0x00, 0x01, 0x12, 0x03, 0x0b, 0x0a, 0x0c, 0x0a, 0x0d, 0x0a, 0x06, + 0x04, 0x00, 0x03, 0x00, 0x02, 0x00, 0x12, 0x03, 0x0c, 0x04, 0x1c, 0x0a, 0x0e, 0x0a, 0x07, 0x04, + 0x00, 0x03, 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, 0x0c, 0x04, 0x09, 0x0a, 0x0e, 0x0a, 0x07, 0x04, + 0x00, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x0c, 0x0a, 0x17, 0x0a, 0x0e, 0x0a, 0x07, 0x04, + 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x0c, 0x1a, 0x1b, 0x0a, 0x0c, 0x0a, 0x04, 0x04, + 0x00, 0x08, 0x00, 0x12, 0x04, 0x0f, 0x02, 0x11, 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x08, + 0x00, 0x01, 0x12, 0x03, 0x0f, 0x08, 0x0f, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x00, 0x12, + 0x03, 0x10, 0x04, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x06, 0x12, 0x03, 0x10, + 0x04, 0x06, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x10, 0x07, 0x09, + 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x10, 0x0c, 0x0d, 0x0a, 0x39, + 0x0a, 0x02, 0x04, 0x01, 0x12, 0x04, 0x15, 0x00, 0x1e, 0x01, 0x1a, 0x2d, 0x20, 0x54, 0x68, 0x65, + 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x20, 0x74, + 0x6f, 0x20, 0x61, 0x64, 0x64, 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x20, 0x74, 0x6f, + 0x20, 0x61, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x01, 0x01, + 0x12, 0x03, 0x15, 0x08, 0x16, 0x0a, 0x2b, 0x0a, 0x04, 0x04, 0x01, 0x03, 0x00, 0x12, 0x04, 0x17, + 0x02, 0x19, 0x03, 0x1a, 0x1d, 0x20, 0x56, 0x31, 0x20, 0x6f, 0x66, 0x20, 0x41, 0x64, 0x64, 0x4d, + 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x44, 0x61, 0x74, + 0x61, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x03, 0x00, 0x01, 0x12, 0x03, 0x17, 0x0a, 0x0c, + 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x01, 0x03, 0x00, 0x02, 0x00, 0x12, 0x03, 0x18, 0x04, 0x28, 0x0a, + 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x03, 0x00, 0x02, 0x00, 0x04, 0x12, 0x03, 0x18, 0x04, 0x0c, 0x0a, + 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x03, 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, 0x18, 0x0d, 0x12, 0x0a, + 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x18, 0x13, 0x23, 0x0a, + 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x18, 0x26, 0x27, 0x0a, + 0x0c, 0x0a, 0x04, 0x04, 0x01, 0x08, 0x00, 0x12, 0x04, 0x1b, 0x02, 0x1d, 0x03, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x01, 0x08, 0x00, 0x01, 0x12, 0x03, 0x1b, 0x08, 0x0f, 0x0a, 0x0b, 0x0a, 0x04, 0x04, + 0x01, 0x02, 0x00, 0x12, 0x03, 0x1c, 0x04, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, + 0x06, 0x12, 0x03, 0x1c, 0x04, 0x06, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x01, 0x12, + 0x03, 0x1c, 0x07, 0x09, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x03, 0x12, 0x03, 0x1c, + 0x0c, 0x0d, 0x0a, 0x3e, 0x0a, 0x02, 0x04, 0x02, 0x12, 0x04, 0x21, 0x00, 0x2a, 0x01, 0x1a, 0x32, + 0x20, 0x54, 0x68, 0x65, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, + 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x20, 0x6d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x20, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x02, 0x01, 0x12, 0x03, 0x21, 0x08, 0x19, 0x0a, 0x2e, + 0x0a, 0x04, 0x04, 0x02, 0x03, 0x00, 0x12, 0x04, 0x23, 0x02, 0x25, 0x03, 0x1a, 0x20, 0x20, 0x56, + 0x31, 0x20, 0x6f, 0x66, 0x20, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x44, 0x61, 0x74, 0x61, 0x0a, 0x0a, 0x0c, + 0x0a, 0x05, 0x04, 0x02, 0x03, 0x00, 0x01, 0x12, 0x03, 0x23, 0x0a, 0x0c, 0x0a, 0x0d, 0x0a, 0x06, + 0x04, 0x02, 0x03, 0x00, 0x02, 0x00, 0x12, 0x03, 0x24, 0x04, 0x28, 0x0a, 0x0e, 0x0a, 0x07, 0x04, + 0x02, 0x03, 0x00, 0x02, 0x00, 0x04, 0x12, 0x03, 0x24, 0x04, 0x0c, 0x0a, 0x0e, 0x0a, 0x07, 0x04, + 0x02, 0x03, 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, 0x24, 0x0d, 0x12, 0x0a, 0x0e, 0x0a, 0x07, 0x04, + 0x02, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x24, 0x13, 0x23, 0x0a, 0x0e, 0x0a, 0x07, 0x04, + 0x02, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x24, 0x26, 0x27, 0x0a, 0x0c, 0x0a, 0x04, 0x04, + 0x02, 0x08, 0x00, 0x12, 0x04, 0x27, 0x02, 0x29, 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x08, + 0x00, 0x01, 0x12, 0x03, 0x27, 0x08, 0x0f, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x02, 0x02, 0x00, 0x12, + 0x03, 0x28, 0x04, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x06, 0x12, 0x03, 0x28, + 0x04, 0x06, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x01, 0x12, 0x03, 0x28, 0x07, 0x09, + 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x03, 0x12, 0x03, 0x28, 0x0c, 0x0d, 0x0a, 0x3b, + 0x0a, 0x02, 0x04, 0x03, 0x12, 0x04, 0x2d, 0x00, 0x37, 0x01, 0x1a, 0x2f, 0x20, 0x47, 0x65, 0x6e, + 0x65, 0x72, 0x69, 0x63, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x20, 0x66, + 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x70, 0x6f, 0x73, 0x74, 0x2d, 0x63, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, + 0x03, 0x01, 0x12, 0x03, 0x2d, 0x08, 0x18, 0x0a, 0x23, 0x0a, 0x04, 0x04, 0x03, 0x03, 0x00, 0x12, + 0x04, 0x2f, 0x02, 0x32, 0x03, 0x1a, 0x15, 0x20, 0x53, 0x65, 0x6e, 0x64, 0x57, 0x65, 0x6c, 0x63, + 0x6f, 0x6d, 0x65, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, + 0x04, 0x03, 0x03, 0x00, 0x01, 0x12, 0x03, 0x2f, 0x0a, 0x16, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x03, + 0x03, 0x00, 0x02, 0x00, 0x12, 0x03, 0x30, 0x04, 0x28, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x03, 0x03, + 0x00, 0x02, 0x00, 0x04, 0x12, 0x03, 0x30, 0x04, 0x0c, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x03, 0x03, + 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, 0x30, 0x0d, 0x12, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x03, 0x03, + 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x30, 0x13, 0x23, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x03, 0x03, + 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x30, 0x26, 0x27, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x03, 0x03, + 0x00, 0x02, 0x01, 0x12, 0x03, 0x31, 0x04, 0x1e, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x03, 0x03, 0x00, + 0x02, 0x01, 0x05, 0x12, 0x03, 0x31, 0x04, 0x09, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x03, 0x03, 0x00, + 0x02, 0x01, 0x01, 0x12, 0x03, 0x31, 0x0a, 0x19, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x03, 0x03, 0x00, + 0x02, 0x01, 0x03, 0x12, 0x03, 0x31, 0x1c, 0x1d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x03, 0x08, 0x00, + 0x12, 0x04, 0x34, 0x02, 0x36, 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x08, 0x00, 0x01, 0x12, + 0x03, 0x34, 0x08, 0x0c, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x03, 0x02, 0x00, 0x12, 0x03, 0x35, 0x04, + 0x23, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x06, 0x12, 0x03, 0x35, 0x04, 0x10, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x01, 0x12, 0x03, 0x35, 0x11, 0x1e, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x03, 0x02, 0x00, 0x03, 0x12, 0x03, 0x35, 0x21, 0x22, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, ]; include!("xmtp.mls.database.serde.rs"); // @@protoc_insertion_point(module) \ No newline at end of file diff --git a/xmtp_proto/src/gen/xmtp.mls.database.serde.rs b/xmtp_proto/src/gen/xmtp.mls.database.serde.rs index 994596974..424806a66 100644 --- a/xmtp_proto/src/gen/xmtp.mls.database.serde.rs +++ b/xmtp_proto/src/gen/xmtp.mls.database.serde.rs @@ -103,12 +103,12 @@ impl serde::Serialize for add_members_data::V1 { { use serde::ser::SerializeStruct; let mut len = 0; - if !self.key_packages_bytes.is_empty() { + if !self.wallet_addresses.is_empty() { len += 1; } let mut struct_ser = serializer.serialize_struct("xmtp.mls.database.AddMembersData.V1", len)?; - if !self.key_packages_bytes.is_empty() { - struct_ser.serialize_field("keyPackagesBytes", &self.key_packages_bytes.iter().map(pbjson::private::base64::encode).collect::>())?; + if !self.wallet_addresses.is_empty() { + struct_ser.serialize_field("walletAddresses", &self.wallet_addresses.iter().map(pbjson::private::base64::encode).collect::>())?; } struct_ser.end() } @@ -120,13 +120,13 @@ impl<'de> serde::Deserialize<'de> for add_members_data::V1 { D: serde::Deserializer<'de>, { const FIELDS: &[&str] = &[ - "key_packages_bytes", - "keyPackagesBytes", + "wallet_addresses", + "walletAddresses", ]; #[allow(clippy::enum_variant_names)] enum GeneratedField { - KeyPackagesBytes, + WalletAddresses, } impl<'de> serde::Deserialize<'de> for GeneratedField { fn deserialize(deserializer: D) -> std::result::Result @@ -148,7 +148,7 @@ impl<'de> serde::Deserialize<'de> for add_members_data::V1 { E: serde::de::Error, { match value { - "keyPackagesBytes" | "key_packages_bytes" => Ok(GeneratedField::KeyPackagesBytes), + "walletAddresses" | "wallet_addresses" => Ok(GeneratedField::WalletAddresses), _ => Err(serde::de::Error::unknown_field(value, FIELDS)), } } @@ -168,14 +168,14 @@ impl<'de> serde::Deserialize<'de> for add_members_data::V1 { where V: serde::de::MapAccess<'de>, { - let mut key_packages_bytes__ = None; + let mut wallet_addresses__ = None; while let Some(k) = map.next_key()? { match k { - GeneratedField::KeyPackagesBytes => { - if key_packages_bytes__.is_some() { - return Err(serde::de::Error::duplicate_field("keyPackagesBytes")); + GeneratedField::WalletAddresses => { + if wallet_addresses__.is_some() { + return Err(serde::de::Error::duplicate_field("walletAddresses")); } - key_packages_bytes__ = + wallet_addresses__ = Some(map.next_value::>>()? .into_iter().map(|x| x.0).collect()) ; @@ -183,7 +183,7 @@ impl<'de> serde::Deserialize<'de> for add_members_data::V1 { } } Ok(add_members_data::V1 { - key_packages_bytes: key_packages_bytes__.unwrap_or_default(), + wallet_addresses: wallet_addresses__.unwrap_or_default(), }) } } diff --git a/xmtp_proto/src/gen/xmtp.mls.message_contents.rs b/xmtp_proto/src/gen/xmtp.mls.message_contents.rs index 81e08ce65..c06b81248 100644 --- a/xmtp_proto/src/gen/xmtp.mls.message_contents.rs +++ b/xmtp_proto/src/gen/xmtp.mls.message_contents.rs @@ -117,24 +117,30 @@ impl Compression { /// A group member and affected installation IDs #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] -pub struct Member { +pub struct MembershipChange { #[prost(bytes="vec", repeated, tag="1")] pub installation_ids: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, #[prost(string, tag="2")] - pub wallet_address: ::prost::alloc::string::String, + pub account_address: ::prost::alloc::string::String, + #[prost(string, tag="3")] + pub initiated_by_account_address: ::prost::alloc::string::String, } /// The group membership change proto #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] -pub struct GroupMembershipChange { +pub struct GroupMembershipChanges { + /// Members that have been added in the commit #[prost(message, repeated, tag="1")] - pub members_added: ::prost::alloc::vec::Vec, + pub members_added: ::prost::alloc::vec::Vec, + /// Members that have been removed in the commit #[prost(message, repeated, tag="2")] - pub members_removed: ::prost::alloc::vec::Vec, + pub members_removed: ::prost::alloc::vec::Vec, + /// Installations that have been added in the commit, grouped by member #[prost(message, repeated, tag="3")] - pub installations_added: ::prost::alloc::vec::Vec, + pub installations_added: ::prost::alloc::vec::Vec, + /// Installations removed in the commit, grouped by member #[prost(message, repeated, tag="4")] - pub installations_removed: ::prost::alloc::vec::Vec, + pub installations_removed: ::prost::alloc::vec::Vec, } /// Encoded file descriptor set for the `xmtp.mls.message_contents` package pub const FILE_DESCRIPTOR_SET: &[u8] = &[ @@ -381,94 +387,119 @@ pub const FILE_DESCRIPTOR_SET: &[u8] = &[ 0x74, 0x65, 0x6e, 0x74, 0x20, 0x69, 0x74, 0x73, 0x65, 0x6c, 0x66, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x04, 0x05, 0x12, 0x03, 0x28, 0x02, 0x07, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x04, 0x01, 0x12, 0x03, 0x28, 0x08, 0x0f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x04, - 0x03, 0x12, 0x03, 0x28, 0x12, 0x13, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x0a, 0xe8, - 0x0a, 0x0a, 0x2e, 0x6d, 0x6c, 0x73, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, + 0x03, 0x12, 0x03, 0x28, 0x12, 0x13, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x0a, 0xf5, + 0x0d, 0x0a, 0x2e, 0x6d, 0x6c, 0x73, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x19, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x5a, 0x0a, 0x06, - 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, - 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, - 0x52, 0x0f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, - 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x77, 0x61, 0x6c, 0x6c, 0x65, - 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0xd7, 0x02, 0x0a, 0x15, 0x47, 0x72, 0x6f, - 0x75, 0x70, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x43, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x12, 0x46, 0x0a, 0x0d, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x5f, 0x61, 0x64, - 0x64, 0x65, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x78, 0x6d, 0x74, 0x70, - 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, - 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x0c, 0x6d, 0x65, - 0x6d, 0x62, 0x65, 0x72, 0x73, 0x41, 0x64, 0x64, 0x65, 0x64, 0x12, 0x4a, 0x0a, 0x0f, 0x6d, 0x65, - 0x6d, 0x62, 0x65, 0x72, 0x73, 0x5f, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, - 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x0e, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, - 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x12, 0x52, 0x0a, 0x13, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, - 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x61, 0x64, 0x64, 0x65, 0x64, 0x18, 0x03, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, - 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x12, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x41, 0x64, 0x64, 0x65, 0x64, 0x12, 0x56, 0x0a, 0x15, 0x69, 0x6e, - 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x72, 0x65, 0x6d, 0x6f, - 0x76, 0x65, 0x64, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x78, 0x6d, 0x74, 0x70, - 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, - 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x14, 0x69, 0x6e, - 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x6d, 0x6f, 0x76, - 0x65, 0x64, 0x42, 0xec, 0x01, 0x0a, 0x1d, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, + 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x22, 0xa7, 0x01, 0x0a, + 0x10, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, + 0x65, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0f, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12, 0x27, 0x0a, 0x0f, + 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x3f, 0x0a, 0x1c, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, + 0x65, 0x64, 0x5f, 0x62, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x61, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x19, 0x69, 0x6e, 0x69, + 0x74, 0x69, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x80, 0x03, 0x0a, 0x16, 0x47, 0x72, 0x6f, 0x75, 0x70, + 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x73, 0x12, 0x50, 0x0a, 0x0d, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x5f, 0x61, 0x64, 0x64, + 0x65, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, - 0x65, 0x6e, 0x74, 0x73, 0x42, 0x17, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, - 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x6d, 0x74, 0x70, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x33, 0x2f, 0x67, 0x6f, 0x2f, 0x6d, 0x6c, 0x73, - 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, - 0x73, 0xa2, 0x02, 0x03, 0x58, 0x4d, 0x4d, 0xaa, 0x02, 0x18, 0x58, 0x6d, 0x74, 0x70, 0x2e, 0x4d, - 0x6c, 0x73, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, - 0x74, 0x73, 0xca, 0x02, 0x18, 0x58, 0x6d, 0x74, 0x70, 0x5c, 0x4d, 0x6c, 0x73, 0x5c, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0xe2, 0x02, 0x24, - 0x58, 0x6d, 0x74, 0x70, 0x5c, 0x4d, 0x6c, 0x73, 0x5c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1a, 0x58, 0x6d, 0x74, 0x70, 0x3a, 0x3a, 0x4d, 0x6c, 0x73, - 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, - 0x73, 0x4a, 0xed, 0x04, 0x0a, 0x06, 0x12, 0x04, 0x01, 0x00, 0x14, 0x01, 0x0a, 0x2f, 0x0a, 0x01, - 0x0c, 0x12, 0x03, 0x01, 0x00, 0x12, 0x1a, 0x25, 0x20, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, - 0x67, 0x20, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x73, 0x0a, 0x0a, 0x08, 0x0a, - 0x01, 0x02, 0x12, 0x03, 0x03, 0x00, 0x22, 0x0a, 0x08, 0x0a, 0x01, 0x08, 0x12, 0x03, 0x05, 0x00, - 0x47, 0x0a, 0x09, 0x0a, 0x02, 0x08, 0x0b, 0x12, 0x03, 0x05, 0x00, 0x47, 0x0a, 0x3a, 0x0a, 0x02, - 0x04, 0x00, 0x12, 0x04, 0x09, 0x00, 0x0c, 0x01, 0x1a, 0x2e, 0x20, 0x41, 0x20, 0x67, 0x72, 0x6f, - 0x75, 0x70, 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x66, - 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x20, 0x49, 0x44, 0x73, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x00, 0x01, 0x12, - 0x03, 0x09, 0x08, 0x0e, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x00, 0x12, 0x03, 0x0a, 0x04, - 0x28, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x04, 0x12, 0x03, 0x0a, 0x04, 0x0c, 0x0a, - 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, 0x0a, 0x0d, 0x12, 0x0a, 0x0c, 0x0a, - 0x05, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x0a, 0x13, 0x23, 0x0a, 0x0c, 0x0a, 0x05, 0x04, - 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x0a, 0x26, 0x27, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, - 0x01, 0x12, 0x03, 0x0b, 0x04, 0x1e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x05, 0x12, - 0x03, 0x0b, 0x04, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x0b, - 0x0b, 0x19, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, 0x0b, 0x1c, 0x1d, - 0x0a, 0x2f, 0x0a, 0x02, 0x04, 0x01, 0x12, 0x04, 0x0f, 0x00, 0x14, 0x01, 0x1a, 0x23, 0x20, 0x54, - 0x68, 0x65, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, - 0x68, 0x69, 0x70, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x01, 0x01, 0x12, 0x03, 0x0f, 0x08, 0x1d, 0x0a, 0x0b, 0x0a, - 0x04, 0x04, 0x01, 0x02, 0x00, 0x12, 0x03, 0x10, 0x04, 0x26, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, - 0x02, 0x00, 0x04, 0x12, 0x03, 0x10, 0x04, 0x0c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, - 0x06, 0x12, 0x03, 0x10, 0x0d, 0x13, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x01, 0x12, - 0x03, 0x10, 0x14, 0x21, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x03, 0x12, 0x03, 0x10, - 0x24, 0x25, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x01, 0x12, 0x03, 0x11, 0x04, 0x28, 0x0a, - 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, 0x04, 0x12, 0x03, 0x11, 0x04, 0x0c, 0x0a, 0x0c, 0x0a, - 0x05, 0x04, 0x01, 0x02, 0x01, 0x06, 0x12, 0x03, 0x11, 0x0d, 0x13, 0x0a, 0x0c, 0x0a, 0x05, 0x04, - 0x01, 0x02, 0x01, 0x01, 0x12, 0x03, 0x11, 0x14, 0x23, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, - 0x01, 0x03, 0x12, 0x03, 0x11, 0x26, 0x27, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x02, 0x12, - 0x03, 0x12, 0x04, 0x2c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x04, 0x12, 0x03, 0x12, - 0x04, 0x0c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x06, 0x12, 0x03, 0x12, 0x0d, 0x13, - 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x01, 0x12, 0x03, 0x12, 0x14, 0x27, 0x0a, 0x0c, - 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x03, 0x12, 0x03, 0x12, 0x2a, 0x2b, 0x0a, 0x0b, 0x0a, 0x04, - 0x04, 0x01, 0x02, 0x03, 0x12, 0x03, 0x13, 0x04, 0x2e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, - 0x03, 0x04, 0x12, 0x03, 0x13, 0x04, 0x0c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x06, - 0x12, 0x03, 0x13, 0x0d, 0x13, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x01, 0x12, 0x03, - 0x13, 0x14, 0x29, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x03, 0x12, 0x03, 0x13, 0x2c, - 0x2d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x43, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0c, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x41, 0x64, + 0x64, 0x65, 0x64, 0x12, 0x54, 0x0a, 0x0f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x5f, 0x72, + 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x78, + 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, + 0x68, 0x69, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0e, 0x6d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x73, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x12, 0x5c, 0x0a, 0x13, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x61, 0x64, 0x64, 0x65, 0x64, + 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, + 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x43, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x52, 0x12, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x41, 0x64, 0x64, 0x65, 0x64, 0x12, 0x60, 0x0a, 0x15, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, + 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, + 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x43, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x52, 0x14, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x42, 0xec, 0x01, 0x0a, 0x1d, 0x63, 0x6f, + 0x6d, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x42, 0x17, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x50, + 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x78, 0x6d, 0x74, 0x70, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x33, + 0x2f, 0x67, 0x6f, 0x2f, 0x6d, 0x6c, 0x73, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0xa2, 0x02, 0x03, 0x58, 0x4d, 0x4d, 0xaa, 0x02, + 0x18, 0x58, 0x6d, 0x74, 0x70, 0x2e, 0x4d, 0x6c, 0x73, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0xca, 0x02, 0x18, 0x58, 0x6d, 0x74, 0x70, + 0x5c, 0x4d, 0x6c, 0x73, 0x5c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x73, 0xe2, 0x02, 0x24, 0x58, 0x6d, 0x74, 0x70, 0x5c, 0x4d, 0x6c, 0x73, 0x5c, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x5c, + 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1a, 0x58, 0x6d, + 0x74, 0x70, 0x3a, 0x3a, 0x4d, 0x6c, 0x73, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x4a, 0x83, 0x07, 0x0a, 0x06, 0x12, 0x04, 0x01, + 0x00, 0x19, 0x01, 0x0a, 0x2f, 0x0a, 0x01, 0x0c, 0x12, 0x03, 0x01, 0x00, 0x12, 0x1a, 0x25, 0x20, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x20, + 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, + 0x72, 0x65, 0x73, 0x0a, 0x0a, 0x08, 0x0a, 0x01, 0x02, 0x12, 0x03, 0x03, 0x00, 0x22, 0x0a, 0x08, + 0x0a, 0x01, 0x08, 0x12, 0x03, 0x05, 0x00, 0x47, 0x0a, 0x09, 0x0a, 0x02, 0x08, 0x0b, 0x12, 0x03, + 0x05, 0x00, 0x47, 0x0a, 0x3a, 0x0a, 0x02, 0x04, 0x00, 0x12, 0x04, 0x09, 0x00, 0x0d, 0x01, 0x1a, + 0x2e, 0x20, 0x41, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x49, 0x44, 0x73, 0x0a, 0x0a, + 0x0a, 0x0a, 0x03, 0x04, 0x00, 0x01, 0x12, 0x03, 0x09, 0x08, 0x18, 0x0a, 0x0b, 0x0a, 0x04, 0x04, + 0x00, 0x02, 0x00, 0x12, 0x03, 0x0a, 0x04, 0x28, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, + 0x04, 0x12, 0x03, 0x0a, 0x04, 0x0c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x05, 0x12, + 0x03, 0x0a, 0x0d, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x0a, + 0x13, 0x23, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x0a, 0x26, 0x27, + 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x01, 0x12, 0x03, 0x0b, 0x04, 0x1f, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x00, 0x02, 0x01, 0x05, 0x12, 0x03, 0x0b, 0x04, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, + 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x0b, 0x0b, 0x1a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, + 0x01, 0x03, 0x12, 0x03, 0x0b, 0x1d, 0x1e, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x02, 0x12, + 0x03, 0x0c, 0x04, 0x2c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x05, 0x12, 0x03, 0x0c, + 0x04, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x03, 0x0c, 0x0b, 0x27, + 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x03, 0x12, 0x03, 0x0c, 0x2a, 0x2b, 0x0a, 0x2f, + 0x0a, 0x02, 0x04, 0x01, 0x12, 0x04, 0x10, 0x00, 0x19, 0x01, 0x1a, 0x23, 0x20, 0x54, 0x68, 0x65, + 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, + 0x70, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x0a, 0x0a, + 0x0a, 0x0a, 0x03, 0x04, 0x01, 0x01, 0x12, 0x03, 0x10, 0x08, 0x1e, 0x0a, 0x39, 0x0a, 0x04, 0x04, + 0x01, 0x02, 0x00, 0x12, 0x03, 0x12, 0x04, 0x30, 0x1a, 0x2c, 0x20, 0x4d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x62, 0x65, 0x65, + 0x6e, 0x20, 0x61, 0x64, 0x64, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x04, 0x12, + 0x03, 0x12, 0x04, 0x0c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x06, 0x12, 0x03, 0x12, + 0x0d, 0x1d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x01, 0x12, 0x03, 0x12, 0x1e, 0x2b, + 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x03, 0x12, 0x03, 0x12, 0x2e, 0x2f, 0x0a, 0x3b, + 0x0a, 0x04, 0x04, 0x01, 0x02, 0x01, 0x12, 0x03, 0x14, 0x04, 0x32, 0x1a, 0x2e, 0x20, 0x4d, 0x65, + 0x6d, 0x62, 0x65, 0x72, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, + 0x62, 0x65, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, + 0x01, 0x02, 0x01, 0x04, 0x12, 0x03, 0x14, 0x04, 0x0c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, + 0x01, 0x06, 0x12, 0x03, 0x14, 0x0d, 0x1d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, 0x01, + 0x12, 0x03, 0x14, 0x1e, 0x2d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, 0x03, 0x12, 0x03, + 0x14, 0x30, 0x31, 0x0a, 0x52, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x02, 0x12, 0x03, 0x16, 0x04, 0x36, + 0x1a, 0x45, 0x20, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x20, + 0x61, 0x64, 0x64, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x2c, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, + 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x04, + 0x12, 0x03, 0x16, 0x04, 0x0c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x06, 0x12, 0x03, + 0x16, 0x0d, 0x1d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x01, 0x12, 0x03, 0x16, 0x1e, + 0x31, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x03, 0x12, 0x03, 0x16, 0x34, 0x35, 0x0a, + 0x45, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x03, 0x12, 0x03, 0x18, 0x04, 0x38, 0x1a, 0x38, 0x20, 0x49, + 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x72, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x2c, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x6d, + 0x65, 0x6d, 0x62, 0x65, 0x72, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x04, 0x12, + 0x03, 0x18, 0x04, 0x0c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x06, 0x12, 0x03, 0x18, + 0x0d, 0x1d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x01, 0x12, 0x03, 0x18, 0x1e, 0x33, + 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x03, 0x12, 0x03, 0x18, 0x36, 0x37, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, ]; include!("xmtp.mls.message_contents.serde.rs"); // @@protoc_insertion_point(module) \ No newline at end of file diff --git a/xmtp_proto/src/gen/xmtp.mls.message_contents.serde.rs b/xmtp_proto/src/gen/xmtp.mls.message_contents.serde.rs index e7ffee853..29abd15b3 100644 --- a/xmtp_proto/src/gen/xmtp.mls.message_contents.serde.rs +++ b/xmtp_proto/src/gen/xmtp.mls.message_contents.serde.rs @@ -387,7 +387,7 @@ impl<'de> serde::Deserialize<'de> for EncodedContent { deserializer.deserialize_struct("xmtp.mls.message_contents.EncodedContent", FIELDS, GeneratedVisitor) } } -impl serde::Serialize for GroupMembershipChange { +impl serde::Serialize for GroupMembershipChanges { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result where @@ -407,7 +407,7 @@ impl serde::Serialize for GroupMembershipChange { if !self.installations_removed.is_empty() { len += 1; } - let mut struct_ser = serializer.serialize_struct("xmtp.mls.message_contents.GroupMembershipChange", len)?; + let mut struct_ser = serializer.serialize_struct("xmtp.mls.message_contents.GroupMembershipChanges", len)?; if !self.members_added.is_empty() { struct_ser.serialize_field("membersAdded", &self.members_added)?; } @@ -423,7 +423,7 @@ impl serde::Serialize for GroupMembershipChange { struct_ser.end() } } -impl<'de> serde::Deserialize<'de> for GroupMembershipChange { +impl<'de> serde::Deserialize<'de> for GroupMembershipChanges { #[allow(deprecated)] fn deserialize(deserializer: D) -> std::result::Result where @@ -480,13 +480,13 @@ impl<'de> serde::Deserialize<'de> for GroupMembershipChange { } struct GeneratedVisitor; impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = GroupMembershipChange; + type Value = GroupMembershipChanges; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("struct xmtp.mls.message_contents.GroupMembershipChange") + formatter.write_str("struct xmtp.mls.message_contents.GroupMembershipChanges") } - fn visit_map(self, mut map: V) -> std::result::Result + fn visit_map(self, mut map: V) -> std::result::Result where V: serde::de::MapAccess<'de>, { @@ -522,7 +522,7 @@ impl<'de> serde::Deserialize<'de> for GroupMembershipChange { } } } - Ok(GroupMembershipChange { + Ok(GroupMembershipChanges { members_added: members_added__.unwrap_or_default(), members_removed: members_removed__.unwrap_or_default(), installations_added: installations_added__.unwrap_or_default(), @@ -530,7 +530,7 @@ impl<'de> serde::Deserialize<'de> for GroupMembershipChange { }) } } - deserializer.deserialize_struct("xmtp.mls.message_contents.GroupMembershipChange", FIELDS, GeneratedVisitor) + deserializer.deserialize_struct("xmtp.mls.message_contents.GroupMembershipChanges", FIELDS, GeneratedVisitor) } } impl serde::Serialize for GroupMessage { @@ -723,7 +723,7 @@ impl<'de> serde::Deserialize<'de> for group_message::V1 { deserializer.deserialize_struct("xmtp.mls.message_contents.GroupMessage.V1", FIELDS, GeneratedVisitor) } } -impl serde::Serialize for Member { +impl serde::Serialize for MembershipChange { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result where @@ -734,20 +734,26 @@ impl serde::Serialize for Member { if !self.installation_ids.is_empty() { len += 1; } - if !self.wallet_address.is_empty() { + if !self.account_address.is_empty() { len += 1; } - let mut struct_ser = serializer.serialize_struct("xmtp.mls.message_contents.Member", len)?; + if !self.initiated_by_account_address.is_empty() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("xmtp.mls.message_contents.MembershipChange", len)?; if !self.installation_ids.is_empty() { struct_ser.serialize_field("installationIds", &self.installation_ids.iter().map(pbjson::private::base64::encode).collect::>())?; } - if !self.wallet_address.is_empty() { - struct_ser.serialize_field("walletAddress", &self.wallet_address)?; + if !self.account_address.is_empty() { + struct_ser.serialize_field("accountAddress", &self.account_address)?; + } + if !self.initiated_by_account_address.is_empty() { + struct_ser.serialize_field("initiatedByAccountAddress", &self.initiated_by_account_address)?; } struct_ser.end() } } -impl<'de> serde::Deserialize<'de> for Member { +impl<'de> serde::Deserialize<'de> for MembershipChange { #[allow(deprecated)] fn deserialize(deserializer: D) -> std::result::Result where @@ -756,14 +762,17 @@ impl<'de> serde::Deserialize<'de> for Member { const FIELDS: &[&str] = &[ "installation_ids", "installationIds", - "wallet_address", - "walletAddress", + "account_address", + "accountAddress", + "initiated_by_account_address", + "initiatedByAccountAddress", ]; #[allow(clippy::enum_variant_names)] enum GeneratedField { InstallationIds, - WalletAddress, + AccountAddress, + InitiatedByAccountAddress, } impl<'de> serde::Deserialize<'de> for GeneratedField { fn deserialize(deserializer: D) -> std::result::Result @@ -786,7 +795,8 @@ impl<'de> serde::Deserialize<'de> for Member { { match value { "installationIds" | "installation_ids" => Ok(GeneratedField::InstallationIds), - "walletAddress" | "wallet_address" => Ok(GeneratedField::WalletAddress), + "accountAddress" | "account_address" => Ok(GeneratedField::AccountAddress), + "initiatedByAccountAddress" | "initiated_by_account_address" => Ok(GeneratedField::InitiatedByAccountAddress), _ => Err(serde::de::Error::unknown_field(value, FIELDS)), } } @@ -796,18 +806,19 @@ impl<'de> serde::Deserialize<'de> for Member { } struct GeneratedVisitor; impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = Member; + type Value = MembershipChange; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("struct xmtp.mls.message_contents.Member") + formatter.write_str("struct xmtp.mls.message_contents.MembershipChange") } - fn visit_map(self, mut map: V) -> std::result::Result + fn visit_map(self, mut map: V) -> std::result::Result where V: serde::de::MapAccess<'de>, { let mut installation_ids__ = None; - let mut wallet_address__ = None; + let mut account_address__ = None; + let mut initiated_by_account_address__ = None; while let Some(k) = map.next_key()? { match k { GeneratedField::InstallationIds => { @@ -819,21 +830,28 @@ impl<'de> serde::Deserialize<'de> for Member { .into_iter().map(|x| x.0).collect()) ; } - GeneratedField::WalletAddress => { - if wallet_address__.is_some() { - return Err(serde::de::Error::duplicate_field("walletAddress")); + GeneratedField::AccountAddress => { + if account_address__.is_some() { + return Err(serde::de::Error::duplicate_field("accountAddress")); + } + account_address__ = Some(map.next_value()?); + } + GeneratedField::InitiatedByAccountAddress => { + if initiated_by_account_address__.is_some() { + return Err(serde::de::Error::duplicate_field("initiatedByAccountAddress")); } - wallet_address__ = Some(map.next_value()?); + initiated_by_account_address__ = Some(map.next_value()?); } } } - Ok(Member { + Ok(MembershipChange { installation_ids: installation_ids__.unwrap_or_default(), - wallet_address: wallet_address__.unwrap_or_default(), + account_address: account_address__.unwrap_or_default(), + initiated_by_account_address: initiated_by_account_address__.unwrap_or_default(), }) } } - deserializer.deserialize_struct("xmtp.mls.message_contents.Member", FIELDS, GeneratedVisitor) + deserializer.deserialize_struct("xmtp.mls.message_contents.MembershipChange", FIELDS, GeneratedVisitor) } } impl serde::Serialize for WelcomeMessage { From 9a8fcbad4868b8ac7119649c1c2841950ae86e5d Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Tue, 5 Dec 2023 17:30:17 -0500 Subject: [PATCH 02/20] fix test --- xmtp_mls/src/groups/intents.rs | 5 ++++- xmtp_mls/src/groups/mod.rs | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/xmtp_mls/src/groups/intents.rs b/xmtp_mls/src/groups/intents.rs index a41f4a757..9ff8b5459 100644 --- a/xmtp_mls/src/groups/intents.rs +++ b/xmtp_mls/src/groups/intents.rs @@ -102,7 +102,10 @@ impl AddMembersIntentData { Some(AddMembersVersion::V1(v1)) => v1.wallet_addresses, None => return Err(IntentError::Generic("missing payload".to_string())), }; - let addresses = address_bytes.iter().map(|addr| hex::encode(addr)).collect(); + let addresses = address_bytes + .iter() + .map(|addr| format!("0x{}", hex::encode(addr))) + .collect(); Ok(Self::new(addresses)) } diff --git a/xmtp_mls/src/groups/mod.rs b/xmtp_mls/src/groups/mod.rs index 2abd1243d..e14ab1869 100644 --- a/xmtp_mls/src/groups/mod.rs +++ b/xmtp_mls/src/groups/mod.rs @@ -566,6 +566,8 @@ where IntentKind::AddMembers => { let intent_data = AddMembersIntentData::from_bytes(intent.data.as_slice())?; + log::debug!("INTENT_DATA: {:?}", intent_data); + let key_packages = self .client .get_key_packages_for_wallet_addresses(intent_data.wallet_addresses) From a8f5d0cc34373f4bcd6eadeea5bd7277797c199e Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Tue, 5 Dec 2023 19:17:05 -0500 Subject: [PATCH 03/20] need to fix one more test --- xmtp_mls/src/client.rs | 2 +- xmtp_mls/src/groups/intents.rs | 49 ++-- xmtp_mls/src/groups/members.rs | 5 +- xmtp_mls/src/groups/mod.rs | 80 ++---- xmtp_proto/src/gen/xmtp.mls.database.rs | 250 +++++++++--------- xmtp_proto/src/gen/xmtp.mls.database.serde.rs | 58 ++-- 6 files changed, 198 insertions(+), 246 deletions(-) diff --git a/xmtp_mls/src/client.rs b/xmtp_mls/src/client.rs index 2d3dced29..7886fe140 100644 --- a/xmtp_mls/src/client.rs +++ b/xmtp_mls/src/client.rs @@ -404,7 +404,7 @@ mod tests { let alice_bob_group = alice.create_group().unwrap(); alice_bob_group - .add_members_by_installation_id(vec![bob.installation_public_key()]) + .add_members(vec![bob.account_address()]) .await .unwrap(); diff --git a/xmtp_mls/src/groups/intents.rs b/xmtp_mls/src/groups/intents.rs index 9ff8b5459..5e6dc1b80 100644 --- a/xmtp_mls/src/groups/intents.rs +++ b/xmtp_mls/src/groups/intents.rs @@ -10,10 +10,7 @@ use xmtp_proto::xmtp::mls::database::{ AddMembersData, PostCommitAction as PostCommitActionProto, RemoveMembersData, SendMessageData, }; -use crate::{ - types::Address, verified_key_package::KeyPackageVerificationError, - xmtp_openmls_provider::XmtpOpenMlsProvider, -}; +use crate::{types::Address, verified_key_package::KeyPackageVerificationError}; #[derive(Debug, Error)] pub enum IntentError { @@ -25,8 +22,6 @@ pub enum IntentError { TlsCodec(#[from] tls_codec::Error), #[error("generic: {0}")] Generic(String), - #[error(transparent)] - FromHex(#[from] hex::FromHexError), } #[derive(Debug, Clone)] @@ -71,24 +66,20 @@ impl From for Vec { #[derive(Debug, Clone)] pub struct AddMembersIntentData { - pub wallet_addresses: Vec
, + pub account_addresses: Vec
, } impl AddMembersIntentData { - pub fn new(wallet_addresses: Vec
) -> Self { - Self { wallet_addresses } + pub fn new(account_addresses: Vec
) -> Self { + Self { account_addresses } } - pub(crate) fn to_bytes(&self) -> Result, IntentError> { + pub(crate) fn to_bytes(self) -> Result, IntentError> { let mut buf = Vec::new(); - let wallet_addresses = self - .wallet_addresses - .iter() - .map(|addr| hex::decode(&addr[2..])) - .collect::, _>>()?; - AddMembersData { - version: Some(AddMembersVersion::V1(AddMembersV1 { wallet_addresses })), + version: Some(AddMembersVersion::V1(AddMembersV1 { + account_addresses: self.account_addresses, + })), } .encode(&mut buf) .expect("encode error"); @@ -98,14 +89,10 @@ impl AddMembersIntentData { pub(crate) fn from_bytes(data: &[u8]) -> Result { let msg = AddMembersData::decode(data)?; - let address_bytes = match msg.version { - Some(AddMembersVersion::V1(v1)) => v1.wallet_addresses, + let addresses = match msg.version { + Some(AddMembersVersion::V1(v1)) => v1.account_addresses, None => return Err(IntentError::Generic("missing payload".to_string())), }; - let addresses = address_bytes - .iter() - .map(|addr| format!("0x{}", hex::encode(addr))) - .collect(); Ok(Self::new(addresses)) } @@ -121,20 +108,20 @@ impl TryFrom for Vec { #[derive(Debug, Clone)] pub struct RemoveMembersIntentData { - pub installation_ids: Vec>, + pub account_addresses: Vec, } impl RemoveMembersIntentData { - pub fn new(installation_ids: Vec>) -> Self { - Self { installation_ids } + pub fn new(account_addresses: Vec) -> Self { + Self { account_addresses } } - pub(crate) fn to_bytes(&self) -> Vec { + pub(crate) fn to_bytes(self) -> Vec { let mut buf = Vec::new(); RemoveMembersData { version: Some(RemoveMembersVersion::V1(RemoveMembersV1 { - installation_ids: self.installation_ids.clone(), + account_addresses: self.account_addresses, })), } .encode(&mut buf) @@ -145,12 +132,12 @@ impl RemoveMembersIntentData { pub(crate) fn from_bytes(data: &[u8]) -> Result { let msg = RemoveMembersData::decode(data)?; - let installation_ids = match msg.version { - Some(RemoveMembersVersion::V1(v1)) => v1.installation_ids, + let account_addresses = match msg.version { + Some(RemoveMembersVersion::V1(v1)) => v1.account_addresses, None => return Err(IntentError::Generic("missing payload".to_string())), }; - Ok(Self::new(installation_ids)) + Ok(Self::new(account_addresses)) } } diff --git a/xmtp_mls/src/groups/members.rs b/xmtp_mls/src/groups/members.rs index 10810529d..0da408d28 100644 --- a/xmtp_mls/src/groups/members.rs +++ b/xmtp_mls/src/groups/members.rs @@ -67,10 +67,7 @@ mod tests { let group = amal.create_group().unwrap(); // Add both of Bola's installations to the group group - .add_members_by_installation_id(vec![ - bola_a.installation_public_key(), - bola_b.installation_public_key(), - ]) + .add_members(vec![bola_a.account_address(), bola_b.account_address()]) .await .unwrap(); diff --git a/xmtp_mls/src/groups/mod.rs b/xmtp_mls/src/groups/mod.rs index e14ab1869..03983bc89 100644 --- a/xmtp_mls/src/groups/mod.rs +++ b/xmtp_mls/src/groups/mod.rs @@ -434,20 +434,9 @@ where self.sync_with_conn(conn).await } - pub async fn add_members_by_installation_id( - &self, - _installation_ids: Vec>, - ) -> Result<(), GroupError> { - // remove - unimplemented!() - } - - pub(crate) async fn remove_members_by_installation_id( - &self, - installation_ids: Vec>, - ) -> Result<(), GroupError> { + pub async fn remove_members(&self, wallet_addresses: Vec) -> Result<(), GroupError> { let conn = &mut self.client.store.conn()?; - let intent_data: Vec = RemoveMembersIntentData::new(installation_ids).into(); + let intent_data: Vec = RemoveMembersIntentData::new(wallet_addresses).into(); let intent = NewGroupIntent::new( IntentKind::RemoveMembers, self.group_id.clone(), @@ -458,20 +447,6 @@ where self.sync_with_conn(conn).await } - pub async fn remove_members(&self, wallet_addresses: Vec) -> Result<(), GroupError> { - let installation_ids = self - .members()? - .into_iter() - .filter(|member| wallet_addresses.contains(&member.wallet_address)) - .fold(vec![], |mut acc, member| { - acc.extend(member.installation_ids); - acc - }); - - self.remove_members_by_installation_id(installation_ids) - .await - } - pub async fn key_update(&self) -> Result<(), GroupError> { let conn = &mut self.client.store.conn()?; let intent = NewGroupIntent::new(IntentKind::KeyUpdate, self.group_id.clone(), vec![]); @@ -566,15 +541,11 @@ where IntentKind::AddMembers => { let intent_data = AddMembersIntentData::from_bytes(intent.data.as_slice())?; - log::debug!("INTENT_DATA: {:?}", intent_data); - let key_packages = self .client - .get_key_packages_for_wallet_addresses(intent_data.wallet_addresses) + .get_key_packages_for_wallet_addresses(intent_data.account_addresses) .await?; - log::debug!("KEY PACKAGES: {:?}", key_packages); - let mls_key_packages: Vec = key_packages.iter().map(|kp| kp.inner.clone()).collect(); @@ -598,18 +569,32 @@ where } IntentKind::RemoveMembers => { let intent_data = RemoveMembersIntentData::from_bytes(intent.data.as_slice())?; + + let installation_ids = self + .members()? + .into_iter() + .filter(|member| { + intent_data + .account_addresses + .contains(&member.wallet_address) + }) + .fold(vec![], |mut acc, member| { + acc.extend(member.installation_ids); + acc + }); + let leaf_nodes: Vec = openmls_group .members() - .filter(|member| intent_data.installation_ids.contains(&member.signature_key)) + .filter(|member| installation_ids.contains(&member.signature_key)) .map(|member| member.index) .collect(); let num_leaf_nodes = leaf_nodes.len(); - if num_leaf_nodes != intent_data.installation_ids.len() { + if num_leaf_nodes != installation_ids.len() { return Err(GroupError::Generic(format!( "expected {} leaf nodes, found {}", - intent_data.installation_ids.len(), + installation_ids.len(), num_leaf_nodes ))); } @@ -741,7 +726,7 @@ mod tests { let amal_group = amal.create_group().unwrap(); // Add bola amal_group - .add_members_by_installation_id(vec![bola.installation_public_key()]) + .add_members(vec![bola.account_address()]) .await .unwrap(); @@ -751,11 +736,11 @@ mod tests { // Have amal and bola both invite charlie. amal_group - .add_members_by_installation_id(vec![charlie.installation_public_key()]) + .add_members(vec![charlie.account_address()]) .await .expect("failed to add charlie"); bola_group - .add_members_by_installation_id(vec![charlie.installation_public_key()]) + .add_members(vec![charlie.account_address()]) .await .unwrap(); @@ -828,9 +813,7 @@ mod tests { let client = ClientBuilder::new_test_client(generate_local_wallet().into()).await; let group = client.create_group().expect("create group"); - let result = group - .add_members_by_installation_id(vec![b"1234".to_vec()]) - .await; + let result = group.add_members(vec!["1234".to_string()]).await; assert!(result.is_err()); } @@ -844,19 +827,13 @@ mod tests { let group = client_1.create_group().expect("create group"); group - .add_members_by_installation_id(vec![client_2 - .identity - .installation_keys - .to_public_vec()]) + .add_members(vec![client_2.account_address()]) .await .expect("group create failure"); // Try and add another member without merging the pending commit group - .remove_members_by_installation_id(vec![client_2 - .identity - .installation_keys - .to_public_vec()]) + .remove_members(vec![client_2.account_address()]) .await .expect("group create failure"); @@ -901,10 +878,7 @@ mod tests { let group = client.create_group().expect("create group"); group - .add_members_by_installation_id(vec![client_2 - .identity - .installation_keys - .to_public_vec()]) + .add_members(vec![client_2.account_address()]) .await .unwrap(); diff --git a/xmtp_proto/src/gen/xmtp.mls.database.rs b/xmtp_proto/src/gen/xmtp.mls.database.rs index d8a838f1b..212fc2fed 100644 --- a/xmtp_proto/src/gen/xmtp.mls.database.rs +++ b/xmtp_proto/src/gen/xmtp.mls.database.rs @@ -35,8 +35,8 @@ pub mod add_members_data { #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct V1 { - #[prost(bytes="vec", repeated, tag="1")] - pub wallet_addresses: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, + #[prost(string, repeated, tag="1")] + pub account_addresses: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Oneof)] @@ -58,8 +58,8 @@ pub mod remove_members_data { #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct V1 { - #[prost(bytes="vec", repeated, tag="1")] - pub installation_ids: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, + #[prost(string, repeated, tag="1")] + pub account_addresses: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Oneof)] @@ -95,7 +95,7 @@ pub mod post_commit_action { } /// Encoded file descriptor set for the `xmtp.mls.database` package pub const FILE_DESCRIPTOR_SET: &[u8] = &[ - 0x0a, 0xf0, 0x10, 0x0a, 0x1a, 0x6d, 0x6c, 0x73, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, + 0x0a, 0xf4, 0x10, 0x0a, 0x1a, 0x6d, 0x6c, 0x73, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x11, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x22, 0x80, 0x01, 0x0a, 0x0f, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, @@ -106,131 +106,131 @@ pub const FILE_DESCRIPTOR_SET: &[u8] = &[ 0x29, 0x0a, 0x02, 0x56, 0x31, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x42, 0x09, 0x0a, 0x07, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x84, 0x01, 0x0a, 0x0e, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x86, 0x01, 0x0a, 0x0e, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x44, 0x61, 0x74, 0x61, 0x12, 0x36, 0x0a, 0x02, 0x76, 0x31, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x31, 0x48, 0x00, 0x52, 0x02, 0x76, 0x31, - 0x1a, 0x2f, 0x0a, 0x02, 0x56, 0x31, 0x12, 0x29, 0x0a, 0x10, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, - 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, - 0x52, 0x0f, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, - 0x73, 0x42, 0x09, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x8a, 0x01, 0x0a, - 0x11, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x44, 0x61, - 0x74, 0x61, 0x12, 0x39, 0x0a, 0x02, 0x76, 0x31, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, - 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, - 0x73, 0x65, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, - 0x44, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x31, 0x48, 0x00, 0x52, 0x02, 0x76, 0x31, 0x1a, 0x2f, 0x0a, - 0x02, 0x56, 0x31, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0f, 0x69, - 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x42, 0x09, - 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xd7, 0x01, 0x0a, 0x10, 0x50, 0x6f, - 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x57, - 0x0a, 0x0d, 0x73, 0x65, 0x6e, 0x64, 0x5f, 0x77, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, - 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x43, 0x6f, - 0x6d, 0x6d, 0x69, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x57, - 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x73, 0x48, 0x00, 0x52, 0x0c, 0x73, 0x65, 0x6e, 0x64, 0x57, - 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x73, 0x1a, 0x62, 0x0a, 0x0c, 0x53, 0x65, 0x6e, 0x64, 0x57, - 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0c, 0x52, 0x0f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, - 0x64, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x77, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x5f, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x77, 0x65, 0x6c, - 0x63, 0x6f, 0x6d, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x06, 0x0a, 0x04, 0x6b, - 0x69, 0x6e, 0x64, 0x42, 0xb5, 0x01, 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x6d, 0x74, 0x70, - 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x42, 0x0c, 0x49, - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x28, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x6d, 0x74, 0x70, 0x2f, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x33, 0x2f, 0x67, 0x6f, 0x2f, 0x6d, 0x6c, 0x73, 0x2f, 0x64, - 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0xa2, 0x02, 0x03, 0x58, 0x4d, 0x44, 0xaa, 0x02, 0x11, - 0x58, 0x6d, 0x74, 0x70, 0x2e, 0x4d, 0x6c, 0x73, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, - 0x65, 0xca, 0x02, 0x11, 0x58, 0x6d, 0x74, 0x70, 0x5c, 0x4d, 0x6c, 0x73, 0x5c, 0x44, 0x61, 0x74, - 0x61, 0x62, 0x61, 0x73, 0x65, 0xe2, 0x02, 0x1d, 0x58, 0x6d, 0x74, 0x70, 0x5c, 0x4d, 0x6c, 0x73, - 0x5c, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13, 0x58, 0x6d, 0x74, 0x70, 0x3a, 0x3a, 0x4d, 0x6c, - 0x73, 0x3a, 0x3a, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x4a, 0x8d, 0x0a, 0x0a, 0x06, - 0x12, 0x04, 0x01, 0x00, 0x37, 0x01, 0x0a, 0x27, 0x0a, 0x01, 0x0c, 0x12, 0x03, 0x01, 0x00, 0x12, - 0x1a, 0x1d, 0x20, 0x56, 0x33, 0x20, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x20, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x20, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x0a, 0x0a, - 0x08, 0x0a, 0x01, 0x02, 0x12, 0x03, 0x03, 0x00, 0x1a, 0x0a, 0x08, 0x0a, 0x01, 0x08, 0x12, 0x03, - 0x05, 0x00, 0x3f, 0x0a, 0x09, 0x0a, 0x02, 0x08, 0x0b, 0x12, 0x03, 0x05, 0x00, 0x3f, 0x0a, 0x34, - 0x0a, 0x02, 0x04, 0x00, 0x12, 0x04, 0x09, 0x00, 0x12, 0x01, 0x1a, 0x28, 0x20, 0x54, 0x68, 0x65, - 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x20, 0x74, - 0x6f, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x20, 0x61, 0x20, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x00, 0x01, 0x12, 0x03, 0x09, 0x08, 0x17, - 0x0a, 0x2c, 0x0a, 0x04, 0x04, 0x00, 0x03, 0x00, 0x12, 0x04, 0x0b, 0x02, 0x0d, 0x03, 0x1a, 0x1e, - 0x20, 0x56, 0x31, 0x20, 0x6f, 0x66, 0x20, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x44, 0x61, 0x74, 0x61, 0x0a, 0x0a, 0x0c, - 0x0a, 0x05, 0x04, 0x00, 0x03, 0x00, 0x01, 0x12, 0x03, 0x0b, 0x0a, 0x0c, 0x0a, 0x0d, 0x0a, 0x06, - 0x04, 0x00, 0x03, 0x00, 0x02, 0x00, 0x12, 0x03, 0x0c, 0x04, 0x1c, 0x0a, 0x0e, 0x0a, 0x07, 0x04, - 0x00, 0x03, 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, 0x0c, 0x04, 0x09, 0x0a, 0x0e, 0x0a, 0x07, 0x04, - 0x00, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x0c, 0x0a, 0x17, 0x0a, 0x0e, 0x0a, 0x07, 0x04, - 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x0c, 0x1a, 0x1b, 0x0a, 0x0c, 0x0a, 0x04, 0x04, - 0x00, 0x08, 0x00, 0x12, 0x04, 0x0f, 0x02, 0x11, 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x08, - 0x00, 0x01, 0x12, 0x03, 0x0f, 0x08, 0x0f, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x00, 0x12, - 0x03, 0x10, 0x04, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x06, 0x12, 0x03, 0x10, - 0x04, 0x06, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x10, 0x07, 0x09, - 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x10, 0x0c, 0x0d, 0x0a, 0x39, - 0x0a, 0x02, 0x04, 0x01, 0x12, 0x04, 0x15, 0x00, 0x1e, 0x01, 0x1a, 0x2d, 0x20, 0x54, 0x68, 0x65, - 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x20, 0x74, - 0x6f, 0x20, 0x61, 0x64, 0x64, 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x20, 0x74, 0x6f, - 0x20, 0x61, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x01, 0x01, - 0x12, 0x03, 0x15, 0x08, 0x16, 0x0a, 0x2b, 0x0a, 0x04, 0x04, 0x01, 0x03, 0x00, 0x12, 0x04, 0x17, - 0x02, 0x19, 0x03, 0x1a, 0x1d, 0x20, 0x56, 0x31, 0x20, 0x6f, 0x66, 0x20, 0x41, 0x64, 0x64, 0x4d, - 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x44, 0x61, 0x74, - 0x61, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x03, 0x00, 0x01, 0x12, 0x03, 0x17, 0x0a, 0x0c, - 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x01, 0x03, 0x00, 0x02, 0x00, 0x12, 0x03, 0x18, 0x04, 0x28, 0x0a, - 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x03, 0x00, 0x02, 0x00, 0x04, 0x12, 0x03, 0x18, 0x04, 0x0c, 0x0a, - 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x03, 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, 0x18, 0x0d, 0x12, 0x0a, - 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x18, 0x13, 0x23, 0x0a, - 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x18, 0x26, 0x27, 0x0a, - 0x0c, 0x0a, 0x04, 0x04, 0x01, 0x08, 0x00, 0x12, 0x04, 0x1b, 0x02, 0x1d, 0x03, 0x0a, 0x0c, 0x0a, - 0x05, 0x04, 0x01, 0x08, 0x00, 0x01, 0x12, 0x03, 0x1b, 0x08, 0x0f, 0x0a, 0x0b, 0x0a, 0x04, 0x04, - 0x01, 0x02, 0x00, 0x12, 0x03, 0x1c, 0x04, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, - 0x06, 0x12, 0x03, 0x1c, 0x04, 0x06, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x01, 0x12, - 0x03, 0x1c, 0x07, 0x09, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x03, 0x12, 0x03, 0x1c, - 0x0c, 0x0d, 0x0a, 0x3e, 0x0a, 0x02, 0x04, 0x02, 0x12, 0x04, 0x21, 0x00, 0x2a, 0x01, 0x1a, 0x32, + 0x1a, 0x31, 0x0a, 0x02, 0x56, 0x31, 0x12, 0x2b, 0x0a, 0x11, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x10, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x65, 0x73, 0x42, 0x09, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x8c, + 0x01, 0x0a, 0x11, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, + 0x44, 0x61, 0x74, 0x61, 0x12, 0x39, 0x0a, 0x02, 0x76, 0x31, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x27, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, 0x61, 0x74, 0x61, + 0x62, 0x61, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x73, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x31, 0x48, 0x00, 0x52, 0x02, 0x76, 0x31, 0x1a, + 0x31, 0x0a, 0x02, 0x56, 0x31, 0x12, 0x2b, 0x0a, 0x11, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x10, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x65, 0x73, 0x42, 0x09, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xd7, 0x01, + 0x0a, 0x10, 0x50, 0x6f, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x41, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x57, 0x0a, 0x0d, 0x73, 0x65, 0x6e, 0x64, 0x5f, 0x77, 0x65, 0x6c, 0x63, 0x6f, + 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x78, 0x6d, 0x74, 0x70, + 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x50, 0x6f, + 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x53, + 0x65, 0x6e, 0x64, 0x57, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x73, 0x48, 0x00, 0x52, 0x0c, 0x73, + 0x65, 0x6e, 0x64, 0x57, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x73, 0x1a, 0x62, 0x0a, 0x0c, 0x53, + 0x65, 0x6e, 0x64, 0x57, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x77, 0x65, 0x6c, 0x63, 0x6f, 0x6d, + 0x65, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x0e, 0x77, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, + 0x06, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x42, 0xb5, 0x01, 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e, + 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, + 0x65, 0x42, 0x0c, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, + 0x01, 0x5a, 0x28, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x6d, + 0x74, 0x70, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x33, 0x2f, 0x67, 0x6f, 0x2f, 0x6d, + 0x6c, 0x73, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0xa2, 0x02, 0x03, 0x58, 0x4d, + 0x44, 0xaa, 0x02, 0x11, 0x58, 0x6d, 0x74, 0x70, 0x2e, 0x4d, 0x6c, 0x73, 0x2e, 0x44, 0x61, 0x74, + 0x61, 0x62, 0x61, 0x73, 0x65, 0xca, 0x02, 0x11, 0x58, 0x6d, 0x74, 0x70, 0x5c, 0x4d, 0x6c, 0x73, + 0x5c, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0xe2, 0x02, 0x1d, 0x58, 0x6d, 0x74, 0x70, + 0x5c, 0x4d, 0x6c, 0x73, 0x5c, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5c, 0x47, 0x50, + 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13, 0x58, 0x6d, 0x74, 0x70, + 0x3a, 0x3a, 0x4d, 0x6c, 0x73, 0x3a, 0x3a, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x4a, + 0x8d, 0x0a, 0x0a, 0x06, 0x12, 0x04, 0x01, 0x00, 0x37, 0x01, 0x0a, 0x27, 0x0a, 0x01, 0x0c, 0x12, + 0x03, 0x01, 0x00, 0x12, 0x1a, 0x1d, 0x20, 0x56, 0x33, 0x20, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, + 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, + 0x72, 0x65, 0x0a, 0x0a, 0x08, 0x0a, 0x01, 0x02, 0x12, 0x03, 0x03, 0x00, 0x1a, 0x0a, 0x08, 0x0a, + 0x01, 0x08, 0x12, 0x03, 0x05, 0x00, 0x3f, 0x0a, 0x09, 0x0a, 0x02, 0x08, 0x0b, 0x12, 0x03, 0x05, + 0x00, 0x3f, 0x0a, 0x34, 0x0a, 0x02, 0x04, 0x00, 0x12, 0x04, 0x09, 0x00, 0x12, 0x01, 0x1a, 0x28, + 0x20, 0x54, 0x68, 0x65, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, + 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x20, 0x61, 0x20, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x00, 0x01, 0x12, + 0x03, 0x09, 0x08, 0x17, 0x0a, 0x2c, 0x0a, 0x04, 0x04, 0x00, 0x03, 0x00, 0x12, 0x04, 0x0b, 0x02, + 0x0d, 0x03, 0x1a, 0x1e, 0x20, 0x56, 0x31, 0x20, 0x6f, 0x66, 0x20, 0x53, 0x65, 0x6e, 0x64, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x44, 0x61, 0x74, + 0x61, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x03, 0x00, 0x01, 0x12, 0x03, 0x0b, 0x0a, 0x0c, + 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x00, 0x03, 0x00, 0x02, 0x00, 0x12, 0x03, 0x0c, 0x04, 0x1c, 0x0a, + 0x0e, 0x0a, 0x07, 0x04, 0x00, 0x03, 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, 0x0c, 0x04, 0x09, 0x0a, + 0x0e, 0x0a, 0x07, 0x04, 0x00, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x0c, 0x0a, 0x17, 0x0a, + 0x0e, 0x0a, 0x07, 0x04, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x0c, 0x1a, 0x1b, 0x0a, + 0x0c, 0x0a, 0x04, 0x04, 0x00, 0x08, 0x00, 0x12, 0x04, 0x0f, 0x02, 0x11, 0x03, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x00, 0x08, 0x00, 0x01, 0x12, 0x03, 0x0f, 0x08, 0x0f, 0x0a, 0x0b, 0x0a, 0x04, 0x04, + 0x00, 0x02, 0x00, 0x12, 0x03, 0x10, 0x04, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, + 0x06, 0x12, 0x03, 0x10, 0x04, 0x06, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, + 0x03, 0x10, 0x07, 0x09, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x10, + 0x0c, 0x0d, 0x0a, 0x39, 0x0a, 0x02, 0x04, 0x01, 0x12, 0x04, 0x15, 0x00, 0x1e, 0x01, 0x1a, 0x2d, 0x20, 0x54, 0x68, 0x65, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, - 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x20, 0x6d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x20, 0x67, 0x72, 0x6f, 0x75, - 0x70, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x02, 0x01, 0x12, 0x03, 0x21, 0x08, 0x19, 0x0a, 0x2e, - 0x0a, 0x04, 0x04, 0x02, 0x03, 0x00, 0x12, 0x04, 0x23, 0x02, 0x25, 0x03, 0x1a, 0x20, 0x20, 0x56, - 0x31, 0x20, 0x6f, 0x66, 0x20, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, - 0x72, 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x44, 0x61, 0x74, 0x61, 0x0a, 0x0a, 0x0c, - 0x0a, 0x05, 0x04, 0x02, 0x03, 0x00, 0x01, 0x12, 0x03, 0x23, 0x0a, 0x0c, 0x0a, 0x0d, 0x0a, 0x06, - 0x04, 0x02, 0x03, 0x00, 0x02, 0x00, 0x12, 0x03, 0x24, 0x04, 0x28, 0x0a, 0x0e, 0x0a, 0x07, 0x04, - 0x02, 0x03, 0x00, 0x02, 0x00, 0x04, 0x12, 0x03, 0x24, 0x04, 0x0c, 0x0a, 0x0e, 0x0a, 0x07, 0x04, - 0x02, 0x03, 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, 0x24, 0x0d, 0x12, 0x0a, 0x0e, 0x0a, 0x07, 0x04, - 0x02, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x24, 0x13, 0x23, 0x0a, 0x0e, 0x0a, 0x07, 0x04, - 0x02, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x24, 0x26, 0x27, 0x0a, 0x0c, 0x0a, 0x04, 0x04, - 0x02, 0x08, 0x00, 0x12, 0x04, 0x27, 0x02, 0x29, 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x08, - 0x00, 0x01, 0x12, 0x03, 0x27, 0x08, 0x0f, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x02, 0x02, 0x00, 0x12, - 0x03, 0x28, 0x04, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x06, 0x12, 0x03, 0x28, - 0x04, 0x06, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x01, 0x12, 0x03, 0x28, 0x07, 0x09, - 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x03, 0x12, 0x03, 0x28, 0x0c, 0x0d, 0x0a, 0x3b, - 0x0a, 0x02, 0x04, 0x03, 0x12, 0x04, 0x2d, 0x00, 0x37, 0x01, 0x1a, 0x2f, 0x20, 0x47, 0x65, 0x6e, - 0x65, 0x72, 0x69, 0x63, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x20, 0x66, - 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x70, 0x6f, 0x73, 0x74, 0x2d, 0x63, 0x6f, 0x6d, 0x6d, - 0x69, 0x74, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, - 0x03, 0x01, 0x12, 0x03, 0x2d, 0x08, 0x18, 0x0a, 0x23, 0x0a, 0x04, 0x04, 0x03, 0x03, 0x00, 0x12, - 0x04, 0x2f, 0x02, 0x32, 0x03, 0x1a, 0x15, 0x20, 0x53, 0x65, 0x6e, 0x64, 0x57, 0x65, 0x6c, 0x63, - 0x6f, 0x6d, 0x65, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, - 0x04, 0x03, 0x03, 0x00, 0x01, 0x12, 0x03, 0x2f, 0x0a, 0x16, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x03, - 0x03, 0x00, 0x02, 0x00, 0x12, 0x03, 0x30, 0x04, 0x28, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x03, 0x03, - 0x00, 0x02, 0x00, 0x04, 0x12, 0x03, 0x30, 0x04, 0x0c, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x03, 0x03, - 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, 0x30, 0x0d, 0x12, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x03, 0x03, - 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x30, 0x13, 0x23, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x03, 0x03, - 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x30, 0x26, 0x27, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x03, 0x03, - 0x00, 0x02, 0x01, 0x12, 0x03, 0x31, 0x04, 0x1e, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x03, 0x03, 0x00, - 0x02, 0x01, 0x05, 0x12, 0x03, 0x31, 0x04, 0x09, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x03, 0x03, 0x00, - 0x02, 0x01, 0x01, 0x12, 0x03, 0x31, 0x0a, 0x19, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x03, 0x03, 0x00, - 0x02, 0x01, 0x03, 0x12, 0x03, 0x31, 0x1c, 0x1d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x03, 0x08, 0x00, - 0x12, 0x04, 0x34, 0x02, 0x36, 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x08, 0x00, 0x01, 0x12, - 0x03, 0x34, 0x08, 0x0c, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x03, 0x02, 0x00, 0x12, 0x03, 0x35, 0x04, - 0x23, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x06, 0x12, 0x03, 0x35, 0x04, 0x10, 0x0a, - 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x01, 0x12, 0x03, 0x35, 0x11, 0x1e, 0x0a, 0x0c, 0x0a, - 0x05, 0x04, 0x03, 0x02, 0x00, 0x03, 0x12, 0x03, 0x35, 0x21, 0x22, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x64, 0x64, 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x73, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x0a, 0x0a, 0x0a, 0x0a, + 0x03, 0x04, 0x01, 0x01, 0x12, 0x03, 0x15, 0x08, 0x16, 0x0a, 0x2b, 0x0a, 0x04, 0x04, 0x01, 0x03, + 0x00, 0x12, 0x04, 0x17, 0x02, 0x19, 0x03, 0x1a, 0x1d, 0x20, 0x56, 0x31, 0x20, 0x6f, 0x66, 0x20, + 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, + 0x68, 0x44, 0x61, 0x74, 0x61, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x03, 0x00, 0x01, 0x12, + 0x03, 0x17, 0x0a, 0x0c, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x01, 0x03, 0x00, 0x02, 0x00, 0x12, 0x03, + 0x18, 0x04, 0x2a, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x03, 0x00, 0x02, 0x00, 0x04, 0x12, 0x03, + 0x18, 0x04, 0x0c, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x03, 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, + 0x18, 0x0d, 0x13, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, + 0x18, 0x14, 0x25, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, + 0x18, 0x28, 0x29, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x01, 0x08, 0x00, 0x12, 0x04, 0x1b, 0x02, 0x1d, + 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x08, 0x00, 0x01, 0x12, 0x03, 0x1b, 0x08, 0x0f, 0x0a, + 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x00, 0x12, 0x03, 0x1c, 0x04, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, + 0x04, 0x01, 0x02, 0x00, 0x06, 0x12, 0x03, 0x1c, 0x04, 0x06, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, + 0x02, 0x00, 0x01, 0x12, 0x03, 0x1c, 0x07, 0x09, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, + 0x03, 0x12, 0x03, 0x1c, 0x0c, 0x0d, 0x0a, 0x3e, 0x0a, 0x02, 0x04, 0x02, 0x12, 0x04, 0x21, 0x00, + 0x2a, 0x01, 0x1a, 0x32, 0x20, 0x54, 0x68, 0x65, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x72, 0x65, + 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x20, + 0x67, 0x72, 0x6f, 0x75, 0x70, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x02, 0x01, 0x12, 0x03, 0x21, + 0x08, 0x19, 0x0a, 0x2e, 0x0a, 0x04, 0x04, 0x02, 0x03, 0x00, 0x12, 0x04, 0x23, 0x02, 0x25, 0x03, + 0x1a, 0x20, 0x20, 0x56, 0x31, 0x20, 0x6f, 0x66, 0x20, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, + 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x44, 0x61, 0x74, + 0x61, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x03, 0x00, 0x01, 0x12, 0x03, 0x23, 0x0a, 0x0c, + 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x02, 0x03, 0x00, 0x02, 0x00, 0x12, 0x03, 0x24, 0x04, 0x2a, 0x0a, + 0x0e, 0x0a, 0x07, 0x04, 0x02, 0x03, 0x00, 0x02, 0x00, 0x04, 0x12, 0x03, 0x24, 0x04, 0x0c, 0x0a, + 0x0e, 0x0a, 0x07, 0x04, 0x02, 0x03, 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, 0x24, 0x0d, 0x13, 0x0a, + 0x0e, 0x0a, 0x07, 0x04, 0x02, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x24, 0x14, 0x25, 0x0a, + 0x0e, 0x0a, 0x07, 0x04, 0x02, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x24, 0x28, 0x29, 0x0a, + 0x0c, 0x0a, 0x04, 0x04, 0x02, 0x08, 0x00, 0x12, 0x04, 0x27, 0x02, 0x29, 0x03, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x02, 0x08, 0x00, 0x01, 0x12, 0x03, 0x27, 0x08, 0x0f, 0x0a, 0x0b, 0x0a, 0x04, 0x04, + 0x02, 0x02, 0x00, 0x12, 0x03, 0x28, 0x04, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, + 0x06, 0x12, 0x03, 0x28, 0x04, 0x06, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x01, 0x12, + 0x03, 0x28, 0x07, 0x09, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x03, 0x12, 0x03, 0x28, + 0x0c, 0x0d, 0x0a, 0x3b, 0x0a, 0x02, 0x04, 0x03, 0x12, 0x04, 0x2d, 0x00, 0x37, 0x01, 0x1a, 0x2f, + 0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x74, 0x79, + 0x70, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x70, 0x6f, 0x73, 0x74, 0x2d, + 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x0a, 0x0a, + 0x0a, 0x0a, 0x03, 0x04, 0x03, 0x01, 0x12, 0x03, 0x2d, 0x08, 0x18, 0x0a, 0x23, 0x0a, 0x04, 0x04, + 0x03, 0x03, 0x00, 0x12, 0x04, 0x2f, 0x02, 0x32, 0x03, 0x1a, 0x15, 0x20, 0x53, 0x65, 0x6e, 0x64, + 0x57, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x0a, + 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x03, 0x00, 0x01, 0x12, 0x03, 0x2f, 0x0a, 0x16, 0x0a, 0x0d, + 0x0a, 0x06, 0x04, 0x03, 0x03, 0x00, 0x02, 0x00, 0x12, 0x03, 0x30, 0x04, 0x28, 0x0a, 0x0e, 0x0a, + 0x07, 0x04, 0x03, 0x03, 0x00, 0x02, 0x00, 0x04, 0x12, 0x03, 0x30, 0x04, 0x0c, 0x0a, 0x0e, 0x0a, + 0x07, 0x04, 0x03, 0x03, 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, 0x30, 0x0d, 0x12, 0x0a, 0x0e, 0x0a, + 0x07, 0x04, 0x03, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x30, 0x13, 0x23, 0x0a, 0x0e, 0x0a, + 0x07, 0x04, 0x03, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x30, 0x26, 0x27, 0x0a, 0x0d, 0x0a, + 0x06, 0x04, 0x03, 0x03, 0x00, 0x02, 0x01, 0x12, 0x03, 0x31, 0x04, 0x1e, 0x0a, 0x0e, 0x0a, 0x07, + 0x04, 0x03, 0x03, 0x00, 0x02, 0x01, 0x05, 0x12, 0x03, 0x31, 0x04, 0x09, 0x0a, 0x0e, 0x0a, 0x07, + 0x04, 0x03, 0x03, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x31, 0x0a, 0x19, 0x0a, 0x0e, 0x0a, 0x07, + 0x04, 0x03, 0x03, 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, 0x31, 0x1c, 0x1d, 0x0a, 0x0c, 0x0a, 0x04, + 0x04, 0x03, 0x08, 0x00, 0x12, 0x04, 0x34, 0x02, 0x36, 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, + 0x08, 0x00, 0x01, 0x12, 0x03, 0x34, 0x08, 0x0c, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x03, 0x02, 0x00, + 0x12, 0x03, 0x35, 0x04, 0x23, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x06, 0x12, 0x03, + 0x35, 0x04, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x01, 0x12, 0x03, 0x35, 0x11, + 0x1e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x03, 0x12, 0x03, 0x35, 0x21, 0x22, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, ]; include!("xmtp.mls.database.serde.rs"); // @@protoc_insertion_point(module) \ No newline at end of file diff --git a/xmtp_proto/src/gen/xmtp.mls.database.serde.rs b/xmtp_proto/src/gen/xmtp.mls.database.serde.rs index 424806a66..936c2727d 100644 --- a/xmtp_proto/src/gen/xmtp.mls.database.serde.rs +++ b/xmtp_proto/src/gen/xmtp.mls.database.serde.rs @@ -103,12 +103,12 @@ impl serde::Serialize for add_members_data::V1 { { use serde::ser::SerializeStruct; let mut len = 0; - if !self.wallet_addresses.is_empty() { + if !self.account_addresses.is_empty() { len += 1; } let mut struct_ser = serializer.serialize_struct("xmtp.mls.database.AddMembersData.V1", len)?; - if !self.wallet_addresses.is_empty() { - struct_ser.serialize_field("walletAddresses", &self.wallet_addresses.iter().map(pbjson::private::base64::encode).collect::>())?; + if !self.account_addresses.is_empty() { + struct_ser.serialize_field("accountAddresses", &self.account_addresses)?; } struct_ser.end() } @@ -120,13 +120,13 @@ impl<'de> serde::Deserialize<'de> for add_members_data::V1 { D: serde::Deserializer<'de>, { const FIELDS: &[&str] = &[ - "wallet_addresses", - "walletAddresses", + "account_addresses", + "accountAddresses", ]; #[allow(clippy::enum_variant_names)] enum GeneratedField { - WalletAddresses, + AccountAddresses, } impl<'de> serde::Deserialize<'de> for GeneratedField { fn deserialize(deserializer: D) -> std::result::Result @@ -148,7 +148,7 @@ impl<'de> serde::Deserialize<'de> for add_members_data::V1 { E: serde::de::Error, { match value { - "walletAddresses" | "wallet_addresses" => Ok(GeneratedField::WalletAddresses), + "accountAddresses" | "account_addresses" => Ok(GeneratedField::AccountAddresses), _ => Err(serde::de::Error::unknown_field(value, FIELDS)), } } @@ -168,22 +168,19 @@ impl<'de> serde::Deserialize<'de> for add_members_data::V1 { where V: serde::de::MapAccess<'de>, { - let mut wallet_addresses__ = None; + let mut account_addresses__ = None; while let Some(k) = map.next_key()? { match k { - GeneratedField::WalletAddresses => { - if wallet_addresses__.is_some() { - return Err(serde::de::Error::duplicate_field("walletAddresses")); + GeneratedField::AccountAddresses => { + if account_addresses__.is_some() { + return Err(serde::de::Error::duplicate_field("accountAddresses")); } - wallet_addresses__ = - Some(map.next_value::>>()? - .into_iter().map(|x| x.0).collect()) - ; + account_addresses__ = Some(map.next_value()?); } } } Ok(add_members_data::V1 { - wallet_addresses: wallet_addresses__.unwrap_or_default(), + account_addresses: account_addresses__.unwrap_or_default(), }) } } @@ -506,12 +503,12 @@ impl serde::Serialize for remove_members_data::V1 { { use serde::ser::SerializeStruct; let mut len = 0; - if !self.installation_ids.is_empty() { + if !self.account_addresses.is_empty() { len += 1; } let mut struct_ser = serializer.serialize_struct("xmtp.mls.database.RemoveMembersData.V1", len)?; - if !self.installation_ids.is_empty() { - struct_ser.serialize_field("installationIds", &self.installation_ids.iter().map(pbjson::private::base64::encode).collect::>())?; + if !self.account_addresses.is_empty() { + struct_ser.serialize_field("accountAddresses", &self.account_addresses)?; } struct_ser.end() } @@ -523,13 +520,13 @@ impl<'de> serde::Deserialize<'de> for remove_members_data::V1 { D: serde::Deserializer<'de>, { const FIELDS: &[&str] = &[ - "installation_ids", - "installationIds", + "account_addresses", + "accountAddresses", ]; #[allow(clippy::enum_variant_names)] enum GeneratedField { - InstallationIds, + AccountAddresses, } impl<'de> serde::Deserialize<'de> for GeneratedField { fn deserialize(deserializer: D) -> std::result::Result @@ -551,7 +548,7 @@ impl<'de> serde::Deserialize<'de> for remove_members_data::V1 { E: serde::de::Error, { match value { - "installationIds" | "installation_ids" => Ok(GeneratedField::InstallationIds), + "accountAddresses" | "account_addresses" => Ok(GeneratedField::AccountAddresses), _ => Err(serde::de::Error::unknown_field(value, FIELDS)), } } @@ -571,22 +568,19 @@ impl<'de> serde::Deserialize<'de> for remove_members_data::V1 { where V: serde::de::MapAccess<'de>, { - let mut installation_ids__ = None; + let mut account_addresses__ = None; while let Some(k) = map.next_key()? { match k { - GeneratedField::InstallationIds => { - if installation_ids__.is_some() { - return Err(serde::de::Error::duplicate_field("installationIds")); + GeneratedField::AccountAddresses => { + if account_addresses__.is_some() { + return Err(serde::de::Error::duplicate_field("accountAddresses")); } - installation_ids__ = - Some(map.next_value::>>()? - .into_iter().map(|x| x.0).collect()) - ; + account_addresses__ = Some(map.next_value()?); } } } Ok(remove_members_data::V1 { - installation_ids: installation_ids__.unwrap_or_default(), + account_addresses: account_addresses__.unwrap_or_default(), }) } } From aae87dde225cc4b58028d4e1b8fa4a8bd99dfa29 Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Wed, 6 Dec 2023 15:15:14 -0500 Subject: [PATCH 04/20] fixup the tests & other proto changes --- xmtp_cryptography/src/signature.rs | 28 ++++++++++++++++++++ xmtp_mls/src/codecs/membership_change.rs | 33 +----------------------- xmtp_mls/src/groups/intents.rs | 29 +++++---------------- xmtp_mls/src/groups/mod.rs | 14 ++++++++++ xmtp_mls/src/retry.rs | 2 +- 5 files changed, 50 insertions(+), 56 deletions(-) diff --git a/xmtp_cryptography/src/signature.rs b/xmtp_cryptography/src/signature.rs index 971e7a4ab..40bf589f0 100644 --- a/xmtp_cryptography/src/signature.rs +++ b/xmtp_cryptography/src/signature.rs @@ -111,8 +111,27 @@ pub fn h160addr_to_string(bytes: H160) -> String { s } +/// Check if an string is a valid ethereum address (valid hex and length 20). +pub fn is_valid_ethereum_address>(address: S) -> bool { + let address = address.as_ref(); + let address = address.strip_prefix(&"0x").unwrap_or(&address); + + if address.len() != 40 { + return false; + } + + for char in address.chars() { + if !char.is_digit(16) { + return false; + } + } + true +} + #[cfg(test)] pub mod tests { + use super::is_valid_ethereum_address; + use ethers::{ core::rand::thread_rng, signers::{LocalWallet, Signer}, @@ -174,4 +193,13 @@ pub mod tests { assert!(sig.verify_signature(addr_bad, msg).is_err()); assert!(sig.verify_signature(addr, msg_bad).is_err()); } + + #[test] + fn test_eth_address() { + assert_eq!( + is_valid_ethereum_address("0x7e57Aed10441c8879ce08E45805EC01Ee9689c9f"), + true + ); + assert_eq!(is_valid_ethereum_address("123"), false); + } } diff --git a/xmtp_mls/src/codecs/membership_change.rs b/xmtp_mls/src/codecs/membership_change.rs index a01e7c228..97733a553 100644 --- a/xmtp_mls/src/codecs/membership_change.rs +++ b/xmtp_mls/src/codecs/membership_change.rs @@ -47,35 +47,4 @@ impl ContentCodec for GroupMembershipChangeCodec { } #[cfg(test)] -mod tests { - // use xmtp_proto::xmtp::mls::message_contents::Member; - - use crate::utils::test::{rand_string, rand_vec}; - - use super::*; - /* TODO::INSIPX: FIX - #[test] - fn test_encode_decode() { - let new_member = Member { - installation_ids: vec![rand_vec()], - wallet_address: rand_string(), - }; - let data = GroupMembershipChanges { - members_added: vec![new_member.clone()], - members_removed: vec![], - installations_added: vec![], - installations_removed: vec![], - }; - - let encoded = GroupMembershipChangeCodec::encode(data).unwrap(); - assert_eq!( - encoded.clone().r#type.unwrap().type_id, - "group_membership_change" - ); - assert!(!encoded.content.is_empty()); - - let decoded = GroupMembershipChangeCodec::decode(encoded).unwrap(); - assert_eq!(decoded.members_added[0], new_member); - } - */ -} +mod tests {} diff --git a/xmtp_mls/src/groups/intents.rs b/xmtp_mls/src/groups/intents.rs index 5e6dc1b80..f43270d95 100644 --- a/xmtp_mls/src/groups/intents.rs +++ b/xmtp_mls/src/groups/intents.rs @@ -224,7 +224,7 @@ mod tests { use xmtp_cryptography::utils::generate_local_wallet; use super::*; - use crate::{builder::ClientBuilder, verified_key_package::VerifiedKeyPackage, InboxOwner}; + use crate::{builder::ClientBuilder, InboxOwner}; #[test] fn test_serialize_send_message() { @@ -236,32 +236,15 @@ mod tests { assert_eq!(restored_intent.message, message); } - /* TODO:INSIPX: FINISH #[tokio::test] async fn test_serialize_add_members() { let wallet = generate_local_wallet(); let wallet_address = wallet.get_address(); - let client = ClientBuilder::new_test_client(wallet.into()).await; - let conn = client.store.conn().unwrap(); - let key_package = client - .identity - .new_key_package(&client.mls_provider(&conn)) - .unwrap(); - let verified_key_package = VerifiedKeyPackage::new(key_package, wallet_address.clone()); - - let intent = AddMembersIntentData::new(vec![verified_key_package.clone()]); + + let intent = AddMembersIntentData::new(vec![wallet_address.clone()]); let as_bytes: Vec = intent.clone().try_into().unwrap(); - let restored_intent = - AddMembersIntentData::from_bytes(as_bytes.as_slice(), &client.mls_provider(&conn)) - .unwrap(); - - assert!(intent.key_packages[0] - .inner - .eq(&restored_intent.key_packages[0].inner)); - assert_eq!( - intent.key_packages[0].wallet_address, - restored_intent.key_packages[0].wallet_address - ); + let restored_intent = AddMembersIntentData::from_bytes(as_bytes.as_slice()).unwrap(); + + assert!(intent.account_addresses[0].eq(&restored_intent.account_addresses[0])); } - */ } diff --git a/xmtp_mls/src/groups/mod.rs b/xmtp_mls/src/groups/mod.rs index 03983bc89..2010a112e 100644 --- a/xmtp_mls/src/groups/mod.rs +++ b/xmtp_mls/src/groups/mod.rs @@ -16,6 +16,7 @@ use openmls_traits::OpenMlsProvider; use std::mem::discriminant; use thiserror::Error; use tls_codec::{Deserialize, Serialize}; +use xmtp_cryptography::signature::is_valid_ethereum_address; use xmtp_proto::api_client::{Envelope, XmtpApiClient, XmtpMlsClient}; pub use self::intents::IntentError; @@ -74,6 +75,8 @@ pub enum GroupError { Generic(String), #[error("diesel error {0}")] Diesel(#[from] diesel::result::Error), + #[error("The address {0:?} is not a valid ethereum address")] + InvalidAddresses(Vec), } impl RetryableError for GroupError { @@ -425,6 +428,16 @@ where } pub async fn add_members(&self, wallet_addresses: Vec) -> Result<(), GroupError> { + let mut invalid = wallet_addresses + .iter() + .filter(|a| !is_valid_ethereum_address(a)) + .peekable(); + if invalid.peek().is_some() { + return Err(GroupError::InvalidAddresses( + invalid.map(Clone::clone).collect::>(), + )); + } + let conn = &mut self.client.store.conn()?; let intent_data: Vec = AddMembersIntentData::new(wallet_addresses).try_into()?; let intent = @@ -810,6 +823,7 @@ mod tests { #[tokio::test] async fn test_add_invalid_member() { + crate::tests::setup(); let client = ClientBuilder::new_test_client(generate_local_wallet().into()).await; let group = client.create_group().expect("create group"); diff --git a/xmtp_mls/src/retry.rs b/xmtp_mls/src/retry.rs index 667a6fc9c..cd0837c41 100644 --- a/xmtp_mls/src/retry.rs +++ b/xmtp_mls/src/retry.rs @@ -213,7 +213,7 @@ macro_rules! retry { /// for i in 0..3 { /// tx.send(i).unwrap(); /// } -/// retry_async!(Retry::default(), (|| async { +/// retry_async!(Retry::default(), (async { /// fallable_fn(&rx.clone()).await /// })) /// } From 187eda902e7a49e6ca0d87573cb31d24597d8674 Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Wed, 6 Dec 2023 15:21:49 -0500 Subject: [PATCH 05/20] revert gen_protos --- dev/gen_protos.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/gen_protos.sh b/dev/gen_protos.sh index d15fe88ff..dfc61150f 100755 --- a/dev/gen_protos.sh +++ b/dev/gen_protos.sh @@ -5,7 +5,7 @@ if ! cargo install --list | grep "protoc-gen-prost-crate" > /dev/null; then exit 1 fi fi -if ! buf generate https://github.com/xmtp/proto.git#branch=insipx/remove-add-wallet-addresses,subdir=proto; then +if ! buf generate https://github.com/xmtp/proto.git#branch=nmolnar/mls-verification-service,subdir=proto; then echo "Failed to generate protobuf definitions" exit 1 fi From 49ff22fc9c822c26d1fe139f354c483a85fb4f21 Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Wed, 6 Dec 2023 20:13:05 -0500 Subject: [PATCH 06/20] remove manual setup calls, use ctor to run before test setup --- Cargo.lock | 11 +++++++++++ xmtp_mls/Cargo.toml | 1 + xmtp_mls/src/api_client_wrapper.rs | 2 -- xmtp_mls/src/groups/mod.rs | 3 --- xmtp_mls/src/lib.rs | 4 +++- xmtp_mls/src/retry.rs | 12 ------------ xmtp_mls/src/storage/encrypted_store/mod.rs | 1 - 7 files changed, 15 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a354030e7..152e0102c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -947,6 +947,16 @@ dependencies = [ "typenum", ] +[[package]] +name = "ctor" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37e366bff8cd32dd8754b0991fb66b279dc48f598c3a18914852a6673deef583" +dependencies = [ + "quote", + "syn 2.0.39", +] + [[package]] name = "ctr" version = "0.9.2" @@ -6581,6 +6591,7 @@ version = "0.1.0" dependencies = [ "anyhow", "async-trait", + "ctor", "diesel", "diesel_migrations", "ethers", diff --git a/xmtp_mls/Cargo.toml b/xmtp_mls/Cargo.toml index ff70743b4..f4407d8d4 100644 --- a/xmtp_mls/Cargo.toml +++ b/xmtp_mls/Cargo.toml @@ -57,3 +57,4 @@ tempfile = "3.5.0" tracing-subscriber = { version = "0.3.17", features = ["env-filter"] } xmtp_api_grpc = { path = "../xmtp_api_grpc" } flume = "0.11" +ctor = "0.2" diff --git a/xmtp_mls/src/api_client_wrapper.rs b/xmtp_mls/src/api_client_wrapper.rs index f5795278f..0194d0da0 100644 --- a/xmtp_mls/src/api_client_wrapper.rs +++ b/xmtp_mls/src/api_client_wrapper.rs @@ -650,8 +650,6 @@ mod tests { #[tokio::test] async fn it_retries_twice_then_succeeds() { - crate::tests::setup(); - let mut mock_api = MockApiClient::new(); let topic = "topic"; let start_time_ns = 10; diff --git a/xmtp_mls/src/groups/mod.rs b/xmtp_mls/src/groups/mod.rs index 2010a112e..4164ff94b 100644 --- a/xmtp_mls/src/groups/mod.rs +++ b/xmtp_mls/src/groups/mod.rs @@ -798,8 +798,6 @@ mod tests { #[tokio::test] async fn test_add_members() { - crate::tests::setup(); - let client = ClientBuilder::new_test_client(generate_local_wallet().into()).await; let client_2 = ClientBuilder::new_test_client(generate_local_wallet().into()).await; client_2.register_identity().await.unwrap(); @@ -823,7 +821,6 @@ mod tests { #[tokio::test] async fn test_add_invalid_member() { - crate::tests::setup(); let client = ClientBuilder::new_test_client(generate_local_wallet().into()).await; let group = client.create_group().expect("create group"); diff --git a/xmtp_mls/src/lib.rs b/xmtp_mls/src/lib.rs index 910c0b31d..a82cb7b69 100644 --- a/xmtp_mls/src/lib.rs +++ b/xmtp_mls/src/lib.rs @@ -43,10 +43,12 @@ pub trait Delete { #[cfg(test)] mod tests { use std::sync::Once; + static INIT: Once = Once::new(); /// Setup for tests - pub fn setup() { + #[ctor::ctor] + fn setup() { INIT.call_once(|| { tracing_subscriber::fmt::init(); }) diff --git a/xmtp_mls/src/retry.rs b/xmtp_mls/src/retry.rs index cd0837c41..8abf02c5a 100644 --- a/xmtp_mls/src/retry.rs +++ b/xmtp_mls/src/retry.rs @@ -292,8 +292,6 @@ mod tests { #[test] fn it_retries_twice_and_succeeds() { - crate::tests::setup(); - let mut i = 0; let mut test_fn = || -> Result<(), SomeError> { if i == 2 { @@ -309,8 +307,6 @@ mod tests { #[test] fn it_works_with_random_args() { - crate::tests::setup(); - let mut i = 0; let list = vec!["String".into(), "Foo".into()]; let mut test_fn = || -> Result<(), SomeError> { @@ -326,8 +322,6 @@ mod tests { #[test] fn it_fails_on_three_retries() { - crate::tests::setup(); - let result: Result<(), SomeError> = retry!( Retry::default(), (|| -> Result<(), SomeError> { @@ -341,8 +335,6 @@ mod tests { #[test] fn it_only_runs_non_retryable_once() { - crate::tests::setup(); - let mut attempts = 0; let mut test_fn = || -> Result<(), SomeError> { attempts += 1; @@ -356,8 +348,6 @@ mod tests { #[tokio::test] async fn it_works_async() { - crate::tests::setup(); - async fn retryable_async_fn(rx: &flume::Receiver) -> Result<(), SomeError> { let val = rx.recv_async().await.unwrap(); if val == 2 { @@ -383,8 +373,6 @@ mod tests { #[tokio::test] async fn it_works_async_mut() { - crate::tests::setup(); - async fn retryable_async_fn(data: &mut usize) -> Result<(), SomeError> { if *data == 2 { return Ok(()); diff --git a/xmtp_mls/src/storage/encrypted_store/mod.rs b/xmtp_mls/src/storage/encrypted_store/mod.rs index fff68c864..8b68d2e84 100644 --- a/xmtp_mls/src/storage/encrypted_store/mod.rs +++ b/xmtp_mls/src/storage/encrypted_store/mod.rs @@ -279,7 +279,6 @@ mod tests { where F: FnOnce(&DbConnection) -> R, { - crate::tests::setup(); let store = EncryptedMessageStore::new( StorageOption::Ephemeral, EncryptedMessageStore::generate_enc_key(), From a028e9a8033a1bb071982dd9315ef409944c9e78 Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Thu, 7 Dec 2023 10:03:10 -0500 Subject: [PATCH 07/20] self by ref --- xmtp_cryptography/src/signature.rs | 4 ++-- xmtp_mls/src/groups/intents.rs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/xmtp_cryptography/src/signature.rs b/xmtp_cryptography/src/signature.rs index 40bf589f0..6011d4517 100644 --- a/xmtp_cryptography/src/signature.rs +++ b/xmtp_cryptography/src/signature.rs @@ -114,14 +114,14 @@ pub fn h160addr_to_string(bytes: H160) -> String { /// Check if an string is a valid ethereum address (valid hex and length 20). pub fn is_valid_ethereum_address>(address: S) -> bool { let address = address.as_ref(); - let address = address.strip_prefix(&"0x").unwrap_or(&address); + let address = address.strip_prefix("0x").unwrap_or(address); if address.len() != 40 { return false; } for char in address.chars() { - if !char.is_digit(16) { + if !char.is_ascii_hexdigit() { return false; } } diff --git a/xmtp_mls/src/groups/intents.rs b/xmtp_mls/src/groups/intents.rs index f43270d95..5e634b99d 100644 --- a/xmtp_mls/src/groups/intents.rs +++ b/xmtp_mls/src/groups/intents.rs @@ -74,11 +74,11 @@ impl AddMembersIntentData { Self { account_addresses } } - pub(crate) fn to_bytes(self) -> Result, IntentError> { + pub(crate) fn to_bytes(&self) -> Result, IntentError> { let mut buf = Vec::new(); AddMembersData { version: Some(AddMembersVersion::V1(AddMembersV1 { - account_addresses: self.account_addresses, + account_addresses: self.account_addresses.clone(), })), } .encode(&mut buf) @@ -116,12 +116,12 @@ impl RemoveMembersIntentData { Self { account_addresses } } - pub(crate) fn to_bytes(self) -> Vec { + pub(crate) fn to_bytes(&self) -> Vec { let mut buf = Vec::new(); RemoveMembersData { version: Some(RemoveMembersVersion::V1(RemoveMembersV1 { - account_addresses: self.account_addresses, + account_addresses: self.account_addresses.clone(), })), } .encode(&mut buf) From 5d8f4649c35cd889465b262bbf53841ff26678ed Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Thu, 7 Dec 2023 10:05:37 -0500 Subject: [PATCH 08/20] use iterator --- xmtp_cryptography/src/signature.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/xmtp_cryptography/src/signature.rs b/xmtp_cryptography/src/signature.rs index 6011d4517..27bbd4ef6 100644 --- a/xmtp_cryptography/src/signature.rs +++ b/xmtp_cryptography/src/signature.rs @@ -120,12 +120,7 @@ pub fn is_valid_ethereum_address>(address: S) -> bool { return false; } - for char in address.chars() { - if !char.is_ascii_hexdigit() { - return false; - } - } - true + address.chars().all(|c| c.is_ascii_hexdigit()) } #[cfg(test)] From 95cdaa82f939c09055507c6fc11b50d51eb9af48 Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Thu, 7 Dec 2023 12:53:46 -0500 Subject: [PATCH 09/20] add new protobufs format --- Cargo.lock | 4 +- dev/gen_protos.sh | 2 +- xmtp_mls/src/groups/intents.rs | 84 +++- xmtp_proto/src/gen/xmtp.mls.database.rs | 396 +++++++++++------- xmtp_proto/src/gen/xmtp.mls.database.serde.rs | 348 +++++++++++++-- 5 files changed, 641 insertions(+), 193 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 152e0102c..bdb63fb22 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6688,9 +6688,9 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" dependencies = [ "zeroize_derive", ] diff --git a/dev/gen_protos.sh b/dev/gen_protos.sh index dfc61150f..d15fe88ff 100755 --- a/dev/gen_protos.sh +++ b/dev/gen_protos.sh @@ -5,7 +5,7 @@ if ! cargo install --list | grep "protoc-gen-prost-crate" > /dev/null; then exit 1 fi fi -if ! buf generate https://github.com/xmtp/proto.git#branch=nmolnar/mls-verification-service,subdir=proto; then +if ! buf generate https://github.com/xmtp/proto.git#branch=insipx/remove-add-wallet-addresses,subdir=proto; then echo "Failed to generate protobuf definitions" exit 1 fi diff --git a/xmtp_mls/src/groups/intents.rs b/xmtp_mls/src/groups/intents.rs index 5e634b99d..70de29ada 100644 --- a/xmtp_mls/src/groups/intents.rs +++ b/xmtp_mls/src/groups/intents.rs @@ -4,10 +4,13 @@ use thiserror::Error; use tls_codec::Serialize; use xmtp_proto::xmtp::mls::database::{ add_members_data::{Version as AddMembersVersion, V1 as AddMembersV1}, + address_or_installation_id::AddressOrInstallationId as AddressOrInstallationIdProto, post_commit_action::{Kind as PostCommitActionKind, SendWelcomes as SendWelcomesProto}, remove_members_data::{Version as RemoveMembersVersion, V1 as RemoveMembersV1}, send_message_data::{Version as SendMessageVersion, V1 as SendMessageV1}, - AddMembersData, PostCommitAction as PostCommitActionProto, RemoveMembersData, SendMessageData, + AccountAddresses, AddMembersData, + AddressOrInstallationId as AddressOrInstallationIdProtoWrapper, InstallationIds, + PostCommitAction as PostCommitActionProto, RemoveMembersData, SendMessageData, }; use crate::{types::Address, verified_key_package::KeyPackageVerificationError}; @@ -64,21 +67,68 @@ impl From for Vec { } } +#[derive(Debug, PartialEq, Eq, Clone)] +pub enum AddressOrInstallationId { + AccountAddresses(Vec), + InstallationIds(Vec>), +} + +impl From for AddressOrInstallationIdProtoWrapper { + fn from(address_or_id: AddressOrInstallationId) -> Self { + match address_or_id { + AddressOrInstallationId::AccountAddresses(account_addresses) => { + AddressOrInstallationIdProtoWrapper { + address_or_installation_id: Some( + AddressOrInstallationIdProto::AccountAddresses(AccountAddresses { + account_addresses, + }), + ), + } + } + AddressOrInstallationId::InstallationIds(installation_ids) => { + AddressOrInstallationIdProtoWrapper { + address_or_installation_id: Some( + AddressOrInstallationIdProto::InstallationIds(InstallationIds { + installation_ids, + }), + ), + } + } + } + } +} + +impl TryFrom for AddressOrInstallationId { + type Error = IntentError; + + fn try_from(wrapper: AddressOrInstallationIdProtoWrapper) -> Result { + match wrapper.address_or_installation_id { + Some(AddressOrInstallationIdProto::AccountAddresses(addrs)) => Ok( + AddressOrInstallationId::AccountAddresses(addrs.account_addresses), + ), + Some(AddressOrInstallationIdProto::InstallationIds(ids)) => Ok( + AddressOrInstallationId::InstallationIds(ids.installation_ids), + ), + _ => Err(IntentError::Generic("missing payload".to_string())), + } + } +} + #[derive(Debug, Clone)] pub struct AddMembersIntentData { - pub account_addresses: Vec
, + pub address_or_id: AddressOrInstallationId, } impl AddMembersIntentData { - pub fn new(account_addresses: Vec
) -> Self { - Self { account_addresses } + pub fn new(address_or_id: AddressOrInstallationId) -> Self { + Self { address_or_id } } pub(crate) fn to_bytes(&self) -> Result, IntentError> { let mut buf = Vec::new(); AddMembersData { version: Some(AddMembersVersion::V1(AddMembersV1 { - account_addresses: self.account_addresses.clone(), + address_or_installation_id: Some(self.address_or_id.into()), })), } .encode(&mut buf) @@ -89,12 +139,14 @@ impl AddMembersIntentData { pub(crate) fn from_bytes(data: &[u8]) -> Result { let msg = AddMembersData::decode(data)?; - let addresses = match msg.version { - Some(AddMembersVersion::V1(v1)) => v1.account_addresses, + let address_or_id = match msg.version { + Some(AddMembersVersion::V1(v1)) => v1 + .address_or_installation_id + .ok_or(IntentError::Generic("missing payload".to_string()))?, None => return Err(IntentError::Generic("missing payload".to_string())), }; - Ok(Self::new(addresses)) + Ok(Self::new(address_or_id.try_into()?)) } } @@ -108,12 +160,12 @@ impl TryFrom for Vec { #[derive(Debug, Clone)] pub struct RemoveMembersIntentData { - pub account_addresses: Vec, + pub address_or_id: AddressOrInstallationId, } impl RemoveMembersIntentData { - pub fn new(account_addresses: Vec) -> Self { - Self { account_addresses } + pub fn new(address_or_id: AddressOrInstallationId) -> Self { + Self { address_or_id } } pub(crate) fn to_bytes(&self) -> Vec { @@ -121,7 +173,7 @@ impl RemoveMembersIntentData { RemoveMembersData { version: Some(RemoveMembersVersion::V1(RemoveMembersV1 { - account_addresses: self.account_addresses.clone(), + address_or_installation_id: Some(self.address_or_id.into()), })), } .encode(&mut buf) @@ -132,12 +184,14 @@ impl RemoveMembersIntentData { pub(crate) fn from_bytes(data: &[u8]) -> Result { let msg = RemoveMembersData::decode(data)?; - let account_addresses = match msg.version { - Some(RemoveMembersVersion::V1(v1)) => v1.account_addresses, + let address_or_id = match msg.version { + Some(RemoveMembersVersion::V1(v1)) => v1 + .address_or_installation_id + .ok_or(IntentError::Generic("missing payload".to_string()))?, None => return Err(IntentError::Generic("missing payload".to_string())), }; - Ok(Self::new(account_addresses)) + Ok(Self::new(address_or_id.try_into()?)) } } diff --git a/xmtp_proto/src/gen/xmtp.mls.database.rs b/xmtp_proto/src/gen/xmtp.mls.database.rs index 212fc2fed..0fae63011 100644 --- a/xmtp_proto/src/gen/xmtp.mls.database.rs +++ b/xmtp_proto/src/gen/xmtp.mls.database.rs @@ -3,45 +3,81 @@ #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SendMessageData { - #[prost(oneof="send_message_data::Version", tags="1")] + #[prost(oneof = "send_message_data::Version", tags = "1")] pub version: ::core::option::Option, } /// Nested message and enum types in `SendMessageData`. pub mod send_message_data { /// V1 of SendMessagePublishData #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] + #[derive(Clone, PartialEq, ::prost::Message)] pub struct V1 { - #[prost(bytes="vec", tag="1")] + #[prost(bytes = "vec", tag = "1")] pub payload_bytes: ::prost::alloc::vec::Vec, } #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Oneof)] + #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Version { - #[prost(message, tag="1")] + #[prost(message, tag = "1")] V1(V1), } } +/// Wrapper around a list af repeated EVM Account Addresses +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct AccountAddresses { + #[prost(string, repeated, tag = "1")] + pub account_addresses: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, +} +/// Wrapper around a list of repeated Installation IDs +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct InstallationIds { + #[prost(bytes = "vec", repeated, tag = "1")] + pub installation_ids: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, +} +/// One of an EVM account address or Installation ID +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct AddressOrInstallationId { + #[prost( + oneof = "address_or_installation_id::AddressOrInstallationId", + tags = "1, 2" + )] + pub address_or_installation_id: + ::core::option::Option, +} +/// Nested message and enum types in `AddressOrInstallationId`. +pub mod address_or_installation_id { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum AddressOrInstallationId { + #[prost(message, tag = "1")] + AccountAddresses(super::AccountAddresses), + #[prost(message, tag = "2")] + InstallationIds(super::InstallationIds), + } +} /// The data required to add members to a group #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct AddMembersData { - #[prost(oneof="add_members_data::Version", tags="1")] + #[prost(oneof = "add_members_data::Version", tags = "1")] pub version: ::core::option::Option, } /// Nested message and enum types in `AddMembersData`. pub mod add_members_data { /// V1 of AddMembersPublishData #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] + #[derive(Clone, PartialEq, ::prost::Message)] pub struct V1 { - #[prost(string, repeated, tag="1")] - pub account_addresses: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(message, optional, tag = "1")] + pub address_or_installation_id: ::core::option::Option, } #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Oneof)] + #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Version { - #[prost(message, tag="1")] + #[prost(message, tag = "1")] V1(V1), } } @@ -49,22 +85,22 @@ pub mod add_members_data { #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct RemoveMembersData { - #[prost(oneof="remove_members_data::Version", tags="1")] + #[prost(oneof = "remove_members_data::Version", tags = "1")] pub version: ::core::option::Option, } /// Nested message and enum types in `RemoveMembersData`. pub mod remove_members_data { /// V1 of RemoveMembersPublishData #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] + #[derive(Clone, PartialEq, ::prost::Message)] pub struct V1 { - #[prost(string, repeated, tag="1")] - pub account_addresses: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(message, optional, tag = "1")] + pub address_or_installation_id: ::core::option::Option, } #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Oneof)] + #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Version { - #[prost(message, tag="1")] + #[prost(message, tag = "1")] V1(V1), } } @@ -72,30 +108,30 @@ pub mod remove_members_data { #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct PostCommitAction { - #[prost(oneof="post_commit_action::Kind", tags="1")] + #[prost(oneof = "post_commit_action::Kind", tags = "1")] pub kind: ::core::option::Option, } /// Nested message and enum types in `PostCommitAction`. pub mod post_commit_action { /// SendWelcome message #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] + #[derive(Clone, PartialEq, ::prost::Message)] pub struct SendWelcomes { - #[prost(bytes="vec", repeated, tag="1")] + #[prost(bytes = "vec", repeated, tag = "1")] pub installation_ids: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, - #[prost(bytes="vec", tag="2")] + #[prost(bytes = "vec", tag = "2")] pub welcome_message: ::prost::alloc::vec::Vec, } #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Oneof)] + #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Kind { - #[prost(message, tag="1")] + #[prost(message, tag = "1")] SendWelcomes(SendWelcomes), } } /// Encoded file descriptor set for the `xmtp.mls.database` package pub const FILE_DESCRIPTOR_SET: &[u8] = &[ - 0x0a, 0xf4, 0x10, 0x0a, 0x1a, 0x6d, 0x6c, 0x73, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, + 0x0a, 0xab, 0x18, 0x0a, 0x1a, 0x6d, 0x6c, 0x73, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x11, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x22, 0x80, 0x01, 0x0a, 0x0f, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, @@ -106,131 +142,191 @@ pub const FILE_DESCRIPTOR_SET: &[u8] = &[ 0x29, 0x0a, 0x02, 0x56, 0x31, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x42, 0x09, 0x0a, 0x07, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x86, 0x01, 0x0a, 0x0e, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x73, 0x44, 0x61, 0x74, 0x61, 0x12, 0x36, 0x0a, 0x02, 0x76, 0x31, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, - 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, - 0x65, 0x72, 0x73, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x31, 0x48, 0x00, 0x52, 0x02, 0x76, 0x31, - 0x1a, 0x31, 0x0a, 0x02, 0x56, 0x31, 0x12, 0x2b, 0x0a, 0x11, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x10, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x65, 0x73, 0x42, 0x09, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x8c, - 0x01, 0x0a, 0x11, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, - 0x44, 0x61, 0x74, 0x61, 0x12, 0x39, 0x0a, 0x02, 0x76, 0x31, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x27, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, 0x61, 0x74, 0x61, - 0x62, 0x61, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, - 0x72, 0x73, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x31, 0x48, 0x00, 0x52, 0x02, 0x76, 0x31, 0x1a, - 0x31, 0x0a, 0x02, 0x56, 0x31, 0x12, 0x2b, 0x0a, 0x11, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x10, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x65, 0x73, 0x42, 0x09, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xd7, 0x01, - 0x0a, 0x10, 0x50, 0x6f, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x41, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x57, 0x0a, 0x0d, 0x73, 0x65, 0x6e, 0x64, 0x5f, 0x77, 0x65, 0x6c, 0x63, 0x6f, - 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x78, 0x6d, 0x74, 0x70, - 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x50, 0x6f, - 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x53, - 0x65, 0x6e, 0x64, 0x57, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x73, 0x48, 0x00, 0x52, 0x0c, 0x73, - 0x65, 0x6e, 0x64, 0x57, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x73, 0x1a, 0x62, 0x0a, 0x0c, 0x53, - 0x65, 0x6e, 0x64, 0x57, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x69, - 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x77, 0x65, 0x6c, 0x63, 0x6f, 0x6d, - 0x65, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x0e, 0x77, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, - 0x06, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x42, 0xb5, 0x01, 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e, - 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, - 0x65, 0x42, 0x0c, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, - 0x01, 0x5a, 0x28, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x6d, - 0x74, 0x70, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x33, 0x2f, 0x67, 0x6f, 0x2f, 0x6d, - 0x6c, 0x73, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0xa2, 0x02, 0x03, 0x58, 0x4d, - 0x44, 0xaa, 0x02, 0x11, 0x58, 0x6d, 0x74, 0x70, 0x2e, 0x4d, 0x6c, 0x73, 0x2e, 0x44, 0x61, 0x74, - 0x61, 0x62, 0x61, 0x73, 0x65, 0xca, 0x02, 0x11, 0x58, 0x6d, 0x74, 0x70, 0x5c, 0x4d, 0x6c, 0x73, - 0x5c, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0xe2, 0x02, 0x1d, 0x58, 0x6d, 0x74, 0x70, - 0x5c, 0x4d, 0x6c, 0x73, 0x5c, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5c, 0x47, 0x50, - 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13, 0x58, 0x6d, 0x74, 0x70, - 0x3a, 0x3a, 0x4d, 0x6c, 0x73, 0x3a, 0x3a, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x4a, - 0x8d, 0x0a, 0x0a, 0x06, 0x12, 0x04, 0x01, 0x00, 0x37, 0x01, 0x0a, 0x27, 0x0a, 0x01, 0x0c, 0x12, - 0x03, 0x01, 0x00, 0x12, 0x1a, 0x1d, 0x20, 0x56, 0x33, 0x20, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, - 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, - 0x72, 0x65, 0x0a, 0x0a, 0x08, 0x0a, 0x01, 0x02, 0x12, 0x03, 0x03, 0x00, 0x1a, 0x0a, 0x08, 0x0a, - 0x01, 0x08, 0x12, 0x03, 0x05, 0x00, 0x3f, 0x0a, 0x09, 0x0a, 0x02, 0x08, 0x0b, 0x12, 0x03, 0x05, - 0x00, 0x3f, 0x0a, 0x34, 0x0a, 0x02, 0x04, 0x00, 0x12, 0x04, 0x09, 0x00, 0x12, 0x01, 0x1a, 0x28, - 0x20, 0x54, 0x68, 0x65, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, - 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x20, 0x61, 0x20, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x00, 0x01, 0x12, - 0x03, 0x09, 0x08, 0x17, 0x0a, 0x2c, 0x0a, 0x04, 0x04, 0x00, 0x03, 0x00, 0x12, 0x04, 0x0b, 0x02, - 0x0d, 0x03, 0x1a, 0x1e, 0x20, 0x56, 0x31, 0x20, 0x6f, 0x66, 0x20, 0x53, 0x65, 0x6e, 0x64, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x44, 0x61, 0x74, - 0x61, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x03, 0x00, 0x01, 0x12, 0x03, 0x0b, 0x0a, 0x0c, - 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x00, 0x03, 0x00, 0x02, 0x00, 0x12, 0x03, 0x0c, 0x04, 0x1c, 0x0a, - 0x0e, 0x0a, 0x07, 0x04, 0x00, 0x03, 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, 0x0c, 0x04, 0x09, 0x0a, - 0x0e, 0x0a, 0x07, 0x04, 0x00, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x0c, 0x0a, 0x17, 0x0a, - 0x0e, 0x0a, 0x07, 0x04, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x0c, 0x1a, 0x1b, 0x0a, - 0x0c, 0x0a, 0x04, 0x04, 0x00, 0x08, 0x00, 0x12, 0x04, 0x0f, 0x02, 0x11, 0x03, 0x0a, 0x0c, 0x0a, - 0x05, 0x04, 0x00, 0x08, 0x00, 0x01, 0x12, 0x03, 0x0f, 0x08, 0x0f, 0x0a, 0x0b, 0x0a, 0x04, 0x04, - 0x00, 0x02, 0x00, 0x12, 0x03, 0x10, 0x04, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, - 0x06, 0x12, 0x03, 0x10, 0x04, 0x06, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, - 0x03, 0x10, 0x07, 0x09, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x10, - 0x0c, 0x0d, 0x0a, 0x39, 0x0a, 0x02, 0x04, 0x01, 0x12, 0x04, 0x15, 0x00, 0x1e, 0x01, 0x1a, 0x2d, - 0x20, 0x54, 0x68, 0x65, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, - 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x64, 0x64, 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x73, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x0a, 0x0a, 0x0a, 0x0a, - 0x03, 0x04, 0x01, 0x01, 0x12, 0x03, 0x15, 0x08, 0x16, 0x0a, 0x2b, 0x0a, 0x04, 0x04, 0x01, 0x03, - 0x00, 0x12, 0x04, 0x17, 0x02, 0x19, 0x03, 0x1a, 0x1d, 0x20, 0x56, 0x31, 0x20, 0x6f, 0x66, 0x20, - 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, - 0x68, 0x44, 0x61, 0x74, 0x61, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x03, 0x00, 0x01, 0x12, - 0x03, 0x17, 0x0a, 0x0c, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x01, 0x03, 0x00, 0x02, 0x00, 0x12, 0x03, - 0x18, 0x04, 0x2a, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x03, 0x00, 0x02, 0x00, 0x04, 0x12, 0x03, - 0x18, 0x04, 0x0c, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x03, 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, - 0x18, 0x0d, 0x13, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, - 0x18, 0x14, 0x25, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x01, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, - 0x18, 0x28, 0x29, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x01, 0x08, 0x00, 0x12, 0x04, 0x1b, 0x02, 0x1d, - 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x08, 0x00, 0x01, 0x12, 0x03, 0x1b, 0x08, 0x0f, 0x0a, - 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x00, 0x12, 0x03, 0x1c, 0x04, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, - 0x04, 0x01, 0x02, 0x00, 0x06, 0x12, 0x03, 0x1c, 0x04, 0x06, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, - 0x02, 0x00, 0x01, 0x12, 0x03, 0x1c, 0x07, 0x09, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, - 0x03, 0x12, 0x03, 0x1c, 0x0c, 0x0d, 0x0a, 0x3e, 0x0a, 0x02, 0x04, 0x02, 0x12, 0x04, 0x21, 0x00, - 0x2a, 0x01, 0x1a, 0x32, 0x20, 0x54, 0x68, 0x65, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x72, 0x65, - 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, - 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x20, - 0x67, 0x72, 0x6f, 0x75, 0x70, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x02, 0x01, 0x12, 0x03, 0x21, - 0x08, 0x19, 0x0a, 0x2e, 0x0a, 0x04, 0x04, 0x02, 0x03, 0x00, 0x12, 0x04, 0x23, 0x02, 0x25, 0x03, - 0x1a, 0x20, 0x20, 0x56, 0x31, 0x20, 0x6f, 0x66, 0x20, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, - 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x44, 0x61, 0x74, - 0x61, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x03, 0x00, 0x01, 0x12, 0x03, 0x23, 0x0a, 0x0c, - 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x02, 0x03, 0x00, 0x02, 0x00, 0x12, 0x03, 0x24, 0x04, 0x2a, 0x0a, - 0x0e, 0x0a, 0x07, 0x04, 0x02, 0x03, 0x00, 0x02, 0x00, 0x04, 0x12, 0x03, 0x24, 0x04, 0x0c, 0x0a, - 0x0e, 0x0a, 0x07, 0x04, 0x02, 0x03, 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, 0x24, 0x0d, 0x13, 0x0a, - 0x0e, 0x0a, 0x07, 0x04, 0x02, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x24, 0x14, 0x25, 0x0a, - 0x0e, 0x0a, 0x07, 0x04, 0x02, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x24, 0x28, 0x29, 0x0a, - 0x0c, 0x0a, 0x04, 0x04, 0x02, 0x08, 0x00, 0x12, 0x04, 0x27, 0x02, 0x29, 0x03, 0x0a, 0x0c, 0x0a, - 0x05, 0x04, 0x02, 0x08, 0x00, 0x01, 0x12, 0x03, 0x27, 0x08, 0x0f, 0x0a, 0x0b, 0x0a, 0x04, 0x04, - 0x02, 0x02, 0x00, 0x12, 0x03, 0x28, 0x04, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, - 0x06, 0x12, 0x03, 0x28, 0x04, 0x06, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x01, 0x12, - 0x03, 0x28, 0x07, 0x09, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x03, 0x12, 0x03, 0x28, - 0x0c, 0x0d, 0x0a, 0x3b, 0x0a, 0x02, 0x04, 0x03, 0x12, 0x04, 0x2d, 0x00, 0x37, 0x01, 0x1a, 0x2f, - 0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x74, 0x79, - 0x70, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x70, 0x6f, 0x73, 0x74, 0x2d, - 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x0a, 0x0a, - 0x0a, 0x0a, 0x03, 0x04, 0x03, 0x01, 0x12, 0x03, 0x2d, 0x08, 0x18, 0x0a, 0x23, 0x0a, 0x04, 0x04, - 0x03, 0x03, 0x00, 0x12, 0x04, 0x2f, 0x02, 0x32, 0x03, 0x1a, 0x15, 0x20, 0x53, 0x65, 0x6e, 0x64, - 0x57, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x0a, - 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x03, 0x00, 0x01, 0x12, 0x03, 0x2f, 0x0a, 0x16, 0x0a, 0x0d, - 0x0a, 0x06, 0x04, 0x03, 0x03, 0x00, 0x02, 0x00, 0x12, 0x03, 0x30, 0x04, 0x28, 0x0a, 0x0e, 0x0a, - 0x07, 0x04, 0x03, 0x03, 0x00, 0x02, 0x00, 0x04, 0x12, 0x03, 0x30, 0x04, 0x0c, 0x0a, 0x0e, 0x0a, - 0x07, 0x04, 0x03, 0x03, 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, 0x30, 0x0d, 0x12, 0x0a, 0x0e, 0x0a, - 0x07, 0x04, 0x03, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x30, 0x13, 0x23, 0x0a, 0x0e, 0x0a, - 0x07, 0x04, 0x03, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x30, 0x26, 0x27, 0x0a, 0x0d, 0x0a, - 0x06, 0x04, 0x03, 0x03, 0x00, 0x02, 0x01, 0x12, 0x03, 0x31, 0x04, 0x1e, 0x0a, 0x0e, 0x0a, 0x07, - 0x04, 0x03, 0x03, 0x00, 0x02, 0x01, 0x05, 0x12, 0x03, 0x31, 0x04, 0x09, 0x0a, 0x0e, 0x0a, 0x07, - 0x04, 0x03, 0x03, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x31, 0x0a, 0x19, 0x0a, 0x0e, 0x0a, 0x07, - 0x04, 0x03, 0x03, 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, 0x31, 0x1c, 0x1d, 0x0a, 0x0c, 0x0a, 0x04, - 0x04, 0x03, 0x08, 0x00, 0x12, 0x04, 0x34, 0x02, 0x36, 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, - 0x08, 0x00, 0x01, 0x12, 0x03, 0x34, 0x08, 0x0c, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x03, 0x02, 0x00, - 0x12, 0x03, 0x35, 0x04, 0x23, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x06, 0x12, 0x03, - 0x35, 0x04, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x01, 0x12, 0x03, 0x35, 0x11, - 0x1e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x03, 0x12, 0x03, 0x35, 0x21, 0x22, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3f, 0x0a, 0x10, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x61, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x22, 0x3c, 0x0a, 0x0f, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, + 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0c, 0x52, 0x0f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x49, 0x64, 0x73, 0x22, 0xdc, 0x01, 0x0a, 0x17, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x4f, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, + 0x12, 0x52, 0x0a, 0x11, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x78, 0x6d, + 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, + 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, + 0x48, 0x00, 0x52, 0x10, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x65, 0x73, 0x12, 0x4f, 0x0a, 0x10, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, + 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, + 0x73, 0x65, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, + 0x64, 0x73, 0x48, 0x00, 0x52, 0x0f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x42, 0x1c, 0x0a, 0x1a, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x5f, 0x6f, 0x72, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x69, 0x64, 0x22, 0xc2, 0x01, 0x0a, 0x0e, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x73, 0x44, 0x61, 0x74, 0x61, 0x12, 0x36, 0x0a, 0x02, 0x76, 0x31, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, 0x61, + 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x73, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x31, 0x48, 0x00, 0x52, 0x02, 0x76, 0x31, 0x1a, 0x6d, + 0x0a, 0x02, 0x56, 0x31, 0x12, 0x67, 0x0a, 0x1a, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, + 0x6f, 0x72, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, + 0x6d, 0x6c, 0x73, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x4f, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x49, 0x64, 0x52, 0x17, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4f, 0x72, 0x49, + 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x42, 0x09, 0x0a, + 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xc8, 0x01, 0x0a, 0x11, 0x52, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x44, 0x61, 0x74, 0x61, 0x12, 0x39, + 0x0a, 0x02, 0x76, 0x31, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x78, 0x6d, 0x74, + 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x52, + 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x44, 0x61, 0x74, 0x61, + 0x2e, 0x56, 0x31, 0x48, 0x00, 0x52, 0x02, 0x76, 0x31, 0x1a, 0x6d, 0x0a, 0x02, 0x56, 0x31, 0x12, + 0x67, 0x0a, 0x1a, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x6f, 0x72, 0x5f, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, + 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4f, + 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x52, + 0x17, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4f, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, + 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x42, 0x09, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x22, 0xd7, 0x01, 0x0a, 0x10, 0x50, 0x6f, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x57, 0x0a, 0x0d, 0x73, 0x65, 0x6e, 0x64, + 0x5f, 0x77, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x30, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, + 0x61, 0x73, 0x65, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x41, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x57, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, + 0x73, 0x48, 0x00, 0x52, 0x0c, 0x73, 0x65, 0x6e, 0x64, 0x57, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, + 0x73, 0x1a, 0x62, 0x0a, 0x0c, 0x53, 0x65, 0x6e, 0x64, 0x57, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, + 0x73, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0f, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12, 0x27, 0x0a, 0x0f, + 0x77, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x77, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x06, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x42, 0xb5, 0x01, + 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, + 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x42, 0x0c, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x28, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x6d, 0x74, 0x70, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, + 0x33, 0x2f, 0x67, 0x6f, 0x2f, 0x6d, 0x6c, 0x73, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, + 0x65, 0xa2, 0x02, 0x03, 0x58, 0x4d, 0x44, 0xaa, 0x02, 0x11, 0x58, 0x6d, 0x74, 0x70, 0x2e, 0x4d, + 0x6c, 0x73, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0xca, 0x02, 0x11, 0x58, 0x6d, + 0x74, 0x70, 0x5c, 0x4d, 0x6c, 0x73, 0x5c, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0xe2, + 0x02, 0x1d, 0x58, 0x6d, 0x74, 0x70, 0x5c, 0x4d, 0x6c, 0x73, 0x5c, 0x44, 0x61, 0x74, 0x61, 0x62, + 0x61, 0x73, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, + 0x02, 0x13, 0x58, 0x6d, 0x74, 0x70, 0x3a, 0x3a, 0x4d, 0x6c, 0x73, 0x3a, 0x3a, 0x44, 0x61, 0x74, + 0x61, 0x62, 0x61, 0x73, 0x65, 0x4a, 0xee, 0x0d, 0x0a, 0x06, 0x12, 0x04, 0x02, 0x00, 0x49, 0x01, + 0x0a, 0x27, 0x0a, 0x01, 0x0c, 0x12, 0x03, 0x02, 0x00, 0x12, 0x32, 0x1d, 0x20, 0x56, 0x33, 0x20, + 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x73, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x0a, 0x0a, 0x08, 0x0a, 0x01, 0x02, 0x12, 0x03, + 0x04, 0x00, 0x1a, 0x0a, 0x08, 0x0a, 0x01, 0x08, 0x12, 0x03, 0x06, 0x00, 0x3f, 0x0a, 0x09, 0x0a, + 0x02, 0x08, 0x0b, 0x12, 0x03, 0x06, 0x00, 0x3f, 0x0a, 0x34, 0x0a, 0x02, 0x04, 0x00, 0x12, 0x04, + 0x0a, 0x00, 0x13, 0x01, 0x1a, 0x28, 0x20, 0x54, 0x68, 0x65, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, + 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x75, 0x62, 0x6c, + 0x69, 0x73, 0x68, 0x20, 0x61, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x0a, 0x0a, 0x0a, + 0x0a, 0x03, 0x04, 0x00, 0x01, 0x12, 0x03, 0x0a, 0x08, 0x17, 0x0a, 0x2c, 0x0a, 0x04, 0x04, 0x00, + 0x03, 0x00, 0x12, 0x04, 0x0c, 0x02, 0x0e, 0x03, 0x1a, 0x1e, 0x20, 0x56, 0x31, 0x20, 0x6f, 0x66, + 0x20, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x50, 0x75, 0x62, 0x6c, + 0x69, 0x73, 0x68, 0x44, 0x61, 0x74, 0x61, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x03, 0x00, + 0x01, 0x12, 0x03, 0x0c, 0x0a, 0x0c, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x00, 0x03, 0x00, 0x02, 0x00, + 0x12, 0x03, 0x0d, 0x04, 0x1c, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x00, 0x03, 0x00, 0x02, 0x00, 0x05, + 0x12, 0x03, 0x0d, 0x04, 0x09, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x00, 0x03, 0x00, 0x02, 0x00, 0x01, + 0x12, 0x03, 0x0d, 0x0a, 0x17, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, + 0x12, 0x03, 0x0d, 0x1a, 0x1b, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x00, 0x08, 0x00, 0x12, 0x04, 0x10, + 0x02, 0x12, 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x08, 0x00, 0x01, 0x12, 0x03, 0x10, 0x08, + 0x0f, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x00, 0x12, 0x03, 0x11, 0x04, 0x0e, 0x0a, 0x0c, + 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x06, 0x12, 0x03, 0x11, 0x04, 0x06, 0x0a, 0x0c, 0x0a, 0x05, + 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x11, 0x07, 0x09, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, + 0x02, 0x00, 0x03, 0x12, 0x03, 0x11, 0x0c, 0x0d, 0x0a, 0x45, 0x0a, 0x02, 0x04, 0x01, 0x12, 0x04, + 0x15, 0x00, 0x17, 0x01, 0x1a, 0x39, 0x20, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x20, 0x61, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x61, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x61, 0x66, 0x20, + 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x45, 0x56, 0x4d, 0x20, 0x41, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x0a, 0x0a, + 0x0a, 0x0a, 0x03, 0x04, 0x01, 0x01, 0x12, 0x03, 0x15, 0x08, 0x18, 0x0a, 0x0b, 0x0a, 0x04, 0x04, + 0x01, 0x02, 0x00, 0x12, 0x03, 0x16, 0x02, 0x28, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, + 0x04, 0x12, 0x03, 0x16, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x05, 0x12, + 0x03, 0x16, 0x0b, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x01, 0x12, 0x03, 0x16, + 0x12, 0x23, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x03, 0x12, 0x03, 0x16, 0x26, 0x27, + 0x0a, 0x40, 0x0a, 0x02, 0x04, 0x02, 0x12, 0x04, 0x1a, 0x00, 0x1c, 0x01, 0x1a, 0x34, 0x20, 0x57, + 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x20, 0x61, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x61, 0x20, + 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x20, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x49, 0x44, + 0x73, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x02, 0x01, 0x12, 0x03, 0x1a, 0x08, 0x17, 0x0a, 0x0b, + 0x0a, 0x04, 0x04, 0x02, 0x02, 0x00, 0x12, 0x03, 0x1b, 0x02, 0x26, 0x0a, 0x0c, 0x0a, 0x05, 0x04, + 0x02, 0x02, 0x00, 0x04, 0x12, 0x03, 0x1b, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, + 0x00, 0x05, 0x12, 0x03, 0x1b, 0x0b, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x01, + 0x12, 0x03, 0x1b, 0x11, 0x21, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x03, 0x12, 0x03, + 0x1b, 0x24, 0x25, 0x0a, 0x3e, 0x0a, 0x02, 0x04, 0x03, 0x12, 0x04, 0x1f, 0x00, 0x24, 0x01, 0x1a, + 0x32, 0x20, 0x4f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x45, 0x56, 0x4d, 0x20, + 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, + 0x6f, 0x72, 0x20, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x49, 0x44, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x03, 0x01, 0x12, 0x03, 0x1f, 0x08, 0x1f, 0x0a, + 0x0c, 0x0a, 0x04, 0x04, 0x03, 0x08, 0x00, 0x12, 0x04, 0x20, 0x02, 0x23, 0x03, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x03, 0x08, 0x00, 0x01, 0x12, 0x03, 0x20, 0x08, 0x22, 0x0a, 0x0b, 0x0a, 0x04, 0x04, + 0x03, 0x02, 0x00, 0x12, 0x03, 0x21, 0x04, 0x2b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, + 0x06, 0x12, 0x03, 0x21, 0x04, 0x14, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x01, 0x12, + 0x03, 0x21, 0x15, 0x26, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x03, 0x12, 0x03, 0x21, + 0x29, 0x2a, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x03, 0x02, 0x01, 0x12, 0x03, 0x22, 0x04, 0x29, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x01, 0x06, 0x12, 0x03, 0x22, 0x04, 0x13, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x12, 0x03, 0x22, 0x14, 0x24, 0x0a, 0x0c, 0x0a, 0x05, 0x04, + 0x03, 0x02, 0x01, 0x03, 0x12, 0x03, 0x22, 0x27, 0x28, 0x0a, 0x39, 0x0a, 0x02, 0x04, 0x04, 0x12, + 0x04, 0x27, 0x00, 0x30, 0x01, 0x1a, 0x2d, 0x20, 0x54, 0x68, 0x65, 0x20, 0x64, 0x61, 0x74, 0x61, + 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x64, 0x64, + 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x67, 0x72, + 0x6f, 0x75, 0x70, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x04, 0x01, 0x12, 0x03, 0x27, 0x08, 0x16, + 0x0a, 0x2b, 0x0a, 0x04, 0x04, 0x04, 0x03, 0x00, 0x12, 0x04, 0x29, 0x02, 0x2b, 0x03, 0x1a, 0x1d, + 0x20, 0x56, 0x31, 0x20, 0x6f, 0x66, 0x20, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x44, 0x61, 0x74, 0x61, 0x0a, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x04, 0x03, 0x00, 0x01, 0x12, 0x03, 0x29, 0x0a, 0x0c, 0x0a, 0x0d, 0x0a, 0x06, 0x04, + 0x04, 0x03, 0x00, 0x02, 0x00, 0x12, 0x03, 0x2a, 0x04, 0x3b, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x04, + 0x03, 0x00, 0x02, 0x00, 0x06, 0x12, 0x03, 0x2a, 0x04, 0x1b, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x04, + 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x2a, 0x1c, 0x36, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x04, + 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x2a, 0x39, 0x3a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x04, + 0x08, 0x00, 0x12, 0x04, 0x2d, 0x02, 0x2f, 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x04, 0x08, 0x00, + 0x01, 0x12, 0x03, 0x2d, 0x08, 0x0f, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x04, 0x02, 0x00, 0x12, 0x03, + 0x2e, 0x04, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x04, 0x02, 0x00, 0x06, 0x12, 0x03, 0x2e, 0x04, + 0x06, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x04, 0x02, 0x00, 0x01, 0x12, 0x03, 0x2e, 0x07, 0x09, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x04, 0x02, 0x00, 0x03, 0x12, 0x03, 0x2e, 0x0c, 0x0d, 0x0a, 0x3e, 0x0a, + 0x02, 0x04, 0x05, 0x12, 0x04, 0x33, 0x00, 0x3c, 0x01, 0x1a, 0x32, 0x20, 0x54, 0x68, 0x65, 0x20, + 0x64, 0x61, 0x74, 0x61, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x20, 0x74, 0x6f, + 0x20, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x20, + 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x0a, 0x0a, 0x0a, 0x0a, + 0x03, 0x04, 0x05, 0x01, 0x12, 0x03, 0x33, 0x08, 0x19, 0x0a, 0x2e, 0x0a, 0x04, 0x04, 0x05, 0x03, + 0x00, 0x12, 0x04, 0x35, 0x02, 0x37, 0x03, 0x1a, 0x20, 0x20, 0x56, 0x31, 0x20, 0x6f, 0x66, 0x20, + 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x50, 0x75, 0x62, + 0x6c, 0x69, 0x73, 0x68, 0x44, 0x61, 0x74, 0x61, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x03, + 0x00, 0x01, 0x12, 0x03, 0x35, 0x0a, 0x0c, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x05, 0x03, 0x00, 0x02, + 0x00, 0x12, 0x03, 0x36, 0x04, 0x3b, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x05, 0x03, 0x00, 0x02, 0x00, + 0x06, 0x12, 0x03, 0x36, 0x04, 0x1b, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x05, 0x03, 0x00, 0x02, 0x00, + 0x01, 0x12, 0x03, 0x36, 0x1c, 0x36, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x05, 0x03, 0x00, 0x02, 0x00, + 0x03, 0x12, 0x03, 0x36, 0x39, 0x3a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x05, 0x08, 0x00, 0x12, 0x04, + 0x39, 0x02, 0x3b, 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x08, 0x00, 0x01, 0x12, 0x03, 0x39, + 0x08, 0x0f, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x05, 0x02, 0x00, 0x12, 0x03, 0x3a, 0x04, 0x0e, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x00, 0x06, 0x12, 0x03, 0x3a, 0x04, 0x06, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x05, 0x02, 0x00, 0x01, 0x12, 0x03, 0x3a, 0x07, 0x09, 0x0a, 0x0c, 0x0a, 0x05, 0x04, + 0x05, 0x02, 0x00, 0x03, 0x12, 0x03, 0x3a, 0x0c, 0x0d, 0x0a, 0x3b, 0x0a, 0x02, 0x04, 0x06, 0x12, + 0x04, 0x3f, 0x00, 0x49, 0x01, 0x1a, 0x2f, 0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x20, + 0x64, 0x61, 0x74, 0x61, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, + 0x6c, 0x20, 0x70, 0x6f, 0x73, 0x74, 0x2d, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x20, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x06, 0x01, 0x12, 0x03, 0x3f, + 0x08, 0x18, 0x0a, 0x23, 0x0a, 0x04, 0x04, 0x06, 0x03, 0x00, 0x12, 0x04, 0x41, 0x02, 0x44, 0x03, + 0x1a, 0x15, 0x20, 0x53, 0x65, 0x6e, 0x64, 0x57, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x20, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x06, 0x03, 0x00, 0x01, + 0x12, 0x03, 0x41, 0x0a, 0x16, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x06, 0x03, 0x00, 0x02, 0x00, 0x12, + 0x03, 0x42, 0x04, 0x28, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x06, 0x03, 0x00, 0x02, 0x00, 0x04, 0x12, + 0x03, 0x42, 0x04, 0x0c, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x06, 0x03, 0x00, 0x02, 0x00, 0x05, 0x12, + 0x03, 0x42, 0x0d, 0x12, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x06, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, + 0x03, 0x42, 0x13, 0x23, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x06, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, + 0x03, 0x42, 0x26, 0x27, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x06, 0x03, 0x00, 0x02, 0x01, 0x12, 0x03, + 0x43, 0x04, 0x1e, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x06, 0x03, 0x00, 0x02, 0x01, 0x05, 0x12, 0x03, + 0x43, 0x04, 0x09, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x06, 0x03, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, + 0x43, 0x0a, 0x19, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x06, 0x03, 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, + 0x43, 0x1c, 0x1d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x06, 0x08, 0x00, 0x12, 0x04, 0x46, 0x02, 0x48, + 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x06, 0x08, 0x00, 0x01, 0x12, 0x03, 0x46, 0x08, 0x0c, 0x0a, + 0x0b, 0x0a, 0x04, 0x04, 0x06, 0x02, 0x00, 0x12, 0x03, 0x47, 0x04, 0x23, 0x0a, 0x0c, 0x0a, 0x05, + 0x04, 0x06, 0x02, 0x00, 0x06, 0x12, 0x03, 0x47, 0x04, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x06, + 0x02, 0x00, 0x01, 0x12, 0x03, 0x47, 0x11, 0x1e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x06, 0x02, 0x00, + 0x03, 0x12, 0x03, 0x47, 0x21, 0x22, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, ]; include!("xmtp.mls.database.serde.rs"); -// @@protoc_insertion_point(module) \ No newline at end of file +// @@protoc_insertion_point(module) + diff --git a/xmtp_proto/src/gen/xmtp.mls.database.serde.rs b/xmtp_proto/src/gen/xmtp.mls.database.serde.rs index 936c2727d..1ed86aad0 100644 --- a/xmtp_proto/src/gen/xmtp.mls.database.serde.rs +++ b/xmtp_proto/src/gen/xmtp.mls.database.serde.rs @@ -1,4 +1,96 @@ // @generated +impl serde::Serialize for AccountAddresses { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if !self.account_addresses.is_empty() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("xmtp.mls.database.AccountAddresses", len)?; + if !self.account_addresses.is_empty() { + struct_ser.serialize_field("accountAddresses", &self.account_addresses)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for AccountAddresses { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "account_addresses", + "accountAddresses", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + AccountAddresses, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "accountAddresses" | "account_addresses" => Ok(GeneratedField::AccountAddresses), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = AccountAddresses; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct xmtp.mls.database.AccountAddresses") + } + + fn visit_map(self, mut map: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut account_addresses__ = None; + while let Some(k) = map.next_key()? { + match k { + GeneratedField::AccountAddresses => { + if account_addresses__.is_some() { + return Err(serde::de::Error::duplicate_field("accountAddresses")); + } + account_addresses__ = Some(map.next_value()?); + } + } + } + Ok(AccountAddresses { + account_addresses: account_addresses__.unwrap_or_default(), + }) + } + } + deserializer.deserialize_struct("xmtp.mls.database.AccountAddresses", FIELDS, GeneratedVisitor) + } +} impl serde::Serialize for AddMembersData { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result @@ -103,17 +195,116 @@ impl serde::Serialize for add_members_data::V1 { { use serde::ser::SerializeStruct; let mut len = 0; - if !self.account_addresses.is_empty() { + if self.address_or_installation_id.is_some() { len += 1; } let mut struct_ser = serializer.serialize_struct("xmtp.mls.database.AddMembersData.V1", len)?; - if !self.account_addresses.is_empty() { - struct_ser.serialize_field("accountAddresses", &self.account_addresses)?; + if let Some(v) = self.address_or_installation_id.as_ref() { + struct_ser.serialize_field("addressOrInstallationId", v)?; } struct_ser.end() } } impl<'de> serde::Deserialize<'de> for add_members_data::V1 { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "address_or_installation_id", + "addressOrInstallationId", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + AddressOrInstallationId, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "addressOrInstallationId" | "address_or_installation_id" => Ok(GeneratedField::AddressOrInstallationId), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = add_members_data::V1; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct xmtp.mls.database.AddMembersData.V1") + } + + fn visit_map(self, mut map: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut address_or_installation_id__ = None; + while let Some(k) = map.next_key()? { + match k { + GeneratedField::AddressOrInstallationId => { + if address_or_installation_id__.is_some() { + return Err(serde::de::Error::duplicate_field("addressOrInstallationId")); + } + address_or_installation_id__ = map.next_value()?; + } + } + } + Ok(add_members_data::V1 { + address_or_installation_id: address_or_installation_id__, + }) + } + } + deserializer.deserialize_struct("xmtp.mls.database.AddMembersData.V1", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for AddressOrInstallationId { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if self.address_or_installation_id.is_some() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("xmtp.mls.database.AddressOrInstallationId", len)?; + if let Some(v) = self.address_or_installation_id.as_ref() { + match v { + address_or_installation_id::AddressOrInstallationId::AccountAddresses(v) => { + struct_ser.serialize_field("accountAddresses", v)?; + } + address_or_installation_id::AddressOrInstallationId::InstallationIds(v) => { + struct_ser.serialize_field("installationIds", v)?; + } + } + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for AddressOrInstallationId { #[allow(deprecated)] fn deserialize(deserializer: D) -> std::result::Result where @@ -122,11 +313,14 @@ impl<'de> serde::Deserialize<'de> for add_members_data::V1 { const FIELDS: &[&str] = &[ "account_addresses", "accountAddresses", + "installation_ids", + "installationIds", ]; #[allow(clippy::enum_variant_names)] enum GeneratedField { AccountAddresses, + InstallationIds, } impl<'de> serde::Deserialize<'de> for GeneratedField { fn deserialize(deserializer: D) -> std::result::Result @@ -149,6 +343,7 @@ impl<'de> serde::Deserialize<'de> for add_members_data::V1 { { match value { "accountAddresses" | "account_addresses" => Ok(GeneratedField::AccountAddresses), + "installationIds" | "installation_ids" => Ok(GeneratedField::InstallationIds), _ => Err(serde::de::Error::unknown_field(value, FIELDS)), } } @@ -158,33 +353,136 @@ impl<'de> serde::Deserialize<'de> for add_members_data::V1 { } struct GeneratedVisitor; impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = add_members_data::V1; + type Value = AddressOrInstallationId; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("struct xmtp.mls.database.AddMembersData.V1") + formatter.write_str("struct xmtp.mls.database.AddressOrInstallationId") } - fn visit_map(self, mut map: V) -> std::result::Result + fn visit_map(self, mut map: V) -> std::result::Result where V: serde::de::MapAccess<'de>, { - let mut account_addresses__ = None; + let mut address_or_installation_id__ = None; while let Some(k) = map.next_key()? { match k { GeneratedField::AccountAddresses => { - if account_addresses__.is_some() { + if address_or_installation_id__.is_some() { return Err(serde::de::Error::duplicate_field("accountAddresses")); } - account_addresses__ = Some(map.next_value()?); + address_or_installation_id__ = map.next_value::<::std::option::Option<_>>()?.map(address_or_installation_id::AddressOrInstallationId::AccountAddresses) +; + } + GeneratedField::InstallationIds => { + if address_or_installation_id__.is_some() { + return Err(serde::de::Error::duplicate_field("installationIds")); + } + address_or_installation_id__ = map.next_value::<::std::option::Option<_>>()?.map(address_or_installation_id::AddressOrInstallationId::InstallationIds) +; } } } - Ok(add_members_data::V1 { - account_addresses: account_addresses__.unwrap_or_default(), + Ok(AddressOrInstallationId { + address_or_installation_id: address_or_installation_id__, }) } } - deserializer.deserialize_struct("xmtp.mls.database.AddMembersData.V1", FIELDS, GeneratedVisitor) + deserializer.deserialize_struct("xmtp.mls.database.AddressOrInstallationId", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for InstallationIds { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if !self.installation_ids.is_empty() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("xmtp.mls.database.InstallationIds", len)?; + if !self.installation_ids.is_empty() { + struct_ser.serialize_field("installationIds", &self.installation_ids.iter().map(pbjson::private::base64::encode).collect::>())?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for InstallationIds { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "installation_ids", + "installationIds", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + InstallationIds, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "installationIds" | "installation_ids" => Ok(GeneratedField::InstallationIds), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = InstallationIds; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct xmtp.mls.database.InstallationIds") + } + + fn visit_map(self, mut map: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut installation_ids__ = None; + while let Some(k) = map.next_key()? { + match k { + GeneratedField::InstallationIds => { + if installation_ids__.is_some() { + return Err(serde::de::Error::duplicate_field("installationIds")); + } + installation_ids__ = + Some(map.next_value::>>()? + .into_iter().map(|x| x.0).collect()) + ; + } + } + } + Ok(InstallationIds { + installation_ids: installation_ids__.unwrap_or_default(), + }) + } + } + deserializer.deserialize_struct("xmtp.mls.database.InstallationIds", FIELDS, GeneratedVisitor) } } impl serde::Serialize for PostCommitAction { @@ -503,12 +801,12 @@ impl serde::Serialize for remove_members_data::V1 { { use serde::ser::SerializeStruct; let mut len = 0; - if !self.account_addresses.is_empty() { + if self.address_or_installation_id.is_some() { len += 1; } let mut struct_ser = serializer.serialize_struct("xmtp.mls.database.RemoveMembersData.V1", len)?; - if !self.account_addresses.is_empty() { - struct_ser.serialize_field("accountAddresses", &self.account_addresses)?; + if let Some(v) = self.address_or_installation_id.as_ref() { + struct_ser.serialize_field("addressOrInstallationId", v)?; } struct_ser.end() } @@ -520,13 +818,13 @@ impl<'de> serde::Deserialize<'de> for remove_members_data::V1 { D: serde::Deserializer<'de>, { const FIELDS: &[&str] = &[ - "account_addresses", - "accountAddresses", + "address_or_installation_id", + "addressOrInstallationId", ]; #[allow(clippy::enum_variant_names)] enum GeneratedField { - AccountAddresses, + AddressOrInstallationId, } impl<'de> serde::Deserialize<'de> for GeneratedField { fn deserialize(deserializer: D) -> std::result::Result @@ -548,7 +846,7 @@ impl<'de> serde::Deserialize<'de> for remove_members_data::V1 { E: serde::de::Error, { match value { - "accountAddresses" | "account_addresses" => Ok(GeneratedField::AccountAddresses), + "addressOrInstallationId" | "address_or_installation_id" => Ok(GeneratedField::AddressOrInstallationId), _ => Err(serde::de::Error::unknown_field(value, FIELDS)), } } @@ -568,19 +866,19 @@ impl<'de> serde::Deserialize<'de> for remove_members_data::V1 { where V: serde::de::MapAccess<'de>, { - let mut account_addresses__ = None; + let mut address_or_installation_id__ = None; while let Some(k) = map.next_key()? { match k { - GeneratedField::AccountAddresses => { - if account_addresses__.is_some() { - return Err(serde::de::Error::duplicate_field("accountAddresses")); + GeneratedField::AddressOrInstallationId => { + if address_or_installation_id__.is_some() { + return Err(serde::de::Error::duplicate_field("addressOrInstallationId")); } - account_addresses__ = Some(map.next_value()?); + address_or_installation_id__ = map.next_value()?; } } } Ok(remove_members_data::V1 { - account_addresses: account_addresses__.unwrap_or_default(), + address_or_installation_id: address_or_installation_id__, }) } } From abe323c0ea8fedc9558c52e42c23f830db265ef1 Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Thu, 7 Dec 2023 13:17:02 -0500 Subject: [PATCH 10/20] get key packages in AddMembers --- xmtp_mls/src/client.rs | 16 +++++++++++++++- xmtp_mls/src/groups/intents.rs | 12 ++++++++++++ xmtp_mls/src/groups/mod.rs | 13 +++++++++---- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/xmtp_mls/src/client.rs b/xmtp_mls/src/client.rs index 7886fe140..3b27e093c 100644 --- a/xmtp_mls/src/client.rs +++ b/xmtp_mls/src/client.rs @@ -13,7 +13,7 @@ use xmtp_proto::api_client::{Envelope, XmtpApiClient, XmtpMlsClient}; use crate::{ api_client_wrapper::{ApiClientWrapper, IdentityUpdate}, - groups::{IntentError, MlsGroup}, + groups::{AddressOrInstallationId, IntentError, MlsGroup}, identity::Identity, retry::Retry, storage::{ @@ -271,6 +271,20 @@ where }) } + pub(crate) async fn get_key_packages( + &self, + address_or_id: AddressOrInstallationId, + ) -> Result, ClientError> { + match address_or_id { + AddressOrInstallationId::AccountAddresses(addrs) => { + self.get_key_packages_for_wallet_addresses(addrs).await + } + AddressOrInstallationId::InstallationIds(ids) => { + self.get_key_packages_for_installation_ids(ids).await + } + } + } + // Get a flat list of one key package per installation for all the wallet addresses provided. // Revoked installations will be omitted from the list #[allow(dead_code)] diff --git a/xmtp_mls/src/groups/intents.rs b/xmtp_mls/src/groups/intents.rs index 70de29ada..398883a20 100644 --- a/xmtp_mls/src/groups/intents.rs +++ b/xmtp_mls/src/groups/intents.rs @@ -114,6 +114,18 @@ impl TryFrom for AddressOrInstallationId { } } +impl From> for AddressOrInstallationId { + fn from(addrs: Vec
) -> Self { + AddressOrInstallationId::AccountAddresses(addrs) + } +} + +impl From>> for AddressOrInstallationId { + fn from(installation_ids: Vec>) -> Self { + AddressOrInstallationId::InstallationIds(installation_ids) + } +} + #[derive(Debug, Clone)] pub struct AddMembersIntentData { pub address_or_id: AddressOrInstallationId, diff --git a/xmtp_mls/src/groups/mod.rs b/xmtp_mls/src/groups/mod.rs index 4164ff94b..a1e318991 100644 --- a/xmtp_mls/src/groups/mod.rs +++ b/xmtp_mls/src/groups/mod.rs @@ -19,8 +19,8 @@ use tls_codec::{Deserialize, Serialize}; use xmtp_cryptography::signature::is_valid_ethereum_address; use xmtp_proto::api_client::{Envelope, XmtpApiClient, XmtpMlsClient}; -pub use self::intents::IntentError; use self::intents::{AddMembersIntentData, PostCommitAction, RemoveMembersIntentData}; +pub use self::intents::{AddressOrInstallationId, IntentError}; use crate::{ api_client_wrapper::WelcomeMessage, client::{ClientError, MessageProcessingError}, @@ -439,7 +439,7 @@ where } let conn = &mut self.client.store.conn()?; - let intent_data: Vec = AddMembersIntentData::new(wallet_addresses).try_into()?; + let intent_data: Vec = AddMembersIntentData::new(wallet_addresses.into()).try_into()?; let intent = NewGroupIntent::new(IntentKind::AddMembers, self.group_id.clone(), intent_data); intent.store(conn)?; @@ -449,7 +449,7 @@ where pub async fn remove_members(&self, wallet_addresses: Vec) -> Result<(), GroupError> { let conn = &mut self.client.store.conn()?; - let intent_data: Vec = RemoveMembersIntentData::new(wallet_addresses).into(); + let intent_data: Vec = RemoveMembersIntentData::new(wallet_addresses.into()).into(); let intent = NewGroupIntent::new( IntentKind::RemoveMembers, self.group_id.clone(), @@ -556,7 +556,7 @@ where let key_packages = self .client - .get_key_packages_for_wallet_addresses(intent_data.account_addresses) + .get_key_packages(intent_data.address_or_id) .await?; let mls_key_packages: Vec = @@ -583,6 +583,11 @@ where IntentKind::RemoveMembers => { let intent_data = RemoveMembersIntentData::from_bytes(intent.data.as_slice())?; + let key_packages = self + .client + .get_key_packages(intent_data.address_or_id) + .await?; + let installation_ids = self .members()? .into_iter() From 66d3750c7d634b1e68e87a96aa6d0063b816c651 Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Thu, 7 Dec 2023 17:39:14 -0500 Subject: [PATCH 11/20] refactor to re-edd removing/adding by installation id --- xmtp_mls/src/client.rs | 2 +- xmtp_mls/src/groups/intents.rs | 8 ++-- xmtp_mls/src/groups/members.rs | 5 ++- xmtp_mls/src/groups/mod.rs | 80 ++++++++++++++++++++++------------ 4 files changed, 62 insertions(+), 33 deletions(-) diff --git a/xmtp_mls/src/client.rs b/xmtp_mls/src/client.rs index 3b27e093c..d58fd9e99 100644 --- a/xmtp_mls/src/client.rs +++ b/xmtp_mls/src/client.rs @@ -418,7 +418,7 @@ mod tests { let alice_bob_group = alice.create_group().unwrap(); alice_bob_group - .add_members(vec![bob.account_address()]) + .add_members_by_installation_id(vec![bob.installation_public_key()]) .await .unwrap(); diff --git a/xmtp_mls/src/groups/intents.rs b/xmtp_mls/src/groups/intents.rs index 398883a20..e27e5bd4e 100644 --- a/xmtp_mls/src/groups/intents.rs +++ b/xmtp_mls/src/groups/intents.rs @@ -140,7 +140,7 @@ impl AddMembersIntentData { let mut buf = Vec::new(); AddMembersData { version: Some(AddMembersVersion::V1(AddMembersV1 { - address_or_installation_id: Some(self.address_or_id.into()), + address_or_installation_id: Some(self.address_or_id.clone().into()), })), } .encode(&mut buf) @@ -185,7 +185,7 @@ impl RemoveMembersIntentData { RemoveMembersData { version: Some(RemoveMembersVersion::V1(RemoveMembersV1 { - address_or_installation_id: Some(self.address_or_id.into()), + address_or_installation_id: Some(self.address_or_id.clone().into()), })), } .encode(&mut buf) @@ -307,10 +307,10 @@ mod tests { let wallet = generate_local_wallet(); let wallet_address = wallet.get_address(); - let intent = AddMembersIntentData::new(vec![wallet_address.clone()]); + let intent = AddMembersIntentData::new(vec![wallet_address.clone()].into()); let as_bytes: Vec = intent.clone().try_into().unwrap(); let restored_intent = AddMembersIntentData::from_bytes(as_bytes.as_slice()).unwrap(); - assert!(intent.account_addresses[0].eq(&restored_intent.account_addresses[0])); + assert_eq!(intent.address_or_id, restored_intent.address_or_id); } } diff --git a/xmtp_mls/src/groups/members.rs b/xmtp_mls/src/groups/members.rs index 0da408d28..10810529d 100644 --- a/xmtp_mls/src/groups/members.rs +++ b/xmtp_mls/src/groups/members.rs @@ -67,7 +67,10 @@ mod tests { let group = amal.create_group().unwrap(); // Add both of Bola's installations to the group group - .add_members(vec![bola_a.account_address(), bola_b.account_address()]) + .add_members_by_installation_id(vec![ + bola_a.installation_public_key(), + bola_b.installation_public_key(), + ]) .await .unwrap(); diff --git a/xmtp_mls/src/groups/mod.rs b/xmtp_mls/src/groups/mod.rs index a1e318991..bbf6cbf5d 100644 --- a/xmtp_mls/src/groups/mod.rs +++ b/xmtp_mls/src/groups/mod.rs @@ -447,6 +447,20 @@ where self.sync_with_conn(conn).await } + pub async fn add_members_by_installation_id( + &self, + installation_ids: Vec>, + ) -> Result<(), GroupError> { + let conn = &mut self.client.store.conn()?; + //FIXME:INSIPX -- VALIDATE installation ID somehow + let intent_data: Vec = AddMembersIntentData::new(installation_ids.into()).try_into()?; + let intent = + NewGroupIntent::new(IntentKind::AddMembers, self.group_id.clone(), intent_data); + intent.store(conn)?; + + self.sync_with_conn(conn).await + } + pub async fn remove_members(&self, wallet_addresses: Vec) -> Result<(), GroupError> { let conn = &mut self.client.store.conn()?; let intent_data: Vec = RemoveMembersIntentData::new(wallet_addresses.into()).into(); @@ -460,6 +474,22 @@ where self.sync_with_conn(conn).await } + pub(crate) async fn remove_members_by_installation_id( + &self, + installation_ids: Vec>, + ) -> Result<(), GroupError> { + let conn = &mut self.client.store.conn()?; + let intent_data: Vec = RemoveMembersIntentData::new(installation_ids.into()).into(); + let intent = NewGroupIntent::new( + IntentKind::RemoveMembers, + self.group_id.clone(), + intent_data, + ); + intent.store(conn)?; + + self.sync_with_conn(conn).await + } + pub async fn key_update(&self) -> Result<(), GroupError> { let conn = &mut self.client.store.conn()?; let intent = NewGroupIntent::new(IntentKind::KeyUpdate, self.group_id.clone(), vec![]); @@ -570,8 +600,6 @@ where let commit_bytes = commit.tls_serialize_detached()?; - // If somehow another installation has made it into the commit, this will be missing - // their installation ID let installation_ids: Vec> = key_packages.iter().map(|kp| kp.installation_id()).collect(); @@ -583,23 +611,14 @@ where IntentKind::RemoveMembers => { let intent_data = RemoveMembersIntentData::from_bytes(intent.data.as_slice())?; - let key_packages = self - .client - .get_key_packages(intent_data.address_or_id) - .await?; - - let installation_ids = self - .members()? - .into_iter() - .filter(|member| { - intent_data - .account_addresses - .contains(&member.wallet_address) - }) - .fold(vec![], |mut acc, member| { - acc.extend(member.installation_ids); - acc - }); + let installation_ids = { + match intent_data.address_or_id { + AddressOrInstallationId::AccountAddresses(addrs) => { + self.client.get_all_active_installation_ids(addrs).await? + } + AddressOrInstallationId::InstallationIds(ids) => ids, + } + }; let leaf_nodes: Vec = openmls_group .members() @@ -744,7 +763,7 @@ mod tests { let amal_group = amal.create_group().unwrap(); // Add bola amal_group - .add_members(vec![bola.account_address()]) + .add_members_by_installation_id(vec![bola.installation_public_key()]) .await .unwrap(); @@ -754,11 +773,11 @@ mod tests { // Have amal and bola both invite charlie. amal_group - .add_members(vec![charlie.account_address()]) + .add_members_by_installation_id(vec![charlie.installation_public_key()]) .await .expect("failed to add charlie"); bola_group - .add_members(vec![charlie.account_address()]) + .add_members_by_installation_id(vec![charlie.installation_public_key()]) .await .unwrap(); @@ -809,7 +828,7 @@ mod tests { let group = client.create_group().expect("create group"); group - .add_members(vec![client_2.account_address()]) + .add_members_by_installation_id(vec![client_2.installation_public_key()]) .await .unwrap(); @@ -829,7 +848,9 @@ mod tests { let client = ClientBuilder::new_test_client(generate_local_wallet().into()).await; let group = client.create_group().expect("create group"); - let result = group.add_members(vec!["1234".to_string()]).await; + let result = group + .add_members_by_installation_id(vec![b"1234".to_vec()]) + .await; assert!(result.is_err()); } @@ -843,13 +864,13 @@ mod tests { let group = client_1.create_group().expect("create group"); group - .add_members(vec![client_2.account_address()]) + .add_members_by_installation_id(vec![client_2.installation_public_key()]) .await .expect("group create failure"); // Try and add another member without merging the pending commit group - .remove_members(vec![client_2.account_address()]) + .remove_members_by_installation_id(vec![client_2.installation_public_key()]) .await .expect("group create failure"); @@ -894,7 +915,7 @@ mod tests { let group = client.create_group().expect("create group"); group - .add_members(vec![client_2.account_address()]) + .add_members_by_installation_id(vec![client_2.installation_public_key()]) .await .unwrap(); @@ -931,4 +952,9 @@ mod tests { .unwrap(); assert_eq!(group.members().unwrap().len(), 2); } + + #[tokio::test] + async fn test_intermittent_installation_id_addition() { + todo!() + } } From 095871f70cad4a90d2d7f0bc0f6d2890e705e670 Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Fri, 8 Dec 2023 12:22:25 -0500 Subject: [PATCH 12/20] ed25519 public key validation --- Cargo.lock | 3 +++ xmtp_cryptography/Cargo.toml | 3 +++ xmtp_cryptography/src/signature.rs | 31 +++++++++++++++++++++++++ xmtp_mls/src/groups/mod.rs | 36 +++++++++++++++++++++++++----- 4 files changed, 67 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bdb63fb22..15d147575 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6571,11 +6571,14 @@ dependencies = [ name = "xmtp_cryptography" version = "0.1.0" dependencies = [ + "curve25519-dalek", "ecdsa 0.15.1", + "ed25519-dalek", "ethers", "ethers-core 2.0.10", "hex", "k256 0.12.0", + "log", "rand 0.8.5", "rand_chacha 0.3.1", "serde", diff --git a/xmtp_cryptography/Cargo.toml b/xmtp_cryptography/Cargo.toml index 459c56f0a..8719e8adc 100644 --- a/xmtp_cryptography/Cargo.toml +++ b/xmtp_cryptography/Cargo.toml @@ -16,6 +16,9 @@ serde = "1.0.163" sha2 = "0.10.7" sha3 = "0.10.6" thiserror = "1.0.40" +curve25519-dalek = "4" +ed25519-dalek = "2" +log = "0.4" [features] ws = ["ethers/ws"] diff --git a/xmtp_cryptography/src/signature.rs b/xmtp_cryptography/src/signature.rs index 27bbd4ef6..ddc0ba8dc 100644 --- a/xmtp_cryptography/src/signature.rs +++ b/xmtp_cryptography/src/signature.rs @@ -1,3 +1,4 @@ +use curve25519_dalek::{edwards::CompressedEdwardsY, traits::IsIdentity}; use ethers_core::types::{self as ethers_types, H160}; pub use k256::ecdsa::{RecoveryId, SigningKey, VerifyingKey}; use k256::Secp256k1; @@ -123,6 +124,36 @@ pub fn is_valid_ethereum_address>(address: S) -> bool { address.chars().all(|c| c.is_ascii_hexdigit()) } +/// Check if an ed25519 public signature key is valid. +pub fn is_valid_ed25519_public_key<'a, Bytes: AsRef<[u8]>>(public_key: Bytes) -> bool { + let public_key = public_key.as_ref(); + + let compressed = match CompressedEdwardsY::from_slice(public_key) { + Ok(v) => v, + Err(_) => { + log::debug!("Invalid ed22519 public key. Does not have length of 32"); + return false; + } + }; + + match compressed.decompress() { + Some(point) => { + if point.is_small_order() || point.is_identity() { + log::debug!( + "Invalid public key, not a point on the curve or is the identity element." + ); + return false; + } + } + None => { + log::debug!("Not a valid ed25519 public key: Decompression failure"); + return false; + } + } + + true +} + #[cfg(test)] pub mod tests { use super::is_valid_ethereum_address; diff --git a/xmtp_mls/src/groups/mod.rs b/xmtp_mls/src/groups/mod.rs index bbf6cbf5d..4626ec34f 100644 --- a/xmtp_mls/src/groups/mod.rs +++ b/xmtp_mls/src/groups/mod.rs @@ -16,7 +16,7 @@ use openmls_traits::OpenMlsProvider; use std::mem::discriminant; use thiserror::Error; use tls_codec::{Deserialize, Serialize}; -use xmtp_cryptography::signature::is_valid_ethereum_address; +use xmtp_cryptography::signature::{is_valid_ed25519_public_key, is_valid_ethereum_address}; use xmtp_proto::api_client::{Envelope, XmtpApiClient, XmtpMlsClient}; use self::intents::{AddMembersIntentData, PostCommitAction, RemoveMembersIntentData}; @@ -77,6 +77,8 @@ pub enum GroupError { Diesel(#[from] diesel::result::Error), #[error("The address {0:?} is not a valid ethereum address")] InvalidAddresses(Vec), + #[error("Public Keys {0:?} are not valid ed25519 public keys")] + InvalidPublicKeys(Vec>), } impl RetryableError for GroupError { @@ -427,17 +429,38 @@ where Ok(()) } - pub async fn add_members(&self, wallet_addresses: Vec) -> Result<(), GroupError> { + fn validate_evm_addresses(wallet_addresses: &Vec) -> Result<(), GroupError> { let mut invalid = wallet_addresses .iter() .filter(|a| !is_valid_ethereum_address(a)) .peekable(); + if invalid.peek().is_some() { return Err(GroupError::InvalidAddresses( + invalid.map(ToString::to_string).collect::>(), + )); + } + + Ok(()) + } + + fn validate_ed25519_keys(keys: &Vec>) -> Result<(), GroupError> { + let mut invalid = keys + .iter() + .filter(|a| !is_valid_ed25519_public_key(a)) + .peekable(); + + if invalid.peek().is_some() { + return Err(GroupError::InvalidPublicKeys( invalid.map(Clone::clone).collect::>(), )); } + Ok(()) + } + + pub async fn add_members(&self, wallet_addresses: Vec) -> Result<(), GroupError> { + Self::validate_evm_addresses(&wallet_addresses)?; let conn = &mut self.client.store.conn()?; let intent_data: Vec = AddMembersIntentData::new(wallet_addresses.into()).try_into()?; let intent = @@ -451,8 +474,8 @@ where &self, installation_ids: Vec>, ) -> Result<(), GroupError> { + Self::validate_ed25519_keys(&installation_ids)?; let conn = &mut self.client.store.conn()?; - //FIXME:INSIPX -- VALIDATE installation ID somehow let intent_data: Vec = AddMembersIntentData::new(installation_ids.into()).try_into()?; let intent = NewGroupIntent::new(IntentKind::AddMembers, self.group_id.clone(), intent_data); @@ -462,6 +485,7 @@ where } pub async fn remove_members(&self, wallet_addresses: Vec) -> Result<(), GroupError> { + Self::validate_evm_addresses(&wallet_addresses)?; let conn = &mut self.client.store.conn()?; let intent_data: Vec = RemoveMembersIntentData::new(wallet_addresses.into()).into(); let intent = NewGroupIntent::new( @@ -474,10 +498,12 @@ where self.sync_with_conn(conn).await } + #[allow(dead_code)] pub(crate) async fn remove_members_by_installation_id( &self, installation_ids: Vec>, ) -> Result<(), GroupError> { + Self::validate_ed25519_keys(&installation_ids)?; let conn = &mut self.client.store.conn()?; let intent_data: Vec = RemoveMembersIntentData::new(installation_ids.into()).into(); let intent = NewGroupIntent::new( @@ -954,7 +980,5 @@ mod tests { } #[tokio::test] - async fn test_intermittent_installation_id_addition() { - todo!() - } + async fn test_intermittent_installation_id_addition() {} } From d3317e12f5570849ac42d60ee4d87506c1e1f228 Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Fri, 8 Dec 2023 13:56:16 -0500 Subject: [PATCH 13/20] clippy --- xmtp_cryptography/src/signature.rs | 2 +- xmtp_mls/Cargo.toml | 1 + xmtp_mls/src/groups/mod.rs | 14 ++++++++------ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/xmtp_cryptography/src/signature.rs b/xmtp_cryptography/src/signature.rs index ddc0ba8dc..a2681d441 100644 --- a/xmtp_cryptography/src/signature.rs +++ b/xmtp_cryptography/src/signature.rs @@ -125,7 +125,7 @@ pub fn is_valid_ethereum_address>(address: S) -> bool { } /// Check if an ed25519 public signature key is valid. -pub fn is_valid_ed25519_public_key<'a, Bytes: AsRef<[u8]>>(public_key: Bytes) -> bool { +pub fn is_valid_ed25519_public_key>(public_key: Bytes) -> bool { let public_key = public_key.as_ref(); let compressed = match CompressedEdwardsY::from_slice(public_key) { diff --git a/xmtp_mls/Cargo.toml b/xmtp_mls/Cargo.toml index f4407d8d4..30e4e0e2f 100644 --- a/xmtp_mls/Cargo.toml +++ b/xmtp_mls/Cargo.toml @@ -58,3 +58,4 @@ tracing-subscriber = { version = "0.3.17", features = ["env-filter"] } xmtp_api_grpc = { path = "../xmtp_api_grpc" } flume = "0.11" ctor = "0.2" +tokio = { version = "1.28.1", features = ["macros", "time", "rt-multi-thread"] } diff --git a/xmtp_mls/src/groups/mod.rs b/xmtp_mls/src/groups/mod.rs index 4626ec34f..b30fdbc41 100644 --- a/xmtp_mls/src/groups/mod.rs +++ b/xmtp_mls/src/groups/mod.rs @@ -429,7 +429,7 @@ where Ok(()) } - fn validate_evm_addresses(wallet_addresses: &Vec) -> Result<(), GroupError> { + fn validate_evm_addresses(wallet_addresses: &[String]) -> Result<(), GroupError> { let mut invalid = wallet_addresses .iter() .filter(|a| !is_valid_ethereum_address(a)) @@ -444,7 +444,7 @@ where Ok(()) } - fn validate_ed25519_keys(keys: &Vec>) -> Result<(), GroupError> { + fn validate_ed25519_keys(keys: &[Vec]) -> Result<(), GroupError> { let mut invalid = keys .iter() .filter(|a| !is_valid_ed25519_public_key(a)) @@ -626,6 +626,8 @@ where let commit_bytes = commit.tls_serialize_detached()?; + // If somehow another installation has made it into the commit, this will be missing + // their installation ID let installation_ids: Vec> = key_packages.iter().map(|kp| kp.installation_id()).collect(); @@ -736,7 +738,10 @@ mod tests { use xmtp_cryptography::utils::generate_local_wallet; use crate::{ - builder::ClientBuilder, storage::group_intent::IntentState, utils::topic::get_welcome_topic, + builder::{ClientBuilder, IdentityStrategy}, + storage::db_connection::DbConnection, + storage::group_intent::IntentState, + utils::topic::get_welcome_topic, }; #[tokio::test] @@ -978,7 +983,4 @@ mod tests { .unwrap(); assert_eq!(group.members().unwrap().len(), 2); } - - #[tokio::test] - async fn test_intermittent_installation_id_addition() {} } From f65b121d2e088560ffcdd2ef7c2a848e2318af04 Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Fri, 8 Dec 2023 13:57:03 -0500 Subject: [PATCH 14/20] clippy --fix --- xmtp_mls/src/groups/intents.rs | 2 +- xmtp_mls/src/groups/mod.rs | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/xmtp_mls/src/groups/intents.rs b/xmtp_mls/src/groups/intents.rs index e27e5bd4e..c11e5ff95 100644 --- a/xmtp_mls/src/groups/intents.rs +++ b/xmtp_mls/src/groups/intents.rs @@ -290,7 +290,7 @@ mod tests { use xmtp_cryptography::utils::generate_local_wallet; use super::*; - use crate::{builder::ClientBuilder, InboxOwner}; + use crate::{InboxOwner}; #[test] fn test_serialize_send_message() { diff --git a/xmtp_mls/src/groups/mod.rs b/xmtp_mls/src/groups/mod.rs index b30fdbc41..f787c359c 100644 --- a/xmtp_mls/src/groups/mod.rs +++ b/xmtp_mls/src/groups/mod.rs @@ -738,8 +738,7 @@ mod tests { use xmtp_cryptography::utils::generate_local_wallet; use crate::{ - builder::{ClientBuilder, IdentityStrategy}, - storage::db_connection::DbConnection, + builder::{ClientBuilder}, storage::group_intent::IntentState, utils::topic::get_welcome_topic, }; From b9e0ea1215632af9d9f6aa1a455f169a34d16468 Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Fri, 8 Dec 2023 13:57:18 -0500 Subject: [PATCH 15/20] fmt --- xmtp_mls/src/groups/intents.rs | 2 +- xmtp_mls/src/groups/mod.rs | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/xmtp_mls/src/groups/intents.rs b/xmtp_mls/src/groups/intents.rs index c11e5ff95..a9784c579 100644 --- a/xmtp_mls/src/groups/intents.rs +++ b/xmtp_mls/src/groups/intents.rs @@ -290,7 +290,7 @@ mod tests { use xmtp_cryptography::utils::generate_local_wallet; use super::*; - use crate::{InboxOwner}; + use crate::InboxOwner; #[test] fn test_serialize_send_message() { diff --git a/xmtp_mls/src/groups/mod.rs b/xmtp_mls/src/groups/mod.rs index f787c359c..4d138e55f 100644 --- a/xmtp_mls/src/groups/mod.rs +++ b/xmtp_mls/src/groups/mod.rs @@ -738,9 +738,7 @@ mod tests { use xmtp_cryptography::utils::generate_local_wallet; use crate::{ - builder::{ClientBuilder}, - storage::group_intent::IntentState, - utils::topic::get_welcome_topic, + builder::ClientBuilder, storage::group_intent::IntentState, utils::topic::get_welcome_topic, }; #[tokio::test] From c9ed44ead27bc580c71d5a0daaacaea48a616016 Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Fri, 8 Dec 2023 14:00:57 -0500 Subject: [PATCH 16/20] remove unused pkgs --- Cargo.lock | 1 - xmtp_cryptography/Cargo.toml | 1 - 2 files changed, 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 15d147575..f900a0214 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6573,7 +6573,6 @@ version = "0.1.0" dependencies = [ "curve25519-dalek", "ecdsa 0.15.1", - "ed25519-dalek", "ethers", "ethers-core 2.0.10", "hex", diff --git a/xmtp_cryptography/Cargo.toml b/xmtp_cryptography/Cargo.toml index 8719e8adc..4193f73c2 100644 --- a/xmtp_cryptography/Cargo.toml +++ b/xmtp_cryptography/Cargo.toml @@ -17,7 +17,6 @@ sha2 = "0.10.7" sha3 = "0.10.6" thiserror = "1.0.40" curve25519-dalek = "4" -ed25519-dalek = "2" log = "0.4" [features] From f6932d508a48f1d9f8b796212c7caf989026f756 Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Fri, 8 Dec 2023 14:04:22 -0500 Subject: [PATCH 17/20] add test for public keys --- xmtp_cryptography/src/signature.rs | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/xmtp_cryptography/src/signature.rs b/xmtp_cryptography/src/signature.rs index a2681d441..b5b8b3b1f 100644 --- a/xmtp_cryptography/src/signature.rs +++ b/xmtp_cryptography/src/signature.rs @@ -163,7 +163,7 @@ pub mod tests { signers::{LocalWallet, Signer}, }; - use crate::signature::RecoverableSignature; + use crate::signature::{is_valid_ed25519_public_key, RecoverableSignature}; pub async fn generate_random_signature(msg: &str) -> (String, Vec) { let wallet = LocalWallet::new(&mut thread_rng()); @@ -222,10 +222,20 @@ pub mod tests { #[test] fn test_eth_address() { - assert_eq!( - is_valid_ethereum_address("0x7e57Aed10441c8879ce08E45805EC01Ee9689c9f"), - true - ); + assert!(is_valid_ethereum_address( + "0x7e57Aed10441c8879ce08E45805EC01Ee9689c9f" + )); assert_eq!(is_valid_ethereum_address("123"), false); } + + #[test] + fn test_ed25519_public_key_validation() { + let public_key = + hex::decode("5E7F70A437963A8B3D0683F949FA0508970ACB87A28139B8BD67D5B01D3B0214") + .unwrap(); + assert!(is_valid_ed25519_public_key(public_key)); + + let invalid_key = b"invalid"; + assert!(!is_valid_ed25519_public_key(invalid_key)); + } } From 97fb721f0176e3393c7f12f1af801c2e31d62b04 Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Fri, 8 Dec 2023 14:17:48 -0500 Subject: [PATCH 18/20] revert gen_protos --- dev/gen_protos.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/gen_protos.sh b/dev/gen_protos.sh index d15fe88ff..dfc61150f 100755 --- a/dev/gen_protos.sh +++ b/dev/gen_protos.sh @@ -5,7 +5,7 @@ if ! cargo install --list | grep "protoc-gen-prost-crate" > /dev/null; then exit 1 fi fi -if ! buf generate https://github.com/xmtp/proto.git#branch=insipx/remove-add-wallet-addresses,subdir=proto; then +if ! buf generate https://github.com/xmtp/proto.git#branch=nmolnar/mls-verification-service,subdir=proto; then echo "Failed to generate protobuf definitions" exit 1 fi From 42a6c6d3c78a23bbff2d4197bfa14a24b4a48e6d Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Fri, 8 Dec 2023 14:23:11 -0500 Subject: [PATCH 19/20] remove unused dev dep --- xmtp_mls/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/xmtp_mls/Cargo.toml b/xmtp_mls/Cargo.toml index 30e4e0e2f..f4407d8d4 100644 --- a/xmtp_mls/Cargo.toml +++ b/xmtp_mls/Cargo.toml @@ -58,4 +58,3 @@ tracing-subscriber = { version = "0.3.17", features = ["env-filter"] } xmtp_api_grpc = { path = "../xmtp_api_grpc" } flume = "0.11" ctor = "0.2" -tokio = { version = "1.28.1", features = ["macros", "time", "rt-multi-thread"] } From cea2db425e0cc488ebe1568ebc017ae71b7fc18c Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Mon, 11 Dec 2023 15:21:44 -0500 Subject: [PATCH 20/20] pluralize AddressOrInstallationId --- xmtp_mls/src/client.rs | 8 +- xmtp_mls/src/groups/intents.rs | 64 +-- xmtp_mls/src/groups/mod.rs | 6 +- xmtp_proto/src/gen/xmtp.mls.database.rs | 425 +++++++++--------- xmtp_proto/src/gen/xmtp.mls.database.serde.rs | 88 ++-- 5 files changed, 294 insertions(+), 297 deletions(-) diff --git a/xmtp_mls/src/client.rs b/xmtp_mls/src/client.rs index d58fd9e99..dc04372c9 100644 --- a/xmtp_mls/src/client.rs +++ b/xmtp_mls/src/client.rs @@ -13,7 +13,7 @@ use xmtp_proto::api_client::{Envelope, XmtpApiClient, XmtpMlsClient}; use crate::{ api_client_wrapper::{ApiClientWrapper, IdentityUpdate}, - groups::{AddressOrInstallationId, IntentError, MlsGroup}, + groups::{AddressesOrInstallationIds, IntentError, MlsGroup}, identity::Identity, retry::Retry, storage::{ @@ -273,13 +273,13 @@ where pub(crate) async fn get_key_packages( &self, - address_or_id: AddressOrInstallationId, + address_or_id: AddressesOrInstallationIds, ) -> Result, ClientError> { match address_or_id { - AddressOrInstallationId::AccountAddresses(addrs) => { + AddressesOrInstallationIds::AccountAddresses(addrs) => { self.get_key_packages_for_wallet_addresses(addrs).await } - AddressOrInstallationId::InstallationIds(ids) => { + AddressesOrInstallationIds::InstallationIds(ids) => { self.get_key_packages_for_installation_ids(ids).await } } diff --git a/xmtp_mls/src/groups/intents.rs b/xmtp_mls/src/groups/intents.rs index a9784c579..4b52f8801 100644 --- a/xmtp_mls/src/groups/intents.rs +++ b/xmtp_mls/src/groups/intents.rs @@ -4,12 +4,12 @@ use thiserror::Error; use tls_codec::Serialize; use xmtp_proto::xmtp::mls::database::{ add_members_data::{Version as AddMembersVersion, V1 as AddMembersV1}, - address_or_installation_id::AddressOrInstallationId as AddressOrInstallationIdProto, + addresses_or_installation_ids::AddressesOrInstallationIds as AddressesOrInstallationIdsProto, post_commit_action::{Kind as PostCommitActionKind, SendWelcomes as SendWelcomesProto}, remove_members_data::{Version as RemoveMembersVersion, V1 as RemoveMembersV1}, send_message_data::{Version as SendMessageVersion, V1 as SendMessageV1}, AccountAddresses, AddMembersData, - AddressOrInstallationId as AddressOrInstallationIdProtoWrapper, InstallationIds, + AddressesOrInstallationIds as AddressesOrInstallationIdsProtoWrapper, InstallationIds, PostCommitAction as PostCommitActionProto, RemoveMembersData, SendMessageData, }; @@ -68,27 +68,27 @@ impl From for Vec { } #[derive(Debug, PartialEq, Eq, Clone)] -pub enum AddressOrInstallationId { +pub enum AddressesOrInstallationIds { AccountAddresses(Vec), InstallationIds(Vec>), } -impl From for AddressOrInstallationIdProtoWrapper { - fn from(address_or_id: AddressOrInstallationId) -> Self { +impl From for AddressesOrInstallationIdsProtoWrapper { + fn from(address_or_id: AddressesOrInstallationIds) -> Self { match address_or_id { - AddressOrInstallationId::AccountAddresses(account_addresses) => { - AddressOrInstallationIdProtoWrapper { - address_or_installation_id: Some( - AddressOrInstallationIdProto::AccountAddresses(AccountAddresses { + AddressesOrInstallationIds::AccountAddresses(account_addresses) => { + AddressesOrInstallationIdsProtoWrapper { + addresses_or_installation_ids: Some( + AddressesOrInstallationIdsProto::AccountAddresses(AccountAddresses { account_addresses, }), ), } } - AddressOrInstallationId::InstallationIds(installation_ids) => { - AddressOrInstallationIdProtoWrapper { - address_or_installation_id: Some( - AddressOrInstallationIdProto::InstallationIds(InstallationIds { + AddressesOrInstallationIds::InstallationIds(installation_ids) => { + AddressesOrInstallationIdsProtoWrapper { + addresses_or_installation_ids: Some( + AddressesOrInstallationIdsProto::InstallationIds(InstallationIds { installation_ids, }), ), @@ -98,41 +98,41 @@ impl From for AddressOrInstallationIdProtoWrapper { } } -impl TryFrom for AddressOrInstallationId { +impl TryFrom for AddressesOrInstallationIds { type Error = IntentError; - fn try_from(wrapper: AddressOrInstallationIdProtoWrapper) -> Result { - match wrapper.address_or_installation_id { - Some(AddressOrInstallationIdProto::AccountAddresses(addrs)) => Ok( - AddressOrInstallationId::AccountAddresses(addrs.account_addresses), + fn try_from(wrapper: AddressesOrInstallationIdsProtoWrapper) -> Result { + match wrapper.addresses_or_installation_ids { + Some(AddressesOrInstallationIdsProto::AccountAddresses(addrs)) => Ok( + AddressesOrInstallationIds::AccountAddresses(addrs.account_addresses), ), - Some(AddressOrInstallationIdProto::InstallationIds(ids)) => Ok( - AddressOrInstallationId::InstallationIds(ids.installation_ids), + Some(AddressesOrInstallationIdsProto::InstallationIds(ids)) => Ok( + AddressesOrInstallationIds::InstallationIds(ids.installation_ids), ), _ => Err(IntentError::Generic("missing payload".to_string())), } } } -impl From> for AddressOrInstallationId { +impl From> for AddressesOrInstallationIds { fn from(addrs: Vec
) -> Self { - AddressOrInstallationId::AccountAddresses(addrs) + AddressesOrInstallationIds::AccountAddresses(addrs) } } -impl From>> for AddressOrInstallationId { +impl From>> for AddressesOrInstallationIds { fn from(installation_ids: Vec>) -> Self { - AddressOrInstallationId::InstallationIds(installation_ids) + AddressesOrInstallationIds::InstallationIds(installation_ids) } } #[derive(Debug, Clone)] pub struct AddMembersIntentData { - pub address_or_id: AddressOrInstallationId, + pub address_or_id: AddressesOrInstallationIds, } impl AddMembersIntentData { - pub fn new(address_or_id: AddressOrInstallationId) -> Self { + pub fn new(address_or_id: AddressesOrInstallationIds) -> Self { Self { address_or_id } } @@ -140,7 +140,7 @@ impl AddMembersIntentData { let mut buf = Vec::new(); AddMembersData { version: Some(AddMembersVersion::V1(AddMembersV1 { - address_or_installation_id: Some(self.address_or_id.clone().into()), + addresses_or_installation_ids: Some(self.address_or_id.clone().into()), })), } .encode(&mut buf) @@ -153,7 +153,7 @@ impl AddMembersIntentData { let msg = AddMembersData::decode(data)?; let address_or_id = match msg.version { Some(AddMembersVersion::V1(v1)) => v1 - .address_or_installation_id + .addresses_or_installation_ids .ok_or(IntentError::Generic("missing payload".to_string()))?, None => return Err(IntentError::Generic("missing payload".to_string())), }; @@ -172,11 +172,11 @@ impl TryFrom for Vec { #[derive(Debug, Clone)] pub struct RemoveMembersIntentData { - pub address_or_id: AddressOrInstallationId, + pub address_or_id: AddressesOrInstallationIds, } impl RemoveMembersIntentData { - pub fn new(address_or_id: AddressOrInstallationId) -> Self { + pub fn new(address_or_id: AddressesOrInstallationIds) -> Self { Self { address_or_id } } @@ -185,7 +185,7 @@ impl RemoveMembersIntentData { RemoveMembersData { version: Some(RemoveMembersVersion::V1(RemoveMembersV1 { - address_or_installation_id: Some(self.address_or_id.clone().into()), + addresses_or_installation_ids: Some(self.address_or_id.clone().into()), })), } .encode(&mut buf) @@ -198,7 +198,7 @@ impl RemoveMembersIntentData { let msg = RemoveMembersData::decode(data)?; let address_or_id = match msg.version { Some(RemoveMembersVersion::V1(v1)) => v1 - .address_or_installation_id + .addresses_or_installation_ids .ok_or(IntentError::Generic("missing payload".to_string()))?, None => return Err(IntentError::Generic("missing payload".to_string())), }; diff --git a/xmtp_mls/src/groups/mod.rs b/xmtp_mls/src/groups/mod.rs index 4d138e55f..ddcf591cf 100644 --- a/xmtp_mls/src/groups/mod.rs +++ b/xmtp_mls/src/groups/mod.rs @@ -20,7 +20,7 @@ use xmtp_cryptography::signature::{is_valid_ed25519_public_key, is_valid_ethereu use xmtp_proto::api_client::{Envelope, XmtpApiClient, XmtpMlsClient}; use self::intents::{AddMembersIntentData, PostCommitAction, RemoveMembersIntentData}; -pub use self::intents::{AddressOrInstallationId, IntentError}; +pub use self::intents::{AddressesOrInstallationIds, IntentError}; use crate::{ api_client_wrapper::WelcomeMessage, client::{ClientError, MessageProcessingError}, @@ -641,10 +641,10 @@ where let installation_ids = { match intent_data.address_or_id { - AddressOrInstallationId::AccountAddresses(addrs) => { + AddressesOrInstallationIds::AccountAddresses(addrs) => { self.client.get_all_active_installation_ids(addrs).await? } - AddressOrInstallationId::InstallationIds(ids) => ids, + AddressesOrInstallationIds::InstallationIds(ids) => ids, } }; diff --git a/xmtp_proto/src/gen/xmtp.mls.database.rs b/xmtp_proto/src/gen/xmtp.mls.database.rs index 0fae63011..9f74c8c05 100644 --- a/xmtp_proto/src/gen/xmtp.mls.database.rs +++ b/xmtp_proto/src/gen/xmtp.mls.database.rs @@ -3,22 +3,22 @@ #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SendMessageData { - #[prost(oneof = "send_message_data::Version", tags = "1")] + #[prost(oneof="send_message_data::Version", tags="1")] pub version: ::core::option::Option, } /// Nested message and enum types in `SendMessageData`. pub mod send_message_data { /// V1 of SendMessagePublishData #[allow(clippy::derive_partial_eq_without_eq)] - #[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct V1 { - #[prost(bytes = "vec", tag = "1")] + #[prost(bytes="vec", tag="1")] pub payload_bytes: ::prost::alloc::vec::Vec, } #[allow(clippy::derive_partial_eq_without_eq)] - #[derive(Clone, PartialEq, ::prost::Oneof)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Version { - #[prost(message, tag = "1")] + #[prost(message, tag="1")] V1(V1), } } @@ -26,35 +26,31 @@ pub mod send_message_data { #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct AccountAddresses { - #[prost(string, repeated, tag = "1")] + #[prost(string, repeated, tag="1")] pub account_addresses: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, } /// Wrapper around a list of repeated Installation IDs #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct InstallationIds { - #[prost(bytes = "vec", repeated, tag = "1")] + #[prost(bytes="vec", repeated, tag="1")] pub installation_ids: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, } /// One of an EVM account address or Installation ID #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] -pub struct AddressOrInstallationId { - #[prost( - oneof = "address_or_installation_id::AddressOrInstallationId", - tags = "1, 2" - )] - pub address_or_installation_id: - ::core::option::Option, +pub struct AddressesOrInstallationIds { + #[prost(oneof="addresses_or_installation_ids::AddressesOrInstallationIds", tags="1, 2")] + pub addresses_or_installation_ids: ::core::option::Option, } -/// Nested message and enum types in `AddressOrInstallationId`. -pub mod address_or_installation_id { +/// Nested message and enum types in `AddressesOrInstallationIds`. +pub mod addresses_or_installation_ids { #[allow(clippy::derive_partial_eq_without_eq)] - #[derive(Clone, PartialEq, ::prost::Oneof)] - pub enum AddressOrInstallationId { - #[prost(message, tag = "1")] +#[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum AddressesOrInstallationIds { + #[prost(message, tag="1")] AccountAddresses(super::AccountAddresses), - #[prost(message, tag = "2")] + #[prost(message, tag="2")] InstallationIds(super::InstallationIds), } } @@ -62,22 +58,22 @@ pub mod address_or_installation_id { #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct AddMembersData { - #[prost(oneof = "add_members_data::Version", tags = "1")] + #[prost(oneof="add_members_data::Version", tags="1")] pub version: ::core::option::Option, } /// Nested message and enum types in `AddMembersData`. pub mod add_members_data { /// V1 of AddMembersPublishData #[allow(clippy::derive_partial_eq_without_eq)] - #[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct V1 { - #[prost(message, optional, tag = "1")] - pub address_or_installation_id: ::core::option::Option, + #[prost(message, optional, tag="1")] + pub addresses_or_installation_ids: ::core::option::Option, } #[allow(clippy::derive_partial_eq_without_eq)] - #[derive(Clone, PartialEq, ::prost::Oneof)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Version { - #[prost(message, tag = "1")] + #[prost(message, tag="1")] V1(V1), } } @@ -85,22 +81,22 @@ pub mod add_members_data { #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct RemoveMembersData { - #[prost(oneof = "remove_members_data::Version", tags = "1")] + #[prost(oneof="remove_members_data::Version", tags="1")] pub version: ::core::option::Option, } /// Nested message and enum types in `RemoveMembersData`. pub mod remove_members_data { /// V1 of RemoveMembersPublishData #[allow(clippy::derive_partial_eq_without_eq)] - #[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct V1 { - #[prost(message, optional, tag = "1")] - pub address_or_installation_id: ::core::option::Option, + #[prost(message, optional, tag="1")] + pub addresses_or_installation_ids: ::core::option::Option, } #[allow(clippy::derive_partial_eq_without_eq)] - #[derive(Clone, PartialEq, ::prost::Oneof)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Version { - #[prost(message, tag = "1")] + #[prost(message, tag="1")] V1(V1), } } @@ -108,30 +104,30 @@ pub mod remove_members_data { #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct PostCommitAction { - #[prost(oneof = "post_commit_action::Kind", tags = "1")] + #[prost(oneof="post_commit_action::Kind", tags="1")] pub kind: ::core::option::Option, } /// Nested message and enum types in `PostCommitAction`. pub mod post_commit_action { /// SendWelcome message #[allow(clippy::derive_partial_eq_without_eq)] - #[derive(Clone, PartialEq, ::prost::Message)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct SendWelcomes { - #[prost(bytes = "vec", repeated, tag = "1")] + #[prost(bytes="vec", repeated, tag="1")] pub installation_ids: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, - #[prost(bytes = "vec", tag = "2")] + #[prost(bytes="vec", tag="2")] pub welcome_message: ::prost::alloc::vec::Vec, } #[allow(clippy::derive_partial_eq_without_eq)] - #[derive(Clone, PartialEq, ::prost::Oneof)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Kind { - #[prost(message, tag = "1")] + #[prost(message, tag="1")] SendWelcomes(SendWelcomes), } } /// Encoded file descriptor set for the `xmtp.mls.database` package pub const FILE_DESCRIPTOR_SET: &[u8] = &[ - 0x0a, 0xab, 0x18, 0x0a, 0x1a, 0x6d, 0x6c, 0x73, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, + 0x0a, 0xc3, 0x18, 0x0a, 0x1a, 0x6d, 0x6c, 0x73, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x11, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x22, 0x80, 0x01, 0x0a, 0x0f, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, @@ -150,183 +146,184 @@ pub const FILE_DESCRIPTOR_SET: &[u8] = &[ 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x49, 0x64, 0x73, 0x22, 0xdc, 0x01, 0x0a, 0x17, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x4f, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, - 0x12, 0x52, 0x0a, 0x11, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x78, 0x6d, - 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, - 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, - 0x48, 0x00, 0x52, 0x10, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x65, 0x73, 0x12, 0x4f, 0x0a, 0x10, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, + 0x6e, 0x49, 0x64, 0x73, 0x22, 0xe2, 0x01, 0x0a, 0x1a, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x65, 0x73, 0x4f, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x49, 0x64, 0x73, 0x12, 0x52, 0x0a, 0x11, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, - 0x73, 0x65, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, - 0x64, 0x73, 0x48, 0x00, 0x52, 0x0f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x42, 0x1c, 0x0a, 0x1a, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x5f, 0x6f, 0x72, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x69, 0x64, 0x22, 0xc2, 0x01, 0x0a, 0x0e, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, - 0x72, 0x73, 0x44, 0x61, 0x74, 0x61, 0x12, 0x36, 0x0a, 0x02, 0x76, 0x31, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, 0x61, - 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x73, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x31, 0x48, 0x00, 0x52, 0x02, 0x76, 0x31, 0x1a, 0x6d, - 0x0a, 0x02, 0x56, 0x31, 0x12, 0x67, 0x0a, 0x1a, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, - 0x6f, 0x72, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, + 0x73, 0x65, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x65, 0x73, 0x48, 0x00, 0x52, 0x10, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x4f, 0x0a, 0x10, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x22, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, 0x61, 0x74, + 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x48, 0x00, 0x52, 0x0f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x42, 0x1f, 0x0a, 0x1d, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x65, 0x73, 0x5f, 0x6f, 0x72, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x22, 0xcb, 0x01, 0x0a, 0x0e, 0x41, 0x64, + 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x44, 0x61, 0x74, 0x61, 0x12, 0x36, 0x0a, 0x02, + 0x76, 0x31, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x41, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x4f, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x49, 0x64, 0x52, 0x17, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4f, 0x72, 0x49, - 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x42, 0x09, 0x0a, - 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xc8, 0x01, 0x0a, 0x11, 0x52, 0x65, 0x6d, - 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x44, 0x61, 0x74, 0x61, 0x12, 0x39, - 0x0a, 0x02, 0x76, 0x31, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x78, 0x6d, 0x74, - 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x52, - 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x44, 0x61, 0x74, 0x61, - 0x2e, 0x56, 0x31, 0x48, 0x00, 0x52, 0x02, 0x76, 0x31, 0x1a, 0x6d, 0x0a, 0x02, 0x56, 0x31, 0x12, - 0x67, 0x0a, 0x1a, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x6f, 0x72, 0x5f, 0x69, 0x6e, - 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, - 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4f, - 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x52, - 0x17, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4f, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, - 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x42, 0x09, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x22, 0xd7, 0x01, 0x0a, 0x10, 0x50, 0x6f, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, - 0x69, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x57, 0x0a, 0x0d, 0x73, 0x65, 0x6e, 0x64, - 0x5f, 0x77, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x30, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, - 0x61, 0x73, 0x65, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x41, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x57, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, - 0x73, 0x48, 0x00, 0x52, 0x0c, 0x73, 0x65, 0x6e, 0x64, 0x57, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, - 0x73, 0x1a, 0x62, 0x0a, 0x0c, 0x53, 0x65, 0x6e, 0x64, 0x57, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, - 0x73, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0f, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12, 0x27, 0x0a, 0x0f, - 0x77, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x77, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x06, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x42, 0xb5, 0x01, - 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, - 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x42, 0x0c, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x28, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x6d, 0x74, 0x70, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, - 0x33, 0x2f, 0x67, 0x6f, 0x2f, 0x6d, 0x6c, 0x73, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, - 0x65, 0xa2, 0x02, 0x03, 0x58, 0x4d, 0x44, 0xaa, 0x02, 0x11, 0x58, 0x6d, 0x74, 0x70, 0x2e, 0x4d, - 0x6c, 0x73, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0xca, 0x02, 0x11, 0x58, 0x6d, - 0x74, 0x70, 0x5c, 0x4d, 0x6c, 0x73, 0x5c, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0xe2, - 0x02, 0x1d, 0x58, 0x6d, 0x74, 0x70, 0x5c, 0x4d, 0x6c, 0x73, 0x5c, 0x44, 0x61, 0x74, 0x61, 0x62, - 0x61, 0x73, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, - 0x02, 0x13, 0x58, 0x6d, 0x74, 0x70, 0x3a, 0x3a, 0x4d, 0x6c, 0x73, 0x3a, 0x3a, 0x44, 0x61, 0x74, - 0x61, 0x62, 0x61, 0x73, 0x65, 0x4a, 0xee, 0x0d, 0x0a, 0x06, 0x12, 0x04, 0x02, 0x00, 0x49, 0x01, - 0x0a, 0x27, 0x0a, 0x01, 0x0c, 0x12, 0x03, 0x02, 0x00, 0x12, 0x32, 0x1d, 0x20, 0x56, 0x33, 0x20, - 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x73, - 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x0a, 0x0a, 0x08, 0x0a, 0x01, 0x02, 0x12, 0x03, - 0x04, 0x00, 0x1a, 0x0a, 0x08, 0x0a, 0x01, 0x08, 0x12, 0x03, 0x06, 0x00, 0x3f, 0x0a, 0x09, 0x0a, - 0x02, 0x08, 0x0b, 0x12, 0x03, 0x06, 0x00, 0x3f, 0x0a, 0x34, 0x0a, 0x02, 0x04, 0x00, 0x12, 0x04, - 0x0a, 0x00, 0x13, 0x01, 0x1a, 0x28, 0x20, 0x54, 0x68, 0x65, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, - 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x75, 0x62, 0x6c, - 0x69, 0x73, 0x68, 0x20, 0x61, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x0a, 0x0a, 0x0a, - 0x0a, 0x03, 0x04, 0x00, 0x01, 0x12, 0x03, 0x0a, 0x08, 0x17, 0x0a, 0x2c, 0x0a, 0x04, 0x04, 0x00, - 0x03, 0x00, 0x12, 0x04, 0x0c, 0x02, 0x0e, 0x03, 0x1a, 0x1e, 0x20, 0x56, 0x31, 0x20, 0x6f, 0x66, - 0x20, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x50, 0x75, 0x62, 0x6c, - 0x69, 0x73, 0x68, 0x44, 0x61, 0x74, 0x61, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x03, 0x00, - 0x01, 0x12, 0x03, 0x0c, 0x0a, 0x0c, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x00, 0x03, 0x00, 0x02, 0x00, - 0x12, 0x03, 0x0d, 0x04, 0x1c, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x00, 0x03, 0x00, 0x02, 0x00, 0x05, - 0x12, 0x03, 0x0d, 0x04, 0x09, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x00, 0x03, 0x00, 0x02, 0x00, 0x01, - 0x12, 0x03, 0x0d, 0x0a, 0x17, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, - 0x12, 0x03, 0x0d, 0x1a, 0x1b, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x00, 0x08, 0x00, 0x12, 0x04, 0x10, - 0x02, 0x12, 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x08, 0x00, 0x01, 0x12, 0x03, 0x10, 0x08, - 0x0f, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x00, 0x12, 0x03, 0x11, 0x04, 0x0e, 0x0a, 0x0c, - 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x06, 0x12, 0x03, 0x11, 0x04, 0x06, 0x0a, 0x0c, 0x0a, 0x05, - 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x11, 0x07, 0x09, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, - 0x02, 0x00, 0x03, 0x12, 0x03, 0x11, 0x0c, 0x0d, 0x0a, 0x45, 0x0a, 0x02, 0x04, 0x01, 0x12, 0x04, - 0x15, 0x00, 0x17, 0x01, 0x1a, 0x39, 0x20, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x20, 0x61, - 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x61, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x61, 0x66, 0x20, - 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x45, 0x56, 0x4d, 0x20, 0x41, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x0a, 0x0a, - 0x0a, 0x0a, 0x03, 0x04, 0x01, 0x01, 0x12, 0x03, 0x15, 0x08, 0x18, 0x0a, 0x0b, 0x0a, 0x04, 0x04, - 0x01, 0x02, 0x00, 0x12, 0x03, 0x16, 0x02, 0x28, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, - 0x04, 0x12, 0x03, 0x16, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x05, 0x12, - 0x03, 0x16, 0x0b, 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x01, 0x12, 0x03, 0x16, - 0x12, 0x23, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x03, 0x12, 0x03, 0x16, 0x26, 0x27, - 0x0a, 0x40, 0x0a, 0x02, 0x04, 0x02, 0x12, 0x04, 0x1a, 0x00, 0x1c, 0x01, 0x1a, 0x34, 0x20, 0x57, + 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x31, 0x48, 0x00, + 0x52, 0x02, 0x76, 0x31, 0x1a, 0x76, 0x0a, 0x02, 0x56, 0x31, 0x12, 0x70, 0x0a, 0x1d, 0x61, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x5f, 0x6f, 0x72, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x2d, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, 0x61, 0x74, + 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x4f, + 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, + 0x52, 0x1a, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x4f, 0x72, 0x49, 0x6e, 0x73, + 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x42, 0x09, 0x0a, 0x07, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xd1, 0x01, 0x0a, 0x11, 0x52, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x44, 0x61, 0x74, 0x61, 0x12, 0x39, 0x0a, + 0x02, 0x76, 0x31, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x78, 0x6d, 0x74, 0x70, + 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x52, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x44, 0x61, 0x74, 0x61, 0x2e, + 0x56, 0x31, 0x48, 0x00, 0x52, 0x02, 0x76, 0x31, 0x1a, 0x76, 0x0a, 0x02, 0x56, 0x31, 0x12, 0x70, + 0x0a, 0x1d, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x5f, 0x6f, 0x72, 0x5f, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, + 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x65, 0x73, 0x4f, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x49, 0x64, 0x73, 0x52, 0x1a, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x4f, + 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, + 0x42, 0x09, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xd7, 0x01, 0x0a, 0x10, + 0x50, 0x6f, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x57, 0x0a, 0x0d, 0x73, 0x65, 0x6e, 0x64, 0x5f, 0x77, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, + 0x6c, 0x73, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x50, 0x6f, 0x73, 0x74, + 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x6e, + 0x64, 0x57, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x73, 0x48, 0x00, 0x52, 0x0c, 0x73, 0x65, 0x6e, + 0x64, 0x57, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x73, 0x1a, 0x62, 0x0a, 0x0c, 0x53, 0x65, 0x6e, + 0x64, 0x57, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0c, 0x52, 0x0f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x49, 0x64, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x77, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x5f, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x77, + 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x06, 0x0a, + 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x42, 0xb5, 0x01, 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x6d, + 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x42, + 0x0c, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, + 0x28, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x6d, 0x74, 0x70, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x33, 0x2f, 0x67, 0x6f, 0x2f, 0x6d, 0x6c, 0x73, + 0x2f, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0xa2, 0x02, 0x03, 0x58, 0x4d, 0x44, 0xaa, + 0x02, 0x11, 0x58, 0x6d, 0x74, 0x70, 0x2e, 0x4d, 0x6c, 0x73, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, + 0x61, 0x73, 0x65, 0xca, 0x02, 0x11, 0x58, 0x6d, 0x74, 0x70, 0x5c, 0x4d, 0x6c, 0x73, 0x5c, 0x44, + 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0xe2, 0x02, 0x1d, 0x58, 0x6d, 0x74, 0x70, 0x5c, 0x4d, + 0x6c, 0x73, 0x5c, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13, 0x58, 0x6d, 0x74, 0x70, 0x3a, 0x3a, + 0x4d, 0x6c, 0x73, 0x3a, 0x3a, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x4a, 0xee, 0x0d, + 0x0a, 0x06, 0x12, 0x04, 0x02, 0x00, 0x49, 0x01, 0x0a, 0x27, 0x0a, 0x01, 0x0c, 0x12, 0x03, 0x02, + 0x00, 0x12, 0x32, 0x1d, 0x20, 0x56, 0x33, 0x20, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x20, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, + 0x0a, 0x0a, 0x08, 0x0a, 0x01, 0x02, 0x12, 0x03, 0x04, 0x00, 0x1a, 0x0a, 0x08, 0x0a, 0x01, 0x08, + 0x12, 0x03, 0x06, 0x00, 0x3f, 0x0a, 0x09, 0x0a, 0x02, 0x08, 0x0b, 0x12, 0x03, 0x06, 0x00, 0x3f, + 0x0a, 0x34, 0x0a, 0x02, 0x04, 0x00, 0x12, 0x04, 0x0a, 0x00, 0x13, 0x01, 0x1a, 0x28, 0x20, 0x54, + 0x68, 0x65, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, + 0x20, 0x74, 0x6f, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x20, 0x61, 0x20, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x00, 0x01, 0x12, 0x03, 0x0a, + 0x08, 0x17, 0x0a, 0x2c, 0x0a, 0x04, 0x04, 0x00, 0x03, 0x00, 0x12, 0x04, 0x0c, 0x02, 0x0e, 0x03, + 0x1a, 0x1e, 0x20, 0x56, 0x31, 0x20, 0x6f, 0x66, 0x20, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x44, 0x61, 0x74, 0x61, 0x0a, + 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x03, 0x00, 0x01, 0x12, 0x03, 0x0c, 0x0a, 0x0c, 0x0a, 0x0d, + 0x0a, 0x06, 0x04, 0x00, 0x03, 0x00, 0x02, 0x00, 0x12, 0x03, 0x0d, 0x04, 0x1c, 0x0a, 0x0e, 0x0a, + 0x07, 0x04, 0x00, 0x03, 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, 0x0d, 0x04, 0x09, 0x0a, 0x0e, 0x0a, + 0x07, 0x04, 0x00, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x0d, 0x0a, 0x17, 0x0a, 0x0e, 0x0a, + 0x07, 0x04, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x0d, 0x1a, 0x1b, 0x0a, 0x0c, 0x0a, + 0x04, 0x04, 0x00, 0x08, 0x00, 0x12, 0x04, 0x10, 0x02, 0x12, 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, + 0x00, 0x08, 0x00, 0x01, 0x12, 0x03, 0x10, 0x08, 0x0f, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, + 0x00, 0x12, 0x03, 0x11, 0x04, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x06, 0x12, + 0x03, 0x11, 0x04, 0x06, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x11, + 0x07, 0x09, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x11, 0x0c, 0x0d, + 0x0a, 0x45, 0x0a, 0x02, 0x04, 0x01, 0x12, 0x04, 0x15, 0x00, 0x17, 0x01, 0x1a, 0x39, 0x20, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x20, 0x61, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x61, 0x20, - 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, - 0x20, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x49, 0x44, - 0x73, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x02, 0x01, 0x12, 0x03, 0x1a, 0x08, 0x17, 0x0a, 0x0b, - 0x0a, 0x04, 0x04, 0x02, 0x02, 0x00, 0x12, 0x03, 0x1b, 0x02, 0x26, 0x0a, 0x0c, 0x0a, 0x05, 0x04, - 0x02, 0x02, 0x00, 0x04, 0x12, 0x03, 0x1b, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, - 0x00, 0x05, 0x12, 0x03, 0x1b, 0x0b, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x01, - 0x12, 0x03, 0x1b, 0x11, 0x21, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x03, 0x12, 0x03, - 0x1b, 0x24, 0x25, 0x0a, 0x3e, 0x0a, 0x02, 0x04, 0x03, 0x12, 0x04, 0x1f, 0x00, 0x24, 0x01, 0x1a, - 0x32, 0x20, 0x4f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x45, 0x56, 0x4d, 0x20, - 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, - 0x6f, 0x72, 0x20, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, - 0x49, 0x44, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x03, 0x01, 0x12, 0x03, 0x1f, 0x08, 0x1f, 0x0a, - 0x0c, 0x0a, 0x04, 0x04, 0x03, 0x08, 0x00, 0x12, 0x04, 0x20, 0x02, 0x23, 0x03, 0x0a, 0x0c, 0x0a, - 0x05, 0x04, 0x03, 0x08, 0x00, 0x01, 0x12, 0x03, 0x20, 0x08, 0x22, 0x0a, 0x0b, 0x0a, 0x04, 0x04, - 0x03, 0x02, 0x00, 0x12, 0x03, 0x21, 0x04, 0x2b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, - 0x06, 0x12, 0x03, 0x21, 0x04, 0x14, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x01, 0x12, - 0x03, 0x21, 0x15, 0x26, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x03, 0x12, 0x03, 0x21, - 0x29, 0x2a, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x03, 0x02, 0x01, 0x12, 0x03, 0x22, 0x04, 0x29, 0x0a, - 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x01, 0x06, 0x12, 0x03, 0x22, 0x04, 0x13, 0x0a, 0x0c, 0x0a, - 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x12, 0x03, 0x22, 0x14, 0x24, 0x0a, 0x0c, 0x0a, 0x05, 0x04, - 0x03, 0x02, 0x01, 0x03, 0x12, 0x03, 0x22, 0x27, 0x28, 0x0a, 0x39, 0x0a, 0x02, 0x04, 0x04, 0x12, - 0x04, 0x27, 0x00, 0x30, 0x01, 0x1a, 0x2d, 0x20, 0x54, 0x68, 0x65, 0x20, 0x64, 0x61, 0x74, 0x61, - 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x64, 0x64, - 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x67, 0x72, - 0x6f, 0x75, 0x70, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x04, 0x01, 0x12, 0x03, 0x27, 0x08, 0x16, - 0x0a, 0x2b, 0x0a, 0x04, 0x04, 0x04, 0x03, 0x00, 0x12, 0x04, 0x29, 0x02, 0x2b, 0x03, 0x1a, 0x1d, - 0x20, 0x56, 0x31, 0x20, 0x6f, 0x66, 0x20, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x44, 0x61, 0x74, 0x61, 0x0a, 0x0a, 0x0c, 0x0a, - 0x05, 0x04, 0x04, 0x03, 0x00, 0x01, 0x12, 0x03, 0x29, 0x0a, 0x0c, 0x0a, 0x0d, 0x0a, 0x06, 0x04, - 0x04, 0x03, 0x00, 0x02, 0x00, 0x12, 0x03, 0x2a, 0x04, 0x3b, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x04, - 0x03, 0x00, 0x02, 0x00, 0x06, 0x12, 0x03, 0x2a, 0x04, 0x1b, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x04, - 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x2a, 0x1c, 0x36, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x04, - 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x2a, 0x39, 0x3a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x04, - 0x08, 0x00, 0x12, 0x04, 0x2d, 0x02, 0x2f, 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x04, 0x08, 0x00, - 0x01, 0x12, 0x03, 0x2d, 0x08, 0x0f, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x04, 0x02, 0x00, 0x12, 0x03, - 0x2e, 0x04, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x04, 0x02, 0x00, 0x06, 0x12, 0x03, 0x2e, 0x04, - 0x06, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x04, 0x02, 0x00, 0x01, 0x12, 0x03, 0x2e, 0x07, 0x09, 0x0a, - 0x0c, 0x0a, 0x05, 0x04, 0x04, 0x02, 0x00, 0x03, 0x12, 0x03, 0x2e, 0x0c, 0x0d, 0x0a, 0x3e, 0x0a, - 0x02, 0x04, 0x05, 0x12, 0x04, 0x33, 0x00, 0x3c, 0x01, 0x1a, 0x32, 0x20, 0x54, 0x68, 0x65, 0x20, - 0x64, 0x61, 0x74, 0x61, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x20, 0x74, 0x6f, - 0x20, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x20, - 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x0a, 0x0a, 0x0a, 0x0a, - 0x03, 0x04, 0x05, 0x01, 0x12, 0x03, 0x33, 0x08, 0x19, 0x0a, 0x2e, 0x0a, 0x04, 0x04, 0x05, 0x03, - 0x00, 0x12, 0x04, 0x35, 0x02, 0x37, 0x03, 0x1a, 0x20, 0x20, 0x56, 0x31, 0x20, 0x6f, 0x66, 0x20, - 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x50, 0x75, 0x62, - 0x6c, 0x69, 0x73, 0x68, 0x44, 0x61, 0x74, 0x61, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x03, - 0x00, 0x01, 0x12, 0x03, 0x35, 0x0a, 0x0c, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x05, 0x03, 0x00, 0x02, - 0x00, 0x12, 0x03, 0x36, 0x04, 0x3b, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x05, 0x03, 0x00, 0x02, 0x00, - 0x06, 0x12, 0x03, 0x36, 0x04, 0x1b, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x05, 0x03, 0x00, 0x02, 0x00, - 0x01, 0x12, 0x03, 0x36, 0x1c, 0x36, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x05, 0x03, 0x00, 0x02, 0x00, - 0x03, 0x12, 0x03, 0x36, 0x39, 0x3a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x05, 0x08, 0x00, 0x12, 0x04, - 0x39, 0x02, 0x3b, 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x08, 0x00, 0x01, 0x12, 0x03, 0x39, - 0x08, 0x0f, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x05, 0x02, 0x00, 0x12, 0x03, 0x3a, 0x04, 0x0e, 0x0a, - 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x00, 0x06, 0x12, 0x03, 0x3a, 0x04, 0x06, 0x0a, 0x0c, 0x0a, - 0x05, 0x04, 0x05, 0x02, 0x00, 0x01, 0x12, 0x03, 0x3a, 0x07, 0x09, 0x0a, 0x0c, 0x0a, 0x05, 0x04, - 0x05, 0x02, 0x00, 0x03, 0x12, 0x03, 0x3a, 0x0c, 0x0d, 0x0a, 0x3b, 0x0a, 0x02, 0x04, 0x06, 0x12, - 0x04, 0x3f, 0x00, 0x49, 0x01, 0x1a, 0x2f, 0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x20, - 0x64, 0x61, 0x74, 0x61, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, - 0x6c, 0x20, 0x70, 0x6f, 0x73, 0x74, 0x2d, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x20, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x06, 0x01, 0x12, 0x03, 0x3f, - 0x08, 0x18, 0x0a, 0x23, 0x0a, 0x04, 0x04, 0x06, 0x03, 0x00, 0x12, 0x04, 0x41, 0x02, 0x44, 0x03, - 0x1a, 0x15, 0x20, 0x53, 0x65, 0x6e, 0x64, 0x57, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x20, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x06, 0x03, 0x00, 0x01, - 0x12, 0x03, 0x41, 0x0a, 0x16, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x06, 0x03, 0x00, 0x02, 0x00, 0x12, - 0x03, 0x42, 0x04, 0x28, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x06, 0x03, 0x00, 0x02, 0x00, 0x04, 0x12, - 0x03, 0x42, 0x04, 0x0c, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x06, 0x03, 0x00, 0x02, 0x00, 0x05, 0x12, - 0x03, 0x42, 0x0d, 0x12, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x06, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, - 0x03, 0x42, 0x13, 0x23, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x06, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, - 0x03, 0x42, 0x26, 0x27, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x06, 0x03, 0x00, 0x02, 0x01, 0x12, 0x03, - 0x43, 0x04, 0x1e, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x06, 0x03, 0x00, 0x02, 0x01, 0x05, 0x12, 0x03, - 0x43, 0x04, 0x09, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x06, 0x03, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, - 0x43, 0x0a, 0x19, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x06, 0x03, 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, - 0x43, 0x1c, 0x1d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x06, 0x08, 0x00, 0x12, 0x04, 0x46, 0x02, 0x48, - 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x06, 0x08, 0x00, 0x01, 0x12, 0x03, 0x46, 0x08, 0x0c, 0x0a, - 0x0b, 0x0a, 0x04, 0x04, 0x06, 0x02, 0x00, 0x12, 0x03, 0x47, 0x04, 0x23, 0x0a, 0x0c, 0x0a, 0x05, - 0x04, 0x06, 0x02, 0x00, 0x06, 0x12, 0x03, 0x47, 0x04, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x06, - 0x02, 0x00, 0x01, 0x12, 0x03, 0x47, 0x11, 0x1e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x06, 0x02, 0x00, - 0x03, 0x12, 0x03, 0x47, 0x21, 0x22, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6c, 0x69, 0x73, 0x74, 0x20, 0x61, 0x66, 0x20, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x20, 0x45, 0x56, 0x4d, 0x20, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x01, 0x01, 0x12, 0x03, + 0x15, 0x08, 0x18, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x00, 0x12, 0x03, 0x16, 0x02, 0x28, + 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x04, 0x12, 0x03, 0x16, 0x02, 0x0a, 0x0a, 0x0c, + 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x05, 0x12, 0x03, 0x16, 0x0b, 0x11, 0x0a, 0x0c, 0x0a, 0x05, + 0x04, 0x01, 0x02, 0x00, 0x01, 0x12, 0x03, 0x16, 0x12, 0x23, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, + 0x02, 0x00, 0x03, 0x12, 0x03, 0x16, 0x26, 0x27, 0x0a, 0x40, 0x0a, 0x02, 0x04, 0x02, 0x12, 0x04, + 0x1a, 0x00, 0x1c, 0x01, 0x1a, 0x34, 0x20, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x20, 0x61, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x61, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, + 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x49, 0x44, 0x73, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x02, + 0x01, 0x12, 0x03, 0x1a, 0x08, 0x17, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x02, 0x02, 0x00, 0x12, 0x03, + 0x1b, 0x02, 0x26, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x04, 0x12, 0x03, 0x1b, 0x02, + 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x05, 0x12, 0x03, 0x1b, 0x0b, 0x10, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x01, 0x12, 0x03, 0x1b, 0x11, 0x21, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x02, 0x02, 0x00, 0x03, 0x12, 0x03, 0x1b, 0x24, 0x25, 0x0a, 0x3e, 0x0a, 0x02, 0x04, + 0x03, 0x12, 0x04, 0x1f, 0x00, 0x24, 0x01, 0x1a, 0x32, 0x20, 0x4f, 0x6e, 0x65, 0x20, 0x6f, 0x66, + 0x20, 0x61, 0x6e, 0x20, 0x45, 0x56, 0x4d, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x6f, 0x72, 0x20, 0x49, 0x6e, 0x73, 0x74, 0x61, + 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x49, 0x44, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, + 0x03, 0x01, 0x12, 0x03, 0x1f, 0x08, 0x22, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x03, 0x08, 0x00, 0x12, + 0x04, 0x20, 0x02, 0x23, 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x08, 0x00, 0x01, 0x12, 0x03, + 0x20, 0x08, 0x25, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x03, 0x02, 0x00, 0x12, 0x03, 0x21, 0x04, 0x2b, + 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x06, 0x12, 0x03, 0x21, 0x04, 0x14, 0x0a, 0x0c, + 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x01, 0x12, 0x03, 0x21, 0x15, 0x26, 0x0a, 0x0c, 0x0a, 0x05, + 0x04, 0x03, 0x02, 0x00, 0x03, 0x12, 0x03, 0x21, 0x29, 0x2a, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x03, + 0x02, 0x01, 0x12, 0x03, 0x22, 0x04, 0x29, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x01, 0x06, + 0x12, 0x03, 0x22, 0x04, 0x13, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x12, 0x03, + 0x22, 0x14, 0x24, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x01, 0x03, 0x12, 0x03, 0x22, 0x27, + 0x28, 0x0a, 0x39, 0x0a, 0x02, 0x04, 0x04, 0x12, 0x04, 0x27, 0x00, 0x30, 0x01, 0x1a, 0x2d, 0x20, + 0x54, 0x68, 0x65, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, + 0x64, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x64, 0x64, 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, + 0x20, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, + 0x04, 0x04, 0x01, 0x12, 0x03, 0x27, 0x08, 0x16, 0x0a, 0x2b, 0x0a, 0x04, 0x04, 0x04, 0x03, 0x00, + 0x12, 0x04, 0x29, 0x02, 0x2b, 0x03, 0x1a, 0x1d, 0x20, 0x56, 0x31, 0x20, 0x6f, 0x66, 0x20, 0x41, + 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, + 0x44, 0x61, 0x74, 0x61, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x04, 0x03, 0x00, 0x01, 0x12, 0x03, + 0x29, 0x0a, 0x0c, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x04, 0x03, 0x00, 0x02, 0x00, 0x12, 0x03, 0x2a, + 0x04, 0x41, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x04, 0x03, 0x00, 0x02, 0x00, 0x06, 0x12, 0x03, 0x2a, + 0x04, 0x1e, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x04, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x2a, + 0x1f, 0x3c, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x04, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x2a, + 0x3f, 0x40, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x04, 0x08, 0x00, 0x12, 0x04, 0x2d, 0x02, 0x2f, 0x03, + 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x04, 0x08, 0x00, 0x01, 0x12, 0x03, 0x2d, 0x08, 0x0f, 0x0a, 0x0b, + 0x0a, 0x04, 0x04, 0x04, 0x02, 0x00, 0x12, 0x03, 0x2e, 0x04, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, + 0x04, 0x02, 0x00, 0x06, 0x12, 0x03, 0x2e, 0x04, 0x06, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x04, 0x02, + 0x00, 0x01, 0x12, 0x03, 0x2e, 0x07, 0x09, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x04, 0x02, 0x00, 0x03, + 0x12, 0x03, 0x2e, 0x0c, 0x0d, 0x0a, 0x3e, 0x0a, 0x02, 0x04, 0x05, 0x12, 0x04, 0x33, 0x00, 0x3c, + 0x01, 0x1a, 0x32, 0x20, 0x54, 0x68, 0x65, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x72, 0x65, 0x71, + 0x75, 0x69, 0x72, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x20, + 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x20, 0x67, + 0x72, 0x6f, 0x75, 0x70, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x05, 0x01, 0x12, 0x03, 0x33, 0x08, + 0x19, 0x0a, 0x2e, 0x0a, 0x04, 0x04, 0x05, 0x03, 0x00, 0x12, 0x04, 0x35, 0x02, 0x37, 0x03, 0x1a, + 0x20, 0x20, 0x56, 0x31, 0x20, 0x6f, 0x66, 0x20, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, + 0x6d, 0x62, 0x65, 0x72, 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x44, 0x61, 0x74, 0x61, + 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x03, 0x00, 0x01, 0x12, 0x03, 0x35, 0x0a, 0x0c, 0x0a, + 0x0d, 0x0a, 0x06, 0x04, 0x05, 0x03, 0x00, 0x02, 0x00, 0x12, 0x03, 0x36, 0x04, 0x41, 0x0a, 0x0e, + 0x0a, 0x07, 0x04, 0x05, 0x03, 0x00, 0x02, 0x00, 0x06, 0x12, 0x03, 0x36, 0x04, 0x1e, 0x0a, 0x0e, + 0x0a, 0x07, 0x04, 0x05, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x36, 0x1f, 0x3c, 0x0a, 0x0e, + 0x0a, 0x07, 0x04, 0x05, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x36, 0x3f, 0x40, 0x0a, 0x0c, + 0x0a, 0x04, 0x04, 0x05, 0x08, 0x00, 0x12, 0x04, 0x39, 0x02, 0x3b, 0x03, 0x0a, 0x0c, 0x0a, 0x05, + 0x04, 0x05, 0x08, 0x00, 0x01, 0x12, 0x03, 0x39, 0x08, 0x0f, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x05, + 0x02, 0x00, 0x12, 0x03, 0x3a, 0x04, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x00, 0x06, + 0x12, 0x03, 0x3a, 0x04, 0x06, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x00, 0x01, 0x12, 0x03, + 0x3a, 0x07, 0x09, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x05, 0x02, 0x00, 0x03, 0x12, 0x03, 0x3a, 0x0c, + 0x0d, 0x0a, 0x3b, 0x0a, 0x02, 0x04, 0x06, 0x12, 0x04, 0x3f, 0x00, 0x49, 0x01, 0x1a, 0x2f, 0x20, + 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x70, 0x6f, 0x73, 0x74, 0x2d, 0x63, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x0a, 0x0a, 0x0a, + 0x0a, 0x03, 0x04, 0x06, 0x01, 0x12, 0x03, 0x3f, 0x08, 0x18, 0x0a, 0x23, 0x0a, 0x04, 0x04, 0x06, + 0x03, 0x00, 0x12, 0x04, 0x41, 0x02, 0x44, 0x03, 0x1a, 0x15, 0x20, 0x53, 0x65, 0x6e, 0x64, 0x57, + 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x65, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x0a, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x06, 0x03, 0x00, 0x01, 0x12, 0x03, 0x41, 0x0a, 0x16, 0x0a, 0x0d, 0x0a, + 0x06, 0x04, 0x06, 0x03, 0x00, 0x02, 0x00, 0x12, 0x03, 0x42, 0x04, 0x28, 0x0a, 0x0e, 0x0a, 0x07, + 0x04, 0x06, 0x03, 0x00, 0x02, 0x00, 0x04, 0x12, 0x03, 0x42, 0x04, 0x0c, 0x0a, 0x0e, 0x0a, 0x07, + 0x04, 0x06, 0x03, 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, 0x42, 0x0d, 0x12, 0x0a, 0x0e, 0x0a, 0x07, + 0x04, 0x06, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x42, 0x13, 0x23, 0x0a, 0x0e, 0x0a, 0x07, + 0x04, 0x06, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x42, 0x26, 0x27, 0x0a, 0x0d, 0x0a, 0x06, + 0x04, 0x06, 0x03, 0x00, 0x02, 0x01, 0x12, 0x03, 0x43, 0x04, 0x1e, 0x0a, 0x0e, 0x0a, 0x07, 0x04, + 0x06, 0x03, 0x00, 0x02, 0x01, 0x05, 0x12, 0x03, 0x43, 0x04, 0x09, 0x0a, 0x0e, 0x0a, 0x07, 0x04, + 0x06, 0x03, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x43, 0x0a, 0x19, 0x0a, 0x0e, 0x0a, 0x07, 0x04, + 0x06, 0x03, 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, 0x43, 0x1c, 0x1d, 0x0a, 0x0c, 0x0a, 0x04, 0x04, + 0x06, 0x08, 0x00, 0x12, 0x04, 0x46, 0x02, 0x48, 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x06, 0x08, + 0x00, 0x01, 0x12, 0x03, 0x46, 0x08, 0x0c, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x06, 0x02, 0x00, 0x12, + 0x03, 0x47, 0x04, 0x23, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x06, 0x02, 0x00, 0x06, 0x12, 0x03, 0x47, + 0x04, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x06, 0x02, 0x00, 0x01, 0x12, 0x03, 0x47, 0x11, 0x1e, + 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x06, 0x02, 0x00, 0x03, 0x12, 0x03, 0x47, 0x21, 0x22, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, ]; include!("xmtp.mls.database.serde.rs"); -// @@protoc_insertion_point(module) - +// @@protoc_insertion_point(module) \ No newline at end of file diff --git a/xmtp_proto/src/gen/xmtp.mls.database.serde.rs b/xmtp_proto/src/gen/xmtp.mls.database.serde.rs index 1ed86aad0..1506070dd 100644 --- a/xmtp_proto/src/gen/xmtp.mls.database.serde.rs +++ b/xmtp_proto/src/gen/xmtp.mls.database.serde.rs @@ -195,12 +195,12 @@ impl serde::Serialize for add_members_data::V1 { { use serde::ser::SerializeStruct; let mut len = 0; - if self.address_or_installation_id.is_some() { + if self.addresses_or_installation_ids.is_some() { len += 1; } let mut struct_ser = serializer.serialize_struct("xmtp.mls.database.AddMembersData.V1", len)?; - if let Some(v) = self.address_or_installation_id.as_ref() { - struct_ser.serialize_field("addressOrInstallationId", v)?; + if let Some(v) = self.addresses_or_installation_ids.as_ref() { + struct_ser.serialize_field("addressesOrInstallationIds", v)?; } struct_ser.end() } @@ -212,13 +212,13 @@ impl<'de> serde::Deserialize<'de> for add_members_data::V1 { D: serde::Deserializer<'de>, { const FIELDS: &[&str] = &[ - "address_or_installation_id", - "addressOrInstallationId", + "addresses_or_installation_ids", + "addressesOrInstallationIds", ]; #[allow(clippy::enum_variant_names)] enum GeneratedField { - AddressOrInstallationId, + AddressesOrInstallationIds, } impl<'de> serde::Deserialize<'de> for GeneratedField { fn deserialize(deserializer: D) -> std::result::Result @@ -240,7 +240,7 @@ impl<'de> serde::Deserialize<'de> for add_members_data::V1 { E: serde::de::Error, { match value { - "addressOrInstallationId" | "address_or_installation_id" => Ok(GeneratedField::AddressOrInstallationId), + "addressesOrInstallationIds" | "addresses_or_installation_ids" => Ok(GeneratedField::AddressesOrInstallationIds), _ => Err(serde::de::Error::unknown_field(value, FIELDS)), } } @@ -260,26 +260,26 @@ impl<'de> serde::Deserialize<'de> for add_members_data::V1 { where V: serde::de::MapAccess<'de>, { - let mut address_or_installation_id__ = None; + let mut addresses_or_installation_ids__ = None; while let Some(k) = map.next_key()? { match k { - GeneratedField::AddressOrInstallationId => { - if address_or_installation_id__.is_some() { - return Err(serde::de::Error::duplicate_field("addressOrInstallationId")); + GeneratedField::AddressesOrInstallationIds => { + if addresses_or_installation_ids__.is_some() { + return Err(serde::de::Error::duplicate_field("addressesOrInstallationIds")); } - address_or_installation_id__ = map.next_value()?; + addresses_or_installation_ids__ = map.next_value()?; } } } Ok(add_members_data::V1 { - address_or_installation_id: address_or_installation_id__, + addresses_or_installation_ids: addresses_or_installation_ids__, }) } } deserializer.deserialize_struct("xmtp.mls.database.AddMembersData.V1", FIELDS, GeneratedVisitor) } } -impl serde::Serialize for AddressOrInstallationId { +impl serde::Serialize for AddressesOrInstallationIds { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result where @@ -287,16 +287,16 @@ impl serde::Serialize for AddressOrInstallationId { { use serde::ser::SerializeStruct; let mut len = 0; - if self.address_or_installation_id.is_some() { + if self.addresses_or_installation_ids.is_some() { len += 1; } - let mut struct_ser = serializer.serialize_struct("xmtp.mls.database.AddressOrInstallationId", len)?; - if let Some(v) = self.address_or_installation_id.as_ref() { + let mut struct_ser = serializer.serialize_struct("xmtp.mls.database.AddressesOrInstallationIds", len)?; + if let Some(v) = self.addresses_or_installation_ids.as_ref() { match v { - address_or_installation_id::AddressOrInstallationId::AccountAddresses(v) => { + addresses_or_installation_ids::AddressesOrInstallationIds::AccountAddresses(v) => { struct_ser.serialize_field("accountAddresses", v)?; } - address_or_installation_id::AddressOrInstallationId::InstallationIds(v) => { + addresses_or_installation_ids::AddressesOrInstallationIds::InstallationIds(v) => { struct_ser.serialize_field("installationIds", v)?; } } @@ -304,7 +304,7 @@ impl serde::Serialize for AddressOrInstallationId { struct_ser.end() } } -impl<'de> serde::Deserialize<'de> for AddressOrInstallationId { +impl<'de> serde::Deserialize<'de> for AddressesOrInstallationIds { #[allow(deprecated)] fn deserialize(deserializer: D) -> std::result::Result where @@ -353,41 +353,41 @@ impl<'de> serde::Deserialize<'de> for AddressOrInstallationId { } struct GeneratedVisitor; impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = AddressOrInstallationId; + type Value = AddressesOrInstallationIds; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("struct xmtp.mls.database.AddressOrInstallationId") + formatter.write_str("struct xmtp.mls.database.AddressesOrInstallationIds") } - fn visit_map(self, mut map: V) -> std::result::Result + fn visit_map(self, mut map: V) -> std::result::Result where V: serde::de::MapAccess<'de>, { - let mut address_or_installation_id__ = None; + let mut addresses_or_installation_ids__ = None; while let Some(k) = map.next_key()? { match k { GeneratedField::AccountAddresses => { - if address_or_installation_id__.is_some() { + if addresses_or_installation_ids__.is_some() { return Err(serde::de::Error::duplicate_field("accountAddresses")); } - address_or_installation_id__ = map.next_value::<::std::option::Option<_>>()?.map(address_or_installation_id::AddressOrInstallationId::AccountAddresses) + addresses_or_installation_ids__ = map.next_value::<::std::option::Option<_>>()?.map(addresses_or_installation_ids::AddressesOrInstallationIds::AccountAddresses) ; } GeneratedField::InstallationIds => { - if address_or_installation_id__.is_some() { + if addresses_or_installation_ids__.is_some() { return Err(serde::de::Error::duplicate_field("installationIds")); } - address_or_installation_id__ = map.next_value::<::std::option::Option<_>>()?.map(address_or_installation_id::AddressOrInstallationId::InstallationIds) + addresses_or_installation_ids__ = map.next_value::<::std::option::Option<_>>()?.map(addresses_or_installation_ids::AddressesOrInstallationIds::InstallationIds) ; } } } - Ok(AddressOrInstallationId { - address_or_installation_id: address_or_installation_id__, + Ok(AddressesOrInstallationIds { + addresses_or_installation_ids: addresses_or_installation_ids__, }) } } - deserializer.deserialize_struct("xmtp.mls.database.AddressOrInstallationId", FIELDS, GeneratedVisitor) + deserializer.deserialize_struct("xmtp.mls.database.AddressesOrInstallationIds", FIELDS, GeneratedVisitor) } } impl serde::Serialize for InstallationIds { @@ -801,12 +801,12 @@ impl serde::Serialize for remove_members_data::V1 { { use serde::ser::SerializeStruct; let mut len = 0; - if self.address_or_installation_id.is_some() { + if self.addresses_or_installation_ids.is_some() { len += 1; } let mut struct_ser = serializer.serialize_struct("xmtp.mls.database.RemoveMembersData.V1", len)?; - if let Some(v) = self.address_or_installation_id.as_ref() { - struct_ser.serialize_field("addressOrInstallationId", v)?; + if let Some(v) = self.addresses_or_installation_ids.as_ref() { + struct_ser.serialize_field("addressesOrInstallationIds", v)?; } struct_ser.end() } @@ -818,13 +818,13 @@ impl<'de> serde::Deserialize<'de> for remove_members_data::V1 { D: serde::Deserializer<'de>, { const FIELDS: &[&str] = &[ - "address_or_installation_id", - "addressOrInstallationId", + "addresses_or_installation_ids", + "addressesOrInstallationIds", ]; #[allow(clippy::enum_variant_names)] enum GeneratedField { - AddressOrInstallationId, + AddressesOrInstallationIds, } impl<'de> serde::Deserialize<'de> for GeneratedField { fn deserialize(deserializer: D) -> std::result::Result @@ -846,7 +846,7 @@ impl<'de> serde::Deserialize<'de> for remove_members_data::V1 { E: serde::de::Error, { match value { - "addressOrInstallationId" | "address_or_installation_id" => Ok(GeneratedField::AddressOrInstallationId), + "addressesOrInstallationIds" | "addresses_or_installation_ids" => Ok(GeneratedField::AddressesOrInstallationIds), _ => Err(serde::de::Error::unknown_field(value, FIELDS)), } } @@ -866,19 +866,19 @@ impl<'de> serde::Deserialize<'de> for remove_members_data::V1 { where V: serde::de::MapAccess<'de>, { - let mut address_or_installation_id__ = None; + let mut addresses_or_installation_ids__ = None; while let Some(k) = map.next_key()? { match k { - GeneratedField::AddressOrInstallationId => { - if address_or_installation_id__.is_some() { - return Err(serde::de::Error::duplicate_field("addressOrInstallationId")); + GeneratedField::AddressesOrInstallationIds => { + if addresses_or_installation_ids__.is_some() { + return Err(serde::de::Error::duplicate_field("addressesOrInstallationIds")); } - address_or_installation_id__ = map.next_value()?; + addresses_or_installation_ids__ = map.next_value()?; } } } Ok(remove_members_data::V1 { - address_or_installation_id: address_or_installation_id__, + addresses_or_installation_ids: addresses_or_installation_ids__, }) } }