improve local cluster stake verification (#5547)

This commit is contained in:
Rob Walker 2019-08-16 15:46:19 -07:00 committed by GitHub
parent d853b20d7f
commit 89fe297416
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 55 additions and 20 deletions

View File

@ -174,6 +174,7 @@ pub fn kill_entry_and_spend_and_verify_rest(
info!("done sleeping for 2 fortnights");
for ingress_node in &cluster_nodes {
if ingress_node.id == entry_point_info.id {
info!("ingress_node.id == entry_point_info.id, continuing...");
continue;
}
@ -217,12 +218,14 @@ pub fn kill_entry_and_spend_and_verify_rest(
Ok(sig) => sig,
}
};
info!("poll_all_nodes_for_signature()");
match poll_all_nodes_for_signature(&entry_point_info, &cluster_nodes, &sig, confs) {
Err(e) => {
info!("poll_all_nodes_for_signature() failed {:?}", e);
result = Err(e);
}
Ok(()) => {
info!("poll_all_nodes_for_signature() succeeded, done.");
break;
}
}

View File

@ -19,11 +19,9 @@ use solana_sdk::system_transaction;
use solana_sdk::timing::DEFAULT_TICKS_PER_SLOT;
use solana_sdk::timing::{DEFAULT_SLOTS_PER_EPOCH, DEFAULT_SLOTS_PER_SEGMENT};
use solana_sdk::transaction::Transaction;
use solana_stake_api::stake_instruction;
use solana_storage_api::storage_contract;
use solana_storage_api::storage_instruction;
use solana_vote_api::vote_instruction;
use solana_vote_api::vote_state::VoteState;
use solana_stake_api::{stake_instruction, stake_state::StakeState};
use solana_storage_api::{storage_contract, storage_instruction};
use solana_vote_api::{vote_instruction, vote_state::VoteState};
use std::collections::HashMap;
use std::fs::remove_dir_all;
use std::io::{Error, ErrorKind, Result};
@ -430,6 +428,8 @@ impl LocalCluster {
) -> Result<()> {
let vote_account_pubkey = vote_account.pubkey();
let node_pubkey = from_account.pubkey();
let stake_account_keypair = Keypair::new();
let stake_account_pubkey = stake_account_keypair.pubkey();
// Create the vote account if necessary
if client.poll_get_balance(&vote_account_pubkey).unwrap_or(0) == 0 {
@ -453,8 +453,6 @@ impl LocalCluster {
.wait_for_balance(&vote_account_pubkey, Some(amount))
.expect("get balance");
let stake_account_keypair = Keypair::new();
let stake_account_pubkey = stake_account_keypair.pubkey();
let mut transaction = Transaction::new_signed_instructions(
&[from_account.as_ref(), &stake_account_keypair],
stake_instruction::create_stake_account_and_delegate_stake(
@ -477,22 +475,56 @@ impl LocalCluster {
client
.wait_for_balance(&stake_account_pubkey, Some(amount))
.expect("get balance");
} else {
warn!(
"{} vote_account already has a balance?!?",
vote_account_pubkey
);
}
info!("Checking for vote account registration");
let vote_account_user_data = client.get_account_data(&vote_account_pubkey);
if let Ok(Some(vote_account_user_data)) = vote_account_user_data {
if let Ok(vote_state) = VoteState::deserialize(&vote_account_user_data) {
if vote_state.node_pubkey == node_pubkey {
info!("vote account registered");
return Ok(());
info!("Checking for vote account registration of {}", node_pubkey);
match (
client.get_account(&stake_account_pubkey),
client.get_account(&vote_account_pubkey),
) {
(Ok(Some(stake_account)), Ok(Some(vote_account))) => {
match (
StakeState::stake_from(&stake_account),
VoteState::from(&vote_account),
) {
(Some(stake_state), Some(vote_state)) => {
if stake_state.voter_pubkey != vote_account_pubkey
|| stake_state.stake != amount
{
Err(Error::new(ErrorKind::Other, "invalid stake account state"))
} else if vote_state.node_pubkey != node_pubkey {
Err(Error::new(ErrorKind::Other, "invalid vote account state"))
} else {
info!("node {} {:?} {:?}", node_pubkey, stake_state, vote_state);
Ok(())
}
}
(None, _) => Err(Error::new(ErrorKind::Other, "invalid stake account data")),
(_, None) => Err(Error::new(ErrorKind::Other, "invalid vote account data")),
}
}
(Ok(None), _) => Err(Error::new(
ErrorKind::Other,
"unable to retrieve stake account data",
)),
(_, Ok(None)) => Err(Error::new(
ErrorKind::Other,
"unable to retrieve vote account data",
)),
(Err(_), _) => Err(Error::new(
ErrorKind::Other,
"unable to retrieve stake account data",
)),
(_, Err(_)) => Err(Error::new(
ErrorKind::Other,
"unable to retrieve vote account data",
)),
}
Err(Error::new(
ErrorKind::Other,
"expected successful vote account registration",
))
}
/// Sets up the storage account for validators/replicators and assumes the funder is the owner