1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
//! Main purpose of this module is to be able to use two different versions of the abft crate.
//! Older version is referred to as 'Legacy' while newer as 'Current'.
//! We achieve this by hiding types & traits from abft crates behind our owns. In case of traits we
//! implement both current and legacy ones. In case of types we implement trait `From` to be able
//! convert them at the 'glueing' spot to the abft library. Current and legacy versions are marked
//! by numbers. Whenever we upgrade to next version of abft we need to increment and mark each version
//! version accordingly.

mod common;
mod crypto;
mod current;
mod legacy;
mod network;
mod traits;
mod types;

use std::fmt::Debug;

use aleph_bft_crypto::{PartialMultisignature, Signature};
pub use crypto::Keychain;
pub use current::{
    create_phron_config as current_create_phron_config, run_member as run_current_member,
    NetworkData as CurrentNetworkData, VERSION as CURRENT_VERSION,
};
pub use legacy::{
    create_phron_config as legacy_create_phron_config, run_member as run_legacy_member,
    NetworkData as LegacyNetworkData, VERSION as LEGACY_VERSION,
};
pub use network::NetworkWrapper;
use parity_scale_codec::{Decode, Encode};
pub use traits::{ SpawnHandle, Wrapper as HashWrapper};
pub use types::{NodeCount, NodeIndex, Recipient};

/// Wrapper for `SignatureSet` to be able to implement both legacy and current `PartialMultisignature` trait.
/// Inner `SignatureSet` is imported from `aleph_bft_crypto` with a fixed version for compatibility reasons:
/// this is also used in the justification that already exists in our chain history, and we
/// need to be careful with changing this.
#[derive(Clone, Debug, Eq, Hash, PartialEq, Encode, Decode)]
pub struct SignatureSet<Signature>(pub aleph_bft_crypto::SignatureSet<Signature>);

impl<S: Clone> SignatureSet<S> {
    pub fn size(&self) -> NodeCount {
        self.0.size().into()
    }

    pub fn with_size(len: NodeCount) -> Self {
        SignatureSet(legacy_aleph_bft::SignatureSet::with_size(len.into()))
    }

    pub fn iter(&self) -> impl Iterator<Item = (NodeIndex, &S)> {
        self.0.iter().map(|(idx, s)| (idx.into(), s))
    }

    pub fn iter_mut(&mut self) -> impl Iterator<Item = (NodeIndex, &mut S)> {
        self.0.iter_mut().map(|(idx, s)| (idx.into(), s))
    }

    pub fn add_signature(self, signature: &S, index: NodeIndex) -> Self
    where
        S: Signature,
    {
        SignatureSet(self.0.add_signature(signature, index.into()))
    }
}

impl<S: 'static> IntoIterator for SignatureSet<S> {
    type Item = (NodeIndex, S);
    type IntoIter = Box<dyn Iterator<Item = (NodeIndex, S)>>;

    fn into_iter(self) -> Self::IntoIter {
        Box::new(self.0.into_iter().map(|(idx, s)| (idx.into(), s)))
    }
}

impl<S: legacy_aleph_bft::Signature> legacy_aleph_bft::PartialMultisignature for SignatureSet<S> {
    type Signature = S;

    fn add_signature(
        self,
        signature: &Self::Signature,
        index: legacy_aleph_bft::NodeIndex,
    ) -> Self {
        SignatureSet::add_signature(self, signature, index.into())
    }
}

impl<S: legacy_aleph_bft::Signature> current_aleph_bft::PartialMultisignature for SignatureSet<S> {
    type Signature = S;

    fn add_signature(
        self,
        signature: &Self::Signature,
        index: current_aleph_bft::NodeIndex,
    ) -> Self {
        SignatureSet::add_signature(self, signature, index.into())
    }
}