Skip to content
This repository has been archived by the owner on Jan 22, 2025. It is now read-only.

Add switching vote instruction #10197

Merged
merged 2 commits into from
May 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 29 additions & 1 deletion core/src/cluster_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2052,10 +2052,11 @@ pub fn stake_weight_peers<S: std::hash::BuildHasher>(
#[cfg(test)]
mod tests {
use super::*;
use crate::crds_value::CrdsValueLabel;
use crate::crds_value::{CrdsValue, CrdsValueLabel, Vote as CrdsVote};
use rayon::prelude::*;
use solana_perf::test_tx::test_tx;
use solana_sdk::signature::{Keypair, Signer};
use solana_vote_program::{vote_instruction, vote_state::Vote};
use std::collections::HashSet;
use std::net::{IpAddr, Ipv4Addr};
use std::sync::Arc;
Expand Down Expand Up @@ -2763,4 +2764,31 @@ mod tests {
assert_eq!(slots, range);
assert!(since.is_some());
}

#[test]
fn test_vote_size() {
let slots = vec![1; 32];
let vote = Vote::new(slots, Hash::default());
let keypair = Arc::new(Keypair::new());

// Create the biggest possible vote transaction
let vote_ix = vote_instruction::vote_switch(
&keypair.pubkey(),
&keypair.pubkey(),
vote,
Hash::default(),
);
let mut vote_tx = Transaction::new_with_payer(&[vote_ix], Some(&keypair.pubkey()));

vote_tx.partial_sign(&[keypair.as_ref()], Hash::default());
vote_tx.partial_sign(&[keypair.as_ref()], Hash::default());

let vote = CrdsVote {
from: keypair.pubkey(),
transaction: vote_tx,
wallclock: 0,
};
let vote = CrdsValue::new_signed(CrdsData::Vote(1, vote), &Keypair::new());
assert!(bincode::serialized_size(&vote).unwrap() <= MAX_PROTOCOL_PAYLOAD_SIZE);
}
}
41 changes: 40 additions & 1 deletion programs/vote/src/vote_instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use serde_derive::{Deserialize, Serialize};
use solana_metrics::inc_new_counter_info;
use solana_sdk::{
account::{get_signers, KeyedAccount},
hash::Hash,
instruction::{AccountMeta, Instruction, InstructionError, WithSigner},
program_utils::{limited_deserialize, next_keyed_account, DecodeError},
pubkey::Pubkey,
Expand Down Expand Up @@ -95,6 +96,15 @@ pub enum VoteInstruction {
/// 1 - New validator identity (node_pubkey)
///
UpdateValidatorIdentity,

/// A Vote instruction with recent votes
/// requires authorized voter signature
///
/// Expects 3 Accounts:
/// 0 - Vote account to vote with
/// 1 - Slot hashes sysvar
/// 2 - Clock sysvar
VoteSwitch(Vote, Hash),
}

fn initialize_account(vote_pubkey: &Pubkey, vote_init: &VoteInit) -> Instruction {
Expand Down Expand Up @@ -195,6 +205,26 @@ pub fn vote(vote_pubkey: &Pubkey, authorized_voter_pubkey: &Pubkey, vote: Vote)
Instruction::new(id(), &VoteInstruction::Vote(vote), account_metas)
}

pub fn vote_switch(
vote_pubkey: &Pubkey,
authorized_voter_pubkey: &Pubkey,
vote: Vote,
proof_hash: Hash,
) -> Instruction {
let account_metas = vec![
AccountMeta::new(*vote_pubkey, false),
AccountMeta::new_readonly(sysvar::slot_hashes::id(), false),
AccountMeta::new_readonly(sysvar::clock::id(), false),
]
.with_signer(authorized_voter_pubkey);

Instruction::new(
id(),
&VoteInstruction::VoteSwitch(vote, proof_hash),
account_metas,
)
}

pub fn withdraw(
vote_pubkey: &Pubkey,
authorized_withdrawer_pubkey: &Pubkey,
Expand Down Expand Up @@ -245,7 +275,7 @@ pub fn process_instruction(
next_keyed_account(keyed_accounts)?.unsigned_key(),
&signers,
),
VoteInstruction::Vote(vote) => {
VoteInstruction::Vote(vote) | VoteInstruction::VoteSwitch(vote, _) => {
inc_new_counter_info!("vote-native", 1);
vote_state::process_vote(
me,
Expand Down Expand Up @@ -328,6 +358,15 @@ mod tests {
)),
Err(InstructionError::InvalidAccountData),
);
assert_eq!(
process_instruction(&vote_switch(
&Pubkey::default(),
&Pubkey::default(),
Vote::default(),
Hash::default(),
)),
Err(InstructionError::InvalidAccountData),
);
assert_eq!(
process_instruction(&authorize(
&Pubkey::default(),
Expand Down