Vote contract (#1552)

* Add Vote Contract

* Move ownership of LeaderScheduler from Fullnode to the bank

* Modified ReplicateStage to consume leader information from bank

* Restart RPC Services in Leader To Validator Transition

* Make VoteContract Context Free

* Remove voting from ClusterInfo and Tpu

* Remove dependency on ActiveValidators in LeaderScheduler

* Switch VoteContract to have two steps 1) Register 2) Vote. Change thin client to create + register a voting account on fullnode startup

* Remove check in leader_to_validator transition for unique references to bank, b/c jsonrpc service and rpcpubsub hold references through jsonhttpserver
This commit is contained in:
carllin
2018-10-25 16:58:40 -07:00
committed by GitHub
parent 160cff4a30
commit f6c8e1a4bf
27 changed files with 1190 additions and 1195 deletions

View File

@ -26,6 +26,7 @@ use std::time::Instant;
use system_transaction::SystemTransaction;
use timing;
use transaction::Transaction;
use vote_transaction::VoteTransaction;
use influx_db_client as influxdb;
use metrics;
@ -148,6 +149,29 @@ impl ThinClient {
))
}
pub fn create_vote_account(
&self,
node_keypair: &Keypair,
vote_account_id: Pubkey,
last_id: &Hash,
num_tokens: i64,
) -> io::Result<Signature> {
let tx =
Transaction::vote_account_new(&node_keypair, vote_account_id, *last_id, num_tokens);
self.transfer_signed(&tx)
}
/// Creates, signs, and processes a Transaction. Useful for writing unit-tests.
pub fn register_vote_account(
&self,
node_keypair: &Keypair,
vote_account_id: Pubkey,
last_id: &Hash,
) -> io::Result<Signature> {
let tx = Transaction::vote_account_register(node_keypair, vote_account_id, *last_id, 0);
self.transfer_signed(&tx)
}
/// Creates, signs, and processes a Transaction. Useful for writing unit-tests.
pub fn transfer(
&self,
@ -170,6 +194,24 @@ impl ThinClient {
result
}
pub fn get_account_userdata(&mut self, pubkey: &Pubkey) -> io::Result<Option<Vec<u8>>> {
let req = Request::GetAccount { key: *pubkey };
let data = serialize(&req).expect("serialize GetAccount in pub fn get_account_userdata");
self.requests_socket
.send_to(&data, &self.requests_addr)
.expect("buffer error in pub fn get_account_userdata");
loop {
let resp = self.recv_response()?;
trace!("recv_response {:?}", resp);
if let Response::Account { key, account } = resp {
if key == *pubkey {
return Ok(account.map(|account| account.userdata));
}
}
}
}
/// Request the balance of the user holding `pubkey`. This method blocks
/// until the server sends a response. If the response packet is dropped
/// by the network, this method will hang indefinitely.
@ -446,17 +488,23 @@ mod tests {
#[ignore]
fn test_thin_client() {
logger::setup();
let leader_keypair = Keypair::new();
let leader_keypair = Arc::new(Keypair::new());
let leader = Node::new_localhost_with_pubkey(leader_keypair.pubkey());
let leader_data = leader.info.clone();
let alice = Mint::new(10_000);
let bank = Bank::new(&alice);
let mut bank = Bank::new(&alice);
let bob_pubkey = Keypair::new().pubkey();
let ledger_path = create_tmp_ledger_with_mint("thin_client", &alice);
let leader_scheduler = Arc::new(RwLock::new(LeaderScheduler::from_bootstrap_leader(
leader_data.id,
)));
bank.leader_scheduler = leader_scheduler;
let vote_account_keypair = Arc::new(Keypair::new());
let server = Fullnode::new_with_bank(
leader_keypair,
vote_account_keypair,
bank,
0,
0,
@ -465,7 +513,6 @@ mod tests {
None,
&ledger_path,
false,
LeaderScheduler::from_bootstrap_leader(leader_data.id),
Some(0),
);
sleep(Duration::from_millis(900));
@ -495,16 +542,22 @@ mod tests {
#[ignore]
fn test_bad_sig() {
logger::setup();
let leader_keypair = Keypair::new();
let leader_keypair = Arc::new(Keypair::new());
let leader = Node::new_localhost_with_pubkey(leader_keypair.pubkey());
let alice = Mint::new(10_000);
let bank = Bank::new(&alice);
let mut bank = Bank::new(&alice);
let bob_pubkey = Keypair::new().pubkey();
let leader_data = leader.info.clone();
let ledger_path = create_tmp_ledger_with_mint("bad_sig", &alice);
let leader_scheduler = Arc::new(RwLock::new(LeaderScheduler::from_bootstrap_leader(
leader_data.id,
)));
bank.leader_scheduler = leader_scheduler;
let vote_account_keypair = Arc::new(Keypair::new());
let server = Fullnode::new_with_bank(
leader_keypair,
vote_account_keypair,
bank,
0,
0,
@ -513,7 +566,6 @@ mod tests {
None,
&ledger_path,
false,
LeaderScheduler::from_bootstrap_leader(leader_data.id),
Some(0),
);
//TODO: remove this sleep, or add a retry so CI is stable
@ -556,18 +608,25 @@ mod tests {
#[test]
fn test_client_check_signature() {
logger::setup();
let leader_keypair = Keypair::new();
let leader_keypair = Arc::new(Keypair::new());
let leader = Node::new_localhost_with_pubkey(leader_keypair.pubkey());
let alice = Mint::new(10_000);
let bank = Bank::new(&alice);
let mut bank = Bank::new(&alice);
let bob_pubkey = Keypair::new().pubkey();
let leader_data = leader.info.clone();
let ledger_path = create_tmp_ledger_with_mint("client_check_signature", &alice);
let genesis_entries = &alice.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 vote_account_keypair = Arc::new(Keypair::new());
let server = Fullnode::new_with_bank(
leader_keypair,
vote_account_keypair,
bank,
0,
entry_height,
@ -576,7 +635,6 @@ mod tests {
None,
&ledger_path,
false,
LeaderScheduler::from_bootstrap_leader(leader_data.id),
Some(0),
);
sleep(Duration::from_millis(300));
@ -620,18 +678,25 @@ mod tests {
#[test]
fn test_zero_balance_after_nonzero() {
logger::setup();
let leader_keypair = Keypair::new();
let leader_keypair = Arc::new(Keypair::new());
let leader = Node::new_localhost_with_pubkey(leader_keypair.pubkey());
let alice = Mint::new(10_000);
let bank = Bank::new(&alice);
let mut bank = Bank::new(&alice);
let bob_keypair = Keypair::new();
let leader_data = leader.info.clone();
let ledger_path = create_tmp_ledger_with_mint("zero_balance_check", &alice);
let genesis_entries = &alice.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 vote_account_keypair = Arc::new(Keypair::new());
let server = Fullnode::new_with_bank(
leader_keypair,
vote_account_keypair,
bank,
0,
entry_height,
@ -640,7 +705,6 @@ mod tests {
None,
&ledger_path,
false,
LeaderScheduler::from_bootstrap_leader(leader_data.id),
Some(0),
);
sleep(Duration::from_millis(900));