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
#![forbid(unsafe_code)]
use crate::{instance::Instance, query_sequence_numbers};
use anyhow::{format_err, Result};
use aptos_crypto::{
ed25519::{Ed25519PrivateKey, Ed25519PublicKey},
test_utils::KeyPair,
Uniform,
};
use aptos_rest_client::Client as RestClient;
use aptos_sdk::{
move_types::account_address::AccountAddress,
types::{account_config::aptos_root_address, chain_id::ChainId, AccountKey, LocalAccount},
};
use rand::seq::SliceRandom;
use std::convert::TryFrom;
pub struct Cluster {
instances: Vec<Instance>,
mint_key_pair: KeyPair<Ed25519PrivateKey, Ed25519PublicKey>,
pub chain_id: ChainId,
}
fn clone(key: &Ed25519PrivateKey) -> Ed25519PrivateKey {
let serialized: &[u8] = &(key.to_bytes());
Ed25519PrivateKey::try_from(serialized).unwrap()
}
impl Cluster {
pub fn from_host_port(
peers: Vec<(String, u32, Option<u32>)>,
mint_key: Ed25519PrivateKey,
chain_id: ChainId,
vasp: bool,
) -> Self {
let instances: Vec<Instance> = peers
.into_iter()
.map(|host_port| {
Instance::new(
format!("{}:{}", &host_port.0, host_port.1),
host_port.0,
host_port.1,
host_port.2,
)
})
.collect();
let mint_key_pair = if vasp {
dummy_key_pair()
} else {
KeyPair::from(mint_key)
};
Self {
instances,
mint_key_pair,
chain_id,
}
}
fn account_key(&self) -> AccountKey {
AccountKey::from_private_key(clone(&self.mint_key_pair.private_key))
}
async fn load_account_with_mint_key(
&self,
client: &RestClient,
address: AccountAddress,
) -> Result<LocalAccount> {
let sequence_number = query_sequence_numbers(client, &[address])
.await
.map_err(|e| {
format_err!(
"query_sequence_numbers on {:?} for account {} failed: {}",
client,
address,
e
)
})?[0];
Ok(LocalAccount::new(
address,
self.account_key(),
sequence_number,
))
}
pub async fn load_aptos_root_account(&self, client: &RestClient) -> Result<LocalAccount> {
self.load_account_with_mint_key(client, aptos_root_address())
.await
}
pub async fn load_faucet_account(&self, client: &RestClient) -> Result<LocalAccount> {
self.load_account_with_mint_key(client, aptos_root_address())
.await
}
pub fn random_instance(&self) -> Instance {
let mut rnd = rand::thread_rng();
self.instances
.choose(&mut rnd)
.expect("random_validator_instance requires non-empty validator_instances")
.clone()
}
pub fn all_instances(&self) -> impl Iterator<Item = &Instance> {
self.instances.iter()
}
}
pub fn dummy_key_pair() -> KeyPair<Ed25519PrivateKey, Ed25519PublicKey> {
Ed25519PrivateKey::generate_for_testing().into()
}