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