-
Notifications
You must be signed in to change notification settings - Fork 36
/
proposal.rs
106 lines (92 loc) · 3.79 KB
/
proposal.rs
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
98
99
100
101
102
103
104
105
106
// Copyright 2022 MaidSafe.net limited.
//
// This SAFE Network Software is licensed to you under The General Public License (GPL), version 3.
// Unless required by applicable law or agreed to in writing, the SAFE Network Software distributed
// under the GPL Licence is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. Please review the Licences for the specific language governing
// permissions and limitations relating to use of the SAFE Network Software.
use crate::node::{dkg::SigShare, Result};
use sn_interface::{
messaging::system::{Proposal as ProposalMsg, SectionAuth},
network_knowledge::{NodeState, SectionAuthorityProvider},
};
#[allow(clippy::large_enum_variant)]
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Proposal {
VoteNodeOffline(NodeState),
SectionInfo(SectionAuthorityProvider),
NewElders(SectionAuth<SectionAuthorityProvider>),
JoinsAllowed(bool),
}
impl Proposal {
/// Create `SigShare` for this proposal.
pub(crate) fn sign_with_key_share(
&self,
public_key_set: bls::PublicKeySet,
index: usize,
secret_key_share: &bls::SecretKeyShare,
) -> Result<SigShare> {
Ok(SigShare::new(
public_key_set,
index,
secret_key_share,
&self.as_signable_bytes()?,
))
}
pub(crate) fn as_signable_bytes(&self) -> Result<Vec<u8>> {
Ok(match self {
Self::VoteNodeOffline(node_state) => bincode::serialize(node_state),
Self::SectionInfo(sap) => bincode::serialize(sap),
Self::NewElders(info) => bincode::serialize(&info.sig.public_key), // the pub key of the new elders
Self::JoinsAllowed(joins_allowed) => bincode::serialize(&joins_allowed),
}?)
}
// Add conversion methods to/from `messaging::...::Proposal`
// We prefer this over `From<...>` to make it easier to read the conversion.
pub(crate) fn into_msg(self) -> ProposalMsg {
match self {
Self::VoteNodeOffline(node_state) => ProposalMsg::VoteNodeOffline(node_state.to_msg()),
Self::SectionInfo(sap) => ProposalMsg::SectionInfo(sap.to_msg()),
Self::NewElders(sap) => ProposalMsg::NewElders(sap.into_authed_msg()),
Self::JoinsAllowed(allowed) => ProposalMsg::JoinsAllowed(allowed),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use sn_interface::network_knowledge::test_utils::random_sap;
use eyre::Result;
use serde::Serialize;
use std::fmt::Debug;
use xor_name::Prefix;
#[test]
fn serialize_for_signing() -> Result<()> {
// Proposal::SectionInfo
let (section_auth, _, _) = random_sap(Prefix::default(), 4, 0, None);
let proposal = Proposal::SectionInfo(section_auth.clone());
verify_serialize_for_signing(&proposal, §ion_auth)?;
// Proposal::NewElders
let new_sk = bls::SecretKey::random();
let new_pk = new_sk.public_key();
let section_signed_auth =
sn_interface::network_knowledge::test_utils::section_signed(&new_sk, section_auth)?;
let proposal = Proposal::NewElders(section_signed_auth);
verify_serialize_for_signing(&proposal, &new_pk)?;
Ok(())
}
// Verify that `SignableView(proposal)` serializes the same as `should_serialize_as`.
fn verify_serialize_for_signing<T>(proposal: &Proposal, should_serialize_as: &T) -> Result<()>
where
T: Serialize + Debug,
{
let actual = proposal.as_signable_bytes()?;
let expected = bincode::serialize(should_serialize_as)?;
assert_eq!(
actual, expected,
"expected SignableView({:?}) to serialize same as {:?}, but didn't",
proposal, should_serialize_as
);
Ok(())
}
}