Skip to content

Commit

Permalink
Add unused proposals to CommitOutput (#67)
Browse files Browse the repository at this point in the history
* Add unused proposals to CommitOutput

* Fix ProposalInfo specialization

- The specialization macro needs to be invoked after the impl block, so
  that macros generated for this block are available at the
  specialization point.
- Macro qualification is not supported in the crate where the macro is
  defined.

---------

Co-authored-by: Stephane Raux <[email protected]>
  • Loading branch information
tomleavy and stefunctional authored Jan 19, 2024
1 parent 468ffc5 commit 405119f
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 12 deletions.
19 changes: 19 additions & 0 deletions mls-rs/src/group/commit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ pub struct CommitOutput {
/// functionality. This value is set if [`MlsRules::commit_options`] returns
/// `allow_external_commit` set to true.
pub external_commit_group_info: Option<MlsMessage>,
/// Proposals that were received in the prior epoch but not included in the following commit.
#[cfg(feature = "by_ref_proposal")]
pub unused_proposals: Vec<crate::mls_rules::ProposalInfo<Proposal>>,
}

#[cfg_attr(all(feature = "ffi", not(test)), ::safer_ffi_gen::safer_ffi_gen)]
Expand All @@ -117,6 +120,20 @@ impl CommitOutput {
pub fn ratchet_tree(&self) -> Option<&ExportedTree<'static>> {
self.ratchet_tree.as_ref()
}

/// A group info that can be provided to new members in order to enable external commit
/// functionality. This value is set if [`MlsRules::commit_options`] returns
/// `allow_external_commit` set to true.
#[cfg(feature = "ffi")]
pub fn external_commit_group_info(&self) -> Option<&MlsMessage> {
self.external_commit_group_info.as_ref()
}

/// Proposals that were received in the prior epoch but not included in the following commit.
#[cfg(all(feature = "ffi", feature = "by_ref_proposal"))]
pub fn unused_proposals(&self) -> &[crate::mls_rules::ProposalInfo<Proposal>] {
&self.unused_proposals
}
}

/// Build a commit with multiple proposals by-value.
Expand Down Expand Up @@ -722,6 +739,8 @@ where
welcome_messages,
ratchet_tree,
external_commit_group_info,
#[cfg(feature = "by_ref_proposal")]
unused_proposals: provisional_state.rejected_proposals,
})
}

Expand Down
4 changes: 4 additions & 0 deletions mls-rs/src/group/framing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ impl From<&Content> for ContentType {
}
}

#[cfg_attr(
all(feature = "ffi", not(test)),
safer_ffi_gen::ffi_type(clone, opaque)
)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, MlsSize, MlsEncode, MlsDecode)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[repr(u8)]
Expand Down
6 changes: 3 additions & 3 deletions mls-rs/src/group/message_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ use super::proposal_ref::ProposalRef;
#[cfg(not(feature = "by_ref_proposal"))]
use crate::group::proposal_cache::resolve_for_commit;

#[cfg(any(feature = "state_update", feature = "by_ref_proposal"))]
#[cfg(feature = "by_ref_proposal")]
use super::proposal::Proposal;

#[cfg(all(feature = "state_update", feature = "custom_proposal"))]
#[cfg(feature = "custom_proposal")]
use super::proposal_filter::ProposalInfo;

#[cfg(feature = "state_update")]
Expand Down Expand Up @@ -72,7 +72,7 @@ pub(crate) struct ProvisionalState {
pub(crate) group_context: GroupContext,
pub(crate) external_init_index: Option<LeafIndex>,
pub(crate) indexes_of_added_kpkgs: Vec<LeafIndex>,
#[cfg(all(feature = "state_update", feature = "by_ref_proposal"))]
#[cfg(feature = "by_ref_proposal")]
pub(crate) rejected_proposals: Vec<crate::mls_rules::ProposalInfo<Proposal>>,
}

Expand Down
10 changes: 5 additions & 5 deletions mls-rs/src/group/proposal_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ impl GroupState {
let roster = self.public_tree.roster();
let group_extensions = &self.context.extensions;

#[cfg(all(feature = "by_ref_proposal", feature = "state_update"))]
#[cfg(feature = "by_ref_proposal")]
let all_proposals = proposals.clone();

let origin = match sender {
Expand Down Expand Up @@ -248,7 +248,7 @@ impl GroupState {
.apply_proposals(&sender, &proposals, commit_time)
.await?;

#[cfg(all(feature = "by_ref_proposal", feature = "state_update"))]
#[cfg(feature = "by_ref_proposal")]
let rejected_proposals =
rejected_proposals(all_proposals, &applier_output.applied_proposals);

Expand All @@ -268,7 +268,7 @@ impl GroupState {
applied_proposals: proposals,
external_init_index: applier_output.external_init_index,
indexes_of_added_kpkgs: applier_output.indexes_of_added_kpkgs,
#[cfg(all(feature = "by_ref_proposal", feature = "state_update"))]
#[cfg(feature = "by_ref_proposal")]
rejected_proposals,
})
}
Expand All @@ -284,14 +284,14 @@ impl Extend<(ProposalRef, CachedProposal)> for ProposalCache {
}
}

