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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
use crate::account_address::AccountAddress;
use diem_crypto::{
ed25519::{Ed25519PrivateKey, Ed25519PublicKey, Ed25519Signature},
hash::CryptoHash,
test_utils::TEST_SEED,
PrivateKey, SigningKey, Uniform,
};
use rand::{rngs::StdRng, SeedableRng};
use serde::ser::Serialize;
use std::convert::TryFrom;
#[derive(Debug)]
#[cfg_attr(any(test, feature = "fuzzing"), derive(Clone))]
pub struct ValidatorSigner {
author: AccountAddress,
private_key: Ed25519PrivateKey,
}
impl ValidatorSigner {
pub fn new(author: AccountAddress, private_key: Ed25519PrivateKey) -> Self {
ValidatorSigner {
author,
private_key,
}
}
pub fn sign<T: Serialize + CryptoHash>(&self, message: &T) -> Ed25519Signature {
self.private_key.sign(message)
}
pub fn author(&self) -> AccountAddress {
self.author
}
pub fn public_key(&self) -> Ed25519PublicKey {
self.private_key.public_key()
}
#[cfg(any(test, feature = "fuzzing"))]
pub fn private_key(&self) -> &Ed25519PrivateKey {
&self.private_key
}
}
impl ValidatorSigner {
pub fn random(opt_rng_seed: impl for<'a> Into<Option<[u8; 32]>>) -> Self {
let mut rng = StdRng::from_seed(opt_rng_seed.into().unwrap_or(TEST_SEED));
Self::new(
AccountAddress::random(),
Ed25519PrivateKey::generate(&mut rng),
)
}
pub fn from_int(num: u8) -> Self {
let mut address = [0; AccountAddress::LENGTH];
address[0] = num;
let private_key = Ed25519PrivateKey::generate_for_testing();
Self::new(AccountAddress::try_from(&address[..]).unwrap(), private_key)
}
}
#[cfg(any(test, feature = "fuzzing"))]
pub mod proptests {
use super::*;
use diem_crypto::Genesis;
use proptest::{prelude::*, sample, strategy::LazyJust};
#[allow(clippy::redundant_closure)]
pub fn arb_signing_key() -> impl Strategy<Value = Ed25519PrivateKey> {
prop_oneof![
LazyJust::new(|| Ed25519PrivateKey::generate_for_testing()),
LazyJust::new(|| Ed25519PrivateKey::genesis()),
]
}
pub fn signer_strategy(
signing_key_strategy: impl Strategy<Value = Ed25519PrivateKey>,
) -> impl Strategy<Value = ValidatorSigner> {
signing_key_strategy
.prop_map(|signing_key| ValidatorSigner::new(AccountAddress::random(), signing_key))
}
#[allow(clippy::redundant_closure)]
pub fn rand_signer() -> impl Strategy<Value = ValidatorSigner> {
signer_strategy(arb_signing_key())
}
#[allow(clippy::redundant_closure)]
pub fn arb_signer() -> impl Strategy<Value = ValidatorSigner> {
prop_oneof![
rand_signer(),
LazyJust::new(|| {
let genesis_key = Ed25519PrivateKey::genesis();
ValidatorSigner::new(AccountAddress::random(), genesis_key)
})
]
}
fn select_keypair(keys: Vec<Ed25519PrivateKey>) -> impl Strategy<Value = Ed25519PrivateKey> {
sample::select(keys)
}
pub fn mostly_in_keypair_pool(
keys: Vec<Ed25519PrivateKey>,
) -> impl Strategy<Value = ValidatorSigner> {
prop::strategy::Union::new_weighted(vec![
(9, signer_strategy(select_keypair(keys)).boxed()),
(1, arb_signer().boxed()),
])
}
proptest! {
#[test]
fn test_new_signer(signing_key in arb_signing_key()){
let public_key = signing_key.public_key();
let signer = ValidatorSigner::new(AccountAddress::random(), signing_key);
prop_assert_eq!(public_key, signer.public_key());
}
}
}