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 VoterSet::new(self.inner().current_authorities.iter().cloned()).expect(
114 "current_authorities is non-empty and weights are non-zero; \
115 constructor and all mutating operations on `AuthoritySet` ensure this; \
116 qed.",
117 )
118 }
119
120 pub fn clone_inner(&self) -> AuthoritySet<H, N> {
122 self.inner().clone()
123 }
124
125 pub fn authority_set_changes(&self) -> AuthoritySetChanges<N> {
127 self.inner().authority_set_changes.clone()
128 }
129}
130
131impl<H, N> From<AuthoritySet<H, N>> for SharedAuthoritySet<H, N> {
132 fn from(set: AuthoritySet<H, N>) -> Self {
133 SharedAuthoritySet { inner: SharedData::new(set) }
134 }
135}
136
137#[derive(Debug)]
139pub(crate) struct Status<H, N> {
140 pub(crate) changed: bool,
142 pub(crate) new_set_block: Option<(H, N)>,
145}
146
147#[derive(Debug, Clone, Encode, Decode, PartialEq)]
149pub struct AuthoritySet<H, N> {
150 pub(crate) current_authorities: AuthorityList,
152 pub(crate) set_id: u64,
154 pub(crate) pending_standard_changes: ForkTree<H, N, PendingChange<H, N>>,
158 pending_forced_changes: Vec<PendingChange<H, N>>,
167 pub(crate) authority_set_changes: AuthoritySetChanges<N>,
171}
172
173impl<H, N> AuthoritySet<H, N>
174where
175 H: PartialEq,
176 N: Ord + Clone,
177{
178 fn invalid_authority_list(authorities: &AuthorityList) -> bool {
180 authorities.is_empty() || authorities.iter().any(|(_, w)| *w == 0)
181 }
182
183 pub(crate) fn genesis(initial: AuthorityList) -> Option<Self> {
185 if Self::invalid_authority_list(&initial) {
186 return None;
187 }
188
189 Some(AuthoritySet {
190 current_authorities: initial,
191 set_id: 0,
192 pending_standard_changes: ForkTree::new(),
193 pending_forced_changes: Vec::new(),
194 authority_set_changes: AuthoritySetChanges::empty(),
195 })
196 }
197
198 pub(crate) fn new(
200 authorities: AuthorityList,
201 set_id: u64,
202 pending_standard_changes: ForkTree<H, N, PendingChange<H, N>>,
203 pending_forced_changes: Vec<PendingChange<H, N>>,
204 authority_set_changes: AuthoritySetChanges<N>,
205 ) -> Option<Self> {
206 if Self::invalid_authority_list(&authorities) {
207 return None;
208 }
209
210 Some(AuthoritySet {
211 current_authorities: authorities,
212 set_id,
213 pending_standard_changes,
214 pending_forced_changes,
215 authority_set_changes,
216 })
217 }
218
219 pub(crate) fn current(&self) -> (u64, &[(AuthorityId, u64)]) {
221 (self.set_id, &self.current_authorities[..])
222 }
223
224 pub(crate) fn revert<F, E>(&mut self, hash: H, number: N, is_descendent_of: &F)
229 where
230 F: Fn(&H, &H) -> Result<bool, E>,
231 {
232 let filter = |node_hash: &H, node_num: &N, _: &PendingChange<H, N>| {
233 if number >= *node_num &&
234 (is_descendent_of(node_hash, &hash).unwrap_or_default() || *node_hash == hash)
235 {
236 FilterAction::KeepNode
238 } else if number < *node_num && is_descendent_of(&hash, node_hash).unwrap_or_default() {
239 FilterAction::Remove
241 } else {
242 FilterAction::KeepTree
244 }
245 };
246
247 let _ = self.pending_standard_changes.drain_filter(&filter);
249
250 self.pending_forced_changes
252 .retain(|change| !is_descendent_of(&hash, &change.canon_hash).unwrap_or_default());
253 }
254}
255
256impl<H: Eq, N> AuthoritySet<H, N>
257where
258 N: Add<Output = N> + Ord + Clone + Debug,
259 H: Clone + Debug,
260{
261 pub(crate) fn next_change<F, E>(
269 &self,
270 best_hash: &H,
271 is_descendent_of: &F,
272 ) -> Result<Option<(H, N)>, Error<N, E>>
273 where
274 F: Fn(&H, &H) -> Result<bool, E>,
275 E: std::error::Error,
276 {
277 let mut forced = None;
278 for change in &self.pending_forced_changes {
279 if is_descendent_of(&change.canon_hash, best_hash)? {
280 forced = Some((change.canon_hash.clone(), change.canon_height.clone()));
281 break;
282 }
283 }
284
285 let mut standard = None;
286 for (_, _, change) in self.pending_standard_changes.roots() {
287 if is_descendent_of(&change.canon_hash, best_hash)? {
288 standard = Some((change.canon_hash.clone(), change.canon_height.clone()));
289 break;
290 }
291 }
292
293 let earliest = match (forced, standard) {
294 (Some(forced), Some(standard)) => {
295 Some(if forced.1 < standard.1 { forced } else { standard })
296 },
297 (Some(forced), None) => Some(forced),
298 (None, Some(standard)) => Some(standard),
299 (None, None) => None,
300 };
301
302 Ok(earliest)
303 }
304
305 fn add_standard_change<F, E>(
306 &mut self,
307 pending: PendingChange<H, N>,
308 is_descendent_of: &F,
309 ) -> Result<(), Error<N, E>>
310 where
311 F: Fn(&H, &H) -> Result<bool, E>,
312 E: std::error::Error,
313 {
314 let hash = pending.canon_hash.clone();
315 let number = pending.canon_height.clone();
316
317 debug!(
318 target: LOG_TARGET,
319 "Inserting potential standard set change signaled at block {:?} (delayed by {:?} blocks).",
320 (&number, &hash),
321 pending.delay,
322 );
323
324 self.pending_standard_changes.import(hash, number, pending, is_descendent_of)?;
325
326 debug!(
327 target: LOG_TARGET,
328 "There are now {} alternatives for the next pending standard change (roots), and a \
329 total of {} pending standard changes (across all forks).",
330 self.pending_standard_changes.roots().count(),
331 self.pending_standard_changes.iter().count(),
332 );
333
334 Ok(())
335 }
336
337 fn add_forced_change<F, E>(
338 &mut self,
339 pending: PendingChange<H, N>,
340 is_descendent_of: &F,
341 ) -> Result<(), Error<N, E>>
342 where
343 F: Fn(&H, &H) -> Result<bool, E>,
344 E: std::error::Error,
345 {
346 for change in &self.pending_forced_changes {
347 if change.canon_hash == pending.canon_hash {
348 return Err(Error::DuplicateAuthoritySetChange);
349 }
350
351 if is_descendent_of(&change.canon_hash, &pending.canon_hash)? {
352 return Err(Error::MultiplePendingForcedAuthoritySetChanges);
353 }
354 }
355
356 let key = (pending.effective_number(), pending.canon_height.clone());
358 let idx = self
359 .pending_forced_changes
360 .binary_search_by_key(&key, |change| {
361 (change.effective_number(), change.canon_height.clone())
362 })
363 .unwrap_or_else(|i| i);
364
365 debug!(
366 target: LOG_TARGET,
367 "Inserting potential forced set change at block {:?} (delayed by {:?} blocks).",
368 (&pending.canon_height, &pending.canon_hash),
369 pending.delay,
370 );
371
372 self.pending_forced_changes.insert(idx, pending);
373
374 debug!(
375 target: LOG_TARGET,
376 "There are now {} pending forced changes.",
377 self.pending_forced_changes.len()
378 );
379
380 Ok(())
381 }
382
383 pub(crate) fn add_pending_change<F, E>(
390 &mut self,
391 pending: PendingChange<H, N>,
392 is_descendent_of: &F,
393 ) -> Result<(), Error<N, E>>
394 where
395 F: Fn(&H, &H) -> Result<bool, E>,
396 E: std::error::Error,
397 {
398 if Self::invalid_authority_list(&pending.next_authorities) {
399 return Err(Error::InvalidAuthoritySet);
400 }
401
402 match pending.delay_kind {
403 DelayKind::Best { .. } => self.add_forced_change(pending, is_descendent_of),
404 DelayKind::Finalized => self.add_standard_change(pending, is_descendent_of),
405 }
406 }
407
408 pub(crate) fn pending_changes(&self) -> impl Iterator<Item = &PendingChange<H, N>> {
412 self.pending_standard_changes
413 .iter()
414 .map(|(_, _, c)| c)
415 .chain(self.pending_forced_changes.iter())
416 }
417
418 pub(crate) fn current_limit(&self, min: N) -> Option<N> {
425 self.pending_standard_changes
426 .roots()
427 .filter(|&(_, _, c)| c.effective_number() >= min)
428 .min_by_key(|&(_, _, c)| c.effective_number())
429 .map(|(_, _, c)| c.effective_number())
430 }
431
432 pub(crate) fn apply_forced_changes<F, E>(
449 &self,
450 best_hash: H,
451 best_number: N,
452 is_descendent_of: &F,
453 initial_sync: bool,
454 telemetry: Option<TelemetryHandle>,
455 ) -> Result<Option<(N, Self)>, Error<N, E>>
456 where
457 F: Fn(&H, &H) -> Result<bool, E>,
458 E: std::error::Error,
459 {
460 let mut new_set = None;
461
462 for change in self
463 .pending_forced_changes
464 .iter()
465 .take_while(|c| c.effective_number() <= best_number) .filter(|c| c.effective_number() == best_number)
467 {
468 if change.canon_hash == best_hash || is_descendent_of(&change.canon_hash, &best_hash)? {
471 let median_last_finalized = match change.delay_kind {
472 DelayKind::Best { ref median_last_finalized } => median_last_finalized.clone(),
473 _ => unreachable!(
474 "pending_forced_changes only contains forced changes; forced changes have delay kind Best; qed."
475 ),
476 };
477
478 for (_, _, standard_change) in self.pending_standard_changes.roots() {
480 if standard_change.effective_number() <= median_last_finalized &&
481 is_descendent_of(&standard_change.canon_hash, &change.canon_hash)?
482 {
483 log::info!(target: LOG_TARGET,
484 "Not applying authority set change forced at block #{:?}, due to pending standard change at block #{:?}",
485 change.canon_height,
486 standard_change.effective_number(),
487 );
488
489 return Err(Error::ForcedAuthoritySetChangeDependencyUnsatisfied(
490 standard_change.effective_number(),
491 ));
492 }
493 }
494
495 grandpa_log!(
497 initial_sync,
498 "👴 Applying authority set change forced at block #{:?}",
499 change.canon_height,
500 );
501
502 telemetry!(
503 telemetry;
504 CONSENSUS_INFO;
505 "afg.applying_forced_authority_set_change";
506 "block" => ?change.canon_height
507 );
508
509 let mut authority_set_changes = self.authority_set_changes.clone();
510 authority_set_changes.append(self.set_id, median_last_finalized.clone());
511
512 new_set = Some((
513 median_last_finalized,
514 AuthoritySet {
515 current_authorities: change.next_authorities.clone(),
516 set_id: self.set_id + 1,
517 pending_standard_changes: ForkTree::new(), pending_forced_changes: Vec::new(),
519 authority_set_changes,
520 },
521 ));
522
523 break;
524 }
525 }
526
527 Ok(new_set)
530 }
531
532 pub(crate) fn apply_standard_changes<F, E>(
543 &mut self,
544 finalized_hash: H,
545 finalized_number: N,
546 is_descendent_of: &F,
547 initial_sync: bool,
548 telemetry: Option<&TelemetryHandle>,
549 ) -> Result<Status<H, N>, Error<N, E>>
550 where
551 F: Fn(&H, &H) -> Result<bool, E>,
552 E: std::error::Error,
553 {
554 let mut status = Status { changed: false, new_set_block: None };
555
556 match self.pending_standard_changes.finalize_with_descendent_if(
557 &finalized_hash,
558 finalized_number.clone(),
559 is_descendent_of,
560 |change| change.effective_number() <= finalized_number,
561 )? {
562 fork_tree::FinalizationResult::Changed(change) => {
563 status.changed = true;
564
565 let pending_forced_changes = std::mem::take(&mut self.pending_forced_changes);
566
567 for change in pending_forced_changes {
570 if change.effective_number() > finalized_number &&
571 is_descendent_of(&finalized_hash, &change.canon_hash)?
572 {
573 self.pending_forced_changes.push(change)
574 }
575 }
576
577 if let Some(change) = change {
578 grandpa_log!(
579 initial_sync,
580 "👴 Applying authority set change scheduled at block #{:?}",
581 change.canon_height,
582 );
583 telemetry!(
584 telemetry;
585 CONSENSUS_INFO;
586 "afg.applying_scheduled_authority_set_change";
587 "block" => ?change.canon_height
588 );
589
590 self.authority_set_changes.append(self.set_id, finalized_number.clone());
592
593 self.current_authorities = change.next_authorities;
594 self.set_id += 1;
595
596 status.new_set_block = Some((finalized_hash, finalized_number));
597 }
598 },
599 fork_tree::FinalizationResult::Unchanged => {},
600 }
601
602 Ok(status)
603 }
604
605 pub fn enacts_standard_change<F, E>(
616 &self,
617 finalized_hash: H,
618 finalized_number: N,
619 is_descendent_of: &F,
620 ) -> Result<Option<bool>, Error<N, E>>
621 where
622 F: Fn(&H, &H) -> Result<bool, E>,
623 E: std::error::Error,
624 {
625 self.pending_standard_changes
626 .finalizes_any_with_descendent_if(
627 &finalized_hash,
628 finalized_number.clone(),
629 is_descendent_of,
630 |change| change.effective_number() == finalized_number,
631 )
632 .map_err(Error::ForkTree)
633 }
634}
635
636#[derive(Debug, Clone, Encode, Decode, PartialEq)]
638pub enum DelayKind<N> {
639 Finalized,
641 Best { median_last_finalized: N },
644}
645
646#[derive(Debug, Clone, Encode, PartialEq)]
651pub struct PendingChange<H, N> {
652 pub(crate) next_authorities: AuthorityList,
654 pub(crate) delay: N,
657 pub(crate) canon_height: N,
659 pub(crate) canon_hash: H,
661 pub(crate) delay_kind: DelayKind<N>,
663}
664
665impl<H: Decode, N: Decode> Decode for PendingChange<H, N> {
666 fn decode<I: codec::Input>(value: &mut I) -> Result<Self, codec::Error> {
667 let next_authorities = Decode::decode(value)?;
668 let delay = Decode::decode(value)?;
669 let canon_height = Decode::decode(value)?;
670 let canon_hash = Decode::decode(value)?;
671
672 let delay_kind = DelayKind::decode(value).unwrap_or(DelayKind::Finalized);
673
674 Ok(PendingChange { next_authorities, delay, canon_height, canon_hash, delay_kind })
675 }
676}
677
678impl<H, N: Add<Output = N> + Clone> PendingChange<H, N> {
679 pub fn effective_number(&self) -> N {
681 self.canon_height.clone() + self.delay.clone()
682 }
683}
684
685#[derive(Debug, Encode, Decode, Clone, PartialEq)]
689pub struct AuthoritySetChanges<N>(Vec<(u64, N)>);
690
691#[derive(Debug, PartialEq)]
695pub enum AuthoritySetChangeId<N> {
696 Latest,
698 Set(SetId, N),
700 Unknown,
703}
704
705impl<N> From<Vec<(u64, N)>> for AuthoritySetChanges<N> {
706 fn from(changes: Vec<(u64, N)>) -> AuthoritySetChanges<N> {
707 AuthoritySetChanges(changes)
708 }
709}
710
711impl<N: Ord + Clone> AuthoritySetChanges<N> {
712 pub(crate) fn empty() -> Self {
713 Self(Default::default())
714 }
715
716 pub(crate) fn append(&mut self, set_id: u64, block_number: N) {
717 self.0.push((set_id, block_number));
718 }
719
720 pub(crate) fn get_set_id(&self, block_number: N) -> AuthoritySetChangeId<N> {
721 if self
722 .0
723 .last()
724 .map(|last_auth_change| last_auth_change.1 < block_number)
725 .unwrap_or(false)
726 {
727 return AuthoritySetChangeId::Latest;
728 }
729
730 let idx = self
731 .0
732 .binary_search_by_key(&block_number, |(_, n)| n.clone())
733 .unwrap_or_else(|b| b);
734
735 if idx < self.0.len() {
736 let (set_id, block_number) = self.0[idx].clone();
737
738 if idx == 0 && set_id != 0 {
740 return AuthoritySetChangeId::Unknown;
741 }
742
743 AuthoritySetChangeId::Set(set_id, block_number)
744 } else {
745 AuthoritySetChangeId::Unknown
746 }
747 }
748
749 pub(crate) fn insert(&mut self, block_number: N) {
750 let idx = self
751 .0
752 .binary_search_by_key(&block_number, |(_, n)| n.clone())
753 .unwrap_or_else(|b| b);
754
755 let set_id = if idx == 0 { 0 } else { self.0[idx - 1].0 + 1 };
756 assert!(idx == self.0.len() || self.0[idx].0 != set_id);
757 self.0.insert(idx, (set_id, block_number));
758 }
759
760 pub fn iter_from(&self, block_number: N) -> Option<impl Iterator<Item = &(u64, N)>> {
764 let idx = self
765 .0
766 .binary_search_by_key(&block_number, |(_, n)| n.clone())
767 .map(|n| n + 1)
770 .unwrap_or_else(|b| b);
771
772 if idx < self.0.len() {
773 let (set_id, _) = self.0[idx].clone();
774
775 if idx == 0 && set_id != 0 {
777 return None;
778 }
779 }
780
781 Some(self.0[idx..].iter())
782 }
783}
784
785#[cfg(test)]
786mod tests {
787 use super::*;
788 use sp_core::crypto::{ByteArray, UncheckedFrom};
789
790 fn static_is_descendent_of<A>(value: bool) -> impl Fn(&A, &A) -> Result<bool, std::io::Error> {
791 move |_, _| Ok(value)
792 }
793
794 fn is_descendent_of<A, F>(f: F) -> impl Fn(&A, &A) -> Result<bool, std::io::Error>
795 where
796 F: Fn(&A, &A) -> bool,
797 {
798 move |base, hash| Ok(f(base, hash))
799 }
800
801 #[test]
802 fn current_limit_filters_min() {
803 let current_authorities = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 1)];
804
805 let mut authorities = AuthoritySet {
806 current_authorities: current_authorities.clone(),
807 set_id: 0,
808 pending_standard_changes: ForkTree::new(),
809 pending_forced_changes: Vec::new(),
810 authority_set_changes: AuthoritySetChanges::empty(),
811 };
812
813 let change = |height| PendingChange {
814 next_authorities: current_authorities.clone(),
815 delay: 0,
816 canon_height: height,
817 canon_hash: height.to_string(),
818 delay_kind: DelayKind::Finalized,
819 };
820
821 let is_descendent_of = static_is_descendent_of(false);
822
823 authorities.add_pending_change(change(1), &is_descendent_of).unwrap();
824 authorities.add_pending_change(change(2), &is_descendent_of).unwrap();
825
826 assert_eq!(authorities.current_limit(0), Some(1));
827
828 assert_eq!(authorities.current_limit(1), Some(1));
829
830 assert_eq!(authorities.current_limit(2), Some(2));
831
832 assert_eq!(authorities.current_limit(3), None);
833 }
834
835 #[test]
836 fn changes_iterated_in_pre_order() {
837 let current_authorities = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 1)];
838
839 let mut authorities = AuthoritySet {
840 current_authorities: current_authorities.clone(),
841 set_id: 0,
842 pending_standard_changes: ForkTree::new(),
843 pending_forced_changes: Vec::new(),
844 authority_set_changes: AuthoritySetChanges::empty(),
845 };
846
847 let change_a = PendingChange {
848 next_authorities: current_authorities.clone(),
849 delay: 10,
850 canon_height: 5,
851 canon_hash: "hash_a",
852 delay_kind: DelayKind::Finalized,
853 };
854
855 let change_b = PendingChange {
856 next_authorities: current_authorities.clone(),
857 delay: 0,
858 canon_height: 5,
859 canon_hash: "hash_b",
860 delay_kind: DelayKind::Finalized,
861 };
862
863 let change_c = PendingChange {
864 next_authorities: current_authorities.clone(),
865 delay: 5,
866 canon_height: 10,
867 canon_hash: "hash_c",
868 delay_kind: DelayKind::Finalized,
869 };
870
871 authorities
872 .add_pending_change(change_a.clone(), &static_is_descendent_of(false))
873 .unwrap();
874 authorities
875 .add_pending_change(change_b.clone(), &static_is_descendent_of(false))
876 .unwrap();
877 authorities
878 .add_pending_change(
879 change_c.clone(),
880 &is_descendent_of(|base, hash| match (*base, *hash) {
881 ("hash_a", "hash_c") => true,
882 ("hash_b", "hash_c") => false,
883 _ => unreachable!(),
884 }),
885 )
886 .unwrap();
887
888 let change_d = PendingChange {
890 next_authorities: current_authorities.clone(),
891 delay: 2,
892 canon_height: 1,
893 canon_hash: "hash_d",
894 delay_kind: DelayKind::Best { median_last_finalized: 0 },
895 };
896
897 let change_e = PendingChange {
898 next_authorities: current_authorities.clone(),
899 delay: 2,
900 canon_height: 0,
901 canon_hash: "hash_e",
902 delay_kind: DelayKind::Best { median_last_finalized: 0 },
903 };
904
905 authorities
906 .add_pending_change(change_d.clone(), &static_is_descendent_of(false))
907 .unwrap();
908 authorities
909 .add_pending_change(change_e.clone(), &static_is_descendent_of(false))
910 .unwrap();
911
912 assert_eq!(
914 authorities.pending_changes().collect::<Vec<_>>(),
915 vec![&change_a, &change_c, &change_b, &change_e, &change_d],
916 );
917 }
918
919 #[test]
920 fn apply_change() {
921 let mut authorities = AuthoritySet {
922 current_authorities: Vec::new(),
923 set_id: 0,
924 pending_standard_changes: ForkTree::new(),
925 pending_forced_changes: Vec::new(),
926 authority_set_changes: AuthoritySetChanges::empty(),
927 };
928
929 let set_a = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 5)];
930 let set_b = vec![(AuthorityId::from_slice(&[2; 32]).unwrap(), 5)];
931
932 let change_a = PendingChange {
934 next_authorities: set_a.clone(),
935 delay: 10,
936 canon_height: 5,
937 canon_hash: "hash_a",
938 delay_kind: DelayKind::Finalized,
939 };
940
941 let change_b = PendingChange {
942 next_authorities: set_b.clone(),
943 delay: 10,
944 canon_height: 5,
945 canon_hash: "hash_b",
946 delay_kind: DelayKind::Finalized,
947 };
948
949 authorities
950 .add_pending_change(change_a.clone(), &static_is_descendent_of(true))
951 .unwrap();
952 authorities
953 .add_pending_change(change_b.clone(), &static_is_descendent_of(true))
954 .unwrap();
955
956 assert_eq!(authorities.pending_changes().collect::<Vec<_>>(), vec![&change_a, &change_b]);
957
958 let status = authorities
961 .apply_standard_changes(
962 "hash_c",
963 11,
964 &is_descendent_of(|base, hash| match (*base, *hash) {
965 ("hash_a", "hash_c") => true,
966 ("hash_b", "hash_c") => false,
967 _ => unreachable!(),
968 }),
969 false,
970 None,
971 )
972 .unwrap();
973
974 assert!(status.changed);
975 assert_eq!(status.new_set_block, None);
976 assert_eq!(authorities.pending_changes().collect::<Vec<_>>(), vec![&change_a]);
977 assert_eq!(authorities.authority_set_changes, AuthoritySetChanges::empty());
978
979 let status = authorities
981 .apply_standard_changes(
982 "hash_d",
983 15,
984 &is_descendent_of(|base, hash| match (*base, *hash) {
985 ("hash_a", "hash_d") => true,
986 _ => unreachable!(),
987 }),
988 false,
989 None,
990 )
991 .unwrap();
992
993 assert!(status.changed);
994 assert_eq!(status.new_set_block, Some(("hash_d", 15)));
995
996 assert_eq!(authorities.current_authorities, set_a);
997 assert_eq!(authorities.set_id, 1);
998 assert_eq!(authorities.pending_changes().count(), 0);
999 assert_eq!(authorities.authority_set_changes, AuthoritySetChanges(vec![(0, 15)]));
1000 }
1001
1002 #[test]
1003 fn disallow_multiple_changes_being_finalized_at_once() {
1004 let mut authorities = AuthoritySet {
1005 current_authorities: Vec::new(),
1006 set_id: 0,
1007 pending_standard_changes: ForkTree::new(),
1008 pending_forced_changes: Vec::new(),
1009 authority_set_changes: AuthoritySetChanges::empty(),
1010 };
1011
1012 let set_a = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 5)];
1013 let set_c = vec![(AuthorityId::from_slice(&[2; 32]).unwrap(), 5)];
1014
1015 let change_a = PendingChange {
1017 next_authorities: set_a.clone(),
1018 delay: 10,
1019 canon_height: 5,
1020 canon_hash: "hash_a",
1021 delay_kind: DelayKind::Finalized,
1022 };
1023
1024 let change_c = PendingChange {
1025 next_authorities: set_c.clone(),
1026 delay: 10,
1027 canon_height: 30,
1028 canon_hash: "hash_c",
1029 delay_kind: DelayKind::Finalized,
1030 };
1031
1032 authorities
1033 .add_pending_change(change_a.clone(), &static_is_descendent_of(true))
1034 .unwrap();
1035 authorities
1036 .add_pending_change(change_c.clone(), &static_is_descendent_of(true))
1037 .unwrap();
1038
1039 let is_descendent_of = is_descendent_of(|base, hash| match (*base, *hash) {
1040 ("hash_a", "hash_b") => true,
1041 ("hash_a", "hash_c") => true,
1042 ("hash_a", "hash_d") => true,
1043
1044 ("hash_c", "hash_b") => false,
1045 ("hash_c", "hash_d") => true,
1046
1047 ("hash_b", "hash_c") => true,
1048 _ => unreachable!(),
1049 });
1050
1051 assert!(matches!(
1053 authorities.apply_standard_changes("hash_d", 40, &is_descendent_of, false, None),
1054 Err(Error::ForkTree(fork_tree::Error::UnfinalizedAncestor))
1055 ));
1056 assert_eq!(authorities.authority_set_changes, AuthoritySetChanges::empty());
1057
1058 let status = authorities
1059 .apply_standard_changes("hash_b", 15, &is_descendent_of, false, None)
1060 .unwrap();
1061
1062 assert!(status.changed);
1063 assert_eq!(status.new_set_block, Some(("hash_b", 15)));
1064
1065 assert_eq!(authorities.current_authorities, set_a);
1066 assert_eq!(authorities.set_id, 1);
1067 assert_eq!(authorities.authority_set_changes, AuthoritySetChanges(vec![(0, 15)]));
1068
1069 let status = authorities
1071 .apply_standard_changes("hash_d", 40, &is_descendent_of, false, None)
1072 .unwrap();
1073
1074 assert!(status.changed);
1075 assert_eq!(status.new_set_block, Some(("hash_d", 40)));
1076
1077 assert_eq!(authorities.current_authorities, set_c);
1078 assert_eq!(authorities.set_id, 2);
1079 assert_eq!(authorities.authority_set_changes, AuthoritySetChanges(vec![(0, 15), (1, 40)]));
1080 }
1081
1082 #[test]
1083 fn enacts_standard_change_works() {
1084 let mut authorities = AuthoritySet {
1085 current_authorities: Vec::new(),
1086 set_id: 0,
1087 pending_standard_changes: ForkTree::new(),
1088 pending_forced_changes: Vec::new(),
1089 authority_set_changes: AuthoritySetChanges::empty(),
1090 };
1091
1092 let set_a = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 5)];
1093
1094 let change_a = PendingChange {
1095 next_authorities: set_a.clone(),
1096 delay: 10,
1097 canon_height: 5,
1098 canon_hash: "hash_a",
1099 delay_kind: DelayKind::Finalized,
1100 };
1101
1102 let change_b = PendingChange {
1103 next_authorities: set_a.clone(),
1104 delay: 10,
1105 canon_height: 20,
1106 canon_hash: "hash_b",
1107 delay_kind: DelayKind::Finalized,
1108 };
1109
1110 authorities
1111 .add_pending_change(change_a.clone(), &static_is_descendent_of(false))
1112 .unwrap();
1113 authorities
1114 .add_pending_change(change_b.clone(), &static_is_descendent_of(true))
1115 .unwrap();
1116
1117 let is_descendent_of = is_descendent_of(|base, hash| match (*base, *hash) {
1118 ("hash_a", "hash_d") => true,
1119 ("hash_a", "hash_e") => true,
1120 ("hash_b", "hash_d") => true,
1121 ("hash_b", "hash_e") => true,
1122 ("hash_a", "hash_c") => false,
1123 ("hash_b", "hash_c") => false,
1124 _ => unreachable!(),
1125 });
1126
1127 assert_eq!(
1129 authorities.enacts_standard_change("hash_c", 15, &is_descendent_of).unwrap(),
1130 None,
1131 );
1132
1133 assert_eq!(
1135 authorities.enacts_standard_change("hash_d", 14, &is_descendent_of).unwrap(),
1136 None,
1137 );
1138
1139 assert_eq!(
1141 authorities.enacts_standard_change("hash_d", 15, &is_descendent_of).unwrap(),
1142 Some(true),
1143 );
1144
1145 assert_eq!(
1148 authorities.enacts_standard_change("hash_e", 30, &is_descendent_of).unwrap(),
1149 Some(false),
1150 );
1151 }
1152
1153 #[test]
1154 fn forced_changes() {
1155 let mut authorities = AuthoritySet {
1156 current_authorities: Vec::new(),
1157 set_id: 0,
1158 pending_standard_changes: ForkTree::new(),
1159 pending_forced_changes: Vec::new(),
1160 authority_set_changes: AuthoritySetChanges::empty(),
1161 };
1162
1163 let set_a = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 5)];
1164 let set_b = vec![(AuthorityId::from_slice(&[2; 32]).unwrap(), 5)];
1165
1166 let change_a = PendingChange {
1167 next_authorities: set_a.clone(),
1168 delay: 10,
1169 canon_height: 5,
1170 canon_hash: "hash_a",
1171 delay_kind: DelayKind::Best { median_last_finalized: 42 },
1172 };
1173
1174 let change_b = PendingChange {
1175 next_authorities: set_b.clone(),
1176 delay: 10,
1177 canon_height: 5,
1178 canon_hash: "hash_b",
1179 delay_kind: DelayKind::Best { median_last_finalized: 0 },
1180 };
1181
1182 authorities
1183 .add_pending_change(change_a, &static_is_descendent_of(false))
1184 .unwrap();
1185 authorities
1186 .add_pending_change(change_b.clone(), &static_is_descendent_of(false))
1187 .unwrap();
1188
1189 assert!(matches!(
1191 authorities.add_pending_change(change_b, &static_is_descendent_of(false)),
1192 Err(Error::DuplicateAuthoritySetChange)
1193 ));
1194
1195 assert_eq!(
1198 authorities
1199 .enacts_standard_change("hash_c", 15, &static_is_descendent_of(true))
1200 .unwrap(),
1201 None,
1202 );
1203
1204 let change_c = PendingChange {
1206 next_authorities: set_b.clone(),
1207 delay: 3,
1208 canon_height: 8,
1209 canon_hash: "hash_a8",
1210 delay_kind: DelayKind::Best { median_last_finalized: 0 },
1211 };
1212
1213 let is_descendent_of_a = is_descendent_of(|base: &&str, _| base.starts_with("hash_a"));
1214
1215 assert!(matches!(
1216 authorities.add_pending_change(change_c, &is_descendent_of_a),
1217 Err(Error::MultiplePendingForcedAuthoritySetChanges)
1218 ));
1219
1220 assert!(authorities
1223 .apply_forced_changes("hash_a10", 10, &static_is_descendent_of(true), false, None)
1224 .unwrap()
1225 .is_none());
1226
1227 assert!(authorities
1229 .apply_forced_changes("hash_a16", 16, &is_descendent_of_a, false, None)
1230 .unwrap()
1231 .is_none());
1232
1233 assert_eq!(
1235 authorities
1236 .apply_forced_changes("hash_a15", 15, &is_descendent_of_a, false, None)
1237 .unwrap()
1238 .unwrap(),
1239 (
1240 42,
1241 AuthoritySet {
1242 current_authorities: set_a,
1243 set_id: 1,
1244 pending_standard_changes: ForkTree::new(),
1245 pending_forced_changes: Vec::new(),
1246 authority_set_changes: AuthoritySetChanges(vec![(0, 42)]),
1247 },
1248 )
1249 );
1250 }
1251
1252 #[test]
1253 fn forced_changes_with_no_delay() {
1254 let mut authorities = AuthoritySet {
1256 current_authorities: Vec::new(),
1257 set_id: 0,
1258 pending_standard_changes: ForkTree::new(),
1259 pending_forced_changes: Vec::new(),
1260 authority_set_changes: AuthoritySetChanges::empty(),
1261 };
1262
1263 let set_a = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 5)];
1264
1265 let change_a = PendingChange {
1267 next_authorities: set_a.clone(),
1268 delay: 0,
1269 canon_height: 5,
1270 canon_hash: "hash_a",
1271 delay_kind: DelayKind::Best { median_last_finalized: 0 },
1272 };
1273
1274 authorities
1276 .add_pending_change(change_a, &static_is_descendent_of(false))
1277 .unwrap();
1278
1279 assert!(authorities
1281 .apply_forced_changes("hash_a", 5, &static_is_descendent_of(false), false, None)
1282 .unwrap()
1283 .is_some());
1284 }
1285
1286 #[test]
1287 fn forced_changes_blocked_by_standard_changes() {
1288 let set_a = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 1)];
1289
1290 let mut authorities = AuthoritySet {
1291 current_authorities: set_a.clone(),
1292 set_id: 0,
1293 pending_standard_changes: ForkTree::new(),
1294 pending_forced_changes: Vec::new(),
1295 authority_set_changes: AuthoritySetChanges::empty(),
1296 };
1297
1298 let change_a = PendingChange {
1300 next_authorities: set_a.clone(),
1301 delay: 5,
1302 canon_height: 10,
1303 canon_hash: "hash_a",
1304 delay_kind: DelayKind::Finalized,
1305 };
1306
1307 let change_b = PendingChange {
1309 next_authorities: set_a.clone(),
1310 delay: 0,
1311 canon_height: 20,
1312 canon_hash: "hash_b",
1313 delay_kind: DelayKind::Finalized,
1314 };
1315
1316 let change_c = PendingChange {
1318 next_authorities: set_a.clone(),
1319 delay: 5,
1320 canon_height: 30,
1321 canon_hash: "hash_c",
1322 delay_kind: DelayKind::Finalized,
1323 };
1324
1325 authorities
1327 .add_pending_change(change_a, &static_is_descendent_of(true))
1328 .unwrap();
1329 authorities
1330 .add_pending_change(change_b, &static_is_descendent_of(true))
1331 .unwrap();
1332 authorities
1333 .add_pending_change(change_c, &static_is_descendent_of(true))
1334 .unwrap();
1335
1336 let change_d = PendingChange {
1338 next_authorities: set_a.clone(),
1339 delay: 5,
1340 canon_height: 40,
1341 canon_hash: "hash_d",
1342 delay_kind: DelayKind::Best { median_last_finalized: 31 },
1343 };
1344
1345 authorities
1347 .add_pending_change(change_d, &static_is_descendent_of(true))
1348 .unwrap();
1349
1350 assert!(matches!(
1353 authorities.apply_forced_changes(
1354 "hash_d45",
1355 45,
1356 &static_is_descendent_of(true),
1357 false,
1358 None
1359 ),
1360 Err(Error::ForcedAuthoritySetChangeDependencyUnsatisfied(15))
1361 ));
1362 assert_eq!(authorities.authority_set_changes, AuthoritySetChanges::empty());
1363
1364 authorities
1366 .apply_standard_changes("hash_a15", 15, &static_is_descendent_of(true), false, None)
1367 .unwrap();
1368 assert_eq!(authorities.authority_set_changes, AuthoritySetChanges(vec![(0, 15)]));
1369
1370 assert!(matches!(
1372 authorities.apply_forced_changes(
1373 "hash_d",
1374 45,
1375 &static_is_descendent_of(true),
1376 false,
1377 None
1378 ),
1379 Err(Error::ForcedAuthoritySetChangeDependencyUnsatisfied(20))
1380 ));
1381 assert_eq!(authorities.authority_set_changes, AuthoritySetChanges(vec![(0, 15)]));
1382
1383 authorities
1385 .apply_standard_changes("hash_b", 20, &static_is_descendent_of(true), false, None)
1386 .unwrap();
1387 assert_eq!(authorities.authority_set_changes, AuthoritySetChanges(vec![(0, 15), (1, 20)]));
1388
1389 assert_eq!(
1393 authorities
1394 .apply_forced_changes("hash_d", 45, &static_is_descendent_of(true), false, None)
1395 .unwrap()
1396 .unwrap(),
1397 (
1398 31,
1399 AuthoritySet {
1400 current_authorities: set_a.clone(),
1401 set_id: 3,
1402 pending_standard_changes: ForkTree::new(),
1403 pending_forced_changes: Vec::new(),
1404 authority_set_changes: AuthoritySetChanges(vec![(0, 15), (1, 20), (2, 31)]),
1405 }
1406 ),
1407 );
1408 assert_eq!(authorities.authority_set_changes, AuthoritySetChanges(vec![(0, 15), (1, 20)]));
1409 }
1410
1411 #[test]
1412 fn next_change_works() {
1413 let current_authorities = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 1)];
1414
1415 let mut authorities = AuthoritySet {
1416 current_authorities: current_authorities.clone(),
1417 set_id: 0,
1418 pending_standard_changes: ForkTree::new(),
1419 pending_forced_changes: Vec::new(),
1420 authority_set_changes: AuthoritySetChanges::empty(),
1421 };
1422
1423 let new_set = current_authorities.clone();
1424
1425 let change_a0 = PendingChange {
1428 next_authorities: new_set.clone(),
1429 delay: 0,
1430 canon_height: 5,
1431 canon_hash: "hash_a0",
1432 delay_kind: DelayKind::Finalized,
1433 };
1434
1435 let change_a1 = PendingChange {
1436 next_authorities: new_set.clone(),
1437 delay: 0,
1438 canon_height: 10,
1439 canon_hash: "hash_a1",
1440 delay_kind: DelayKind::Finalized,
1441 };
1442
1443 let change_b = PendingChange {
1444 next_authorities: new_set.clone(),
1445 delay: 0,
1446 canon_height: 4,
1447 canon_hash: "hash_b",
1448 delay_kind: DelayKind::Finalized,
1449 };
1450
1451 let is_descendent_of = is_descendent_of(|base, hash| match (*base, *hash) {
1454 ("hash_a0", "hash_a1") => true,
1455 ("hash_a0", "best_a") => true,
1456 ("hash_a1", "best_a") => true,
1457 ("hash_a10", "best_a") => true,
1458 ("hash_b", "best_b") => true,
1459 _ => false,
1460 });
1461
1462 authorities.add_pending_change(change_b, &is_descendent_of).unwrap();
1464 authorities.add_pending_change(change_a0, &is_descendent_of).unwrap();
1465 authorities.add_pending_change(change_a1, &is_descendent_of).unwrap();
1466
1467 assert_eq!(
1469 authorities.next_change(&"best_a", &is_descendent_of).unwrap(),
1470 Some(("hash_a0", 5)),
1471 );
1472
1473 assert_eq!(
1475 authorities.next_change(&"best_b", &is_descendent_of).unwrap(),
1476 Some(("hash_b", 4)),
1477 );
1478
1479 authorities
1481 .apply_standard_changes("hash_a0", 5, &is_descendent_of, false, None)
1482 .unwrap();
1483
1484 assert_eq!(
1486 authorities.next_change(&"best_a", &is_descendent_of).unwrap(),
1487 Some(("hash_a1", 10)),
1488 );
1489
1490 assert_eq!(authorities.next_change(&"best_b", &is_descendent_of).unwrap(), None);
1492
1493 let change_a10 = PendingChange {
1495 next_authorities: new_set.clone(),
1496 delay: 0,
1497 canon_height: 8,
1498 canon_hash: "hash_a10",
1499 delay_kind: DelayKind::Best { median_last_finalized: 0 },
1500 };
1501
1502 authorities
1503 .add_pending_change(change_a10, &static_is_descendent_of(false))
1504 .unwrap();
1505
1506 assert_eq!(
1508 authorities.next_change(&"best_a", &is_descendent_of).unwrap(),
1509 Some(("hash_a10", 8)),
1510 );
1511 }
1512
1513 #[test]
1514 fn maintains_authority_list_invariants() {
1515 assert_eq!(AuthoritySet::<(), ()>::genesis(vec![]), None);
1517 assert_eq!(
1518 AuthoritySet::<(), ()>::new(
1519 vec![],
1520 0,
1521 ForkTree::new(),
1522 Vec::new(),
1523 AuthoritySetChanges::empty(),
1524 ),
1525 None,
1526 );
1527
1528 let invalid_authorities_weight = vec![
1529 (AuthorityId::from_slice(&[1; 32]).unwrap(), 5),
1530 (AuthorityId::from_slice(&[2; 32]).unwrap(), 0),
1531 ];
1532
1533 assert_eq!(AuthoritySet::<(), ()>::genesis(invalid_authorities_weight.clone()), None);
1535 assert_eq!(
1536 AuthoritySet::<(), ()>::new(
1537 invalid_authorities_weight.clone(),
1538 0,
1539 ForkTree::new(),
1540 Vec::new(),
1541 AuthoritySetChanges::empty(),
1542 ),
1543 None,
1544 );
1545
1546 let mut authority_set =
1547 AuthoritySet::<(), u64>::genesis(vec![(AuthorityId::unchecked_from([1; 32]), 5)])
1548 .unwrap();
1549
1550 let invalid_change_empty_authorities = PendingChange {
1551 next_authorities: vec![],
1552 delay: 10,
1553 canon_height: 5,
1554 canon_hash: (),
1555 delay_kind: DelayKind::Finalized,
1556 };
1557
1558 assert!(matches!(
1560 authority_set.add_pending_change(
1561 invalid_change_empty_authorities.clone(),
1562 &static_is_descendent_of(false)
1563 ),
1564 Err(Error::InvalidAuthoritySet)
1565 ));
1566
1567 let invalid_change_authorities_weight = PendingChange {
1568 next_authorities: invalid_authorities_weight,
1569 delay: 10,
1570 canon_height: 5,
1571 canon_hash: (),
1572 delay_kind: DelayKind::Best { median_last_finalized: 0 },
1573 };
1574
1575 assert!(matches!(
1578 authority_set.add_pending_change(
1579 invalid_change_authorities_weight,
1580 &static_is_descendent_of(false)
1581 ),
1582 Err(Error::InvalidAuthoritySet)
1583 ));
1584 }
1585
1586 #[test]
1587 fn cleans_up_stale_forced_changes_when_applying_standard_change() {
1588 let current_authorities = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 1)];
1589
1590 let mut authorities = AuthoritySet {
1591 current_authorities: current_authorities.clone(),
1592 set_id: 0,
1593 pending_standard_changes: ForkTree::new(),
1594 pending_forced_changes: Vec::new(),
1595 authority_set_changes: AuthoritySetChanges::empty(),
1596 };
1597
1598 let new_set = current_authorities.clone();
1599
1600 let is_descendent_of = {
1614 let hashes = vec!["B", "C0", "C1", "C2", "C3", "D"];
1615 is_descendent_of(move |base, hash| match (*base, *hash) {
1616 ("B", "B") => false, ("A", b) | ("B", b) => hashes.iter().any(|h| *h == b),
1618 ("C0", "D") => true,
1619 _ => false,
1620 })
1621 };
1622
1623 let mut add_pending_change = |canon_height, canon_hash, forced| {
1624 let change = PendingChange {
1625 next_authorities: new_set.clone(),
1626 delay: 0,
1627 canon_height,
1628 canon_hash,
1629 delay_kind: if forced {
1630 DelayKind::Best { median_last_finalized: 0 }
1631 } else {
1632 DelayKind::Finalized
1633 },
1634 };
1635
1636 authorities.add_pending_change(change, &is_descendent_of).unwrap();
1637 };
1638
1639 add_pending_change(5, "A", false);
1640 add_pending_change(10, "B", false);
1641 add_pending_change(15, "C0", false);
1642 add_pending_change(15, "C1", true);
1643 add_pending_change(15, "C2", false);
1644 add_pending_change(15, "C3", true);
1645 add_pending_change(20, "D", true);
1646
1647 authorities
1650 .apply_standard_changes("A", 5, &is_descendent_of, false, None)
1651 .unwrap();
1652
1653 assert_eq!(authorities.pending_changes().count(), 6);
1654
1655 authorities
1657 .apply_standard_changes("B", 10, &is_descendent_of, false, None)
1658 .unwrap();
1659
1660 assert_eq!(authorities.pending_changes().count(), 5);
1661
1662 let authorities2 = authorities.clone();
1663
1664 authorities
1666 .apply_standard_changes("C2", 15, &is_descendent_of, false, None)
1667 .unwrap();
1668
1669 assert_eq!(authorities.pending_forced_changes.len(), 0);
1670
1671 let mut authorities = authorities2;
1673 authorities
1674 .apply_standard_changes("C0", 15, &is_descendent_of, false, None)
1675 .unwrap();
1676
1677 assert_eq!(authorities.pending_forced_changes.len(), 1);
1678 assert_eq!(authorities.pending_forced_changes.first().unwrap().canon_hash, "D");
1679 }
1680
1681 #[test]
1682 fn authority_set_changes_insert() {
1683 let mut authority_set_changes = AuthoritySetChanges::empty();
1684 authority_set_changes.append(0, 41);
1685 authority_set_changes.append(1, 81);
1686 authority_set_changes.append(4, 121);
1687
1688 authority_set_changes.insert(101);
1689 assert_eq!(authority_set_changes.get_set_id(100), AuthoritySetChangeId::Set(2, 101));
1690 assert_eq!(authority_set_changes.get_set_id(101), AuthoritySetChangeId::Set(2, 101));
1691 }
1692
1693 #[test]
1694 fn authority_set_changes_for_complete_data() {
1695 let mut authority_set_changes = AuthoritySetChanges::empty();
1696 authority_set_changes.append(0, 41);
1697 authority_set_changes.append(1, 81);
1698 authority_set_changes.append(2, 121);
1699
1700 assert_eq!(authority_set_changes.get_set_id(20), AuthoritySetChangeId::Set(0, 41));
1701 assert_eq!(authority_set_changes.get_set_id(40), AuthoritySetChangeId::Set(0, 41));
1702 assert_eq!(authority_set_changes.get_set_id(41), AuthoritySetChangeId::Set(0, 41));
1703 assert_eq!(authority_set_changes.get_set_id(42), AuthoritySetChangeId::Set(1, 81));
1704 assert_eq!(authority_set_changes.get_set_id(141), AuthoritySetChangeId::Latest);
1705 }
1706
1707 #[test]
1708 fn authority_set_changes_for_incomplete_data() {
1709 let mut authority_set_changes = AuthoritySetChanges::empty();
1710 authority_set_changes.append(2, 41);
1711 authority_set_changes.append(3, 81);
1712 authority_set_changes.append(4, 121);
1713
1714 assert_eq!(authority_set_changes.get_set_id(20), AuthoritySetChangeId::Unknown);
1715 assert_eq!(authority_set_changes.get_set_id(40), AuthoritySetChangeId::Unknown);
1716 assert_eq!(authority_set_changes.get_set_id(41), AuthoritySetChangeId::Unknown);
1717 assert_eq!(authority_set_changes.get_set_id(42), AuthoritySetChangeId::Set(3, 81));
1718 assert_eq!(authority_set_changes.get_set_id(141), AuthoritySetChangeId::Latest);
1719 }
1720
1721 #[test]
1722 fn iter_from_works() {
1723 let mut authority_set_changes = AuthoritySetChanges::empty();
1724 authority_set_changes.append(1, 41);
1725 authority_set_changes.append(2, 81);
1726
1727 assert_eq!(None, authority_set_changes.iter_from(40).map(|it| it.collect::<Vec<_>>()));
1729
1730 let mut authority_set_changes = AuthoritySetChanges::empty();
1732 authority_set_changes.append(0, 21);
1733 authority_set_changes.append(1, 41);
1734 authority_set_changes.append(2, 81);
1735 authority_set_changes.append(3, 121);
1736
1737 assert_eq!(
1738 Some(vec![(1, 41), (2, 81), (3, 121)]),
1739 authority_set_changes.iter_from(40).map(|it| it.cloned().collect::<Vec<_>>()),
1740 );
1741
1742 assert_eq!(
1743 Some(vec![(2, 81), (3, 121)]),
1744 authority_set_changes.iter_from(41).map(|it| it.cloned().collect::<Vec<_>>()),
1745 );
1746
1747 assert_eq!(0, authority_set_changes.iter_from(121).unwrap().count());
1748
1749 assert_eq!(0, authority_set_changes.iter_from(200).unwrap().count());
1750 }
1751}