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, thiserror::Error)]
688#[error("authority set change would duplicate set id {0}")]
689pub(crate) struct SetIdConflict(SetId);
690
691#[derive(Debug, Encode, Decode, Clone, PartialEq)]
695pub struct AuthoritySetChanges<N>(Vec<(u64, N)>);
696
697#[derive(Debug, PartialEq)]
701pub enum AuthoritySetChangeId<N> {
702 Latest,
704 Set(SetId, N),
706 Unknown,
709}
710
711impl<N> From<Vec<(u64, N)>> for AuthoritySetChanges<N> {
712 fn from(changes: Vec<(u64, N)>) -> AuthoritySetChanges<N> {
713 AuthoritySetChanges(changes)
714 }
715}
716
717impl<N: Ord + Clone> AuthoritySetChanges<N> {
718 pub(crate) fn empty() -> Self {
719 Self(Default::default())
720 }
721
722 pub(crate) fn append(&mut self, set_id: u64, block_number: N) {
723 self.0.push((set_id, block_number));
724 }
725
726 pub(crate) fn get_set_id(&self, block_number: N) -> AuthoritySetChangeId<N> {
727 if self
728 .0
729 .last()
730 .map(|last_auth_change| last_auth_change.1 < block_number)
731 .unwrap_or(false)
732 {
733 return AuthoritySetChangeId::Latest;
734 }
735
736 let idx = self
737 .0
738 .binary_search_by_key(&block_number, |(_, n)| n.clone())
739 .unwrap_or_else(|b| b);
740
741 if idx < self.0.len() {
742 let (set_id, block_number) = self.0[idx].clone();
743
744 if idx == 0 && set_id != 0 {
746 return AuthoritySetChangeId::Unknown;
747 }
748
749 AuthoritySetChangeId::Set(set_id, block_number)
750 } else {
751 AuthoritySetChangeId::Unknown
752 }
753 }
754
755 pub(crate) fn insert(&mut self, block_number: N) -> Result<(), SetIdConflict> {
760 let idx = self
761 .0
762 .binary_search_by_key(&block_number, |(_, n)| n.clone())
763 .unwrap_or_else(|b| b);
764
765 let set_id = if idx == 0 { 0 } else { self.0[idx - 1].0 + 1 };
766 if idx != self.0.len() && self.0[idx].0 == set_id {
767 return Err(SetIdConflict(set_id));
768 }
769
770 self.0.insert(idx, (set_id, block_number));
771 Ok(())
772 }
773
774 pub fn iter_from(&self, block_number: N) -> Option<impl Iterator<Item = &(u64, N)>> {
778 let idx = self
779 .0
780 .binary_search_by_key(&block_number, |(_, n)| n.clone())
781 .map(|n| n + 1)
784 .unwrap_or_else(|b| b);
785
786 if idx < self.0.len() {
787 let (set_id, _) = self.0[idx].clone();
788
789 if idx == 0 && set_id != 0 {
791 return None;
792 }
793 }
794
795 Some(self.0[idx..].iter())
796 }
797}
798
799#[cfg(test)]
800mod tests {
801 use super::*;
802 use sp_core::crypto::{ByteArray, UncheckedFrom};
803
804 fn static_is_descendent_of<A>(value: bool) -> impl Fn(&A, &A) -> Result<bool, std::io::Error> {
805 move |_, _| Ok(value)
806 }
807
808 fn is_descendent_of<A, F>(f: F) -> impl Fn(&A, &A) -> Result<bool, std::io::Error>
809 where
810 F: Fn(&A, &A) -> bool,
811 {
812 move |base, hash| Ok(f(base, hash))
813 }
814
815 #[test]
816 fn current_limit_filters_min() {
817 let current_authorities = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 1)];
818
819 let mut authorities = AuthoritySet {
820 current_authorities: current_authorities.clone(),
821 set_id: 0,
822 pending_standard_changes: ForkTree::new(),
823 pending_forced_changes: Vec::new(),
824 authority_set_changes: AuthoritySetChanges::empty(),
825 };
826
827 let change = |height| PendingChange {
828 next_authorities: current_authorities.clone(),
829 delay: 0,
830 canon_height: height,
831 canon_hash: height.to_string(),
832 delay_kind: DelayKind::Finalized,
833 };
834
835 let is_descendent_of = static_is_descendent_of(false);
836
837 authorities.add_pending_change(change(1), &is_descendent_of).unwrap();
838 authorities.add_pending_change(change(2), &is_descendent_of).unwrap();
839
840 assert_eq!(authorities.current_limit(0), Some(1));
841
842 assert_eq!(authorities.current_limit(1), Some(1));
843
844 assert_eq!(authorities.current_limit(2), Some(2));
845
846 assert_eq!(authorities.current_limit(3), None);
847 }
848
849 #[test]
850 fn changes_iterated_in_pre_order() {
851 let current_authorities = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 1)];
852
853 let mut authorities = AuthoritySet {
854 current_authorities: current_authorities.clone(),
855 set_id: 0,
856 pending_standard_changes: ForkTree::new(),
857 pending_forced_changes: Vec::new(),
858 authority_set_changes: AuthoritySetChanges::empty(),
859 };
860
861 let change_a = PendingChange {
862 next_authorities: current_authorities.clone(),
863 delay: 10,
864 canon_height: 5,
865 canon_hash: "hash_a",
866 delay_kind: DelayKind::Finalized,
867 };
868
869 let change_b = PendingChange {
870 next_authorities: current_authorities.clone(),
871 delay: 0,
872 canon_height: 5,
873 canon_hash: "hash_b",
874 delay_kind: DelayKind::Finalized,
875 };
876
877 let change_c = PendingChange {
878 next_authorities: current_authorities.clone(),
879 delay: 5,
880 canon_height: 10,
881 canon_hash: "hash_c",
882 delay_kind: DelayKind::Finalized,
883 };
884
885 authorities
886 .add_pending_change(change_a.clone(), &static_is_descendent_of(false))
887 .unwrap();
888 authorities
889 .add_pending_change(change_b.clone(), &static_is_descendent_of(false))
890 .unwrap();
891 authorities
892 .add_pending_change(
893 change_c.clone(),
894 &is_descendent_of(|base, hash| match (*base, *hash) {
895 ("hash_a", "hash_c") => true,
896 ("hash_b", "hash_c") => false,
897 _ => unreachable!(),
898 }),
899 )
900 .unwrap();
901
902 let change_d = PendingChange {
904 next_authorities: current_authorities.clone(),
905 delay: 2,
906 canon_height: 1,
907 canon_hash: "hash_d",
908 delay_kind: DelayKind::Best { median_last_finalized: 0 },
909 };
910
911 let change_e = PendingChange {
912 next_authorities: current_authorities.clone(),
913 delay: 2,
914 canon_height: 0,
915 canon_hash: "hash_e",
916 delay_kind: DelayKind::Best { median_last_finalized: 0 },
917 };
918
919 authorities
920 .add_pending_change(change_d.clone(), &static_is_descendent_of(false))
921 .unwrap();
922 authorities
923 .add_pending_change(change_e.clone(), &static_is_descendent_of(false))
924 .unwrap();
925
926 assert_eq!(
928 authorities.pending_changes().collect::<Vec<_>>(),
929 vec![&change_a, &change_c, &change_b, &change_e, &change_d],
930 );
931 }
932
933 #[test]
934 fn apply_change() {
935 let mut authorities = AuthoritySet {
936 current_authorities: Vec::new(),
937 set_id: 0,
938 pending_standard_changes: ForkTree::new(),
939 pending_forced_changes: Vec::new(),
940 authority_set_changes: AuthoritySetChanges::empty(),
941 };
942
943 let set_a = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 5)];
944 let set_b = vec![(AuthorityId::from_slice(&[2; 32]).unwrap(), 5)];
945
946 let change_a = PendingChange {
948 next_authorities: set_a.clone(),
949 delay: 10,
950 canon_height: 5,
951 canon_hash: "hash_a",
952 delay_kind: DelayKind::Finalized,
953 };
954
955 let change_b = PendingChange {
956 next_authorities: set_b.clone(),
957 delay: 10,
958 canon_height: 5,
959 canon_hash: "hash_b",
960 delay_kind: DelayKind::Finalized,
961 };
962
963 authorities
964 .add_pending_change(change_a.clone(), &static_is_descendent_of(true))
965 .unwrap();
966 authorities
967 .add_pending_change(change_b.clone(), &static_is_descendent_of(true))
968 .unwrap();
969
970 assert_eq!(authorities.pending_changes().collect::<Vec<_>>(), vec![&change_a, &change_b]);
971
972 let status = authorities
975 .apply_standard_changes(
976 "hash_c",
977 11,
978 &is_descendent_of(|base, hash| match (*base, *hash) {
979 ("hash_a", "hash_c") => true,
980 ("hash_b", "hash_c") => false,
981 _ => unreachable!(),
982 }),
983 false,
984 None,
985 )
986 .unwrap();
987
988 assert!(status.changed);
989 assert_eq!(status.new_set_block, None);
990 assert_eq!(authorities.pending_changes().collect::<Vec<_>>(), vec![&change_a]);
991 assert_eq!(authorities.authority_set_changes, AuthoritySetChanges::empty());
992
993 let status = authorities
995 .apply_standard_changes(
996 "hash_d",
997 15,
998 &is_descendent_of(|base, hash| match (*base, *hash) {
999 ("hash_a", "hash_d") => true,
1000 _ => unreachable!(),
1001 }),
1002 false,
1003 None,
1004 )
1005 .unwrap();
1006
1007 assert!(status.changed);
1008 assert_eq!(status.new_set_block, Some(("hash_d", 15)));
1009
1010 assert_eq!(authorities.current_authorities, set_a);
1011 assert_eq!(authorities.set_id, 1);
1012 assert_eq!(authorities.pending_changes().count(), 0);
1013 assert_eq!(authorities.authority_set_changes, AuthoritySetChanges(vec![(0, 15)]));
1014 }
1015
1016 #[test]
1017 fn disallow_multiple_changes_being_finalized_at_once() {
1018 let mut authorities = AuthoritySet {
1019 current_authorities: Vec::new(),
1020 set_id: 0,
1021 pending_standard_changes: ForkTree::new(),
1022 pending_forced_changes: Vec::new(),
1023 authority_set_changes: AuthoritySetChanges::empty(),
1024 };
1025
1026 let set_a = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 5)];
1027 let set_c = vec![(AuthorityId::from_slice(&[2; 32]).unwrap(), 5)];
1028
1029 let change_a = PendingChange {
1031 next_authorities: set_a.clone(),
1032 delay: 10,
1033 canon_height: 5,
1034 canon_hash: "hash_a",
1035 delay_kind: DelayKind::Finalized,
1036 };
1037
1038 let change_c = PendingChange {
1039 next_authorities: set_c.clone(),
1040 delay: 10,
1041 canon_height: 30,
1042 canon_hash: "hash_c",
1043 delay_kind: DelayKind::Finalized,
1044 };
1045
1046 authorities
1047 .add_pending_change(change_a.clone(), &static_is_descendent_of(true))
1048 .unwrap();
1049 authorities
1050 .add_pending_change(change_c.clone(), &static_is_descendent_of(true))
1051 .unwrap();
1052
1053 let is_descendent_of = is_descendent_of(|base, hash| match (*base, *hash) {
1054 ("hash_a", "hash_b") => true,
1055 ("hash_a", "hash_c") => true,
1056 ("hash_a", "hash_d") => true,
1057
1058 ("hash_c", "hash_b") => false,
1059 ("hash_c", "hash_d") => true,
1060
1061 ("hash_b", "hash_c") => true,
1062 _ => unreachable!(),
1063 });
1064
1065 assert!(matches!(
1067 authorities.apply_standard_changes("hash_d", 40, &is_descendent_of, false, None),
1068 Err(Error::ForkTree(fork_tree::Error::UnfinalizedAncestor))
1069 ));
1070 assert_eq!(authorities.authority_set_changes, AuthoritySetChanges::empty());
1071
1072 let status = authorities
1073 .apply_standard_changes("hash_b", 15, &is_descendent_of, false, None)
1074 .unwrap();
1075
1076 assert!(status.changed);
1077 assert_eq!(status.new_set_block, Some(("hash_b", 15)));
1078
1079 assert_eq!(authorities.current_authorities, set_a);
1080 assert_eq!(authorities.set_id, 1);
1081 assert_eq!(authorities.authority_set_changes, AuthoritySetChanges(vec![(0, 15)]));
1082
1083 let status = authorities
1085 .apply_standard_changes("hash_d", 40, &is_descendent_of, false, None)
1086 .unwrap();
1087
1088 assert!(status.changed);
1089 assert_eq!(status.new_set_block, Some(("hash_d", 40)));
1090
1091 assert_eq!(authorities.current_authorities, set_c);
1092 assert_eq!(authorities.set_id, 2);
1093 assert_eq!(authorities.authority_set_changes, AuthoritySetChanges(vec![(0, 15), (1, 40)]));
1094 }
1095
1096 #[test]
1097 fn enacts_standard_change_works() {
1098 let mut authorities = AuthoritySet {
1099 current_authorities: Vec::new(),
1100 set_id: 0,
1101 pending_standard_changes: ForkTree::new(),
1102 pending_forced_changes: Vec::new(),
1103 authority_set_changes: AuthoritySetChanges::empty(),
1104 };
1105
1106 let set_a = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 5)];
1107
1108 let change_a = PendingChange {
1109 next_authorities: set_a.clone(),
1110 delay: 10,
1111 canon_height: 5,
1112 canon_hash: "hash_a",
1113 delay_kind: DelayKind::Finalized,
1114 };
1115
1116 let change_b = PendingChange {
1117 next_authorities: set_a.clone(),
1118 delay: 10,
1119 canon_height: 20,
1120 canon_hash: "hash_b",
1121 delay_kind: DelayKind::Finalized,
1122 };
1123
1124 authorities
1125 .add_pending_change(change_a.clone(), &static_is_descendent_of(false))
1126 .unwrap();
1127 authorities
1128 .add_pending_change(change_b.clone(), &static_is_descendent_of(true))
1129 .unwrap();
1130
1131 let is_descendent_of = is_descendent_of(|base, hash| match (*base, *hash) {
1132 ("hash_a", "hash_d") => true,
1133 ("hash_a", "hash_e") => true,
1134 ("hash_b", "hash_d") => true,
1135 ("hash_b", "hash_e") => true,
1136 ("hash_a", "hash_c") => false,
1137 ("hash_b", "hash_c") => false,
1138 _ => unreachable!(),
1139 });
1140
1141 assert_eq!(
1143 authorities.enacts_standard_change("hash_c", 15, &is_descendent_of).unwrap(),
1144 None,
1145 );
1146
1147 assert_eq!(
1149 authorities.enacts_standard_change("hash_d", 14, &is_descendent_of).unwrap(),
1150 None,
1151 );
1152
1153 assert_eq!(
1155 authorities.enacts_standard_change("hash_d", 15, &is_descendent_of).unwrap(),
1156 Some(true),
1157 );
1158
1159 assert_eq!(
1162 authorities.enacts_standard_change("hash_e", 30, &is_descendent_of).unwrap(),
1163 Some(false),
1164 );
1165 }
1166
1167 #[test]
1168 fn forced_changes() {
1169 let mut authorities = AuthoritySet {
1170 current_authorities: Vec::new(),
1171 set_id: 0,
1172 pending_standard_changes: ForkTree::new(),
1173 pending_forced_changes: Vec::new(),
1174 authority_set_changes: AuthoritySetChanges::empty(),
1175 };
1176
1177 let set_a = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 5)];
1178 let set_b = vec![(AuthorityId::from_slice(&[2; 32]).unwrap(), 5)];
1179
1180 let change_a = PendingChange {
1181 next_authorities: set_a.clone(),
1182 delay: 10,
1183 canon_height: 5,
1184 canon_hash: "hash_a",
1185 delay_kind: DelayKind::Best { median_last_finalized: 42 },
1186 };
1187
1188 let change_b = PendingChange {
1189 next_authorities: set_b.clone(),
1190 delay: 10,
1191 canon_height: 5,
1192 canon_hash: "hash_b",
1193 delay_kind: DelayKind::Best { median_last_finalized: 0 },
1194 };
1195
1196 authorities
1197 .add_pending_change(change_a, &static_is_descendent_of(false))
1198 .unwrap();
1199 authorities
1200 .add_pending_change(change_b.clone(), &static_is_descendent_of(false))
1201 .unwrap();
1202
1203 assert!(matches!(
1205 authorities.add_pending_change(change_b, &static_is_descendent_of(false)),
1206 Err(Error::DuplicateAuthoritySetChange)
1207 ));
1208
1209 assert_eq!(
1212 authorities
1213 .enacts_standard_change("hash_c", 15, &static_is_descendent_of(true))
1214 .unwrap(),
1215 None,
1216 );
1217
1218 let change_c = PendingChange {
1220 next_authorities: set_b.clone(),
1221 delay: 3,
1222 canon_height: 8,
1223 canon_hash: "hash_a8",
1224 delay_kind: DelayKind::Best { median_last_finalized: 0 },
1225 };
1226
1227 let is_descendent_of_a = is_descendent_of(|base: &&str, _| base.starts_with("hash_a"));
1228
1229 assert!(matches!(
1230 authorities.add_pending_change(change_c, &is_descendent_of_a),
1231 Err(Error::MultiplePendingForcedAuthoritySetChanges)
1232 ));
1233
1234 assert!(authorities
1237 .apply_forced_changes("hash_a10", 10, &static_is_descendent_of(true), false, None)
1238 .unwrap()
1239 .is_none());
1240
1241 assert!(authorities
1243 .apply_forced_changes("hash_a16", 16, &is_descendent_of_a, false, None)
1244 .unwrap()
1245 .is_none());
1246
1247 assert_eq!(
1249 authorities
1250 .apply_forced_changes("hash_a15", 15, &is_descendent_of_a, false, None)
1251 .unwrap()
1252 .unwrap(),
1253 (
1254 42,
1255 AuthoritySet {
1256 current_authorities: set_a,
1257 set_id: 1,
1258 pending_standard_changes: ForkTree::new(),
1259 pending_forced_changes: Vec::new(),
1260 authority_set_changes: AuthoritySetChanges(vec![(0, 42)]),
1261 },
1262 )
1263 );
1264 }
1265
1266 #[test]
1267 fn forced_changes_with_no_delay() {
1268 let mut authorities = AuthoritySet {
1270 current_authorities: Vec::new(),
1271 set_id: 0,
1272 pending_standard_changes: ForkTree::new(),
1273 pending_forced_changes: Vec::new(),
1274 authority_set_changes: AuthoritySetChanges::empty(),
1275 };
1276
1277 let set_a = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 5)];
1278
1279 let change_a = PendingChange {
1281 next_authorities: set_a.clone(),
1282 delay: 0,
1283 canon_height: 5,
1284 canon_hash: "hash_a",
1285 delay_kind: DelayKind::Best { median_last_finalized: 0 },
1286 };
1287
1288 authorities
1290 .add_pending_change(change_a, &static_is_descendent_of(false))
1291 .unwrap();
1292
1293 assert!(authorities
1295 .apply_forced_changes("hash_a", 5, &static_is_descendent_of(false), false, None)
1296 .unwrap()
1297 .is_some());
1298 }
1299
1300 #[test]
1301 fn forced_changes_blocked_by_standard_changes() {
1302 let set_a = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 1)];
1303
1304 let mut authorities = AuthoritySet {
1305 current_authorities: set_a.clone(),
1306 set_id: 0,
1307 pending_standard_changes: ForkTree::new(),
1308 pending_forced_changes: Vec::new(),
1309 authority_set_changes: AuthoritySetChanges::empty(),
1310 };
1311
1312 let change_a = PendingChange {
1314 next_authorities: set_a.clone(),
1315 delay: 5,
1316 canon_height: 10,
1317 canon_hash: "hash_a",
1318 delay_kind: DelayKind::Finalized,
1319 };
1320
1321 let change_b = PendingChange {
1323 next_authorities: set_a.clone(),
1324 delay: 0,
1325 canon_height: 20,
1326 canon_hash: "hash_b",
1327 delay_kind: DelayKind::Finalized,
1328 };
1329
1330 let change_c = PendingChange {
1332 next_authorities: set_a.clone(),
1333 delay: 5,
1334 canon_height: 30,
1335 canon_hash: "hash_c",
1336 delay_kind: DelayKind::Finalized,
1337 };
1338
1339 authorities
1341 .add_pending_change(change_a, &static_is_descendent_of(true))
1342 .unwrap();
1343 authorities
1344 .add_pending_change(change_b, &static_is_descendent_of(true))
1345 .unwrap();
1346 authorities
1347 .add_pending_change(change_c, &static_is_descendent_of(true))
1348 .unwrap();
1349
1350 let change_d = PendingChange {
1352 next_authorities: set_a.clone(),
1353 delay: 5,
1354 canon_height: 40,
1355 canon_hash: "hash_d",
1356 delay_kind: DelayKind::Best { median_last_finalized: 31 },
1357 };
1358
1359 authorities
1361 .add_pending_change(change_d, &static_is_descendent_of(true))
1362 .unwrap();
1363
1364 assert!(matches!(
1367 authorities.apply_forced_changes(
1368 "hash_d45",
1369 45,
1370 &static_is_descendent_of(true),
1371 false,
1372 None
1373 ),
1374 Err(Error::ForcedAuthoritySetChangeDependencyUnsatisfied(15))
1375 ));
1376 assert_eq!(authorities.authority_set_changes, AuthoritySetChanges::empty());
1377
1378 authorities
1380 .apply_standard_changes("hash_a15", 15, &static_is_descendent_of(true), false, None)
1381 .unwrap();
1382 assert_eq!(authorities.authority_set_changes, AuthoritySetChanges(vec![(0, 15)]));
1383
1384 assert!(matches!(
1386 authorities.apply_forced_changes(
1387 "hash_d",
1388 45,
1389 &static_is_descendent_of(true),
1390 false,
1391 None
1392 ),
1393 Err(Error::ForcedAuthoritySetChangeDependencyUnsatisfied(20))
1394 ));
1395 assert_eq!(authorities.authority_set_changes, AuthoritySetChanges(vec![(0, 15)]));
1396
1397 authorities
1399 .apply_standard_changes("hash_b", 20, &static_is_descendent_of(true), false, None)
1400 .unwrap();
1401 assert_eq!(authorities.authority_set_changes, AuthoritySetChanges(vec![(0, 15), (1, 20)]));
1402
1403 assert_eq!(
1407 authorities
1408 .apply_forced_changes("hash_d", 45, &static_is_descendent_of(true), false, None)
1409 .unwrap()
1410 .unwrap(),
1411 (
1412 31,
1413 AuthoritySet {
1414 current_authorities: set_a.clone(),
1415 set_id: 3,
1416 pending_standard_changes: ForkTree::new(),
1417 pending_forced_changes: Vec::new(),
1418 authority_set_changes: AuthoritySetChanges(vec![(0, 15), (1, 20), (2, 31)]),
1419 }
1420 ),
1421 );
1422 assert_eq!(authorities.authority_set_changes, AuthoritySetChanges(vec![(0, 15), (1, 20)]));
1423 }
1424
1425 #[test]
1426 fn next_change_works() {
1427 let current_authorities = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 1)];
1428
1429 let mut authorities = AuthoritySet {
1430 current_authorities: current_authorities.clone(),
1431 set_id: 0,
1432 pending_standard_changes: ForkTree::new(),
1433 pending_forced_changes: Vec::new(),
1434 authority_set_changes: AuthoritySetChanges::empty(),
1435 };
1436
1437 let new_set = current_authorities.clone();
1438
1439 let change_a0 = PendingChange {
1442 next_authorities: new_set.clone(),
1443 delay: 0,
1444 canon_height: 5,
1445 canon_hash: "hash_a0",
1446 delay_kind: DelayKind::Finalized,
1447 };
1448
1449 let change_a1 = PendingChange {
1450 next_authorities: new_set.clone(),
1451 delay: 0,
1452 canon_height: 10,
1453 canon_hash: "hash_a1",
1454 delay_kind: DelayKind::Finalized,
1455 };
1456
1457 let change_b = PendingChange {
1458 next_authorities: new_set.clone(),
1459 delay: 0,
1460 canon_height: 4,
1461 canon_hash: "hash_b",
1462 delay_kind: DelayKind::Finalized,
1463 };
1464
1465 let is_descendent_of = is_descendent_of(|base, hash| match (*base, *hash) {
1468 ("hash_a0", "hash_a1") => true,
1469 ("hash_a0", "best_a") => true,
1470 ("hash_a1", "best_a") => true,
1471 ("hash_a10", "best_a") => true,
1472 ("hash_b", "best_b") => true,
1473 _ => false,
1474 });
1475
1476 authorities.add_pending_change(change_b, &is_descendent_of).unwrap();
1478 authorities.add_pending_change(change_a0, &is_descendent_of).unwrap();
1479 authorities.add_pending_change(change_a1, &is_descendent_of).unwrap();
1480
1481 assert_eq!(
1483 authorities.next_change(&"best_a", &is_descendent_of).unwrap(),
1484 Some(("hash_a0", 5)),
1485 );
1486
1487 assert_eq!(
1489 authorities.next_change(&"best_b", &is_descendent_of).unwrap(),
1490 Some(("hash_b", 4)),
1491 );
1492
1493 authorities
1495 .apply_standard_changes("hash_a0", 5, &is_descendent_of, false, None)
1496 .unwrap();
1497
1498 assert_eq!(
1500 authorities.next_change(&"best_a", &is_descendent_of).unwrap(),
1501 Some(("hash_a1", 10)),
1502 );
1503
1504 assert_eq!(authorities.next_change(&"best_b", &is_descendent_of).unwrap(), None);
1506
1507 let change_a10 = PendingChange {
1509 next_authorities: new_set.clone(),
1510 delay: 0,
1511 canon_height: 8,
1512 canon_hash: "hash_a10",
1513 delay_kind: DelayKind::Best { median_last_finalized: 0 },
1514 };
1515
1516 authorities
1517 .add_pending_change(change_a10, &static_is_descendent_of(false))
1518 .unwrap();
1519
1520 assert_eq!(
1522 authorities.next_change(&"best_a", &is_descendent_of).unwrap(),
1523 Some(("hash_a10", 8)),
1524 );
1525 }
1526
1527 #[test]
1528 fn maintains_authority_list_invariants() {
1529 assert_eq!(AuthoritySet::<(), ()>::genesis(vec![]), None);
1531 assert_eq!(
1532 AuthoritySet::<(), ()>::new(
1533 vec![],
1534 0,
1535 ForkTree::new(),
1536 Vec::new(),
1537 AuthoritySetChanges::empty(),
1538 ),
1539 None,
1540 );
1541
1542 let invalid_authorities_weight = vec![
1543 (AuthorityId::from_slice(&[1; 32]).unwrap(), 5),
1544 (AuthorityId::from_slice(&[2; 32]).unwrap(), 0),
1545 ];
1546
1547 assert_eq!(AuthoritySet::<(), ()>::genesis(invalid_authorities_weight.clone()), None);
1549 assert_eq!(
1550 AuthoritySet::<(), ()>::new(
1551 invalid_authorities_weight.clone(),
1552 0,
1553 ForkTree::new(),
1554 Vec::new(),
1555 AuthoritySetChanges::empty(),
1556 ),
1557 None,
1558 );
1559
1560 let mut authority_set =
1561 AuthoritySet::<(), u64>::genesis(vec![(AuthorityId::unchecked_from([1; 32]), 5)])
1562 .unwrap();
1563
1564 let invalid_change_empty_authorities = PendingChange {
1565 next_authorities: vec![],
1566 delay: 10,
1567 canon_height: 5,
1568 canon_hash: (),
1569 delay_kind: DelayKind::Finalized,
1570 };
1571
1572 assert!(matches!(
1574 authority_set.add_pending_change(
1575 invalid_change_empty_authorities.clone(),
1576 &static_is_descendent_of(false)
1577 ),
1578 Err(Error::InvalidAuthoritySet)
1579 ));
1580
1581 let invalid_change_authorities_weight = PendingChange {
1582 next_authorities: invalid_authorities_weight,
1583 delay: 10,
1584 canon_height: 5,
1585 canon_hash: (),
1586 delay_kind: DelayKind::Best { median_last_finalized: 0 },
1587 };
1588
1589 assert!(matches!(
1592 authority_set.add_pending_change(
1593 invalid_change_authorities_weight,
1594 &static_is_descendent_of(false)
1595 ),
1596 Err(Error::InvalidAuthoritySet)
1597 ));
1598 }
1599
1600 #[test]
1601 fn cleans_up_stale_forced_changes_when_applying_standard_change() {
1602 let current_authorities = vec![(AuthorityId::from_slice(&[1; 32]).unwrap(), 1)];
1603
1604 let mut authorities = AuthoritySet {
1605 current_authorities: current_authorities.clone(),
1606 set_id: 0,
1607 pending_standard_changes: ForkTree::new(),
1608 pending_forced_changes: Vec::new(),
1609 authority_set_changes: AuthoritySetChanges::empty(),
1610 };
1611
1612 let new_set = current_authorities.clone();
1613
1614 let is_descendent_of = {
1628 let hashes = vec!["B", "C0", "C1", "C2", "C3", "D"];
1629 is_descendent_of(move |base, hash| match (*base, *hash) {
1630 ("B", "B") => false, ("A", b) | ("B", b) => hashes.iter().any(|h| *h == b),
1632 ("C0", "D") => true,
1633 _ => false,
1634 })
1635 };
1636
1637 let mut add_pending_change = |canon_height, canon_hash, forced| {
1638 let change = PendingChange {
1639 next_authorities: new_set.clone(),
1640 delay: 0,
1641 canon_height,
1642 canon_hash,
1643 delay_kind: if forced {
1644 DelayKind::Best { median_last_finalized: 0 }
1645 } else {
1646 DelayKind::Finalized
1647 },
1648 };
1649
1650 authorities.add_pending_change(change, &is_descendent_of).unwrap();
1651 };
1652
1653 add_pending_change(5, "A", false);
1654 add_pending_change(10, "B", false);
1655 add_pending_change(15, "C0", false);
1656 add_pending_change(15, "C1", true);
1657 add_pending_change(15, "C2", false);
1658 add_pending_change(15, "C3", true);
1659 add_pending_change(20, "D", true);
1660
1661 authorities
1664 .apply_standard_changes("A", 5, &is_descendent_of, false, None)
1665 .unwrap();
1666
1667 assert_eq!(authorities.pending_changes().count(), 6);
1668
1669 authorities
1671 .apply_standard_changes("B", 10, &is_descendent_of, false, None)
1672 .unwrap();
1673
1674 assert_eq!(authorities.pending_changes().count(), 5);
1675
1676 let authorities2 = authorities.clone();
1677
1678 authorities
1680 .apply_standard_changes("C2", 15, &is_descendent_of, false, None)
1681 .unwrap();
1682
1683 assert_eq!(authorities.pending_forced_changes.len(), 0);
1684
1685 let mut authorities = authorities2;
1687 authorities
1688 .apply_standard_changes("C0", 15, &is_descendent_of, false, None)
1689 .unwrap();
1690
1691 assert_eq!(authorities.pending_forced_changes.len(), 1);
1692 assert_eq!(authorities.pending_forced_changes.first().unwrap().canon_hash, "D");
1693 }
1694
1695 #[test]
1696 fn authority_set_changes_insert() {
1697 let mut authority_set_changes = AuthoritySetChanges::empty();
1698 authority_set_changes.append(0, 41);
1699 authority_set_changes.append(1, 81);
1700 authority_set_changes.append(4, 121);
1701
1702 authority_set_changes.insert(101).unwrap();
1703 assert_eq!(authority_set_changes.get_set_id(100), AuthoritySetChangeId::Set(2, 101));
1704 assert_eq!(authority_set_changes.get_set_id(101), AuthoritySetChangeId::Set(2, 101));
1705 }
1706
1707 #[test]
1708 fn authority_set_changes_insert_rejects_duplicate_set_id() {
1709 let mut changes = AuthoritySetChanges::empty();
1710 changes.insert(10).unwrap();
1711 changes.insert(20).unwrap();
1712 changes.insert(30).unwrap();
1713
1714 let before = changes.clone();
1715 assert_eq!(changes.insert(25).unwrap_err().0, 2);
1716 assert_eq!(changes, before);
1717 }
1718
1719 #[test]
1720 fn authority_set_changes_for_complete_data() {
1721 let mut authority_set_changes = AuthoritySetChanges::empty();
1722 authority_set_changes.append(0, 41);
1723 authority_set_changes.append(1, 81);
1724 authority_set_changes.append(2, 121);
1725
1726 assert_eq!(authority_set_changes.get_set_id(20), AuthoritySetChangeId::Set(0, 41));
1727 assert_eq!(authority_set_changes.get_set_id(40), AuthoritySetChangeId::Set(0, 41));
1728 assert_eq!(authority_set_changes.get_set_id(41), AuthoritySetChangeId::Set(0, 41));
1729 assert_eq!(authority_set_changes.get_set_id(42), AuthoritySetChangeId::Set(1, 81));
1730 assert_eq!(authority_set_changes.get_set_id(141), AuthoritySetChangeId::Latest);
1731 }
1732
1733 #[test]
1734 fn authority_set_changes_for_incomplete_data() {
1735 let mut authority_set_changes = AuthoritySetChanges::empty();
1736 authority_set_changes.append(2, 41);
1737 authority_set_changes.append(3, 81);
1738 authority_set_changes.append(4, 121);
1739
1740 assert_eq!(authority_set_changes.get_set_id(20), AuthoritySetChangeId::Unknown);
1741 assert_eq!(authority_set_changes.get_set_id(40), AuthoritySetChangeId::Unknown);
1742 assert_eq!(authority_set_changes.get_set_id(41), AuthoritySetChangeId::Unknown);
1743 assert_eq!(authority_set_changes.get_set_id(42), AuthoritySetChangeId::Set(3, 81));
1744 assert_eq!(authority_set_changes.get_set_id(141), AuthoritySetChangeId::Latest);
1745 }
1746
1747 #[test]
1748 fn iter_from_works() {
1749 let mut authority_set_changes = AuthoritySetChanges::empty();
1750 authority_set_changes.append(1, 41);
1751 authority_set_changes.append(2, 81);
1752
1753 assert_eq!(None, authority_set_changes.iter_from(40).map(|it| it.collect::<Vec<_>>()));
1755
1756 let mut authority_set_changes = AuthoritySetChanges::empty();
1758 authority_set_changes.append(0, 21);
1759 authority_set_changes.append(1, 41);
1760 authority_set_changes.append(2, 81);
1761 authority_set_changes.append(3, 121);
1762
1763 assert_eq!(
1764 Some(vec![(1, 41), (2, 81), (3, 121)]),
1765 authority_set_changes.iter_from(40).map(|it| it.cloned().collect::<Vec<_>>()),
1766 );
1767
1768 assert_eq!(
1769 Some(vec![(2, 81), (3, 121)]),
1770 authority_set_changes.iter_from(41).map(|it| it.cloned().collect::<Vec<_>>()),
1771 );
1772
1773 assert_eq!(0, authority_set_changes.iter_from(121).unwrap().count());
1774
1775 assert_eq!(0, authority_set_changes.iter_from(200).unwrap().count());
1776 }
1777}