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:
@ -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
|
||||
|
Reference in New Issue
Block a user