Skip to content

Commit 876cd19

Browse files
committed
Allow nodes to gradually drop out during the protocol
1 parent 5790889 commit 876cd19

File tree

3 files changed

+24
-9
lines changed

3 files changed

+24
-9
lines changed

manul/src/protocol/round.rs

+5
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ impl<Id: Ord> IdSet<Id> {
5050
// TODO: assuming `ids` are a subset of `self.ids`. Can we?
5151
ids.len() >= self.threshold
5252
}
53+
54+
pub(crate) fn is_quorum_possible(&self, banned_ids: &BTreeSet<Id>) -> bool {
55+
let ids = self.ids.intersection(banned_ids).collect::<BTreeSet<_>>();
56+
self.ids.len() - ids.len() >= self.threshold
57+
}
5358
}
5459

5560
/// Describes what other parties this rounds sends messages to, and what other parties it expects messages from.

manul/src/session/session.rs

+13-9
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ where
300300
) -> Result<PreprocessOutcome<SP::Verifier>, LocalError> {
301301
// Quick preliminary checks, before we proceed with more expensive verification
302302
let key = self.verifier();
303-
if self.transcript.is_banned(from) || accum.is_banned(from) {
303+
if accum.is_banned(from) {
304304
trace!("{key:?} Banned.");
305305
return Ok(PreprocessOutcome::remote_error("The sender is banned"));
306306
}
@@ -417,7 +417,10 @@ where
417417

418418
/// Makes an accumulator for a new round.
419419
pub fn make_accumulator(&self) -> RoundAccumulator<P, SP> {
420-
RoundAccumulator::new(&self.communication_info.expecting_messages_from)
420+
RoundAccumulator::new(
421+
&self.communication_info.expecting_messages_from,
422+
self.transcript.banned_ids(),
423+
)
421424
}
422425

423426
fn terminate_inner(
@@ -549,6 +552,7 @@ pub enum CanFinalize {
549552
/// A mutable accumulator for collecting the results and errors from processing messages for a single round.
550553
#[derive_where::derive_where(Debug)]
551554
pub struct RoundAccumulator<P: Protocol<SP::Verifier>, SP: SessionParameters> {
555+
banned_ids: BTreeSet<SP::Verifier>,
552556
still_have_not_sent_messages: BTreeSet<SP::Verifier>,
553557
expecting_messages_from: IdSet<SP::Verifier>,
554558
processing: BTreeSet<SP::Verifier>,
@@ -567,8 +571,9 @@ where
567571
P: Protocol<SP::Verifier>,
568572
SP: SessionParameters,
569573
{
570-
fn new(expecting_messages_from: &IdSet<SP::Verifier>) -> Self {
574+
fn new(expecting_messages_from: &IdSet<SP::Verifier>, banned_ids: BTreeSet<SP::Verifier>) -> Self {
571575
Self {
576+
banned_ids,
572577
still_have_not_sent_messages: expecting_messages_from.all().clone(),
573578
expecting_messages_from: expecting_messages_from.clone(),
574579
processing: BTreeSet::new(),
@@ -589,15 +594,15 @@ where
589594
.is_quorum(&self.payloads.keys().cloned().collect::<BTreeSet<_>>())
590595
{
591596
CanFinalize::Yes
592-
} else if !self.still_have_not_sent_messages.is_empty() {
597+
} else if self.expecting_messages_from.is_quorum_possible(&self.banned_ids) {
593598
CanFinalize::NotYet
594599
} else {
595600
CanFinalize::Never
596601
}
597602
}
598603

599604
fn is_banned(&self, from: &SP::Verifier) -> bool {
600-
self.provable_errors.contains_key(from) || self.unprovable_errors.contains_key(from)
605+
self.banned_ids.contains(from)
601606
}
602607

603608
fn message_is_being_processed(&self, from: &SP::Verifier) -> bool {
@@ -619,6 +624,7 @@ where
619624
from
620625
)))
621626
} else {
627+
self.banned_ids.insert(from.clone());
622628
Ok(())
623629
}
624630
}
@@ -630,6 +636,7 @@ where
630636
from
631637
)))
632638
} else {
639+
self.banned_ids.insert(from.clone());
633640
Ok(())
634641
}
635642
}
@@ -728,10 +735,7 @@ where
728735
)?;
729736
self.register_provable_error(&from, evidence)
730737
}
731-
ReceiveErrorType::Unprovable(error) => {
732-
self.unprovable_errors.insert(from.clone(), error);
733-
Ok(())
734-
}
738+
ReceiveErrorType::Unprovable(error) => self.register_unprovable_error(&from, error),
735739
ReceiveErrorType::Echo(error) => {
736740
let (_echo_broadcast, normal_broadcast, _direct_message) = processed.message.into_parts();
737741
let evidence = Evidence::new_echo_round_error(&from, normal_broadcast, *error)?;

manul/src/session/transcript.rs

+6
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,12 @@ where
163163
.ok_or_else(|| LocalError::new(format!("No direct messages registered for {from:?} in {round_id:?}")))
164164
}
165165

166+
pub fn banned_ids(&self) -> BTreeSet<SP::Verifier> {
167+
let mut banned = self.provable_errors.keys().cloned().collect::<BTreeSet<_>>();
168+
banned.extend(self.unprovable_errors.keys().cloned());
169+
banned
170+
}
171+
166172
pub fn is_banned(&self, from: &SP::Verifier) -> bool {
167173
self.provable_errors.contains_key(from) || self.unprovable_errors.contains_key(from)
168174
}

0 commit comments

Comments
 (0)