Add --trusted-validator support for snapshot hash validation (#8390)

This commit is contained in:
sakridge
2020-02-21 18:42:24 -08:00
committed by GitHub
parent 223f9707ca
commit b7386f9d84
8 changed files with 135 additions and 32 deletions

View File

@ -8,7 +8,7 @@ use log::*;
use rand::{thread_rng, Rng};
use solana_clap_utils::{
input_parsers::pubkey_of,
input_validators::{is_keypair, is_pubkey_or_keypair},
input_validators::{is_keypair, is_pubkey, is_pubkey_or_keypair},
keypair::{
self, keypair_input, KeypairWithSource, ASK_SEED_PHRASE_ARG,
SKIP_SEED_PHRASE_VALIDATION_ARG,
@ -32,6 +32,7 @@ use solana_sdk::{
signature::{Keypair, Signer},
};
use std::{
collections::HashSet,
fs::{self, File},
io::{self, Read},
net::{SocketAddr, TcpListener},
@ -201,6 +202,7 @@ fn get_rpc_addr(
identity_keypair: &Arc<Keypair>,
entrypoint_gossip: &SocketAddr,
expected_shred_version: Option<u16>,
trusted_validators: Option<&HashSet<Pubkey>>,
snapshot_not_required: bool,
) -> (RpcClient, SocketAddr) {
let mut cluster_info = ClusterInfo::new(
@ -247,6 +249,22 @@ fn get_rpc_addr(
}
}
let trusted_slots = if let Some(trusted_validators) = trusted_validators {
let trusted_slots = HashSet::new();
for trusted_validator in trusted_validators {
if let Some(slot_hash) = cluster_info
.read()
.unwrap()
.get_snapshot_hash_for_node(trusted_validator)
{
trusted_slots.union(&slot_hash.iter().collect());
}
}
Some(trusted_slots)
} else {
None
};
if rpc_peers.is_empty() {
info!("No RPC services found ");
} else {
@ -262,9 +280,16 @@ fn get_rpc_addr(
.unwrap()
.get_snapshot_hash_for_node(&rpc_peer.id)
{
let highest_snapshot_slot_for_node = snapshot_hash
.iter()
.fold(0, |a, (slot, _hash)| a.max(*slot));
let highest_snapshot_slot_for_node =
snapshot_hash.iter().fold(0, |highest_slot, snapshot_hash| {
if let Some(ref trusted_slots) = trusted_slots {
if !trusted_slots.contains(snapshot_hash) {
// Ignore all untrusted slots
return highest_slot;
}
}
highest_slot.max(snapshot_hash.0)
});
if highest_snapshot_slot_for_node > highest_snapshot_slot {
// Found a higher snapshot, remove all rpc peers with a lower snapshot
@ -682,6 +707,16 @@ pub fn main() {
.takes_value(true)
.help("Add a hard fork at this slot"),
)
.arg(
Arg::with_name("trusted_validators")
.long("trusted-validator")
.validator(is_pubkey)
.value_name("PUBKEY")
.multiple(true)
.takes_value(true)
.help("A snapshot hash must be published in gossip by this validator to be accepted. \
May be specified multiple times. If unspecified any snapshot hash will be accepted"),
)
.get_matches();
let identity_keypair = Arc::new(
@ -723,6 +758,13 @@ pub fn main() {
exit(1);
});
let trusted_validators = if matches.is_present("trusted_validators") {
let trusted_validators = values_t_or_exit!(matches, "trusted_validators", Pubkey);
Some(trusted_validators.into_iter().collect())
} else {
None
};
let mut validator_config = ValidatorConfig {
blockstream_unix_socket: matches
.value_of("blockstream_unix_socket")
@ -794,6 +836,7 @@ pub fn main() {
},
snapshot_path,
snapshot_package_output_path: ledger_path.clone(),
trusted_validators,
});
if matches.is_present("limit_ledger_size") {
@ -956,6 +999,12 @@ pub fn main() {
&identity_keypair,
&cluster_entrypoint.gossip,
validator_config.expected_shred_version,
validator_config
.snapshot_config
.as_ref()
.unwrap()
.trusted_validators
.as_ref(),
no_snapshot_fetch,
);