#[cfg(all(feature = "by_ref_proposal", feature = "state_update"))]
#[cfg(feature = "by_ref_proposal")]
fn has_ref(proposals: &ProposalBundle, reference: &ProposalRef) -> bool {
proposals
.iter_proposals()
.any(|p| matches!(&p.source, ProposalSource::ByReference(r) if r == reference))
}

#[cfg(all(feature = "by_ref_proposal", feature = "state_update"))]
#[cfg(feature = "by_ref_proposal")]
fn rejected_proposals(
all_proposals: ProposalBundle,
accepted_proposals: &ProposalBundle,
Expand Down
28 changes: 24 additions & 4 deletions mls-rs/src/group/proposal_filter/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,10 @@ impl ProposalBundle {
}
}

#[cfg_attr(
all(feature = "ffi", not(test)),
safer_ffi_gen::ffi_type(clone, opaque)
)]
#[derive(Clone, Debug, PartialEq)]
pub enum ProposalSource {
ByValue,
Expand All @@ -442,6 +446,7 @@ pub enum ProposalSource {
Local,
}

#[cfg_attr(all(feature = "ffi", not(test)), safer_ffi_gen::ffi_type(opaque))]
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
/// Proposal description used as input to a
Expand All @@ -455,7 +460,8 @@ pub struct ProposalInfo<T> {
pub source: ProposalSource,
}

impl ProposalInfo<Proposal> {
#[cfg_attr(all(feature = "ffi", not(test)), ::safer_ffi_gen::safer_ffi_gen)]
impl<T> ProposalInfo<T> {
/// Create a new ProposalInfo.
///
/// The resulting value will be either transmitted with a commit or
Expand All @@ -464,7 +470,8 @@ impl ProposalInfo<Proposal> {
///
/// This function is useful when implementing custom
/// [`MlsRules`](crate::MlsRules).
pub fn new(proposal: Proposal, sender: Sender, can_transmit: bool) -> ProposalInfo<Proposal> {
#[cfg_attr(all(feature = "ffi", not(test)), safer_ffi_gen::safer_ffi_gen_ignore)]
pub fn new(proposal: T, sender: Sender, can_transmit: bool) -> Self {
let source = if can_transmit {
ProposalSource::ByValue
} else {
Expand All @@ -477,9 +484,18 @@ impl ProposalInfo<Proposal> {
source,
}
}
}

impl<T> ProposalInfo<T> {
#[cfg(all(feature = "ffi", not(test)))]
pub fn sender(&self) -> &Sender {
&self.sender
}

#[cfg(all(feature = "ffi", not(test)))]
pub fn source(&self) -> &ProposalSource {
&self.source
}

#[cfg_attr(all(feature = "ffi", not(test)), safer_ffi_gen::safer_ffi_gen_ignore)]
pub fn map<U, F>(self, f: F) -> ProposalInfo<U>
where
F: FnOnce(T) -> U,
Expand All @@ -491,6 +507,7 @@ impl<T> ProposalInfo<T> {
}
}

#[cfg_attr(all(feature = "ffi", not(test)), safer_ffi_gen::safer_ffi_gen_ignore)]
pub fn as_ref(&self) -> ProposalInfo<&T> {
ProposalInfo {
proposal: &self.proposal,
Expand Down Expand Up @@ -519,6 +536,9 @@ impl<T> ProposalInfo<T> {
}
}

#[cfg(all(feature = "ffi", not(test)))]
safer_ffi_gen::specialize!(ProposalInfoFfi = ProposalInfo<Proposal>);

pub trait Proposable: Sized {
const TYPE: ProposalType;

Expand Down
9 changes: 9 additions & 0 deletions mls-rs/src/group/proposal_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
use super::*;
use crate::hash_reference::HashReference;

#[cfg_attr(
all(feature = "ffi", not(test)),
safer_ffi_gen::ffi_type(clone, opaque)
)]
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, MlsSize, MlsEncode, MlsDecode)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
/// Unique identifier for a proposal message.
Expand All @@ -18,6 +22,7 @@ impl Deref for ProposalRef {
}
}

#[cfg_attr(all(feature = "ffi", not(test)), ::safer_ffi_gen::safer_ffi_gen)]
impl ProposalRef {
#[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
pub(crate) async fn from_content<CS: CipherSuiteProvider>(
Expand All @@ -31,6 +36,10 @@ impl ProposalRef {
.await?,
))
}

pub fn as_slice(&self) -> &[u8] {
&self.0
}
}

#[cfg(test)]
Expand Down

0 comments on commit 405119f

Please sign in to comment.