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
use crate::{
json_rpc::JsonRpcClientWrapper,
validator_config::{fullnode_addresses, validator_addresses, DecryptedValidatorConfig},
};
use diem_crypto::ed25519::Ed25519PublicKey;
use diem_management::{config::ConfigPath, error::Error, secure_backend::ValidatorBackend};
use diem_network_address_encryption::Encryptor;
use diem_secure_storage::Storage;
use diem_types::{
account_address::AccountAddress, network_address::NetworkAddress, validator_info::ValidatorInfo,
};
use serde::Serialize;
use structopt::StructOpt;
#[derive(Debug, StructOpt)]
pub struct ValidatorSet {
#[structopt(flatten)]
config: ConfigPath,
#[structopt(long, required_unless = "config")]
json_server: Option<String>,
#[structopt(long, help = "AccountAddress to retrieve the validator set info")]
account_address: Option<AccountAddress>,
#[structopt(
long,
help = "The secure backend that contains the network address encryption keys"
)]
validator_backend: Option<ValidatorBackend>,
}
impl ValidatorSet {
pub fn execute(self) -> Result<Vec<DecryptedValidatorInfo>, Error> {
let mut config = self.config.load()?.override_json_server(&self.json_server);
let client = JsonRpcClientWrapper::new(config.clone().json_server);
let encryptor = if let Some(backend) = &self.validator_backend {
config = config.override_validator_backend(&backend.validator_backend)?;
config.validator_backend().encryptor()
} else {
Encryptor::empty()
};
decode_validator_set(encryptor, client, self.account_address)
}
}
pub fn decode_validator_set(
encryptor: Encryptor<Storage>,
client: JsonRpcClientWrapper,
account_address: Option<AccountAddress>,
) -> Result<Vec<DecryptedValidatorInfo>, Error> {
let set = client.validator_set(account_address)?;
let mut decoded_set = Vec::new();
for info in set {
let config = DecryptedValidatorConfig::from_validator_config(
info.config(),
*info.account_address(),
&encryptor,
)
.map_err(|e| Error::NetworkAddressDecodeError(e.to_string()))?;
let config_resource = client.validator_config(*info.account_address())?;
let name = DecryptedValidatorConfig::human_name(&config_resource.human_name);
let info = DecryptedValidatorInfo {
name,
account_address: *info.account_address(),
consensus_public_key: config.consensus_public_key,
fullnode_network_address: config.fullnode_network_address,
validator_network_address: config.validator_network_address,
};
decoded_set.push(info);
}
Ok(decoded_set)
}
pub fn validator_set_full_node_addresses(
client: JsonRpcClientWrapper,
account_address: Option<AccountAddress>,
) -> Result<Vec<(String, AccountAddress, Vec<NetworkAddress>)>, Error> {
validator_set_addresses(client, account_address, |info| {
fullnode_addresses(info.config())
})
}
pub fn validator_set_validator_addresses(
client: JsonRpcClientWrapper,
encryptor: &Encryptor<Storage>,
account_address: Option<AccountAddress>,
) -> Result<Vec<(String, AccountAddress, Vec<NetworkAddress>)>, Error> {
validator_set_addresses(client, account_address, |info| {
validator_addresses(info.config(), *info.account_address(), encryptor)
})
}
fn validator_set_addresses<F: Fn(ValidatorInfo) -> Result<Vec<NetworkAddress>, Error>>(
client: JsonRpcClientWrapper,
account_address: Option<AccountAddress>,
address_accessor: F,
) -> Result<Vec<(String, AccountAddress, Vec<NetworkAddress>)>, Error> {
let set = client.validator_set(account_address)?;
let mut decoded_set = Vec::new();
for info in set {
let config_resource = client.validator_config(*info.account_address())?;
let name = DecryptedValidatorConfig::human_name(&config_resource.human_name);
let peer_id = *info.account_address();
let addrs = address_accessor(info)?;
decoded_set.push((name, peer_id, addrs));
}
Ok(decoded_set)
}
#[derive(Serialize)]
pub struct DecryptedValidatorInfo {
pub name: String,
pub account_address: AccountAddress,
pub consensus_public_key: Ed25519PublicKey,
pub fullnode_network_address: NetworkAddress,
pub validator_network_address: NetworkAddress,
}