diff --git a/core/src/cluster_info_vote_listener.rs b/core/src/cluster_info_vote_listener.rs index 4a11fb02ee..8159301ffc 100644 --- a/core/src/cluster_info_vote_listener.rs +++ b/core/src/cluster_info_vote_listener.rs @@ -101,14 +101,10 @@ mod tests { let votes = (0..MAX_RECENT_VOTES) .map(|i| Vote::new(i as u64, Hash::default())) .collect::>(); - let vote_ix = vote_instruction::vote( - &node_keypair.pubkey(), - &vote_keypair.pubkey(), - &vote_keypair.pubkey(), - votes, - ); + let vote_ix = vote_instruction::vote(&vote_keypair.pubkey(), &vote_keypair.pubkey(), votes); + + let mut vote_tx = Transaction::new_with_payer(vec![vote_ix], Some(&node_keypair.pubkey())); - let mut vote_tx = Transaction::new_unsigned_instructions(vec![vote_ix]); vote_tx.partial_sign(&[&node_keypair], Hash::default()); vote_tx.partial_sign(&[&vote_keypair], Hash::default()); diff --git a/core/src/replay_stage.rs b/core/src/replay_stage.rs index ff33042b9c..6bf65f712e 100644 --- a/core/src/replay_stage.rs +++ b/core/src/replay_stage.rs @@ -333,13 +333,14 @@ impl ReplayStage { // Send our last few votes along with the new one let vote_ix = vote_instruction::vote( - &node_keypair.pubkey(), &vote_account, &voting_keypair.pubkey(), locktower.recent_votes(), ); - let mut vote_tx = Transaction::new_unsigned_instructions(vec![vote_ix]); + let mut vote_tx = + Transaction::new_with_payer(vec![vote_ix], Some(&node_keypair.pubkey()));; + let blockhash = bank.last_blockhash(); vote_tx.partial_sign(&[node_keypair.as_ref()], blockhash); vote_tx.partial_sign(&[voting_keypair.as_ref()], blockhash); diff --git a/programs/vote_api/src/vote_instruction.rs b/programs/vote_api/src/vote_instruction.rs index 7e68b8d83a..0840cb3e18 100644 --- a/programs/vote_api/src/vote_instruction.rs +++ b/programs/vote_api/src/vote_instruction.rs @@ -26,16 +26,8 @@ pub enum VoteInstruction { Vote(Vec), } -fn initialize_account( - from_pubkey: &Pubkey, - vote_pubkey: &Pubkey, - node_pubkey: &Pubkey, - commission: u32, -) -> Instruction { - let account_metas = vec![ - AccountMeta::new(*from_pubkey, true), - AccountMeta::new(*vote_pubkey, false), - ]; +fn initialize_account(vote_pubkey: &Pubkey, node_pubkey: &Pubkey, commission: u32) -> Instruction { + let account_metas = vec![AccountMeta::new(*vote_pubkey, false)]; Instruction::new( id(), &VoteInstruction::InitializeAccount(*node_pubkey, commission), @@ -53,20 +45,18 @@ pub fn create_account( let space = VoteState::size_of() as u64; let create_ix = system_instruction::create_account(from_pubkey, vote_pubkey, lamports, space, &id()); - let init_ix = initialize_account(from_pubkey, vote_pubkey, node_pubkey, commission); + let init_ix = initialize_account(vote_pubkey, node_pubkey, commission); vec![create_ix, init_ix] } fn metas_for_authorized_signer( - from_pubkey: &Pubkey, vote_pubkey: &Pubkey, authorized_voter_pubkey: &Pubkey, // currently authorized ) -> Vec { - let mut account_metas = vec![AccountMeta::new(*from_pubkey, true)]; // sender - let is_own_signer = authorized_voter_pubkey == vote_pubkey; - account_metas.push(AccountMeta::new(*vote_pubkey, is_own_signer)); // vote account + // vote account + let mut account_metas = vec![AccountMeta::new(*vote_pubkey, is_own_signer)]; if !is_own_signer { account_metas.push(AccountMeta::new(*authorized_voter_pubkey, true)) // signer @@ -75,13 +65,11 @@ fn metas_for_authorized_signer( } pub fn authorize_voter( - from_pubkey: &Pubkey, vote_pubkey: &Pubkey, authorized_voter_pubkey: &Pubkey, // currently authorized new_authorized_voter_pubkey: &Pubkey, ) -> Instruction { - let account_metas = - metas_for_authorized_signer(from_pubkey, vote_pubkey, authorized_voter_pubkey); + let account_metas = metas_for_authorized_signer(vote_pubkey, authorized_voter_pubkey); Instruction::new( id(), @@ -91,16 +79,14 @@ pub fn authorize_voter( } pub fn vote( - from_pubkey: &Pubkey, vote_pubkey: &Pubkey, authorized_voter_pubkey: &Pubkey, recent_votes: Vec, ) -> Instruction { - let mut account_metas = - metas_for_authorized_signer(from_pubkey, vote_pubkey, authorized_voter_pubkey); + let mut account_metas = metas_for_authorized_signer(vote_pubkey, authorized_voter_pubkey); // request slot_hashes syscall account after vote_pubkey - account_metas.insert(2, AccountMeta::new(slot_hashes::id(), false)); + account_metas.insert(1, AccountMeta::new(slot_hashes::id(), false)); Instruction::new(id(), &VoteInstruction::Vote(recent_votes), account_metas) } @@ -116,13 +102,13 @@ pub fn process_instruction( trace!("process_instruction: {:?}", data); trace!("keyed_accounts: {:?}", keyed_accounts); - if keyed_accounts.len() < 2 { + if keyed_accounts.is_empty() { Err(InstructionError::InvalidInstructionData)?; } - // 0th index is the guy who paid for the transaction - let (me, rest) = &mut keyed_accounts.split_at_mut(2); - let me = &mut me[1]; + // 0th index is vote account + let (me, rest) = &mut keyed_accounts.split_at_mut(1); + let me = &mut me[0]; // TODO: data-driven unpack and dispatch of KeyedAccounts match deserialize(data).map_err(|_| InstructionError::InvalidInstructionData)? { @@ -191,7 +177,6 @@ mod tests { ); assert_eq!( process_instruction(&vote( - &Pubkey::default(), &Pubkey::default(), &Pubkey::default(), vec![Vote::default()] @@ -203,7 +188,6 @@ mod tests { &Pubkey::default(), &Pubkey::default(), &Pubkey::default(), - &Pubkey::default(), )), Err(InstructionError::InvalidAccountData), ); diff --git a/sdk/src/transaction.rs b/sdk/src/transaction.rs index 427a47d11d..08427323ae 100644 --- a/sdk/src/transaction.rs +++ b/sdk/src/transaction.rs @@ -75,6 +75,21 @@ impl Transaction { } } + pub fn new_with_payer(instructions: Vec, payer: Option<&Pubkey>) -> Self { + let message = Message::new_with_payer(instructions, payer); + Self::new_unsigned(message) + } + + pub fn new_signed_with_payer( + instructions: Vec, + payer: Option<&Pubkey>, + signing_keypairs: &[&T], + recent_blockhash: Hash, + ) -> Self { + let message = Message::new_with_payer(instructions, payer); + Self::new(signing_keypairs, message, recent_blockhash) + } + pub fn new_unsigned_instructions(instructions: Vec) -> Self { let message = Message::new(instructions); Self::new_unsigned(message) @@ -167,25 +182,11 @@ impl Transaction { serialize(&self.message()).unwrap() } - /// Sign this transaction. - pub fn sign_unchecked(&mut self, keypairs: &[&T], recent_blockhash: Hash) { - self.message.recent_blockhash = recent_blockhash; - let message_data = self.message_data(); - self.signatures = keypairs - .iter() - .map(|keypair| keypair.sign_message(&message_data)) - .collect(); - } - /// Check keys and keypair lengths, then sign this transaction. pub fn sign(&mut self, keypairs: &[&T], recent_blockhash: Hash) { - let signed_keys = - &self.message.account_keys[0..self.message.header.num_required_signatures as usize]; - for (i, keypair) in keypairs.iter().enumerate() { - assert_eq!(keypair.pubkey(), signed_keys[i], "keypair-pubkey mismatch"); - } - assert_eq!(keypairs.len(), signed_keys.len(), "not enough keypairs"); - self.sign_unchecked(keypairs, recent_blockhash); + self.partial_sign(keypairs, recent_blockhash); + + assert_eq!(self.is_signed(), true, "not enough keypairs"); } /// Sign using some subset of required keys diff --git a/wallet/src/wallet.rs b/wallet/src/wallet.rs index 3e08108f09..c67cb1cbe2 100644 --- a/wallet/src/wallet.rs +++ b/wallet/src/wallet.rs @@ -472,18 +472,19 @@ fn process_authorize_voter( ) -> ProcessResult { let (recent_blockhash, _fee_calculator) = rpc_client.get_recent_blockhash()?; let ixs = vec![vote_instruction::authorize_voter( - &config.keypair.pubkey(), // from voting_account_pubkey, // vote account to update &authorized_voter_keypair.pubkey(), // current authorized voter (often the vote account itself) new_authorized_voter_pubkey, // new vote signer )]; - let mut tx = Transaction::new_signed_instructions( - &[&config.keypair, &authorized_voter_keypair], + let mut tx = Transaction::new_signed_with_payer( ixs, + Some(&config.keypair.pubkey()), + &[&config.keypair, &authorized_voter_keypair], recent_blockhash, ); - let signature_str = rpc_client.send_and_confirm_transaction(&mut tx, &[&config.keypair])?; + let signature_str = rpc_client + .send_and_confirm_transaction(&mut tx, &[&config.keypair, &authorized_voter_keypair])?; Ok(signature_str.to_string()) }