1#![deny(unused_crate_dependencies)]
20#![warn(missing_docs)]
21
22use codec::{Decode, Encode};
23use polkadot_primitives::{BlockNumber, Hash};
24use std::fmt;
25
26#[doc(hidden)]
27pub use sc_network::IfDisconnected;
28pub use sc_network_types::PeerId;
29#[doc(hidden)]
30pub use std::sync::Arc;
31
32mod reputation;
33pub use self::reputation::{ReputationChange, UnifiedReputationChange};
34
35pub mod peer_set;
37
38pub mod request_response;
40
41pub mod authority_discovery;
43pub mod grid_topology;
45
46pub const MIN_GOSSIP_PEERS: usize = 25;
48
49#[derive(Debug, Clone, Copy, PartialEq)]
51pub struct WrongVariant;
52
53impl fmt::Display for WrongVariant {
54 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
55 write!(formatter, "Wrong message variant")
56 }
57}
58
59impl std::error::Error for WrongVariant {}
60
61#[derive(Debug, Clone, Copy, PartialEq)]
63pub enum ObservedRole {
64 Light,
66 Full,
68 Authority,
70}
71
72impl From<sc_network::ObservedRole> for ObservedRole {
73 fn from(role: sc_network::ObservedRole) -> ObservedRole {
74 match role {
75 sc_network::ObservedRole::Light => ObservedRole::Light,
76 sc_network::ObservedRole::Authority => ObservedRole::Authority,
77 sc_network::ObservedRole::Full => ObservedRole::Full,
78 }
79 }
80}
81
82impl Into<sc_network::ObservedRole> for ObservedRole {
83 fn into(self) -> sc_network::ObservedRole {
84 match self {
85 ObservedRole::Light => sc_network::ObservedRole::Light,
86 ObservedRole::Full => sc_network::ObservedRole::Full,
87 ObservedRole::Authority => sc_network::ObservedRole::Authority,
88 }
89 }
90}
91
92#[derive(Debug, Clone, Default)]
94pub struct OurView {
95 view: View,
96}
97
98impl OurView {
99 pub fn new(heads: impl IntoIterator<Item = Hash>, finalized_number: BlockNumber) -> Self {
101 let view = View::new(heads, finalized_number);
102 Self { view }
103 }
104}
105
106impl PartialEq for OurView {
107 fn eq(&self, other: &Self) -> bool {
108 self.view == other.view
109 }
110}
111
112impl std::ops::Deref for OurView {
113 type Target = View;
114
115 fn deref(&self) -> &View {
116 &self.view
117 }
118}
119
120#[macro_export]
132macro_rules! our_view {
133 ( $( $hash:expr ),* $(,)? ) => {
134 $crate::OurView::new(
135 vec![ $( $hash.clone() ),* ].into_iter().map(|h| h),
136 0,
137 )
138 };
139}
140
141#[derive(Default, Debug, Clone, PartialEq, Eq, Encode, Decode)]
146pub struct View {
147 heads: Vec<Hash>,
150 pub finalized_number: BlockNumber,
152}
153
154#[macro_export]
166macro_rules! view {
167 ( $( $hash:expr ),* $(,)? ) => {
168 $crate::View::new(vec![ $( $hash.clone() ),* ], 0)
169 };
170}
171
172impl View {
173 pub fn new(heads: impl IntoIterator<Item = Hash>, finalized_number: BlockNumber) -> Self {
175 let mut heads = heads.into_iter().collect::<Vec<Hash>>();
176 heads.sort();
177 Self { heads, finalized_number }
178 }
179
180 pub fn with_finalized(finalized_number: BlockNumber) -> Self {
182 Self { heads: Vec::new(), finalized_number }
183 }
184
185 pub fn len(&self) -> usize {
187 self.heads.len()
188 }
189
190 pub fn is_empty(&self) -> bool {
192 self.heads.is_empty()
193 }
194
195 pub fn iter(&self) -> impl Iterator<Item = &Hash> {
197 self.heads.iter()
198 }
199
200 pub fn into_iter(self) -> impl Iterator<Item = Hash> {
202 self.heads.into_iter()
203 }
204
205 pub fn replace_difference(&mut self, new: View) -> impl Iterator<Item = &Hash> {
209 let old = std::mem::replace(self, new);
210
211 self.heads.iter().filter(move |h| !old.contains(h))
212 }
213
214 pub fn difference<'a>(&'a self, other: &'a View) -> impl Iterator<Item = &'a Hash> + 'a {
216 self.heads.iter().filter(move |h| !other.contains(h))
217 }
218
219 pub fn intersection<'a>(&'a self, other: &'a View) -> impl Iterator<Item = &'a Hash> + 'a {
221 self.heads.iter().filter(move |h| other.contains(h))
222 }
223
224 pub fn contains(&self, hash: &Hash) -> bool {
226 self.heads.contains(hash)
227 }
228
229 pub fn check_heads_eq(&self, other: &Self) -> bool {
234 self.heads == other.heads
235 }
236}
237
238#[derive(Debug, Clone, PartialEq, Eq)]
240pub enum Versioned<V1, V2, V3 = V2> {
241 V1(V1),
243 V2(V2),
245 V3(V3),
247}
248
249impl<V1: Clone, V2: Clone, V3: Clone> Versioned<&'_ V1, &'_ V2, &'_ V3> {
250 pub fn clone_inner(&self) -> Versioned<V1, V2, V3> {
252 match *self {
253 Versioned::V1(inner) => Versioned::V1(inner.clone()),
254 Versioned::V2(inner) => Versioned::V2(inner.clone()),
255 Versioned::V3(inner) => Versioned::V3(inner.clone()),
256 }
257 }
258}
259
260pub type VersionedValidationProtocol =
262 Versioned<v1::ValidationProtocol, v2::ValidationProtocol, v3::ValidationProtocol>;
263
264impl From<v1::ValidationProtocol> for VersionedValidationProtocol {
265 fn from(v1: v1::ValidationProtocol) -> Self {
266 VersionedValidationProtocol::V1(v1)
267 }
268}
269
270impl From<v2::ValidationProtocol> for VersionedValidationProtocol {
271 fn from(v2: v2::ValidationProtocol) -> Self {
272 VersionedValidationProtocol::V2(v2)
273 }
274}
275
276impl From<v3::ValidationProtocol> for VersionedValidationProtocol {
277 fn from(v3: v3::ValidationProtocol) -> Self {
278 VersionedValidationProtocol::V3(v3)
279 }
280}
281
282pub type VersionedCollationProtocol = Versioned<v1::CollationProtocol, v2::CollationProtocol>;
284
285impl From<v1::CollationProtocol> for VersionedCollationProtocol {
286 fn from(v1: v1::CollationProtocol) -> Self {
287 VersionedCollationProtocol::V1(v1)
288 }
289}
290
291impl From<v2::CollationProtocol> for VersionedCollationProtocol {
292 fn from(v2: v2::CollationProtocol) -> Self {
293 VersionedCollationProtocol::V2(v2)
294 }
295}
296
297macro_rules! impl_versioned_full_protocol_from {
298 ($from:ty, $out:ty, $variant:ident) => {
299 impl From<$from> for $out {
300 fn from(versioned_from: $from) -> $out {
301 match versioned_from {
302 Versioned::V1(x) => Versioned::V1(x.into()),
303 Versioned::V2(x) => Versioned::V2(x.into()),
304 Versioned::V3(x) => Versioned::V3(x.into()),
305 }
306 }
307 }
308 };
309}
310macro_rules! impl_versioned_try_from {
313 (
314 $from:ty,
315 $out:ty,
316 $v1_pat:pat => $v1_out:expr,
317 $v2_pat:pat => $v2_out:expr,
318 $v3_pat:pat => $v3_out:expr
319 ) => {
320 impl TryFrom<$from> for $out {
321 type Error = crate::WrongVariant;
322
323 fn try_from(x: $from) -> Result<$out, Self::Error> {
324 #[allow(unreachable_patterns)] match x {
326 Versioned::V1($v1_pat) => Ok(Versioned::V1($v1_out)),
327 Versioned::V2($v2_pat) => Ok(Versioned::V2($v2_out)),
328 Versioned::V3($v3_pat) => Ok(Versioned::V3($v3_out)),
329 _ => Err(crate::WrongVariant),
330 }
331 }
332 }
333
334 impl<'a> TryFrom<&'a $from> for $out {
335 type Error = crate::WrongVariant;
336
337 fn try_from(x: &'a $from) -> Result<$out, Self::Error> {
338 #[allow(unreachable_patterns)] match x {
340 Versioned::V1($v1_pat) => Ok(Versioned::V1($v1_out.clone())),
341 Versioned::V2($v2_pat) => Ok(Versioned::V2($v2_out.clone())),
342 Versioned::V3($v3_pat) => Ok(Versioned::V3($v3_out.clone())),
343 _ => Err(crate::WrongVariant),
344 }
345 }
346 }
347 };
348}
349
350pub type BitfieldDistributionMessage = Versioned<
352 v1::BitfieldDistributionMessage,
353 v2::BitfieldDistributionMessage,
354 v3::BitfieldDistributionMessage,
355>;
356impl_versioned_full_protocol_from!(
357 BitfieldDistributionMessage,
358 VersionedValidationProtocol,
359 BitfieldDistribution
360);
361impl_versioned_try_from!(
362 VersionedValidationProtocol,
363 BitfieldDistributionMessage,
364 v1::ValidationProtocol::BitfieldDistribution(x) => x,
365 v2::ValidationProtocol::BitfieldDistribution(x) => x,
366 v3::ValidationProtocol::BitfieldDistribution(x) => x
367);
368
369pub type StatementDistributionMessage = Versioned<
371 v1::StatementDistributionMessage,
372 v2::StatementDistributionMessage,
373 v3::StatementDistributionMessage,
374>;
375impl_versioned_full_protocol_from!(
376 StatementDistributionMessage,
377 VersionedValidationProtocol,
378 StatementDistribution
379);
380impl_versioned_try_from!(
381 VersionedValidationProtocol,
382 StatementDistributionMessage,
383 v1::ValidationProtocol::StatementDistribution(x) => x,
384 v2::ValidationProtocol::StatementDistribution(x) => x,
385 v3::ValidationProtocol::StatementDistribution(x) => x
386);
387
388pub type ApprovalDistributionMessage = Versioned<
390 v1::ApprovalDistributionMessage,
391 v2::ApprovalDistributionMessage,
392 v3::ApprovalDistributionMessage,
393>;
394impl_versioned_full_protocol_from!(
395 ApprovalDistributionMessage,
396 VersionedValidationProtocol,
397 ApprovalDistribution
398);
399impl_versioned_try_from!(
400 VersionedValidationProtocol,
401 ApprovalDistributionMessage,
402 v1::ValidationProtocol::ApprovalDistribution(x) => x,
403 v2::ValidationProtocol::ApprovalDistribution(x) => x,
404 v3::ValidationProtocol::ApprovalDistribution(x) => x
405
406);
407
408pub type GossipSupportNetworkMessage = Versioned<
410 v1::GossipSupportNetworkMessage,
411 v2::GossipSupportNetworkMessage,
412 v3::GossipSupportNetworkMessage,
413>;
414
415impl TryFrom<VersionedValidationProtocol> for GossipSupportNetworkMessage {
417 type Error = WrongVariant;
418 fn try_from(_: VersionedValidationProtocol) -> Result<Self, Self::Error> {
419 Err(WrongVariant)
420 }
421}
422
423impl<'a> TryFrom<&'a VersionedValidationProtocol> for GossipSupportNetworkMessage {
424 type Error = WrongVariant;
425 fn try_from(_: &'a VersionedValidationProtocol) -> Result<Self, Self::Error> {
426 Err(WrongVariant)
427 }
428}
429
430pub type CollatorProtocolMessage =
432 Versioned<v1::CollatorProtocolMessage, v2::CollatorProtocolMessage>;
433impl_versioned_full_protocol_from!(
434 CollatorProtocolMessage,
435 VersionedCollationProtocol,
436 CollatorProtocol
437);
438impl_versioned_try_from!(
439 VersionedCollationProtocol,
440 CollatorProtocolMessage,
441 v1::CollationProtocol::CollatorProtocol(x) => x,
442 v2::CollationProtocol::CollatorProtocol(x) => x,
443 v2::CollationProtocol::CollatorProtocol(x) => x
444);
445
446pub mod v1 {
448 use codec::{Decode, Encode};
449
450 use polkadot_primitives::{
451 CandidateHash, CandidateIndex, CollatorId, CollatorSignature, CompactStatement, Hash,
452 Id as ParaId, UncheckedSignedAvailabilityBitfield, ValidatorIndex, ValidatorSignature,
453 };
454
455 use polkadot_node_primitives::{
456 approval::v1::{IndirectAssignmentCert, IndirectSignedApprovalVote},
457 UncheckedSignedFullStatement,
458 };
459
460 #[derive(Debug, Clone, Encode, Decode, PartialEq, Eq)]
462 pub enum BitfieldDistributionMessage {
463 #[codec(index = 0)]
465 Bitfield(Hash, UncheckedSignedAvailabilityBitfield),
466 }
467
468 #[derive(Debug, Clone, Encode, Decode, PartialEq, Eq)]
470 pub enum StatementDistributionMessage {
471 #[codec(index = 0)]
473 Statement(Hash, UncheckedSignedFullStatement),
474 #[codec(index = 1)]
479 LargeStatement(StatementMetadata),
480 }
481
482 #[derive(Debug, Clone, Encode, Decode, PartialEq, Eq, Hash)]
484 pub struct StatementMetadata {
485 pub relay_parent: Hash,
487 pub candidate_hash: CandidateHash,
489 pub signed_by: ValidatorIndex,
491 pub signature: ValidatorSignature,
493 }
494
495 impl StatementDistributionMessage {
496 pub fn get_fingerprint(&self) -> (CompactStatement, ValidatorIndex) {
498 match self {
499 Self::Statement(_, statement) => (
500 statement.unchecked_payload().to_compact(),
501 statement.unchecked_validator_index(),
502 ),
503 Self::LargeStatement(meta) =>
504 (CompactStatement::Seconded(meta.candidate_hash), meta.signed_by),
505 }
506 }
507
508 pub fn get_signature(&self) -> ValidatorSignature {
510 match self {
511 Self::Statement(_, statement) => statement.unchecked_signature().clone(),
512 Self::LargeStatement(metadata) => metadata.signature.clone(),
513 }
514 }
515
516 pub fn get_relay_parent(&self) -> Hash {
518 match self {
519 Self::Statement(r, _) => *r,
520 Self::LargeStatement(meta) => meta.relay_parent,
521 }
522 }
523
524 pub fn is_large_statement(&self) -> bool {
526 if let Self::LargeStatement(_) = self {
527 true
528 } else {
529 false
530 }
531 }
532 }
533
534 #[derive(Debug, Clone, Encode, Decode, PartialEq, Eq)]
536 pub enum ApprovalDistributionMessage {
537 #[codec(index = 0)]
541 Assignments(Vec<(IndirectAssignmentCert, CandidateIndex)>),
542 #[codec(index = 1)]
544 Approvals(Vec<IndirectSignedApprovalVote>),
545 }
546
547 #[derive(Debug, Clone, PartialEq, Eq)]
549 pub enum GossipSupportNetworkMessage {}
550
551 #[derive(Debug, Clone, Encode, Decode, PartialEq, Eq)]
553 pub enum CollatorProtocolMessage {
554 #[codec(index = 0)]
557 Declare(CollatorId, ParaId, CollatorSignature),
558 #[codec(index = 1)]
561 AdvertiseCollation(Hash),
562 #[codec(index = 4)]
564 CollationSeconded(Hash, UncheckedSignedFullStatement),
565 }
566
567 #[derive(Debug, Clone, Encode, Decode, PartialEq, Eq, derive_more::From)]
569 pub enum ValidationProtocol {
570 #[codec(index = 1)]
572 #[from]
573 BitfieldDistribution(BitfieldDistributionMessage),
574 #[codec(index = 3)]
576 #[from]
577 StatementDistribution(StatementDistributionMessage),
578 #[codec(index = 4)]
580 #[from]
581 ApprovalDistribution(ApprovalDistributionMessage),
582 }
583
584 #[derive(Debug, Clone, Encode, Decode, PartialEq, Eq, derive_more::From)]
586 pub enum CollationProtocol {
587 #[codec(index = 0)]
589 #[from]
590 CollatorProtocol(CollatorProtocolMessage),
591 }
592
593 pub fn declare_signature_payload(peer_id: &sc_network_types::PeerId) -> Vec<u8> {
598 let mut payload = peer_id.to_bytes();
599 payload.extend_from_slice(b"COLL");
600 payload
601 }
602}
603
604pub mod v2 {
606 use bitvec::{order::Lsb0, slice::BitSlice, vec::BitVec};
607 use codec::{Decode, Encode};
608
609 use polkadot_primitives::{
610 CandidateHash, CandidateIndex, CollatorId, CollatorSignature, GroupIndex, Hash,
611 Id as ParaId, UncheckedSignedAvailabilityBitfield, UncheckedSignedStatement,
612 };
613
614 use polkadot_node_primitives::{
615 approval::v1::{IndirectAssignmentCert, IndirectSignedApprovalVote},
616 UncheckedSignedFullStatement,
617 };
618
619 #[derive(Debug, Clone, Encode, Decode, PartialEq, Eq)]
621 pub enum BitfieldDistributionMessage {
622 #[codec(index = 0)]
624 Bitfield(Hash, UncheckedSignedAvailabilityBitfield),
625 }
626
627 #[derive(Debug, Clone, Encode, Decode, PartialEq, Eq)]
630 pub struct StatementFilter {
631 pub seconded_in_group: BitVec<u8, Lsb0>,
633 pub validated_in_group: BitVec<u8, Lsb0>,
635 }
636
637 impl StatementFilter {
638 pub fn blank(group_size: usize) -> Self {
640 StatementFilter {
641 seconded_in_group: BitVec::repeat(false, group_size),
642 validated_in_group: BitVec::repeat(false, group_size),
643 }
644 }
645
646 pub fn full(group_size: usize) -> Self {
648 StatementFilter {
649 seconded_in_group: BitVec::repeat(true, group_size),
650 validated_in_group: BitVec::repeat(true, group_size),
651 }
652 }
653
654 pub fn has_len(&self, len: usize) -> bool {
657 self.seconded_in_group.len() == len && self.validated_in_group.len() == len
658 }
659
660 pub fn backing_validators(&self) -> usize {
662 self.seconded_in_group
663 .iter()
664 .by_vals()
665 .zip(self.validated_in_group.iter().by_vals())
666 .filter(|&(s, v)| s || v) .count()
668 }
669
670 pub fn has_seconded(&self) -> bool {
672 self.seconded_in_group.iter().by_vals().any(|x| x)
673 }
674
675 pub fn mask_seconded(&mut self, mask: &BitSlice<u8, Lsb0>) {
678 for (mut x, mask) in self
679 .seconded_in_group
680 .iter_mut()
681 .zip(mask.iter().by_vals().chain(std::iter::repeat(false)))
682 {
683 *x = *x && !mask;
689 }
690 }
691
692 pub fn mask_valid(&mut self, mask: &BitSlice<u8, Lsb0>) {
695 for (mut x, mask) in self
696 .validated_in_group
697 .iter_mut()
698 .zip(mask.iter().by_vals().chain(std::iter::repeat(false)))
699 {
700 *x = *x && !mask;
706 }
707 }
708 }
709
710 #[derive(Debug, Clone, Encode, Decode, PartialEq, Eq)]
713 pub struct BackedCandidateManifest {
714 pub relay_parent: Hash,
716 pub candidate_hash: CandidateHash,
718 pub group_index: GroupIndex,
720 pub para_id: ParaId,
724 pub parent_head_data_hash: Hash,
726 pub statement_knowledge: StatementFilter,
734 }
735
736 #[derive(Debug, Clone, Encode, Decode, PartialEq, Eq)]
738 pub struct BackedCandidateAcknowledgement {
739 pub candidate_hash: CandidateHash,
741 pub statement_knowledge: StatementFilter,
749 }
750
751 #[derive(Debug, Clone, Encode, Decode, PartialEq, Eq)]
753 pub enum StatementDistributionMessage {
754 #[codec(index = 0)]
756 Statement(Hash, UncheckedSignedStatement),
757
758 #[codec(index = 1)]
762 BackedCandidateManifest(BackedCandidateManifest),
763
764 #[codec(index = 2)]
767 BackedCandidateKnown(BackedCandidateAcknowledgement),
768
769 #[codec(index = 255)]
777 V1Compatibility(crate::v1::StatementDistributionMessage),
778 }
779
780 #[derive(Debug, Clone, Encode, Decode, PartialEq, Eq)]
782 pub enum ApprovalDistributionMessage {
783 #[codec(index = 0)]
787 Assignments(Vec<(IndirectAssignmentCert, CandidateIndex)>),
788 #[codec(index = 1)]
790 Approvals(Vec<IndirectSignedApprovalVote>),
791 }
792
793 #[derive(Debug, Clone, PartialEq, Eq)]
795 pub enum GossipSupportNetworkMessage {}
796
797 #[derive(Debug, Clone, Encode, Decode, PartialEq, Eq)]
799 pub enum CollatorProtocolMessage {
800 #[codec(index = 0)]
803 Declare(CollatorId, ParaId, CollatorSignature),
804 #[codec(index = 1)]
807 AdvertiseCollation {
808 relay_parent: Hash,
810 candidate_hash: CandidateHash,
812 parent_head_data_hash: Hash,
814 },
815 #[codec(index = 4)]
817 CollationSeconded(Hash, UncheckedSignedFullStatement),
818 }
819
820 #[derive(Debug, Clone, Encode, Decode, PartialEq, Eq, derive_more::From)]
822 pub enum ValidationProtocol {
823 #[codec(index = 1)]
825 #[from]
826 BitfieldDistribution(BitfieldDistributionMessage),
827 #[codec(index = 3)]
829 #[from]
830 StatementDistribution(StatementDistributionMessage),
831 #[codec(index = 4)]
833 #[from]
834 ApprovalDistribution(ApprovalDistributionMessage),
835 }
836
837 #[derive(Debug, Clone, Encode, Decode, PartialEq, Eq, derive_more::From)]
839 pub enum CollationProtocol {
840 #[codec(index = 0)]
842 #[from]
843 CollatorProtocol(CollatorProtocolMessage),
844 }
845
846 pub fn declare_signature_payload(peer_id: &sc_network_types::PeerId) -> Vec<u8> {
851 let mut payload = peer_id.to_bytes();
852 payload.extend_from_slice(b"COLL");
853 payload
854 }
855}
856
857pub mod v3 {
861 use codec::{Decode, Encode};
862
863 use polkadot_node_primitives::approval::v2::{
864 CandidateBitfield, IndirectAssignmentCertV2, IndirectSignedApprovalVoteV2,
865 };
866
867 pub use super::v2::{
869 declare_signature_payload, BackedCandidateAcknowledgement, BackedCandidateManifest,
870 BitfieldDistributionMessage, GossipSupportNetworkMessage, StatementDistributionMessage,
871 StatementFilter,
872 };
873
874 #[derive(Debug, Clone, Encode, Decode, PartialEq, Eq)]
876 pub enum ApprovalDistributionMessage {
877 #[codec(index = 0)]
887 Assignments(Vec<(IndirectAssignmentCertV2, CandidateBitfield)>),
888 #[codec(index = 1)]
890 Approvals(Vec<IndirectSignedApprovalVoteV2>),
891 }
892
893 #[derive(Debug, Clone, Encode, Decode, PartialEq, Eq, derive_more::From)]
895 pub enum ValidationProtocol {
896 #[codec(index = 1)]
898 #[from]
899 BitfieldDistribution(BitfieldDistributionMessage),
900 #[codec(index = 3)]
902 #[from]
903 StatementDistribution(StatementDistributionMessage),
904 #[codec(index = 4)]
906 #[from]
907 ApprovalDistribution(ApprovalDistributionMessage),
908 }
909}
910
911pub fn filter_by_peer_version(
913 peers: &[(PeerId, peer_set::ProtocolVersion)],
914 version: peer_set::ProtocolVersion,
915) -> Vec<PeerId> {
916 peers.iter().filter(|(_, v)| v == &version).map(|(p, _)| *p).collect::<Vec<_>>()
917}