1use std::{cmp::Ord, fmt::Debug, ops::Add};
22
23use codec::{Decode, Encode};
24use finality_grandpa::voter_set::VoterSet;
25use fork_tree::{FilterAction, ForkTree};
26use log::debug;
27use parking_lot::MappedMutexGuard;
28use sc_consensus::shared_data::{SharedData, SharedDataLocked};
29use sc_telemetry::{telemetry, TelemetryHandle, CONSENSUS_INFO};
30use sp_consensus_grandpa::{AuthorityId, AuthorityList};
31
32use crate::{SetId, LOG_TARGET};
33
34#[derive(Debug, thiserror::Error)]
36pub enum Error<N, E> {
37 #[error("Invalid authority set, either empty or with an authority weight set to 0.")]
38 InvalidAuthoritySet,
39 #[error("Client error during ancestry lookup: {0}")]
40 Client(E),
41 #[error("Duplicate authority set change.")]
42 DuplicateAuthoritySetChange,
43 #[error("Multiple pending forced authority set changes are not allowed.")]
44 MultiplePendingForcedAuthoritySetChanges,
45 #[error(
46 "A pending forced authority set change could not be applied since it must be applied \
47 after the pending standard change at #{0}"
48 )]
49 ForcedAuthoritySetChangeDependencyUnsatisfied(N),
50 #[error("Invalid operation in the pending changes tree: {0}")]
51 ForkTree(fork_tree::Error<E>),
52}
53
54impl<N, E> From<fork_tree::Error<E>> for Error<N, E> {
55 fn from(err: fork_tree::Error<E>) -> Error<N, E> {
56 match err {
57 fork_tree::Error::Client(err) => Error::Client(err),
58 fork_tree::Error::Duplicate => Error::DuplicateAuthoritySetChange,
59 err => Error::ForkTree(err),
60 }
61 }
62}
63
64impl<N, E: std::error::Error> From<E> for Error<N, E> {
65 fn from(err: E) -> Error<N, E> {
66 Error::Client(err)
67 }
68}
69
70pub struct SharedAuthoritySet<H, N> {
72 inner: SharedData<AuthoritySet<H, N>>,
73}
74
75impl<H, N> Clone for SharedAuthoritySet<H, N> {
76 fn clone(&self) -> Self {
77 SharedAuthoritySet { inner: self.inner.clone() }
78 }
79}
80
81impl<H, N> SharedAuthoritySet<H, N> {
82 pub(crate) fn inner(&self) -> MappedMutexGuard<'_, AuthoritySet<H, N>> {
84 self.inner.shared_data()
85 }
86
87 pub(crate) fn inner_locked(&self) -> SharedDataLocked<'_, AuthoritySet<H, N>> {
91 self.inner.shared_data_locked()
92 }
93}
94
95impl<H: Eq, N> SharedAuthoritySet<H, N>
96where
97 N: Add<Output = N> + Ord + Clone + Debug,
98 H: Clone + Debug,
99{
100 pub(crate) fn current_limit(&self, min: N) -> Option<N> {
103 self.inner().current_limit(min)
104 }
105
106 pub fn set_id(&self) -> u64 {
108 self.inner().set_id
109 }
110
111 pub fn current_authorities(&self) -> VoterSet<AuthorityId> {
113 self.inner().current_voter_set()
114 }
115
116 pub fn clone_inner(&self) -> AuthoritySet<H, N> {
118 self.inner().clone()
119 }
120
121 pub fn authority_set_changes(&self) -> AuthoritySetChanges<N> {
123 self.inner().authority_set_changes.clone()
124 }
125}
126
127impl<H, N> From<AuthoritySet<H, N>> for SharedAuthoritySet<H, N> {
128 fn from(set: AuthoritySet<H, N>) -> Self {
129 SharedAuthoritySet { inner: SharedData::new(set) }
130 }
131}
132
133#[derive(Debug)]
135pub(crate) struct Status<H, N> {
136 pub(crate) changed: bool,
138 pub(crate) new_set_block: Option<(H, N)>,
141}
142
143#[derive(Debug, Clone, Encode, Decode, PartialEq)]
145pub struct AuthoritySet<H, N> {
146 pub(crate) current_authorities: AuthorityList,
148 pub(crate) set_id: u64,
150 pub(crate) pending_standard_changes: ForkTree<H, N, PendingChange<H, N>>,
154 pending_forced_changes: Vec<PendingChange<H, N>>,
163 pub(crate) authority_set_changes: AuthoritySetChanges<N>,
167}
168
169impl<H, N> AuthoritySet<H, N>
170where
171 H: PartialEq,
172 N: Ord + Clone,
173{
174 fn invalid_authority_list(authorities: &AuthorityList) -> bool {
176 authorities.is_empty() || authorities.iter().any(|(_, w)| *w == 0)
177 }
178
179 pub(crate) fn genesis(initial: AuthorityList) -> Option<Self> {
181 if Self::invalid_authority_list(&initial) {
182 return None;
183 }
184
185 Some(AuthoritySet {
186 current_authorities: initial,
187 set_id: 0,
188 pending_standard_changes: ForkTree::new(),
189 pending_forced_changes: Vec::new(),
190 authority_set_changes: AuthoritySetChanges::empty(),
191 })
192 }
193
194 pub(crate) fn new(
196 authorities: AuthorityList,
197 set_id: u64,
198 pending_standard_changes: ForkTree<H, N, PendingChange<H, N>>,
199 pending_forced_changes: Vec<PendingChange<H, N>>,
200 authority_set_changes: AuthoritySetChanges<N>,
201 ) -> Option<Self> {
202 if Self::invalid_authority_list(&authorities) {
203 return None;
204 }
205
206 Some(AuthoritySet {
207 current_authorities: authorities,
208 set_id,
209 pending_standard_changes,
210 pending_forced_changes,
211 authority_set_changes,
212 })
213 }
214
215 pub(crate) fn current(&self) -> (u64, &[(AuthorityId, u64)]) {
217 (self.set_id, &self.current_authorities[..])
218 }
219
220 pub(crate) fn current_voter_set(&self) -> VoterSet<AuthorityId> {
222 VoterSet::new(self.current_authorities.iter().cloned()).expect(
223 "current_authorities is non-empty and weights are non-zero; \
224 constructor and all mutating operations on `AuthoritySet` ensure this; \
225 qed.",
226 )
227 }
228
229 pub(crate) fn revert<F, E>(&mut self, hash: H, number: N, is_descendent_of: &F)
234 where
235 F: Fn(&H, &H) -> Result<bool, E>,
236 {
237 let filter = |node_hash: &H, node_num: &N, _: &PendingChange<H, N>| {
238 if number >= *node_num &&
239 (is_descendent_of(node_hash, &hash).unwrap_or_default() || *node_hash == hash)
240 {
241 FilterAction::KeepNode
243 } else if number < *node_num && is_descendent_of(&hash, node_hash).unwrap_or_default() {
244 FilterAction::Remove
246 } else {
247 FilterAction::KeepTree
249 }
250 };
251
252 let _ = self.pending_standard_changes.drain_filter(&filter);
254
255 self.pending_forced_changes
257 .retain(|change| !is_descendent_of(&hash, &change.canon_hash).unwrap_or_default());
258 }
259}
260
261impl<H: Eq, N> AuthoritySet<H, N>
262where
263 N: Add<Output = N> + Ord + Clone + Debug,
264 H: Clone + Debug,
265{
266 pub(crate) fn next_change<F, E>(
274 &self,
275 best_hash: &H,
276 is_descendent_of: &F,
277 ) -> Result<Option<(H, N)>, Error<N, E>>
278 where
279 F: Fn(&H, &H) -> Result<bool, E>,
280 E: std::error::Error,
281 {
282 let mut forced = None;
283 for change in &self.pending_forced_changes {
284 if is_descendent_of(&change.canon_hash, best_hash)? {
285 forced = Some((change.canon_hash.clone(), change.canon_height.clone()));
286 break;
287 }
288 }
289
290 let mut standard = None;
291 for (_, _, change) in self.pending_standard_changes.roots() {
292 if is_descendent_of(&change.canon_hash, best_hash)? {
293 standard = Some((change.canon_hash.clone(), change.canon_height.clone()));
294 break;
295 }
296 }
297
298 let earliest = match (forced, standard) {
299 (Some(forced), Some(standard)) => {
300 Some(if forced.1 < standard.1 { forced } else { standard })
301 },
302 (Some(forced), None) => Some(forced),
303 (None, Some(standard)) => Some(standard),
304 (None, None) => None,
305 };
306
307 Ok(earliest)
308 }
309
310 fn add_standard_change<F, E>(
311 &mut self,
312 pending: PendingChange<H, N>,
313 is_descendent_of: &F,
314 ) -> Result<(), Error<N, E>>
315 where
316 F: Fn(&H, &H) -> Result<bool, E>,
317 E: std::error::Error,
318 {
319 let hash = pending.canon_hash.clone();
320 let number = pending.canon_height.clone();
321
322 debug!(
323 target: LOG_TARGET,
324 "Inserting potential standard set change signaled at block {:?} (delayed by {:?} blocks).",
325 (&number, &hash),
326 pending.delay,
327 );
328
329 self.pending_standard_changes.import(hash, number, pending, is_descendent_of)?;
330
331 debug!(
332 target: LOG_TARGET,
333 "There are now {} alternatives for the next pending standard change (roots), and a \
334 total of {} pending standard changes (across all forks).",
335 self.pending_standard_changes.roots().count(),
336 self.pending_standard_changes.iter().count(),
337 );
338
339 Ok(())
340 }
341
342 fn add_forced_change<F, E>(
343 &mut self,
344 pending: PendingChange<H, N>,
345 is_descendent_of: &F,
346 ) -> Result<(), Error<N, E>>
347 where
348 F: Fn(&H, &H) -> Result<bool, E>,
349 E: std::error::Error,
350 {
351 for change in &self.pending_forced_changes {
352 if change.canon_hash == pending.canon_hash {
353 return Err(Error::DuplicateAuthoritySetChange);
354 }
355
356 if is_descendent_of(&change.canon_hash, &pending.canon_hash)? {
357 return Err(Error::MultiplePendingForcedAuthoritySetChanges);
358 }
359 }
360
361 let key = (pending.effective_number(), pending.canon_height.clone());
363 let idx = self
364 .pending_forced_changes
365 .binary_search_by_key(&key, |change| {
366 (change.effective_number(), change.canon_height.clone())
367 })
368 .unwrap_or_else(|i| i);
369
370 debug!(
371 target: LOG_TARGET,
372 "Inserting potential forced set change at block {:?} (delayed by {:?} blocks).",
373 (&pending.canon_height, &pending.canon_hash),
374 pending.delay,
375 );
376
377 self.pending_forced_changes.insert(idx, pending);
378
379 debug!(
380 target: LOG_TARGET,
381 "There are now {} pending forced changes.",
382 self.pending_forced_changes.len()
383 );
384
385 Ok(())
386 }
387
388 pub(crate) fn add_pending_change<F, E>(
395 &mut self,
396 pending: PendingChange<H, N>,
397 is_descendent_of: &F,
398 ) -> Result<(), Error<N, E>>
399 where
400 F: Fn(&H, &H) -> Result<bool, E>,
401 E: std::error::Error,
402 {
403 if Self::invalid_authority_list(&pending.next_authorities) {
404 return Err(Error::InvalidAuthoritySet);
405 }
406
407 match pending.delay_kind {
408 DelayKind::Best { .. } => self.add_forced_change(pending, is_descendent_of),
409 DelayKind::Finalized => self.add_standard_change(pending, is_descendent_of),
410 }
411 }
412
413 pub(crate) fn pending_changes(&self) -> impl Iterator<Item = &PendingChange<H, N>> {
417 self.pending_standard_changes
418 .iter()
419 .map(|(_, _, c)| c)
420 .chain(self.pending_forced_changes.iter())
421 }
422
423 pub(crate) fn current_limit(&self, min: N) -> Option<N> {
430 self.pending_standard_changes
431 .roots()
432 .filter(|&(_, _, c)| c.effective_number() >= min)
433 .min_by_key(|&(_, _, c)| c.effective_number())
434 .map(|(_, _, c)| c.effective_number())
435 }
436
437 pub(crate) fn apply_forced_changes<F, E>(
454 &self,
455 best_hash: H,
456 best_number: N,
457 is_descendent_of: &F,
458 initial_sync: bool,
459 telemetry: Option<TelemetryHandle>,
460 ) -> Result<Option<(N, Self)>, Error<N, E>>
461 where
462 F: Fn(&H, &H) -> Result<bool, E>,
463 E: std::error::Error,
464 {
465 let mut new_set = None;
466
467 for change in self
468 .pending_forced_changes
469 .iter()
470 .take_while(|c| c.effective_number() <= best_number) .filter(|c| c.effective_number() == best_number)
472 {
473 if change.canon_hash == best_hash || is_descendent_of(&change.canon_hash, &best_hash)? {
476 let median_last_finalized = match change.delay_kind {
477 DelayKind::Best { ref median_last_finalized } => median_last_finalized.clone(),
478 _ => unreachable!(
479 "pending_forced_changes only contains forced changes; forced changes have delay kind Best; qed."
480 ),
481 };
482
483 for (_, _, standard_change) in self.pending_standard_changes.roots() {
485 if standard_change.effective_number() <= median_last_finalized &&
486 is_descendent_of(&standard_change.canon_hash, &change.canon_hash)?
487 {
488 log::info!(target: LOG_TARGET,
489 "Not applying authority set change forced at block #{:?}, due to pending standard change at block #{:?}",
490 change.canon_height,
491 standard_change.effective_number(),
492 );
493
494 return Err(Error::ForcedAuthoritySetChangeDependencyUnsatisfied(
495 standard_change.effective_number(),
496 ));
497 }
498 }
499
500 grandpa_log!(
502 initial_sync,
503 "👴 Applying authority set change forced at block #{:?}",
504 change.canon_height,
505 );
506
507 telemetry!(
508 telemetry;
509 CONSENSUS_INFO;
510 "afg.applying_forced_authority_set_change";
511 "block" => ?change.canon_height
512 );
513
514 let mut authority_set_changes = self.authority_set_changes.clone();
515 authority_set_changes.append(self.set_id, median_last_finalized.clone());
516
517 new_set = Some((
518 median_last_finalized,
519 AuthoritySet {
520 current_authorities: change.next_authorities.clone(),
521 set_id: self.set_id + 1,
522 pending_standard_changes: ForkTree::new(), pending_forced_changes: Vec::new(),
524 authority_set_changes,
525 },
526 ));
527
528 break;
529 }
530 }
531
532 Ok(new_set)
535 }
536
537 pub(crate) fn apply_standard_changes<F, E>(
548 &mut self,
549 finalized_hash: H,
550 finalized_number: N,
551 is_descendent_of: &F,
552 initial_sync: bool,
553 telemetry: Option<&TelemetryHandle>,
554 ) -> Result<Status<H, N>, Error<N, E>>
555 where
556 F: Fn(&H, &H) -> Result<bool, E>,
557 E: std::error::Error,
558 {
559 let mut status = Status { changed: false, new_set_block: None };
560
561 match self.pending_standard_changes.finalize_with_descendent_if(
562 &finalized_hash,
563 finalized_number.clone(),
564 is_descendent_of,
565 |change| change.effective_number() <= finalized_number,
566 )? {
567 fork_tree::FinalizationResult::Changed(change) => {
568 status.changed = true;
569
570 let pending_forced_changes = std::mem::take(&mut self.pending_forced_changes);
571
572 for change in pending_forced_changes {
575 if change.effective_number() > finalized_number &&
576 is_descendent_of(&finalized_hash, &change.canon_hash)?
577 {
578 self.pending_forced_changes.push(change)
579 }
580 }
581
582 if let Some(change) = change {
583 grandpa_log!(
584 initial_sync,
585 "👴 Applying authority set change scheduled at block #{:?}",
586 change.canon_height,
587 );
588 telemetry!(
589 telemetry;
590 CONSENSUS_INFO;
591 "afg.applying_scheduled_authority_set_change";
592 "block" => ?change.canon_height
593 );
594
595 self.authority_set_changes.append(self.set_id, finalized_number.clone());
597
598 self.current_authorities = change.next_authorities;
599 self.set_id += 1;
600
601 status.new_set_block = Some((finalized_hash, finalized_number));
602 }
603 },
604 fork_tree::FinalizationResult::Unchanged => {},
605 }
606
607 Ok(status)
608 }
609
610 pub fn enacts_standard_change<F, E>(
621 &self,
622 finalized_hash: H,
623 finalized_number: N,
624 is_descendent_of: &F,
625 ) -> Result<Option<bool>, Error<N, E>>
626 where
627 F: Fn(&H, &H) -> Result<bool, E>,
628 E: std::error::Error,
629 {
630 self.pending_standard_changes
631 .finalizes_any_with_descendent_if(
632 &finalized_hash,
633 finalized_number.clone(),
634 is_descendent_of,
635 |change| change.effective_number() == finalized_number,
636 )
637 .map_err(Error::ForkTree)
638 }
639}
640
641#[derive(Debug, Clone, Encode, Decode, PartialEq)]
643pub enum DelayKind<N> {
644 Finalized,
646 Best { median_last_finalized: N },
649}
650
651#[derive(Debug, Clone, Encode, PartialEq)]
656pub struct PendingChange<H, N> {
657 pub(crate) next_authorities: AuthorityList,
659 pub(crate) delay: N,
662 pub(crate) canon_height: N,
664 pub(crate) canon_hash: H,
666 pub(crate) delay_kind: DelayKind<N>,
668}
669
670impl<H: Decode, N: Decode> Decode for PendingChange<H, N> {
671 fn decode<I: codec::Input>(value: &mut I) -> Result<Self, codec::Error> {
672 let next_authorities = Decode::decode(value)?;
673 let delay = Decode::decode(value)?;
674 let canon_height = Decode::decode(value)?;
675 let canon_hash = Decode::decode(value)?;
676
677 let delay_kind = DelayKind::decode(value).unwrap_or(DelayKind::Finalized);
678
679 Ok(PendingChange { next_authorities, delay, canon_height, canon_hash, delay_kind })
680 }
681}
682
683impl<H, N: Add<Output = N> + Clone> PendingChange<H, N> {
684 pub fn effective_number(&self) -> N {
686 self.canon_height.clone() + self.delay.clone()
687 }
688}
689
690#[derive(Debug, thiserror::Error)]
693#[error("authority set change would duplicate set id {0}")]
694pub(crate) struct SetIdConflict(SetId);
695
696#[derive(Debug, Encode, Decode, Clone, PartialEq)]
700pub struct AuthoritySetChanges<N>(Vec<(u64, N)>);
701
702#[derive(Debug, PartialEq)]
706pub enum AuthoritySetChangeId<N> {
707 Latest,
709 Set(SetId, N),
711 Unknown,
714}
715
716impl<N> From<Vec<(u64, N)>> for AuthoritySetChanges<N> {
717 fn from(changes: Vec<(u64, N)>) -> AuthoritySetChanges<N> {
718 AuthoritySetChanges(changes)
719 }
720}
721
722impl<N: Ord + Clone> AuthoritySetChanges<N> {
723 pub(crate) fn empty() -> Self {
724 Self(Default::default())
725 }
726
727 pub(crate) fn append(&mut self, set_id: u64, block_number: N) {
728 self.0.push((set_id, block_number));
729 }
730
731 pub(crate) fn get_set_id(&self, block_number: N) -> AuthoritySetChangeId<N> {
732 if self
733 .0
734 .last()
735 .map(|last_auth_change| last_auth_change.1 < block_number)
736 .unwrap_or(false)
737 {
738 return AuthoritySetChangeId::Latest;
739 }
740
741 let idx = self
742 .0
743 .binary_search_by_key(&block_number, |(_, n)| n.clone())
744 .unwrap_or_else(|b| b);
745
746 if idx < self.0.len() {
747 let (set_id, block_number) = self.0[idx].clone();
748
749 if idx == 0 && set_id != 0 {
751 return AuthoritySetChangeId::Unknown;
752 }
753
754 AuthoritySetChangeId::Set(set_id, block_number)
755 } else {
756 AuthoritySetChangeId::Unknown
757 }
758 }
759
760 pub(crate) fn insert(&mut self, block_number: N) -> Result<(), SetIdConflict> {
765 let idx = self
766 .0
767 .binary_search_by_key(&block_number, |(_, n)| n.clone())
768 .unwrap_or_else(|b| b);
769
770 let set_id = if idx == 0 { 0 } else { self.0[idx - 1].0 + 1 };
771 if idx != self.0.len() && self.0[idx].0 == set_id {
772 return Err(SetIdConflict(set_id));
773 }
774
775 self.0.insert(idx, (set_id, block_number));
776 Ok(())
777 }
778
779 pub fn iter_from(&self, block_number: N) -> Option<impl Iterator<Item = &(u64, N)>> {
783 let idx = self
784 .0
785 .binary_search_by_key(&block_number, |(_, n)| n.clone())
786 .map(|n| n + 1)
789 .unwrap_or_else(|b| b);
790
791 if idx < self.0.len() {
792 let (set_id, _) = self.0[idx].clone();
793
794 if idx == 0 && set_id != 0 {
796 return None;
797 }
798 }
799
800 Some(self.0[idx..].iter())
801 }
802}
803
804#[cfg(test)]
805mod tests {
806 use super::*;
807 use sp_core::crypto::{ByteArray, UncheckedFrom};
808
809 fn static_is_descendent_of<A>(value: bool) -> impl Fn(&A, &A) -> Result<bool, std::io::Error> {
810 move |_, _| Ok(value)
811 }
812
813 fn is_descendent_of<A, F>(f: F) -> impl Fn(&A, &A) -> Result<bool, std::io::Error>
814 where
815 F: Fn(&A, &A) -> bool,
816 {
817 move |base, hash| Ok(f(base, hash))
818 }
819
820 #[test]
821 fn current_limit_filters_min() {
822 let current_authorities = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 1)];
823
824 let mut authorities = AuthoritySet {
825 current_authorities: current_authorities.clone(),
826 set_id: 0,
827 pending_standard_changes: ForkTree::new(),
828 pending_forced_changes: Vec::new(),
829 authority_set_changes: AuthoritySetChanges::empty(),
830 };
831
832 let change = |height| PendingChange {
833 next_authorities: current_authorities.clone(),
834 delay: 0,
835 canon_height: height,
836 canon_hash: height.to_string(),
837 delay_kind: DelayKind::Finalized,
838 };
839
840 let is_descendent_of = static_is_descendent_of(false);
841
842 authorities.add_pending_change(change(1), &is_descendent_of).unwrap();
843 authorities.add_pending_change(change(2), &is_descendent_of).unwrap();
844
845 assert_eq!(authorities.current_limit(0), Some(1));
846
847 assert_eq!(authorities.current_limit(1), Some(1));
848
849 assert_eq!(authorities.current_limit(2), Some(2));
850
851 assert_eq!(authorities.current_limit(3), None);
852 }
853
854 #[test]
855 fn changes_iterated_in_pre_order() {
856 let current_authorities = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 1)];
857
858 let mut authorities = AuthoritySet {
859 current_authorities: current_authorities.clone(),
860 set_id: 0,
861 pending_standard_changes: ForkTree::new(),
862 pending_forced_changes: Vec::new(),
863 authority_set_changes: AuthoritySetChanges::empty(),
864 };
865
866 let change_a = PendingChange {
867 next_authorities: current_authorities.clone(),
868 delay: 10,
869 canon_height: 5,
870 canon_hash: "hash_a",
871 delay_kind: DelayKind::Finalized,
872 };
873
874 let change_b = PendingChange {
875 next_authorities: current_authorities.clone(),
876 delay: 0,
877 canon_height: 5,
878 canon_hash: "hash_b",
879 delay_kind: DelayKind::Finalized,
880 };
881
882 let change_c = PendingChange {
883 next_authorities: current_authorities.clone(),
884 delay: 5,
885 canon_height: 10,
886 canon_hash: "hash_c",
887 delay_kind: DelayKind::Finalized,
888 };
889
890 authorities
891 .add_pending_change(change_a.clone(), &static_is_descendent_of(false))
892 .unwrap();
893 authorities
894 .add_pending_change(change_b.clone(), &static_is_descendent_of(false))
895 .unwrap();
896 authorities
897 .add_pending_change(
898 change_c.clone(),
899 &is_descendent_of(|base, hash| match (*base, *hash) {
900 ("hash_a", "hash_c") => true,
901 ("hash_b", "hash_c") => false,
902 _ => unreachable!(),
903 }),
904 )
905 .unwrap();
906
907 let change_d = PendingChange {
909 next_authorities: current_authorities.clone(),
910 delay: 2,
911 canon_height: 1,
912 canon_hash: "hash_d",
913 delay_kind: DelayKind::Best { median_last_finalized: 0 },
914 };
915
916 let change_e = PendingChange {
917 next_authorities: current_authorities.clone(),
918 delay: 2,
919 canon_height: 0,
920 canon_hash: "hash_e",
921 delay_kind: DelayKind::Best { median_last_finalized: 0 },
922 };
923
924 authorities
925 .add_pending_change(change_d.clone(), &static_is_descendent_of(false))
926 .unwrap();
927 authorities
928 .add_pending_change(change_e.clone(), &static_is_descendent_of(false))
929 .unwrap();
930
931 assert_eq!(
933 authorities.pending_changes().collect::<Vec<_>>(),
934 vec![&change_a, &change_c, &change_b, &change_e, &change_d],
935 );
936 }
937
938 #[test]
939 fn apply_change() {
940 let mut authorities = AuthoritySet {
941 current_authorities: Vec::new(),
942 set_id: 0,
943 pending_standard_changes: ForkTree::new(),
944 pending_forced_changes: Vec::new(),
945 authority_set_changes: AuthoritySetChanges::empty(),
946 };
947
948 let set_a = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 5)];
949 let set_b = vec![(AuthorityId::from_slice(&[2; 32]).unwrap(), 5)];
950
951 let change_a = PendingChange {
953 next_authorities: set_a.clone(),
954 delay: 10,
955 canon_height: 5,
956 canon_hash: "hash_a",
957 delay_kind: DelayKind::Finalized,
958 };
959
960 let change_b = PendingChange {
961 next_authorities: set_b.clone(),
962 delay: 10,
963 canon_height: 5,
964 canon_hash: "hash_b",
965 delay_kind: DelayKind::Finalized,
966 };
967
968 authorities
969 .add_pending_change(change_a.clone(), &static_is_descendent_of(true))
970 .unwrap();
971 authorities
972 .add_pending_change(change_b.clone(), &static_is_descendent_of(true))
973 .unwrap();
974
975 assert_eq!(authorities.pending_changes().collect::<Vec<_>>(), vec![&change_a, &change_b]);
976
977 let status = authorities
980 .apply_standard_changes(
981 "hash_c",
982 11,
983 &is_descendent_of(|base, hash| match (*base, *hash) {
984 ("hash_a", "hash_c") => true,
985 ("hash_b", "hash_c") => false,
986 _ => unreachable!(),
987 }),
988 false,
989 None,
990 )
991 .unwrap();
992
993 assert!(status.changed);
994 assert_eq!(status.new_set_block, None);
995 assert_eq!(authorities.pending_changes().collect::<Vec<_>>(), vec![&change_a]);
996 assert_eq!(authorities.authority_set_changes, AuthoritySetChanges::empty());
997
998 let status = authorities
1000 .apply_standard_changes(
1001 "hash_d",
1002 15,
1003 &is_descendent_of(|base, hash| match (*base, *hash) {
1004 ("hash_a", "hash_d") => true,
1005 _ => unreachable!(),
1006 }),
1007 false,
1008 None,
1009 )
1010 .unwrap();
1011
1012 assert!(status.changed);
1013 assert_eq!(status.new_set_block, Some(("hash_d", 15)));
1014
1015 assert_eq!(authorities.current_authorities, set_a);
1016 assert_eq!(authorities.set_id, 1);
1017 assert_eq!(authorities.pending_changes().count(), 0);
1018 assert_eq!(authorities.authority_set_changes, AuthoritySetChanges(vec![(0, 15)]));
1019 }
1020
1021 #[test]
1022 fn disallow_multiple_changes_being_finalized_at_once() {
1023 let mut authorities = AuthoritySet {
1024 current_authorities: Vec::new(),
1025 set_id: 0,
1026 pending_standard_changes: ForkTree::new(),
1027 pending_forced_changes: Vec::new(),
1028 authority_set_changes: AuthoritySetChanges::empty(),
1029 };
1030
1031 let set_a = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 5)];
1032 let set_c = vec![(AuthorityId::from_slice(&[2; 32]).unwrap(), 5)];
1033
1034 let change_a = PendingChange {
1036 next_authorities: set_a.clone(),
1037 delay: 10,
1038 canon_height: 5,
1039 canon_hash: "hash_a",
1040 delay_kind: DelayKind::Finalized,
1041 };
1042
1043 let change_c = PendingChange {
1044 next_authorities: set_c.clone(),
1045 delay: 10,
1046 canon_height: 30,
1047 canon_hash: "hash_c",
1048 delay_kind: DelayKind::Finalized,
1049 };
1050
1051 authorities
1052 .add_pending_change(change_a.clone(), &static_is_descendent_of(true))
1053 .unwrap();
1054 authorities
1055 .add_pending_change(change_c.clone(), &static_is_descendent_of(true))
1056 .unwrap();
1057
1058 let is_descendent_of = is_descendent_of(|base, hash| match (*base, *hash) {
1059 ("hash_a", "hash_b") => true,
1060 ("hash_a", "hash_c") => true,
1061 ("hash_a", "hash_d") => true,
1062
1063 ("hash_c", "hash_b") => false,
1064 ("hash_c", "hash_d") => true,
1065
1066 ("hash_b", "hash_c") => true,
1067 _ => unreachable!(),
1068 });
1069
1070 assert!(matches!(
1072 authorities.apply_standard_changes("hash_d", 40, &is_descendent_of, false, None),
1073 Err(Error::ForkTree(fork_tree::Error::UnfinalizedAncestor))
1074 ));
1075 assert_eq!(authorities.authority_set_changes, AuthoritySetChanges::empty());
1076
1077 let status = authorities
1078 .apply_standard_changes("hash_b", 15, &is_descendent_of, false, None)
1079 .unwrap();
1080
1081 assert!(status.changed);
1082 assert_eq!(status.new_set_block, Some(("hash_b", 15)));
1083
1084 assert_eq!(authorities.current_authorities, set_a);
1085 assert_eq!(authorities.set_id, 1);
1086 assert_eq!(authorities.authority_set_changes, AuthoritySetChanges(vec![(0, 15)]));
1087
1088 let status = authorities
1090 .apply_standard_changes("hash_d", 40, &is_descendent_of, false, None)
1091 .unwrap();
1092
1093 assert!(status.changed);
1094 assert_eq!(status.new_set_block, Some(("hash_d", 40)));
1095
1096 assert_eq!(authorities.current_authorities, set_c);
1097 assert_eq!(authorities.set_id, 2);
1098 assert_eq!(authorities.authority_set_changes, AuthoritySetChanges(vec![(0, 15), (1, 40)]));
1099 }
1100
1101 #[test]
1102 fn enacts_standard_change_works() {
1103 let mut authorities = AuthoritySet {
1104 current_authorities: Vec::new(),
1105 set_id: 0,
1106 pending_standard_changes: ForkTree::new(),
1107 pending_forced_changes: Vec::new(),
1108 authority_set_changes: AuthoritySetChanges::empty(),
1109 };
1110
1111 let set_a = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 5)];
1112
1113 let change_a = PendingChange {
1114 next_authorities: set_a.clone(),
1115 delay: 10,
1116 canon_height: 5,
1117 canon_hash: "hash_a",
1118 delay_kind: DelayKind::Finalized,
1119 };
1120
1121 let change_b = PendingChange {
1122 next_authorities: set_a.clone(),
1123 delay: 10,
1124 canon_height: 20,
1125 canon_hash: "hash_b",
1126 delay_kind: DelayKind::Finalized,
1127 };
1128
1129 authorities
1130 .add_pending_change(change_a.clone(), &static_is_descendent_of(false))
1131 .unwrap();
1132 authorities
1133 .add_pending_change(change_b.clone(), &static_is_descendent_of(true))
1134 .unwrap();
1135
1136 let is_descendent_of = is_descendent_of(|base, hash| match (*base, *hash) {
1137 ("hash_a", "hash_d") => true,
1138 ("hash_a", "hash_e") => true,
1139 ("hash_b", "hash_d") => true,
1140 ("hash_b", "hash_e") => true,
1141 ("hash_a", "hash_c") => false,
1142 ("hash_b", "hash_c") => false,
1143 _ => unreachable!(),
1144 });
1145
1146 assert_eq!(
1148 authorities.enacts_standard_change("hash_c", 15, &is_descendent_of).unwrap(),
1149 None,
1150 );
1151
1152 assert_eq!(
1154 authorities.enacts_standard_change("hash_d", 14, &is_descendent_of).unwrap(),
1155 None,
1156 );
1157
1158 assert_eq!(
1160 authorities.enacts_standard_change("hash_d", 15, &is_descendent_of).unwrap(),
1161 Some(true),
1162 );
1163
1164 assert_eq!(
1167 authorities.enacts_standard_change("hash_e", 30, &is_descendent_of).unwrap(),
1168 Some(false),
1169 );
1170 }
1171
1172 #[test]
1173 fn forced_changes() {
1174 let mut authorities = AuthoritySet {
1175 current_authorities: Vec::new(),
1176 set_id: 0,
1177 pending_standard_changes: ForkTree::new(),
1178 pending_forced_changes: Vec::new(),
1179 authority_set_changes: AuthoritySetChanges::empty(),
1180 };
1181
1182 let set_a = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 5)];
1183 let set_b = vec![(AuthorityId::from_slice(&[2; 32]).unwrap(), 5)];
1184
1185 let change_a = PendingChange {
1186 next_authorities: set_a.clone(),
1187 delay: 10,
1188 canon_height: 5,
1189 canon_hash: "hash_a",
1190 delay_kind: DelayKind::Best { median_last_finalized: 42 },
1191 };
1192
1193 let change_b = PendingChange {
1194 next_authorities: set_b.clone(),
1195 delay: 10,
1196 canon_height: 5,
1197 canon_hash: "hash_b",
1198 delay_kind: DelayKind::Best { median_last_finalized: 0 },
1199 };
1200
1201 authorities
1202 .add_pending_change(change_a, &static_is_descendent_of(false))
1203 .unwrap();
1204 authorities
1205 .add_pending_change(change_b.clone(), &static_is_descendent_of(false))
1206 .unwrap();
1207
1208 assert!(matches!(
1210 authorities.add_pending_change(change_b, &static_is_descendent_of(false)),
1211 Err(Error::DuplicateAuthoritySetChange)
1212 ));
1213
1214 assert_eq!(
1217 authorities
1218 .enacts_standard_change("hash_c", 15, &static_is_descendent_of(true))
1219 .unwrap(),
1220 None,
1221 );
1222
1223 let change_c = PendingChange {
1225 next_authorities: set_b.clone(),
1226 delay: 3,
1227 canon_height: 8,
1228 canon_hash: "hash_a8",
1229 delay_kind: DelayKind::Best { median_last_finalized: 0 },
1230 };
1231
1232 let is_descendent_of_a = is_descendent_of(|base: &&str, _| base.starts_with("hash_a"));
1233
1234 assert!(matches!(
1235 authorities.add_pending_change(change_c, &is_descendent_of_a),
1236 Err(Error::MultiplePendingForcedAuthoritySetChanges)
1237 ));
1238
1239 assert!(authorities
1242 .apply_forced_changes("hash_a10", 10, &static_is_descendent_of(true), false, None)
1243 .unwrap()
1244 .is_none());
1245
1246 assert!(authorities
1248 .apply_forced_changes("hash_a16", 16, &is_descendent_of_a, false, None)
1249 .unwrap()
1250 .is_none());
1251
1252 assert_eq!(
1254 authorities
1255 .apply_forced_changes("hash_a15", 15, &is_descendent_of_a, false, None)
1256 .unwrap()
1257 .unwrap(),
1258 (
1259 42,
1260 AuthoritySet {
1261 current_authorities: set_a,
1262 set_id: 1,
1263 pending_standard_changes: ForkTree::new(),
1264 pending_forced_changes: Vec::new(),
1265 authority_set_changes: AuthoritySetChanges(vec![(0, 42)]),
1266 },
1267 )
1268 );
1269 }
1270
1271 #[test]
1272 fn forced_changes_with_no_delay() {
1273 let mut authorities = AuthoritySet {
1275 current_authorities: Vec::new(),
1276 set_id: 0,
1277 pending_standard_changes: ForkTree::new(),
1278 pending_forced_changes: Vec::new(),
1279 authority_set_changes: AuthoritySetChanges::empty(),
1280 };
1281
1282 let set_a = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 5)];
1283
1284 let change_a = PendingChange {
1286 next_authorities: set_a.clone(),
1287 delay: 0,
1288 canon_height: 5,
1289 canon_hash: "hash_a",
1290 delay_kind: DelayKind::Best { median_last_finalized: 0 },
1291 };
1292
1293 authorities
1295 .add_pending_change(change_a, &static_is_descendent_of(false))
1296 .unwrap();
1297
1298 assert!(authorities
1300 .apply_forced_changes("hash_a", 5, &static_is_descendent_of(false), false, None)
1301 .unwrap()
1302 .is_some());
1303 }
1304
1305 #[test]
1306 fn forced_changes_blocked_by_standard_changes() {
1307 let set_a = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 1)];
1308
1309 let mut authorities = AuthoritySet {
1310 current_authorities: set_a.clone(),
1311 set_id: 0,
1312 pending_standard_changes: ForkTree::new(),
1313 pending_forced_changes: Vec::new(),
1314 authority_set_changes: AuthoritySetChanges::empty(),
1315 };
1316
1317 let change_a = PendingChange {
1319 next_authorities: set_a.clone(),
1320 delay: 5,
1321 canon_height: 10,
1322 canon_hash: "hash_a",
1323 delay_kind: DelayKind::Finalized,
1324 };
1325
1326 let change_b = PendingChange {
1328 next_authorities: set_a.clone(),
1329 delay: 0,
1330 canon_height: 20,
1331 canon_hash: "hash_b",
1332 delay_kind: DelayKind::Finalized,
1333 };
1334
1335 let change_c = PendingChange {
1337 next_authorities: set_a.clone(),
1338 delay: 5,
1339 canon_height: 30,
1340 canon_hash: "hash_c",
1341 delay_kind: DelayKind::Finalized,
1342 };
1343
1344 authorities
1346 .add_pending_change(change_a, &static_is_descendent_of(true))
1347 .unwrap();
1348 authorities
1349 .add_pending_change(change_b, &static_is_descendent_of(true))
1350 .unwrap();
1351 authorities
1352 .add_pending_change(change_c, &static_is_descendent_of(true))
1353 .unwrap();
1354
1355 let change_d = PendingChange {
1357 next_authorities: set_a.clone(),
1358 delay: 5,
1359 canon_height: 40,
1360 canon_hash: "hash_d",
1361 delay_kind: DelayKind::Best { median_last_finalized: 31 },
1362 };
1363
1364 authorities
1366 .add_pending_change(change_d, &static_is_descendent_of(true))
1367 .unwrap();
1368
1369 assert!(matches!(
1372 authorities.apply_forced_changes(
1373 "hash_d45",
1374 45,
1375 &static_is_descendent_of(true),
1376 false,
1377 None
1378 ),
1379 Err(Error::ForcedAuthoritySetChangeDependencyUnsatisfied(15))
1380 ));
1381 assert_eq!(authorities.authority_set_changes, AuthoritySetChanges::empty());
1382
1383 authorities
1385 .apply_standard_changes("hash_a15", 15, &static_is_descendent_of(true), false, None)
1386 .unwrap();
1387 assert_eq!(authorities.authority_set_changes, AuthoritySetChanges(vec![(0, 15)]));
1388
1389 assert!(matches!(
1391 authorities.apply_forced_changes(
1392 "hash_d",
1393 45,
1394 &static_is_descendent_of(true),
1395 false,
1396 None
1397 ),
1398 Err(Error::ForcedAuthoritySetChangeDependencyUnsatisfied(20))
1399 ));
1400 assert_eq!(authorities.authority_set_changes, AuthoritySetChanges(vec![(0, 15)]));
1401
1402 authorities
1404 .apply_standard_changes("hash_b", 20, &static_is_descendent_of(true), false, None)
1405 .unwrap();
1406 assert_eq!(authorities.authority_set_changes, AuthoritySetChanges(vec![(0, 15), (1, 20)]));
1407
1408 assert_eq!(
1412 authorities
1413 .apply_forced_changes("hash_d", 45, &static_is_descendent_of(true), false, None)
1414 .unwrap()
1415 .unwrap(),
1416 (
1417 31,
1418 AuthoritySet {
1419 current_authorities: set_a.clone(),
1420 set_id: 3,
1421 pending_standard_changes: ForkTree::new(),
1422 pending_forced_changes: Vec::new(),
1423 authority_set_changes: AuthoritySetChanges(vec![(0, 15), (1, 20), (2, 31)]),
1424 }
1425 ),
1426 );
1427 assert_eq!(authorities.authority_set_changes, AuthoritySetChanges(vec![(0, 15), (1, 20)]));
1428 }
1429
1430 #[test]
1431 fn next_change_works() {
1432 let current_authorities = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 1)];
1433
1434 let mut authorities = AuthoritySet {
1435 current_authorities: current_authorities.clone(),
1436 set_id: 0,
1437 pending_standard_changes: ForkTree::new(),
1438 pending_forced_changes: Vec::new(),
1439 authority_set_changes: AuthoritySetChanges::empty(),
1440 };
1441
1442 let new_set = current_authorities.clone();
1443
1444 let change_a0 = PendingChange {
1447 next_authorities: new_set.clone(),
1448 delay: 0,
1449 canon_height: 5,
1450 canon_hash: "hash_a0",
1451 delay_kind: DelayKind::Finalized,
1452 };
1453
1454 let change_a1 = PendingChange {
1455 next_authorities: new_set.clone(),
1456 delay: 0,
1457 canon_height: 10,
1458 canon_hash: "hash_a1",
1459 delay_kind: DelayKind::Finalized,
1460 };
1461
1462 let change_b = PendingChange {
1463 next_authorities: new_set.clone(),
1464 delay: 0,
1465 canon_height: 4,
1466 canon_hash: "hash_b",
1467 delay_kind: DelayKind::Finalized,
1468 };
1469
1470 let is_descendent_of = is_descendent_of(|base, hash| match (*base, *hash) {
1473 ("hash_a0", "hash_a1") => true,
1474 ("hash_a0", "best_a") => true,
1475 ("hash_a1", "best_a") => true,
1476 ("hash_a10", "best_a") => true,
1477 ("hash_b", "best_b") => true,
1478 _ => false,
1479 });
1480
1481 authorities.add_pending_change(change_b, &is_descendent_of).unwrap();
1483 authorities.add_pending_change(change_a0, &is_descendent_of).unwrap();
1484 authorities.add_pending_change(change_a1, &is_descendent_of).unwrap();
1485
1486 assert_eq!(
1488 authorities.next_change(&"best_a", &is_descendent_of).unwrap(),
1489 Some(("hash_a0", 5)),
1490 );
1491
1492 assert_eq!(
1494 authorities.next_change(&"best_b", &is_descendent_of).unwrap(),
1495 Some(("hash_b", 4)),
1496 );
1497
1498 authorities
1500 .apply_standard_changes("hash_a0", 5, &is_descendent_of, false, None)
1501 .unwrap();
1502
1503 assert_eq!(
1505 authorities.next_change(&"best_a", &is_descendent_of).unwrap(),
1506 Some(("hash_a1", 10)),
1507 );
1508
1509 assert_eq!(authorities.next_change(&"best_b", &is_descendent_of).unwrap(), None);
1511
1512 let change_a10 = PendingChange {
1514 next_authorities: new_set.clone(),
1515 delay: 0,
1516 canon_height: 8,
1517 canon_hash: "hash_a10",
1518 delay_kind: DelayKind::Best { median_last_finalized: 0 },
1519 };
1520
1521 authorities
1522 .add_pending_change(change_a10, &static_is_descendent_of(false))
1523 .unwrap();
1524
1525 assert_eq!(
1527 authorities.next_change(&"best_a", &is_descendent_of).unwrap(),
1528 Some(("hash_a10", 8)),
1529 );
1530 }
1531
1532 #[test]
1533 fn maintains_authority_list_invariants() {
1534 assert_eq!(AuthoritySet::<(), ()>::genesis(vec![]), None);
1536 assert_eq!(
1537 AuthoritySet::<(), ()>::new(
1538 vec![],
1539 0,
1540 ForkTree::new(),
1541 Vec::new(),
1542 AuthoritySetChanges::empty(),
1543 ),
1544 None,
1545 );
1546
1547 let invalid_authorities_weight = vec![
1548 (AuthorityId::from_slice(&[1; 32]).unwrap(), 5),
1549 (AuthorityId::from_slice(&[2; 32]).unwrap(), 0),
1550 ];
1551
1552 assert_eq!(AuthoritySet::<(), ()>::genesis(invalid_authorities_weight.clone()), None);
1554 assert_eq!(
1555 AuthoritySet::<(), ()>::new(
1556 invalid_authorities_weight.clone(),
1557 0,
1558 ForkTree::new(),
1559 Vec::new(),
1560 AuthoritySetChanges::empty(),
1561 ),
1562 None,
1563 );
1564
1565 let mut authority_set =
1566 AuthoritySet::<(), u64>::genesis(vec![(AuthorityId::unchecked_from([1; 32]), 5)])
1567 .unwrap();
1568
1569 let invalid_change_empty_authorities = PendingChange {
1570 next_authorities: vec![],
1571 delay: 10,
1572 canon_height: 5,
1573 canon_hash: (),
1574 delay_kind: DelayKind::Finalized,
1575 };
1576
1577 assert!(matches!(
1579 authority_set.add_pending_change(
1580 invalid_change_empty_authorities.clone(),
1581 &static_is_descendent_of(false)
1582 ),
1583 Err(Error::InvalidAuthoritySet)
1584 ));
1585
1586 let invalid_change_authorities_weight = PendingChange {
1587 next_authorities: invalid_authorities_weight,
1588 delay: 10,
1589 canon_height: 5,
1590 canon_hash: (),
1591 delay_kind: DelayKind::Best { median_last_finalized: 0 },
1592 };
1593
1594 assert!(matches!(
1597 authority_set.add_pending_change(
1598 invalid_change_authorities_weight,
1599 &static_is_descendent_of(false)
1600 ),
1601 Err(Error::InvalidAuthoritySet)
1602 ));
1603 }
1604
1605 #[test]
1606 fn cleans_up_stale_forced_changes_when_applying_standard_change() {
1607 let current_authorities = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 1)];
1608
1609 let mut authorities = AuthoritySet {
1610 current_authorities: current_authorities.clone(),
1611 set_id: 0,
1612 pending_standard_changes: ForkTree::new(),
1613 pending_forced_changes: Vec::new(),
1614 authority_set_changes: AuthoritySetChanges::empty(),
1615 };
1616
1617 let new_set = current_authorities.clone();
1618
1619 let is_descendent_of = {
1633 let hashes = vec!["B", "C0", "C1", "C2", "C3", "D"];
1634 is_descendent_of(move |base, hash| match (*base, *hash) {
1635 ("B", "B") => false, ("A", b) | ("B", b) => hashes.iter().any(|h| *h == b),
1637 ("C0", "D") => true,
1638 _ => false,
1639 })
1640 };
1641
1642 let mut add_pending_change = |canon_height, canon_hash, forced| {
1643 let change = PendingChange {
1644 next_authorities: new_set.clone(),
1645 delay: 0,
1646 canon_height,
1647 canon_hash,
1648 delay_kind: if forced {
1649 DelayKind::Best { median_last_finalized: 0 }
1650 } else {
1651 DelayKind::Finalized
1652 },
1653 };
1654
1655 authorities.add_pending_change(change, &is_descendent_of).unwrap();
1656 };
1657
1658 add_pending_change(5, "A", false);
1659 add_pending_change(10, "B", false);
1660 add_pending_change(15, "C0", false);
1661 add_pending_change(15, "C1", true);
1662 add_pending_change(15, "C2", false);
1663 add_pending_change(15, "C3", true);
1664 add_pending_change(20, "D", true);
1665
1666 authorities
1669 .apply_standard_changes("A", 5, &is_descendent_of, false, None)
1670 .unwrap();
1671
1672 assert_eq!(authorities.pending_changes().count(), 6);
1673
1674 authorities
1676 .apply_standard_changes("B", 10, &is_descendent_of, false, None)
1677 .unwrap();
1678
1679 assert_eq!(authorities.pending_changes().count(), 5);
1680
1681 let authorities2 = authorities.clone();
1682
1683 authorities
1685 .apply_standard_changes("C2", 15, &is_descendent_of, false, None)
1686 .unwrap();
1687
1688 assert_eq!(authorities.pending_forced_changes.len(), 0);
1689
1690 let mut authorities = authorities2;
1692 authorities
1693 .apply_standard_changes("C0", 15, &is_descendent_of, false, None)
1694 .unwrap();
1695
1696 assert_eq!(authorities.pending_forced_changes.len(), 1);
1697 assert_eq!(authorities.pending_forced_changes.first().unwrap().canon_hash, "D");
1698 }
1699
1700 #[test]
1701 fn authority_set_changes_insert() {
1702 let mut authority_set_changes = AuthoritySetChanges::empty();
1703 authority_set_changes.append(0, 41);
1704 authority_set_changes.append(1, 81);
1705 authority_set_changes.append(4, 121);
1706
1707 authority_set_changes.insert(101).unwrap();
1708 assert_eq!(authority_set_changes.get_set_id(100), AuthoritySetChangeId::Set(2, 101));
1709 assert_eq!(authority_set_changes.get_set_id(101), AuthoritySetChangeId::Set(2, 101));
1710 }
1711
1712 #[test]
1713 fn authority_set_changes_insert_rejects_duplicate_set_id() {
1714 let mut changes = AuthoritySetChanges::empty();
1715 changes.insert(10).unwrap();
1716 changes.insert(20).unwrap();
1717 changes.insert(30).unwrap();
1718
1719 let before = changes.clone();
1720 assert_eq!(changes.insert(25).unwrap_err().0, 2);
1721 assert_eq!(changes, before);
1722 }
1723
1724 #[test]
1725 fn authority_set_changes_for_complete_data() {
1726 let mut authority_set_changes = AuthoritySetChanges::empty();
1727 authority_set_changes.append(0, 41);
1728 authority_set_changes.append(1, 81);
1729 authority_set_changes.append(2, 121);
1730
1731 assert_eq!(authority_set_changes.get_set_id(20), AuthoritySetChangeId::Set(0, 41));
1732 assert_eq!(authority_set_changes.get_set_id(40), AuthoritySetChangeId::Set(0, 41));
1733 assert_eq!(authority_set_changes.get_set_id(41), AuthoritySetChangeId::Set(0, 41));
1734 assert_eq!(authority_set_changes.get_set_id(42), AuthoritySetChangeId::Set(1, 81));
1735 assert_eq!(authority_set_changes.get_set_id(141), AuthoritySetChangeId::Latest);
1736 }
1737
1738 #[test]
1739 fn authority_set_changes_for_incomplete_data() {
1740 let mut authority_set_changes = AuthoritySetChanges::empty();
1741 authority_set_changes.append(2, 41);
1742 authority_set_changes.append(3, 81);
1743 authority_set_changes.append(4, 121);
1744
1745 assert_eq!(authority_set_changes.get_set_id(20), AuthoritySetChangeId::Unknown);
1746 assert_eq!(authority_set_changes.get_set_id(40), AuthoritySetChangeId::Unknown);
1747 assert_eq!(authority_set_changes.get_set_id(41), AuthoritySetChangeId::Unknown);
1748 assert_eq!(authority_set_changes.get_set_id(42), AuthoritySetChangeId::Set(3, 81));
1749 assert_eq!(authority_set_changes.get_set_id(141), AuthoritySetChangeId::Latest);
1750 }
1751
1752 #[test]
1753 fn iter_from_works() {
1754 let mut authority_set_changes = AuthoritySetChanges::empty();
1755 authority_set_changes.append(1, 41);
1756 authority_set_changes.append(2, 81);
1757
1758 assert_eq!(None, authority_set_changes.iter_from(40).map(|it| it.collect::<Vec<_>>()));
1760
1761 let mut authority_set_changes = AuthoritySetChanges::empty();
1763 authority_set_changes.append(0, 21);
1764 authority_set_changes.append(1, 41);
1765 authority_set_changes.append(2, 81);
1766 authority_set_changes.append(3, 121);
1767
1768 assert_eq!(
1769 Some(vec![(1, 41), (2, 81), (3, 121)]),
1770 authority_set_changes.iter_from(40).map(|it| it.cloned().collect::<Vec<_>>()),
1771 );
1772
1773 assert_eq!(
1774 Some(vec![(2, 81), (3, 121)]),
1775 authority_set_changes.iter_from(41).map(|it| it.cloned().collect::<Vec<_>>()),
1776 );
1777
1778 assert_eq!(0, authority_set_changes.iter_from(121).unwrap().count());
1779
1780 assert_eq!(0, authority_set_changes.iter_from(200).unwrap().count());
1781 }
1782}