Add thin client test for vote functionality, fix sizing errors in vote contract (#1643)

* Added tests to thin client to test VoteContract calls, fix VoteContract sizing errors

* Calculate upper bound on VoteProgram size at runtime, add test for serializing/deserializing a max sized VoteProgram state
This commit is contained in:
carllin
2018-10-31 17:47:50 -07:00
committed by GitHub
parent 6ddd494826
commit ba884b4e36
4 changed files with 158 additions and 31 deletions

View File

@ -161,7 +161,7 @@ impl ThinClient {
self.transfer_signed(&tx)
}
/// Creates, signs, and processes a Transaction. Useful for writing unit-tests.
/// Creates, signs, and processes a vote Transaction. Useful for writing unit-tests.
pub fn register_vote_account(
&self,
node_keypair: &Keypair,
@ -470,6 +470,32 @@ pub fn poll_gossip_for_leader(leader_ncp: SocketAddr, timeout: Option<u64>) -> R
Ok(leader.unwrap().clone())
}
pub fn retry_get_balance(
client: &mut ThinClient,
bob_pubkey: &Pubkey,
expected_balance: Option<i64>,
) -> Option<i64> {
const LAST: usize = 30;
for run in 0..LAST {
let balance_result = client.poll_get_balance(bob_pubkey);
if expected_balance.is_none() {
return balance_result.ok();
}
trace!(
"retry_get_balance[{}] {:?} {:?}",
run,
balance_result,
expected_balance
);
if let (Some(expected_balance), Ok(balance_result)) = (expected_balance, balance_result) {
if expected_balance == balance_result {
return Some(balance_result);
}
}
}
None
}
#[cfg(test)]
mod tests {
use super::*;
@ -483,6 +509,7 @@ mod tests {
use signature::{Keypair, KeypairUtil};
use std::fs::remove_dir_all;
use system_program::SystemProgram;
use vote_program::VoteProgram;
#[test]
#[ignore]
@ -659,6 +686,104 @@ mod tests {
remove_dir_all(ledger_path).unwrap();
}
#[test]
fn test_register_vote_account() {
logger::setup();
let leader_keypair = Arc::new(Keypair::new());
let leader = Node::new_localhost_with_pubkey(leader_keypair.pubkey());
let mint = Mint::new(10_000);
let mut bank = Bank::new(&mint);
let leader_data = leader.info.clone();
let ledger_path = create_tmp_ledger_with_mint("client_check_signature", &mint);
let genesis_entries = &mint.create_entries();
let entry_height = genesis_entries.len() as u64;
let leader_scheduler = Arc::new(RwLock::new(LeaderScheduler::from_bootstrap_leader(
leader_data.id,
)));
bank.leader_scheduler = leader_scheduler;
let leader_vote_account_keypair = Arc::new(Keypair::new());
let server = Fullnode::new_with_bank(
leader_keypair,
leader_vote_account_keypair.clone(),
bank,
0,
entry_height,
&genesis_entries,
leader,
None,
&ledger_path,
false,
Some(0),
);
sleep(Duration::from_millis(300));
let requests_socket = UdpSocket::bind("0.0.0.0:0").unwrap();
requests_socket
.set_read_timeout(Some(Duration::new(5, 0)))
.unwrap();
let transactions_socket = UdpSocket::bind("0.0.0.0:0").unwrap();
let mut client = ThinClient::new(
leader_data.contact_info.rpu,
requests_socket,
leader_data.contact_info.tpu,
transactions_socket,
);
// Create the validator account, transfer some tokens to that account
let validator_keypair = Keypair::new();
let last_id = client.get_last_id();
let signature = client
.transfer(500, &mint.keypair(), validator_keypair.pubkey(), &last_id)
.unwrap();
assert!(client.poll_for_signature(&signature).is_ok());
// Create the vote account
let validator_vote_account_keypair = Keypair::new();
let vote_account_id = validator_vote_account_keypair.pubkey();
let last_id = client.get_last_id();
let signature = client
.create_vote_account(&validator_keypair, vote_account_id, &last_id, 1)
.unwrap();
assert!(client.poll_for_signature(&signature).is_ok());
let balance = retry_get_balance(&mut client, &vote_account_id, Some(1))
.expect("Expected balance for new account to exist");
assert_eq!(balance, 1);
// Register the vote account to the validator
let last_id = client.get_last_id();
let signature = client
.register_vote_account(&validator_keypair, vote_account_id, &last_id)
.unwrap();
assert!(client.poll_for_signature(&signature).is_ok());
const LAST: usize = 30;
for run in 0..=LAST {
println!("Checking for account registered: {}", run);
let account_user_data = client
.get_account_userdata(&vote_account_id)
.expect("Expected valid response for account userdata")
.expect("Expected valid account userdata to exist after account creation");
let vote_state = VoteProgram::deserialize(&account_user_data);
if vote_state.map(|vote_state| vote_state.node_id) == Ok(validator_keypair.pubkey()) {
break;
}
if run == LAST {
panic!("Expected successful vote account registration");
}
sleep(Duration::from_millis(900));
}
server.close().unwrap();
remove_dir_all(ledger_path).unwrap();
}
#[test]
fn test_transaction_count() {
// set a bogus address, see that we don't hang