Vote InitializeAccount and UpdateNode instructions now need a signature from the validator identity (#8947)
automerge
This commit is contained in:
@ -354,7 +354,7 @@ pub enum CliCommand {
|
|||||||
// Vote Commands
|
// Vote Commands
|
||||||
CreateVoteAccount {
|
CreateVoteAccount {
|
||||||
seed: Option<String>,
|
seed: Option<String>,
|
||||||
node_pubkey: Pubkey,
|
identity_account: SignerIndex,
|
||||||
authorized_voter: Option<Pubkey>,
|
authorized_voter: Option<Pubkey>,
|
||||||
authorized_withdrawer: Option<Pubkey>,
|
authorized_withdrawer: Option<Pubkey>,
|
||||||
commission: u8,
|
commission: u8,
|
||||||
@ -377,7 +377,7 @@ pub enum CliCommand {
|
|||||||
},
|
},
|
||||||
VoteUpdateValidator {
|
VoteUpdateValidator {
|
||||||
vote_account_pubkey: Pubkey,
|
vote_account_pubkey: Pubkey,
|
||||||
new_identity_pubkey: Pubkey,
|
new_identity_account: SignerIndex,
|
||||||
},
|
},
|
||||||
// Wallet Commands
|
// Wallet Commands
|
||||||
Address,
|
Address,
|
||||||
@ -1947,7 +1947,7 @@ pub fn process_command(config: &CliConfig) -> ProcessResult {
|
|||||||
// Create vote account
|
// Create vote account
|
||||||
CliCommand::CreateVoteAccount {
|
CliCommand::CreateVoteAccount {
|
||||||
seed,
|
seed,
|
||||||
node_pubkey,
|
identity_account,
|
||||||
authorized_voter,
|
authorized_voter,
|
||||||
authorized_withdrawer,
|
authorized_withdrawer,
|
||||||
commission,
|
commission,
|
||||||
@ -1955,7 +1955,7 @@ pub fn process_command(config: &CliConfig) -> ProcessResult {
|
|||||||
&rpc_client,
|
&rpc_client,
|
||||||
config,
|
config,
|
||||||
seed,
|
seed,
|
||||||
&node_pubkey,
|
*identity_account,
|
||||||
authorized_voter,
|
authorized_voter,
|
||||||
authorized_withdrawer,
|
authorized_withdrawer,
|
||||||
*commission,
|
*commission,
|
||||||
@ -1997,12 +1997,12 @@ pub fn process_command(config: &CliConfig) -> ProcessResult {
|
|||||||
),
|
),
|
||||||
CliCommand::VoteUpdateValidator {
|
CliCommand::VoteUpdateValidator {
|
||||||
vote_account_pubkey,
|
vote_account_pubkey,
|
||||||
new_identity_pubkey,
|
new_identity_account,
|
||||||
} => process_vote_update_validator(
|
} => process_vote_update_validator(
|
||||||
&rpc_client,
|
&rpc_client,
|
||||||
config,
|
config,
|
||||||
&vote_account_pubkey,
|
&vote_account_pubkey,
|
||||||
&new_identity_pubkey,
|
*new_identity_account,
|
||||||
),
|
),
|
||||||
|
|
||||||
// Wallet Commands
|
// Wallet Commands
|
||||||
@ -3210,15 +3210,15 @@ mod tests {
|
|||||||
|
|
||||||
let bob_keypair = Keypair::new();
|
let bob_keypair = Keypair::new();
|
||||||
let bob_pubkey = bob_keypair.pubkey();
|
let bob_pubkey = bob_keypair.pubkey();
|
||||||
let node_pubkey = Pubkey::new_rand();
|
let identity_keypair = Keypair::new();
|
||||||
config.command = CliCommand::CreateVoteAccount {
|
config.command = CliCommand::CreateVoteAccount {
|
||||||
seed: None,
|
seed: None,
|
||||||
node_pubkey,
|
identity_account: 2,
|
||||||
authorized_voter: Some(bob_pubkey),
|
authorized_voter: Some(bob_pubkey),
|
||||||
authorized_withdrawer: Some(bob_pubkey),
|
authorized_withdrawer: Some(bob_pubkey),
|
||||||
commission: 0,
|
commission: 0,
|
||||||
};
|
};
|
||||||
config.signers = vec![&keypair, &bob_keypair];
|
config.signers = vec![&keypair, &bob_keypair, &identity_keypair];
|
||||||
let signature = process_command(&config);
|
let signature = process_command(&config);
|
||||||
assert_eq!(signature.unwrap(), SIGNATURE.to_string());
|
assert_eq!(signature.unwrap(), SIGNATURE.to_string());
|
||||||
|
|
||||||
@ -3232,11 +3232,11 @@ mod tests {
|
|||||||
let signature = process_command(&config);
|
let signature = process_command(&config);
|
||||||
assert_eq!(signature.unwrap(), SIGNATURE.to_string());
|
assert_eq!(signature.unwrap(), SIGNATURE.to_string());
|
||||||
|
|
||||||
let new_identity_pubkey = Pubkey::new_rand();
|
let new_identity_keypair = Keypair::new();
|
||||||
config.signers = vec![&keypair, &bob_keypair];
|
config.signers = vec![&keypair, &bob_keypair, &new_identity_keypair];
|
||||||
config.command = CliCommand::VoteUpdateValidator {
|
config.command = CliCommand::VoteUpdateValidator {
|
||||||
vote_account_pubkey: bob_pubkey,
|
vote_account_pubkey: bob_pubkey,
|
||||||
new_identity_pubkey,
|
new_identity_account: 2,
|
||||||
};
|
};
|
||||||
let signature = process_command(&config);
|
let signature = process_command(&config);
|
||||||
assert_eq!(signature.unwrap(), SIGNATURE.to_string());
|
assert_eq!(signature.unwrap(), SIGNATURE.to_string());
|
||||||
@ -3454,14 +3454,15 @@ mod tests {
|
|||||||
assert!(process_command(&config).is_err());
|
assert!(process_command(&config).is_err());
|
||||||
|
|
||||||
let bob_keypair = Keypair::new();
|
let bob_keypair = Keypair::new();
|
||||||
|
let identity_keypair = Keypair::new();
|
||||||
config.command = CliCommand::CreateVoteAccount {
|
config.command = CliCommand::CreateVoteAccount {
|
||||||
seed: None,
|
seed: None,
|
||||||
node_pubkey,
|
identity_account: 2,
|
||||||
authorized_voter: Some(bob_pubkey),
|
authorized_voter: Some(bob_pubkey),
|
||||||
authorized_withdrawer: Some(bob_pubkey),
|
authorized_withdrawer: Some(bob_pubkey),
|
||||||
commission: 0,
|
commission: 0,
|
||||||
};
|
};
|
||||||
config.signers = vec![&keypair, &bob_keypair];
|
config.signers = vec![&keypair, &bob_keypair, &identity_keypair];
|
||||||
assert!(process_command(&config).is_err());
|
assert!(process_command(&config).is_err());
|
||||||
|
|
||||||
config.command = CliCommand::VoteAuthorize {
|
config.command = CliCommand::VoteAuthorize {
|
||||||
@ -3473,7 +3474,7 @@ mod tests {
|
|||||||
|
|
||||||
config.command = CliCommand::VoteUpdateValidator {
|
config.command = CliCommand::VoteUpdateValidator {
|
||||||
vote_account_pubkey: bob_pubkey,
|
vote_account_pubkey: bob_pubkey,
|
||||||
new_identity_pubkey: bob_pubkey,
|
new_identity_account: 1,
|
||||||
};
|
};
|
||||||
assert!(process_command(&config).is_err());
|
assert!(process_command(&config).is_err());
|
||||||
|
|
||||||
|
107
cli/src/vote.rs
107
cli/src/vote.rs
@ -40,13 +40,13 @@ impl VoteSubCommands for App<'_, '_> {
|
|||||||
.help("Vote account keypair to fund"),
|
.help("Vote account keypair to fund"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("identity_pubkey")
|
Arg::with_name("identity_account")
|
||||||
.index(2)
|
.index(2)
|
||||||
.value_name("PUBKEY")
|
.value_name("KEYPAIR")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.required(true)
|
.required(true)
|
||||||
.validator(is_valid_pubkey)
|
.validator(is_valid_signer)
|
||||||
.help("Validator that will vote with this account"),
|
.help("Keypair of validator that will vote with this account"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("commission")
|
Arg::with_name("commission")
|
||||||
@ -137,22 +137,22 @@ impl VoteSubCommands for App<'_, '_> {
|
|||||||
.help("Vote account to update"),
|
.help("Vote account to update"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("new_identity_pubkey")
|
Arg::with_name("new_identity_account")
|
||||||
.index(2)
|
.index(2)
|
||||||
.value_name("PUBKEY")
|
.value_name("KEYPAIR")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.required(true)
|
.required(true)
|
||||||
.validator(is_valid_pubkey)
|
.validator(is_valid_signer)
|
||||||
.help("New validator that will vote with this account"),
|
.help("Keypair of new validator that will vote with this account"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("authorized_voter")
|
Arg::with_name("authorized_withdrawer")
|
||||||
.index(3)
|
.index(3)
|
||||||
.value_name("KEYPAIR")
|
.value_name("KEYPAIR")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.required(true)
|
.required(true)
|
||||||
.validator(is_valid_signer)
|
.validator(is_valid_signer)
|
||||||
.help("Authorized voter keypair"),
|
.help("Authorized withdrawer keypair"),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
@ -232,14 +232,15 @@ pub fn parse_create_vote_account(
|
|||||||
) -> Result<CliCommandInfo, CliError> {
|
) -> Result<CliCommandInfo, CliError> {
|
||||||
let (vote_account, _) = signer_of(matches, "vote_account", wallet_manager)?;
|
let (vote_account, _) = signer_of(matches, "vote_account", wallet_manager)?;
|
||||||
let seed = matches.value_of("seed").map(|s| s.to_string());
|
let seed = matches.value_of("seed").map(|s| s.to_string());
|
||||||
let identity_pubkey = pubkey_of_signer(matches, "identity_pubkey", wallet_manager)?.unwrap();
|
let (identity_account, identity_pubkey) =
|
||||||
|
signer_of(matches, "identity_account", wallet_manager)?;
|
||||||
let commission = value_t_or_exit!(matches, "commission", u8);
|
let commission = value_t_or_exit!(matches, "commission", u8);
|
||||||
let authorized_voter = pubkey_of_signer(matches, "authorized_voter", wallet_manager)?;
|
let authorized_voter = pubkey_of_signer(matches, "authorized_voter", wallet_manager)?;
|
||||||
let authorized_withdrawer = pubkey_of_signer(matches, "authorized_withdrawer", wallet_manager)?;
|
let authorized_withdrawer = pubkey_of_signer(matches, "authorized_withdrawer", wallet_manager)?;
|
||||||
|
|
||||||
let payer_provided = None;
|
let payer_provided = None;
|
||||||
let CliSignerInfo { signers } = generate_unique_signers(
|
let signer_info = generate_unique_signers(
|
||||||
vec![payer_provided, vote_account],
|
vec![payer_provided, vote_account, identity_account],
|
||||||
matches,
|
matches,
|
||||||
default_signer_path,
|
default_signer_path,
|
||||||
wallet_manager,
|
wallet_manager,
|
||||||
@ -248,12 +249,12 @@ pub fn parse_create_vote_account(
|
|||||||
Ok(CliCommandInfo {
|
Ok(CliCommandInfo {
|
||||||
command: CliCommand::CreateVoteAccount {
|
command: CliCommand::CreateVoteAccount {
|
||||||
seed,
|
seed,
|
||||||
node_pubkey: identity_pubkey,
|
identity_account: signer_info.index_of(identity_pubkey).unwrap(),
|
||||||
authorized_voter,
|
authorized_voter,
|
||||||
authorized_withdrawer,
|
authorized_withdrawer,
|
||||||
commission,
|
commission,
|
||||||
},
|
},
|
||||||
signers,
|
signers: signer_info.signers,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,13 +294,13 @@ pub fn parse_vote_update_validator(
|
|||||||
) -> Result<CliCommandInfo, CliError> {
|
) -> Result<CliCommandInfo, CliError> {
|
||||||
let vote_account_pubkey =
|
let vote_account_pubkey =
|
||||||
pubkey_of_signer(matches, "vote_account_pubkey", wallet_manager)?.unwrap();
|
pubkey_of_signer(matches, "vote_account_pubkey", wallet_manager)?.unwrap();
|
||||||
let new_identity_pubkey =
|
let (new_identity_account, new_identity_pubkey) =
|
||||||
pubkey_of_signer(matches, "new_identity_pubkey", wallet_manager)?.unwrap();
|
signer_of(matches, "new_identity_account", wallet_manager)?;
|
||||||
let (authorized_voter, _) = signer_of(matches, "authorized_voter", wallet_manager)?;
|
let (authorized_withdrawer, _) = signer_of(matches, "authorized_withdrawer", wallet_manager)?;
|
||||||
|
|
||||||
let payer_provided = None;
|
let payer_provided = None;
|
||||||
let CliSignerInfo { signers } = generate_unique_signers(
|
let signer_info = generate_unique_signers(
|
||||||
vec![payer_provided, authorized_voter],
|
vec![payer_provided, authorized_withdrawer, new_identity_account],
|
||||||
matches,
|
matches,
|
||||||
default_signer_path,
|
default_signer_path,
|
||||||
wallet_manager,
|
wallet_manager,
|
||||||
@ -308,9 +309,9 @@ pub fn parse_vote_update_validator(
|
|||||||
Ok(CliCommandInfo {
|
Ok(CliCommandInfo {
|
||||||
command: CliCommand::VoteUpdateValidator {
|
command: CliCommand::VoteUpdateValidator {
|
||||||
vote_account_pubkey,
|
vote_account_pubkey,
|
||||||
new_identity_pubkey,
|
new_identity_account: signer_info.index_of(new_identity_pubkey).unwrap(),
|
||||||
},
|
},
|
||||||
signers,
|
signers: signer_info.signers,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -372,7 +373,7 @@ pub fn process_create_vote_account(
|
|||||||
rpc_client: &RpcClient,
|
rpc_client: &RpcClient,
|
||||||
config: &CliConfig,
|
config: &CliConfig,
|
||||||
seed: &Option<String>,
|
seed: &Option<String>,
|
||||||
identity_pubkey: &Pubkey,
|
identity_account: SignerIndex,
|
||||||
authorized_voter: &Option<Pubkey>,
|
authorized_voter: &Option<Pubkey>,
|
||||||
authorized_withdrawer: &Option<Pubkey>,
|
authorized_withdrawer: &Option<Pubkey>,
|
||||||
commission: u8,
|
commission: u8,
|
||||||
@ -389,6 +390,8 @@ pub fn process_create_vote_account(
|
|||||||
(&vote_account_address, "vote_account".to_string()),
|
(&vote_account_address, "vote_account".to_string()),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
let identity_account = config.signers[identity_account];
|
||||||
|
let identity_pubkey = identity_account.pubkey();
|
||||||
check_unique_pubkeys(
|
check_unique_pubkeys(
|
||||||
(&vote_account_address, "vote_account".to_string()),
|
(&vote_account_address, "vote_account".to_string()),
|
||||||
(&identity_pubkey, "identity_pubkey".to_string()),
|
(&identity_pubkey, "identity_pubkey".to_string()),
|
||||||
@ -411,9 +414,9 @@ pub fn process_create_vote_account(
|
|||||||
.max(1);
|
.max(1);
|
||||||
|
|
||||||
let vote_init = VoteInit {
|
let vote_init = VoteInit {
|
||||||
node_pubkey: *identity_pubkey,
|
node_pubkey: identity_pubkey,
|
||||||
authorized_voter: authorized_voter.unwrap_or(*identity_pubkey),
|
authorized_voter: authorized_voter.unwrap_or(identity_pubkey),
|
||||||
authorized_withdrawer: authorized_withdrawer.unwrap_or(*identity_pubkey),
|
authorized_withdrawer: authorized_withdrawer.unwrap_or(identity_pubkey),
|
||||||
commission,
|
commission,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -486,18 +489,20 @@ pub fn process_vote_update_validator(
|
|||||||
rpc_client: &RpcClient,
|
rpc_client: &RpcClient,
|
||||||
config: &CliConfig,
|
config: &CliConfig,
|
||||||
vote_account_pubkey: &Pubkey,
|
vote_account_pubkey: &Pubkey,
|
||||||
new_identity_pubkey: &Pubkey,
|
new_identity_account: SignerIndex,
|
||||||
) -> ProcessResult {
|
) -> ProcessResult {
|
||||||
let authorized_voter = config.signers[1];
|
let authorized_withdrawer = config.signers[1];
|
||||||
|
let new_identity_account = config.signers[new_identity_account];
|
||||||
|
let new_identity_pubkey = new_identity_account.pubkey();
|
||||||
check_unique_pubkeys(
|
check_unique_pubkeys(
|
||||||
(vote_account_pubkey, "vote_account_pubkey".to_string()),
|
(vote_account_pubkey, "vote_account_pubkey".to_string()),
|
||||||
(new_identity_pubkey, "new_identity_pubkey".to_string()),
|
(&new_identity_pubkey, "new_identity_account".to_string()),
|
||||||
)?;
|
)?;
|
||||||
let (recent_blockhash, fee_calculator) = rpc_client.get_recent_blockhash()?;
|
let (recent_blockhash, fee_calculator) = rpc_client.get_recent_blockhash()?;
|
||||||
let ixs = vec![vote_instruction::update_node(
|
let ixs = vec![vote_instruction::update_node(
|
||||||
vote_account_pubkey,
|
vote_account_pubkey,
|
||||||
&authorized_voter.pubkey(),
|
&authorized_withdrawer.pubkey(),
|
||||||
new_identity_pubkey,
|
&new_identity_pubkey,
|
||||||
)];
|
)];
|
||||||
|
|
||||||
let message = Message::new_with_payer(&ixs, Some(&config.signers[0].pubkey()));
|
let message = Message::new_with_payer(&ixs, Some(&config.signers[0].pubkey()));
|
||||||
@ -675,13 +680,14 @@ mod tests {
|
|||||||
let keypair = Keypair::new();
|
let keypair = Keypair::new();
|
||||||
write_keypair(&keypair, tmp_file.as_file_mut()).unwrap();
|
write_keypair(&keypair, tmp_file.as_file_mut()).unwrap();
|
||||||
// Test CreateVoteAccount SubCommand
|
// Test CreateVoteAccount SubCommand
|
||||||
let node_pubkey = Pubkey::new_rand();
|
let (identity_keypair_file, mut tmp_file) = make_tmp_file();
|
||||||
let node_pubkey_string = format!("{}", node_pubkey);
|
let identity_keypair = Keypair::new();
|
||||||
|
write_keypair(&identity_keypair, tmp_file.as_file_mut()).unwrap();
|
||||||
let test_create_vote_account = test_commands.clone().get_matches_from(vec![
|
let test_create_vote_account = test_commands.clone().get_matches_from(vec![
|
||||||
"test",
|
"test",
|
||||||
"create-vote-account",
|
"create-vote-account",
|
||||||
&keypair_file,
|
&keypair_file,
|
||||||
&node_pubkey_string,
|
&identity_keypair_file,
|
||||||
"--commission",
|
"--commission",
|
||||||
"10",
|
"10",
|
||||||
]);
|
]);
|
||||||
@ -690,14 +696,15 @@ mod tests {
|
|||||||
CliCommandInfo {
|
CliCommandInfo {
|
||||||
command: CliCommand::CreateVoteAccount {
|
command: CliCommand::CreateVoteAccount {
|
||||||
seed: None,
|
seed: None,
|
||||||
node_pubkey,
|
identity_account: 2,
|
||||||
authorized_voter: None,
|
authorized_voter: None,
|
||||||
authorized_withdrawer: None,
|
authorized_withdrawer: None,
|
||||||
commission: 10,
|
commission: 10,
|
||||||
},
|
},
|
||||||
signers: vec![
|
signers: vec![
|
||||||
read_keypair_file(&default_keypair_file).unwrap().into(),
|
read_keypair_file(&default_keypair_file).unwrap().into(),
|
||||||
Box::new(keypair)
|
Box::new(keypair),
|
||||||
|
read_keypair_file(&identity_keypair_file).unwrap().into(),
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -710,21 +717,22 @@ mod tests {
|
|||||||
"test",
|
"test",
|
||||||
"create-vote-account",
|
"create-vote-account",
|
||||||
&keypair_file,
|
&keypair_file,
|
||||||
&node_pubkey_string,
|
&identity_keypair_file,
|
||||||
]);
|
]);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse_command(&test_create_vote_account2, &default_keypair_file, None).unwrap(),
|
parse_command(&test_create_vote_account2, &default_keypair_file, None).unwrap(),
|
||||||
CliCommandInfo {
|
CliCommandInfo {
|
||||||
command: CliCommand::CreateVoteAccount {
|
command: CliCommand::CreateVoteAccount {
|
||||||
seed: None,
|
seed: None,
|
||||||
node_pubkey,
|
identity_account: 2,
|
||||||
authorized_voter: None,
|
authorized_voter: None,
|
||||||
authorized_withdrawer: None,
|
authorized_withdrawer: None,
|
||||||
commission: 100,
|
commission: 100,
|
||||||
},
|
},
|
||||||
signers: vec![
|
signers: vec![
|
||||||
read_keypair_file(&default_keypair_file).unwrap().into(),
|
read_keypair_file(&default_keypair_file).unwrap().into(),
|
||||||
Box::new(keypair)
|
Box::new(keypair),
|
||||||
|
read_keypair_file(&identity_keypair_file).unwrap().into(),
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -739,7 +747,7 @@ mod tests {
|
|||||||
"test",
|
"test",
|
||||||
"create-vote-account",
|
"create-vote-account",
|
||||||
&keypair_file,
|
&keypair_file,
|
||||||
&node_pubkey_string,
|
&identity_keypair_file,
|
||||||
"--authorized-voter",
|
"--authorized-voter",
|
||||||
&authed.to_string(),
|
&authed.to_string(),
|
||||||
]);
|
]);
|
||||||
@ -748,14 +756,15 @@ mod tests {
|
|||||||
CliCommandInfo {
|
CliCommandInfo {
|
||||||
command: CliCommand::CreateVoteAccount {
|
command: CliCommand::CreateVoteAccount {
|
||||||
seed: None,
|
seed: None,
|
||||||
node_pubkey,
|
identity_account: 2,
|
||||||
authorized_voter: Some(authed),
|
authorized_voter: Some(authed),
|
||||||
authorized_withdrawer: None,
|
authorized_withdrawer: None,
|
||||||
commission: 100
|
commission: 100
|
||||||
},
|
},
|
||||||
signers: vec![
|
signers: vec![
|
||||||
read_keypair_file(&default_keypair_file).unwrap().into(),
|
read_keypair_file(&default_keypair_file).unwrap().into(),
|
||||||
Box::new(keypair)
|
Box::new(keypair),
|
||||||
|
read_keypair_file(&identity_keypair_file).unwrap().into(),
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -768,7 +777,7 @@ mod tests {
|
|||||||
"test",
|
"test",
|
||||||
"create-vote-account",
|
"create-vote-account",
|
||||||
&keypair_file,
|
&keypair_file,
|
||||||
&node_pubkey_string,
|
&identity_keypair_file,
|
||||||
"--authorized-withdrawer",
|
"--authorized-withdrawer",
|
||||||
&authed.to_string(),
|
&authed.to_string(),
|
||||||
]);
|
]);
|
||||||
@ -777,14 +786,15 @@ mod tests {
|
|||||||
CliCommandInfo {
|
CliCommandInfo {
|
||||||
command: CliCommand::CreateVoteAccount {
|
command: CliCommand::CreateVoteAccount {
|
||||||
seed: None,
|
seed: None,
|
||||||
node_pubkey,
|
identity_account: 2,
|
||||||
authorized_voter: None,
|
authorized_voter: None,
|
||||||
authorized_withdrawer: Some(authed),
|
authorized_withdrawer: Some(authed),
|
||||||
commission: 100
|
commission: 100
|
||||||
},
|
},
|
||||||
signers: vec![
|
signers: vec![
|
||||||
read_keypair_file(&default_keypair_file).unwrap().into(),
|
read_keypair_file(&default_keypair_file).unwrap().into(),
|
||||||
Box::new(keypair)
|
Box::new(keypair),
|
||||||
|
read_keypair_file(&identity_keypair_file).unwrap().into(),
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -793,7 +803,7 @@ mod tests {
|
|||||||
"test",
|
"test",
|
||||||
"vote-update-validator",
|
"vote-update-validator",
|
||||||
&pubkey_string,
|
&pubkey_string,
|
||||||
&pubkey2_string,
|
&identity_keypair_file,
|
||||||
&keypair_file,
|
&keypair_file,
|
||||||
]);
|
]);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@ -801,11 +811,12 @@ mod tests {
|
|||||||
CliCommandInfo {
|
CliCommandInfo {
|
||||||
command: CliCommand::VoteUpdateValidator {
|
command: CliCommand::VoteUpdateValidator {
|
||||||
vote_account_pubkey: pubkey,
|
vote_account_pubkey: pubkey,
|
||||||
new_identity_pubkey: pubkey2,
|
new_identity_account: 2,
|
||||||
},
|
},
|
||||||
signers: vec![
|
signers: vec![
|
||||||
read_keypair_file(&default_keypair_file).unwrap().into(),
|
read_keypair_file(&default_keypair_file).unwrap().into(),
|
||||||
Box::new(read_keypair_file(&keypair_file).unwrap())
|
Box::new(read_keypair_file(&keypair_file).unwrap()),
|
||||||
|
read_keypair_file(&identity_keypair_file).unwrap().into(),
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -68,7 +68,7 @@ fn test_stake_delegation_force() {
|
|||||||
config.signers = vec![&default_signer, &vote_keypair];
|
config.signers = vec![&default_signer, &vote_keypair];
|
||||||
config.command = CliCommand::CreateVoteAccount {
|
config.command = CliCommand::CreateVoteAccount {
|
||||||
seed: None,
|
seed: None,
|
||||||
node_pubkey: config.signers[0].pubkey(),
|
identity_account: 0,
|
||||||
authorized_voter: None,
|
authorized_voter: None,
|
||||||
authorized_withdrawer: None,
|
authorized_withdrawer: None,
|
||||||
commission: 0,
|
commission: 0,
|
||||||
|
@ -57,7 +57,7 @@ fn test_vote_authorize_and_withdraw() {
|
|||||||
config.signers = vec![&default_signer, &vote_account_keypair];
|
config.signers = vec![&default_signer, &vote_account_keypair];
|
||||||
config.command = CliCommand::CreateVoteAccount {
|
config.command = CliCommand::CreateVoteAccount {
|
||||||
seed: None,
|
seed: None,
|
||||||
node_pubkey: config.signers[0].pubkey(),
|
identity_account: 0,
|
||||||
authorized_voter: None,
|
authorized_voter: None,
|
||||||
authorized_withdrawer: Some(config.signers[0].pubkey()),
|
authorized_withdrawer: Some(config.signers[0].pubkey()),
|
||||||
commission: 0,
|
commission: 0,
|
||||||
@ -104,6 +104,15 @@ fn test_vote_authorize_and_withdraw() {
|
|||||||
check_balance(expected_balance - 100, &rpc_client, &vote_account_pubkey);
|
check_balance(expected_balance - 100, &rpc_client, &vote_account_pubkey);
|
||||||
check_balance(100, &rpc_client, &destination_account);
|
check_balance(100, &rpc_client, &destination_account);
|
||||||
|
|
||||||
|
// Re-assign validator identity
|
||||||
|
let new_identity_keypair = Keypair::new();
|
||||||
|
config.signers.push(&new_identity_keypair);
|
||||||
|
config.command = CliCommand::VoteUpdateValidator {
|
||||||
|
vote_account_pubkey,
|
||||||
|
new_identity_account: 2,
|
||||||
|
};
|
||||||
|
process_command(&config).unwrap();
|
||||||
|
|
||||||
server.close().unwrap();
|
server.close().unwrap();
|
||||||
remove_dir_all(ledger_path).unwrap();
|
remove_dir_all(ledger_path).unwrap();
|
||||||
}
|
}
|
||||||
|
@ -272,7 +272,7 @@ mod tests {
|
|||||||
EpochSchedule, DEFAULT_LEADER_SCHEDULE_SLOT_OFFSET, DEFAULT_SLOTS_PER_EPOCH,
|
EpochSchedule, DEFAULT_LEADER_SCHEDULE_SLOT_OFFSET, DEFAULT_SLOTS_PER_EPOCH,
|
||||||
MINIMUM_SLOTS_PER_EPOCH,
|
MINIMUM_SLOTS_PER_EPOCH,
|
||||||
};
|
};
|
||||||
use solana_sdk::signature::Keypair;
|
use solana_sdk::signature::{Keypair, Signer};
|
||||||
use std::{sync::mpsc::channel, sync::Arc, thread::Builder};
|
use std::{sync::mpsc::channel, sync::Arc, thread::Builder};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -526,15 +526,16 @@ mod tests {
|
|||||||
let cache = Arc::new(LeaderScheduleCache::new_from_bank(&bank));
|
let cache = Arc::new(LeaderScheduleCache::new_from_bank(&bank));
|
||||||
|
|
||||||
// Create new vote account
|
// Create new vote account
|
||||||
let node_pubkey = Pubkey::new_rand();
|
let validator_identity = Keypair::new();
|
||||||
let vote_account = Keypair::new();
|
let vote_account = Keypair::new();
|
||||||
setup_vote_and_stake_accounts(
|
setup_vote_and_stake_accounts(
|
||||||
&bank,
|
&bank,
|
||||||
&mint_keypair,
|
&mint_keypair,
|
||||||
&vote_account,
|
&vote_account,
|
||||||
&node_pubkey,
|
&validator_identity,
|
||||||
BOOTSTRAP_VALIDATOR_LAMPORTS,
|
BOOTSTRAP_VALIDATOR_LAMPORTS,
|
||||||
);
|
);
|
||||||
|
let node_pubkey = validator_identity.pubkey();
|
||||||
|
|
||||||
// Have to wait until the epoch at after the epoch stakes generated at genesis
|
// Have to wait until the epoch at after the epoch stakes generated at genesis
|
||||||
// for the new votes to take effect.
|
// for the new votes to take effect.
|
||||||
|
@ -130,7 +130,7 @@ pub(crate) mod tests {
|
|||||||
bank: &Bank,
|
bank: &Bank,
|
||||||
from_account: &Keypair,
|
from_account: &Keypair,
|
||||||
vote_account: &Keypair,
|
vote_account: &Keypair,
|
||||||
node_pubkey: &Pubkey,
|
validator_identity_account: &Keypair,
|
||||||
amount: u64,
|
amount: u64,
|
||||||
) {
|
) {
|
||||||
let vote_pubkey = vote_account.pubkey();
|
let vote_pubkey = vote_account.pubkey();
|
||||||
@ -146,12 +146,12 @@ pub(crate) mod tests {
|
|||||||
|
|
||||||
process_instructions(
|
process_instructions(
|
||||||
bank,
|
bank,
|
||||||
&[from_account, vote_account],
|
&[from_account, vote_account, validator_identity_account],
|
||||||
vote_instruction::create_account(
|
vote_instruction::create_account(
|
||||||
&from_account.pubkey(),
|
&from_account.pubkey(),
|
||||||
&vote_pubkey,
|
&vote_pubkey,
|
||||||
&VoteInit {
|
&VoteInit {
|
||||||
node_pubkey: *node_pubkey,
|
node_pubkey: validator_identity_account.pubkey(),
|
||||||
authorized_voter: vote_pubkey,
|
authorized_voter: vote_pubkey,
|
||||||
authorized_withdrawer: vote_pubkey,
|
authorized_withdrawer: vote_pubkey,
|
||||||
commission: 0,
|
commission: 0,
|
||||||
@ -209,13 +209,7 @@ pub(crate) mod tests {
|
|||||||
|
|
||||||
// Make a mint vote account. Because the mint has nonzero stake, this
|
// Make a mint vote account. Because the mint has nonzero stake, this
|
||||||
// should show up in the active set
|
// should show up in the active set
|
||||||
setup_vote_and_stake_accounts(
|
setup_vote_and_stake_accounts(&bank, &mint_keypair, &vote_account, &mint_keypair, stake);
|
||||||
&bank,
|
|
||||||
&mint_keypair,
|
|
||||||
&vote_account,
|
|
||||||
&mint_keypair.pubkey(),
|
|
||||||
stake,
|
|
||||||
);
|
|
||||||
|
|
||||||
// simulated stake
|
// simulated stake
|
||||||
let other_stake = Stake {
|
let other_stake = Stake {
|
||||||
|
@ -51,6 +51,7 @@ impl<E> DecodeError<E> for VoteError {
|
|||||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
|
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
|
||||||
pub enum VoteInstruction {
|
pub enum VoteInstruction {
|
||||||
/// Initialize the VoteState for this `vote account`
|
/// Initialize the VoteState for this `vote account`
|
||||||
|
/// requires VoteInit::node_pubkey signature
|
||||||
///
|
///
|
||||||
/// Expects 3 Accounts:
|
/// Expects 3 Accounts:
|
||||||
/// 0 - Uninitialized Vote account
|
/// 0 - Uninitialized Vote account
|
||||||
@ -87,13 +88,13 @@ pub enum VoteInstruction {
|
|||||||
Withdraw(u64),
|
Withdraw(u64),
|
||||||
|
|
||||||
/// Update the vote account's validator identity (node id)
|
/// Update the vote account's validator identity (node id)
|
||||||
/// requires authorized voter signature
|
/// requires authorized withdrawer and new validator identity signature
|
||||||
///
|
///
|
||||||
/// Expects 2 Accounts:
|
/// Expects 2 Accounts:
|
||||||
/// 0 - Vote account to be updated with the Pubkey for authorization
|
/// 0 - Vote account to be updated with the Pubkey for authorization
|
||||||
/// 1 - Clock sysvar Account that carries clock bank epoch
|
/// 1 - New validator identity (node id)
|
||||||
///
|
///
|
||||||
UpdateNode(Pubkey),
|
UpdateNode,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn initialize_account(vote_pubkey: &Pubkey, vote_init: &VoteInit) -> Instruction {
|
fn initialize_account(vote_pubkey: &Pubkey, vote_init: &VoteInit) -> Instruction {
|
||||||
@ -101,7 +102,9 @@ fn initialize_account(vote_pubkey: &Pubkey, vote_init: &VoteInit) -> Instruction
|
|||||||
AccountMeta::new(*vote_pubkey, false),
|
AccountMeta::new(*vote_pubkey, false),
|
||||||
AccountMeta::new_readonly(sysvar::rent::id(), false),
|
AccountMeta::new_readonly(sysvar::rent::id(), false),
|
||||||
AccountMeta::new_readonly(sysvar::clock::id(), false),
|
AccountMeta::new_readonly(sysvar::clock::id(), false),
|
||||||
];
|
]
|
||||||
|
.with_signer(&vote_init.node_pubkey);
|
||||||
|
|
||||||
Instruction::new(
|
Instruction::new(
|
||||||
id(),
|
id(),
|
||||||
&VoteInstruction::InitializeAccount(*vote_init),
|
&VoteInstruction::InitializeAccount(*vote_init),
|
||||||
@ -165,20 +168,16 @@ pub fn authorize(
|
|||||||
|
|
||||||
pub fn update_node(
|
pub fn update_node(
|
||||||
vote_pubkey: &Pubkey,
|
vote_pubkey: &Pubkey,
|
||||||
authorized_voter_pubkey: &Pubkey,
|
authorized_withdrawer_pubkey: &Pubkey,
|
||||||
node_pubkey: &Pubkey,
|
node_pubkey: &Pubkey,
|
||||||
) -> Instruction {
|
) -> Instruction {
|
||||||
let account_metas = vec![
|
let account_metas = vec![
|
||||||
AccountMeta::new(*vote_pubkey, false),
|
AccountMeta::new(*vote_pubkey, false),
|
||||||
AccountMeta::new_readonly(sysvar::clock::id(), false),
|
AccountMeta::new_readonly(*node_pubkey, true),
|
||||||
]
|
]
|
||||||
.with_signer(authorized_voter_pubkey);
|
.with_signer(authorized_withdrawer_pubkey);
|
||||||
|
|
||||||
Instruction::new(
|
Instruction::new(id(), &VoteInstruction::UpdateNode, account_metas)
|
||||||
id(),
|
|
||||||
&VoteInstruction::UpdateNode(*node_pubkey),
|
|
||||||
account_metas,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vote(vote_pubkey: &Pubkey, authorized_voter_pubkey: &Pubkey, vote: Vote) -> Instruction {
|
pub fn vote(vote_pubkey: &Pubkey, authorized_voter_pubkey: &Pubkey, vote: Vote) -> Instruction {
|
||||||
@ -194,7 +193,7 @@ pub fn vote(vote_pubkey: &Pubkey, authorized_voter_pubkey: &Pubkey, vote: Vote)
|
|||||||
|
|
||||||
pub fn withdraw(
|
pub fn withdraw(
|
||||||
vote_pubkey: &Pubkey,
|
vote_pubkey: &Pubkey,
|
||||||
withdrawer_pubkey: &Pubkey,
|
authorized_withdrawer_pubkey: &Pubkey,
|
||||||
lamports: u64,
|
lamports: u64,
|
||||||
to_pubkey: &Pubkey,
|
to_pubkey: &Pubkey,
|
||||||
) -> Instruction {
|
) -> Instruction {
|
||||||
@ -202,7 +201,7 @@ pub fn withdraw(
|
|||||||
AccountMeta::new(*vote_pubkey, false),
|
AccountMeta::new(*vote_pubkey, false),
|
||||||
AccountMeta::new(*to_pubkey, false),
|
AccountMeta::new(*to_pubkey, false),
|
||||||
]
|
]
|
||||||
.with_signer(withdrawer_pubkey);
|
.with_signer(authorized_withdrawer_pubkey);
|
||||||
|
|
||||||
Instruction::new(id(), &VoteInstruction::Withdraw(lamports), account_metas)
|
Instruction::new(id(), &VoteInstruction::Withdraw(lamports), account_metas)
|
||||||
}
|
}
|
||||||
@ -228,6 +227,7 @@ pub fn process_instruction(
|
|||||||
vote_state::initialize_account(
|
vote_state::initialize_account(
|
||||||
me,
|
me,
|
||||||
&vote_init,
|
&vote_init,
|
||||||
|
&signers,
|
||||||
&Clock::from_keyed_account(next_keyed_account(keyed_accounts)?)?,
|
&Clock::from_keyed_account(next_keyed_account(keyed_accounts)?)?,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -238,11 +238,10 @@ pub fn process_instruction(
|
|||||||
&signers,
|
&signers,
|
||||||
&Clock::from_keyed_account(next_keyed_account(keyed_accounts)?)?,
|
&Clock::from_keyed_account(next_keyed_account(keyed_accounts)?)?,
|
||||||
),
|
),
|
||||||
VoteInstruction::UpdateNode(node_pubkey) => vote_state::update_node(
|
VoteInstruction::UpdateNode => vote_state::update_node(
|
||||||
me,
|
me,
|
||||||
&node_pubkey,
|
next_keyed_account(keyed_accounts)?.unsigned_key(),
|
||||||
&signers,
|
&signers,
|
||||||
&Clock::from_keyed_account(next_keyed_account(keyed_accounts)?)?,
|
|
||||||
),
|
),
|
||||||
VoteInstruction::Vote(vote) => {
|
VoteInstruction::Vote(vote) => {
|
||||||
inc_new_counter_info!("vote-native", 1);
|
inc_new_counter_info!("vote-native", 1);
|
||||||
|
@ -582,16 +582,15 @@ pub fn update_node<S: std::hash::BuildHasher>(
|
|||||||
vote_account: &KeyedAccount,
|
vote_account: &KeyedAccount,
|
||||||
node_pubkey: &Pubkey,
|
node_pubkey: &Pubkey,
|
||||||
signers: &HashSet<Pubkey, S>,
|
signers: &HashSet<Pubkey, S>,
|
||||||
clock: &Clock,
|
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
let mut vote_state: VoteState =
|
let mut vote_state: VoteState =
|
||||||
State::<VoteStateVersions>::state(vote_account)?.convert_to_current();
|
State::<VoteStateVersions>::state(vote_account)?.convert_to_current();
|
||||||
let authorized_voter = vote_state
|
|
||||||
.get_and_update_authorized_voter(clock.epoch)
|
|
||||||
.expect("the clock epoch is monotonically increasing, so authorized voter must be known");
|
|
||||||
|
|
||||||
// current authorized voter must say "yay"
|
// current authorized withdrawer must say "yay"
|
||||||
verify_authorized_signer(&authorized_voter, signers)?;
|
verify_authorized_signer(&vote_state.authorized_withdrawer, signers)?;
|
||||||
|
|
||||||
|
// new node must say "yay"
|
||||||
|
verify_authorized_signer(&node_pubkey, signers)?;
|
||||||
|
|
||||||
vote_state.node_pubkey = *node_pubkey;
|
vote_state.node_pubkey = *node_pubkey;
|
||||||
|
|
||||||
@ -632,9 +631,10 @@ pub fn withdraw<S: std::hash::BuildHasher>(
|
|||||||
/// Initialize the vote_state for a vote account
|
/// Initialize the vote_state for a vote account
|
||||||
/// Assumes that the account is being init as part of a account creation or balance transfer and
|
/// Assumes that the account is being init as part of a account creation or balance transfer and
|
||||||
/// that the transaction must be signed by the staker's keys
|
/// that the transaction must be signed by the staker's keys
|
||||||
pub fn initialize_account(
|
pub fn initialize_account<S: std::hash::BuildHasher>(
|
||||||
vote_account: &KeyedAccount,
|
vote_account: &KeyedAccount,
|
||||||
vote_init: &VoteInit,
|
vote_init: &VoteInit,
|
||||||
|
signers: &HashSet<Pubkey, S>,
|
||||||
clock: &Clock,
|
clock: &Clock,
|
||||||
) -> Result<(), InstructionError> {
|
) -> Result<(), InstructionError> {
|
||||||
let versioned = State::<VoteStateVersions>::state(vote_account)?;
|
let versioned = State::<VoteStateVersions>::state(vote_account)?;
|
||||||
@ -643,6 +643,9 @@ pub fn initialize_account(
|
|||||||
return Err(InstructionError::AccountAlreadyInitialized);
|
return Err(InstructionError::AccountAlreadyInitialized);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// node must agree to accept this vote account
|
||||||
|
verify_authorized_signer(&vote_init.node_pubkey, signers)?;
|
||||||
|
|
||||||
vote_account.set_state(&VoteStateVersions::Current(Box::new(VoteState::new(
|
vote_account.set_state(&VoteStateVersions::Current(Box::new(VoteState::new(
|
||||||
vote_init, clock,
|
vote_init, clock,
|
||||||
))))
|
))))
|
||||||
@ -664,7 +667,7 @@ pub fn process_vote<S: std::hash::BuildHasher>(
|
|||||||
let mut vote_state = versioned.convert_to_current();
|
let mut vote_state = versioned.convert_to_current();
|
||||||
let authorized_voter = vote_state
|
let authorized_voter = vote_state
|
||||||
.get_and_update_authorized_voter(clock.epoch)
|
.get_and_update_authorized_voter(clock.epoch)
|
||||||
.expect("the clock epoch is monotonically increasinig, so authorized voter must be known");
|
.expect("the clock epoch is monotonically increasing, so authorized voter must be known");
|
||||||
verify_authorized_signer(&authorized_voter, signers)?;
|
verify_authorized_signer(&authorized_voter, signers)?;
|
||||||
|
|
||||||
vote_state.process_vote(vote, slot_hashes, clock.epoch)?;
|
vote_state.process_vote(vote, slot_hashes, clock.epoch)?;
|
||||||
@ -745,11 +748,14 @@ mod tests {
|
|||||||
fn test_initialize_vote_account() {
|
fn test_initialize_vote_account() {
|
||||||
let vote_account_pubkey = Pubkey::new_rand();
|
let vote_account_pubkey = Pubkey::new_rand();
|
||||||
let vote_account = Account::new_ref(100, VoteState::size_of(), &id());
|
let vote_account = Account::new_ref(100, VoteState::size_of(), &id());
|
||||||
|
let vote_account = KeyedAccount::new(&vote_account_pubkey, false, &vote_account);
|
||||||
|
|
||||||
let node_pubkey = Pubkey::new_rand();
|
let node_pubkey = Pubkey::new_rand();
|
||||||
|
let node_account = RefCell::new(Account::default());
|
||||||
|
let keyed_accounts = &[];
|
||||||
|
let signers: HashSet<Pubkey> = get_signers(keyed_accounts);
|
||||||
|
|
||||||
//init should pass
|
//init should fail, node_pubkey didn't sign the transaction
|
||||||
let vote_account = KeyedAccount::new(&vote_account_pubkey, false, &vote_account);
|
|
||||||
let res = initialize_account(
|
let res = initialize_account(
|
||||||
&vote_account,
|
&vote_account,
|
||||||
&VoteInit {
|
&VoteInit {
|
||||||
@ -758,6 +764,24 @@ mod tests {
|
|||||||
authorized_withdrawer: vote_account_pubkey,
|
authorized_withdrawer: vote_account_pubkey,
|
||||||
commission: 0,
|
commission: 0,
|
||||||
},
|
},
|
||||||
|
&signers,
|
||||||
|
&Clock::default(),
|
||||||
|
);
|
||||||
|
assert_eq!(res, Err(InstructionError::MissingRequiredSignature));
|
||||||
|
|
||||||
|
let keyed_accounts = &[KeyedAccount::new(&node_pubkey, true, &node_account)];
|
||||||
|
let signers: HashSet<Pubkey> = get_signers(keyed_accounts);
|
||||||
|
|
||||||
|
//init should pass
|
||||||
|
let res = initialize_account(
|
||||||
|
&vote_account,
|
||||||
|
&VoteInit {
|
||||||
|
node_pubkey,
|
||||||
|
authorized_voter: vote_account_pubkey,
|
||||||
|
authorized_withdrawer: vote_account_pubkey,
|
||||||
|
commission: 0,
|
||||||
|
},
|
||||||
|
&signers,
|
||||||
&Clock::default(),
|
&Clock::default(),
|
||||||
);
|
);
|
||||||
assert_eq!(res, Ok(()));
|
assert_eq!(res, Ok(()));
|
||||||
@ -771,6 +795,7 @@ mod tests {
|
|||||||
authorized_withdrawer: vote_account_pubkey,
|
authorized_withdrawer: vote_account_pubkey,
|
||||||
commission: 0,
|
commission: 0,
|
||||||
},
|
},
|
||||||
|
&signers,
|
||||||
&Clock::default(),
|
&Clock::default(),
|
||||||
);
|
);
|
||||||
assert_eq!(res, Err(InstructionError::AccountAlreadyInitialized));
|
assert_eq!(res, Err(InstructionError::AccountAlreadyInitialized));
|
||||||
@ -789,6 +814,25 @@ mod tests {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn create_test_account_with_authorized() -> (Pubkey, Pubkey, Pubkey, RefCell<Account>) {
|
||||||
|
let vote_pubkey = Pubkey::new_rand();
|
||||||
|
let authorized_voter = Pubkey::new_rand();
|
||||||
|
let authorized_withdrawer = Pubkey::new_rand();
|
||||||
|
|
||||||
|
(
|
||||||
|
vote_pubkey,
|
||||||
|
authorized_voter,
|
||||||
|
authorized_withdrawer,
|
||||||
|
RefCell::new(vote_state::create_account_with_authorized(
|
||||||
|
&Pubkey::new_rand(),
|
||||||
|
&authorized_voter,
|
||||||
|
&authorized_withdrawer,
|
||||||
|
0,
|
||||||
|
100,
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn simulate_process_vote(
|
fn simulate_process_vote(
|
||||||
vote_pubkey: &Pubkey,
|
vote_pubkey: &Pubkey,
|
||||||
vote_account: &RefCell<Account>,
|
vote_account: &RefCell<Account>,
|
||||||
@ -906,43 +950,46 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_vote_update_node_id() {
|
fn test_vote_update_node_id() {
|
||||||
let (vote_pubkey, vote_account) = create_test_account();
|
let (vote_pubkey, _authorized_voter, authorized_withdrawer, vote_account) =
|
||||||
|
create_test_account_with_authorized();
|
||||||
|
|
||||||
let node_pubkey = Pubkey::new_rand();
|
let node_pubkey = Pubkey::new_rand();
|
||||||
|
let node_account = RefCell::new(Account::default());
|
||||||
|
let authorized_withdrawer_account = RefCell::new(Account::default());
|
||||||
|
|
||||||
let keyed_accounts = &[KeyedAccount::new(&vote_pubkey, false, &vote_account)];
|
let keyed_accounts = &[
|
||||||
|
KeyedAccount::new(&vote_pubkey, true, &vote_account),
|
||||||
|
KeyedAccount::new(&node_pubkey, false, &node_account),
|
||||||
|
KeyedAccount::new(&authorized_withdrawer, true, &authorized_withdrawer_account),
|
||||||
|
];
|
||||||
let signers: HashSet<Pubkey> = get_signers(keyed_accounts);
|
let signers: HashSet<Pubkey> = get_signers(keyed_accounts);
|
||||||
let res = update_node(
|
let res = update_node(&keyed_accounts[0], &node_pubkey, &signers);
|
||||||
&keyed_accounts[0],
|
assert_eq!(res, Err(InstructionError::MissingRequiredSignature));
|
||||||
&node_pubkey,
|
|
||||||
&signers,
|
let keyed_accounts = &[
|
||||||
&Clock::default(),
|
KeyedAccount::new(&vote_pubkey, true, &vote_account),
|
||||||
);
|
KeyedAccount::new(&node_pubkey, true, &node_account),
|
||||||
|
KeyedAccount::new(
|
||||||
|
&authorized_withdrawer,
|
||||||
|
false,
|
||||||
|
&authorized_withdrawer_account,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
let signers: HashSet<Pubkey> = get_signers(keyed_accounts);
|
||||||
|
let res = update_node(&keyed_accounts[0], &node_pubkey, &signers);
|
||||||
assert_eq!(res, Err(InstructionError::MissingRequiredSignature));
|
assert_eq!(res, Err(InstructionError::MissingRequiredSignature));
|
||||||
let vote_state: VoteState = StateMut::<VoteStateVersions>::state(&*vote_account.borrow())
|
let vote_state: VoteState = StateMut::<VoteStateVersions>::state(&*vote_account.borrow())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.convert_to_current();
|
.convert_to_current();
|
||||||
assert!(vote_state.node_pubkey != node_pubkey);
|
assert!(vote_state.node_pubkey != node_pubkey);
|
||||||
|
|
||||||
let keyed_accounts = &[KeyedAccount::new(&vote_pubkey, true, &vote_account)];
|
let keyed_accounts = &[
|
||||||
|
KeyedAccount::new(&vote_pubkey, true, &vote_account),
|
||||||
|
KeyedAccount::new(&node_pubkey, true, &node_account),
|
||||||
|
KeyedAccount::new(&authorized_withdrawer, true, &authorized_withdrawer_account),
|
||||||
|
];
|
||||||
let signers: HashSet<Pubkey> = get_signers(keyed_accounts);
|
let signers: HashSet<Pubkey> = get_signers(keyed_accounts);
|
||||||
let res = update_node(
|
let res = update_node(&keyed_accounts[0], &node_pubkey, &signers);
|
||||||
&keyed_accounts[0],
|
|
||||||
&node_pubkey,
|
|
||||||
&signers,
|
|
||||||
&Clock::default(),
|
|
||||||
);
|
|
||||||
assert_eq!(res, Ok(()));
|
|
||||||
let vote_state: VoteState = StateMut::<VoteStateVersions>::state(&*vote_account.borrow())
|
|
||||||
.unwrap()
|
|
||||||
.convert_to_current();
|
|
||||||
assert_eq!(vote_state.node_pubkey, node_pubkey);
|
|
||||||
|
|
||||||
let keyed_accounts = &[KeyedAccount::new(&vote_pubkey, true, &vote_account)];
|
|
||||||
let signers: HashSet<Pubkey> = get_signers(keyed_accounts);
|
|
||||||
let mut clock = Clock::default();
|
|
||||||
clock.epoch += 10;
|
|
||||||
let res = update_node(&keyed_accounts[0], &node_pubkey, &signers, &clock);
|
|
||||||
assert_eq!(res, Ok(()));
|
assert_eq!(res, Ok(()));
|
||||||
let vote_state: VoteState = StateMut::<VoteStateVersions>::state(&*vote_account.borrow())
|
let vote_state: VoteState = StateMut::<VoteStateVersions>::state(&*vote_account.borrow())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
@ -4905,15 +4905,19 @@ mod tests {
|
|||||||
assert!(bank.get_account(&solana_vote_program::id()).is_some());
|
assert!(bank.get_account(&solana_vote_program::id()).is_some());
|
||||||
|
|
||||||
let mock_account = Keypair::new();
|
let mock_account = Keypair::new();
|
||||||
|
let mock_validator_identity = Keypair::new();
|
||||||
let instructions = vote_instruction::create_account(
|
let instructions = vote_instruction::create_account(
|
||||||
&mint_keypair.pubkey(),
|
&mint_keypair.pubkey(),
|
||||||
&mock_account.pubkey(),
|
&mock_account.pubkey(),
|
||||||
&VoteInit::default(),
|
&VoteInit {
|
||||||
|
node_pubkey: mock_validator_identity.pubkey(),
|
||||||
|
..VoteInit::default()
|
||||||
|
},
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
|
|
||||||
let transaction = Transaction::new_signed_instructions(
|
let transaction = Transaction::new_signed_instructions(
|
||||||
&[&mint_keypair, &mock_account],
|
&[&mint_keypair, &mock_account, &mock_validator_identity],
|
||||||
instructions,
|
instructions,
|
||||||
bank.last_blockhash(),
|
bank.last_blockhash(),
|
||||||
);
|
);
|
||||||
@ -4946,15 +4950,19 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mock_account = Keypair::new();
|
let mock_account = Keypair::new();
|
||||||
|
let mock_validator_identity = Keypair::new();
|
||||||
let instructions = vote_instruction::create_account(
|
let instructions = vote_instruction::create_account(
|
||||||
&mint_keypair.pubkey(),
|
&mint_keypair.pubkey(),
|
||||||
&mock_account.pubkey(),
|
&mock_account.pubkey(),
|
||||||
&VoteInit::default(),
|
&VoteInit {
|
||||||
|
node_pubkey: mock_validator_identity.pubkey(),
|
||||||
|
..VoteInit::default()
|
||||||
|
},
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
|
|
||||||
let transaction = Transaction::new_signed_instructions(
|
let transaction = Transaction::new_signed_instructions(
|
||||||
&[&mint_keypair, &mock_account],
|
&[&mint_keypair, &mock_account, &mock_validator_identity],
|
||||||
instructions,
|
instructions,
|
||||||
bank.last_blockhash(),
|
bank.last_blockhash(),
|
||||||
);
|
);
|
||||||
|
@ -163,7 +163,8 @@ fn test_stake_account_lifetime() {
|
|||||||
let stake_pubkey = stake_keypair.pubkey();
|
let stake_pubkey = stake_keypair.pubkey();
|
||||||
let vote_keypair = Keypair::new();
|
let vote_keypair = Keypair::new();
|
||||||
let vote_pubkey = vote_keypair.pubkey();
|
let vote_pubkey = vote_keypair.pubkey();
|
||||||
let node_pubkey = Pubkey::new_rand();
|
let identity_keypair = Keypair::new();
|
||||||
|
let identity_pubkey = identity_keypair.pubkey();
|
||||||
|
|
||||||
let GenesisConfigInfo {
|
let GenesisConfigInfo {
|
||||||
mut genesis_config,
|
mut genesis_config,
|
||||||
@ -183,7 +184,7 @@ fn test_stake_account_lifetime() {
|
|||||||
&mint_pubkey,
|
&mint_pubkey,
|
||||||
&vote_pubkey,
|
&vote_pubkey,
|
||||||
&VoteInit {
|
&VoteInit {
|
||||||
node_pubkey,
|
node_pubkey: identity_pubkey,
|
||||||
authorized_voter: vote_pubkey,
|
authorized_voter: vote_pubkey,
|
||||||
authorized_withdrawer: vote_pubkey,
|
authorized_withdrawer: vote_pubkey,
|
||||||
commission: 50,
|
commission: 50,
|
||||||
@ -191,7 +192,7 @@ fn test_stake_account_lifetime() {
|
|||||||
10,
|
10,
|
||||||
));
|
));
|
||||||
bank_client
|
bank_client
|
||||||
.send_message(&[&mint_keypair, &vote_keypair], message)
|
.send_message(&[&mint_keypair, &vote_keypair, &identity_keypair], message)
|
||||||
.expect("failed to create vote account");
|
.expect("failed to create vote account");
|
||||||
|
|
||||||
let authorized = stake_state::Authorized::auto(&stake_pubkey);
|
let authorized = stake_state::Authorized::auto(&stake_pubkey);
|
||||||
@ -394,7 +395,8 @@ fn test_stake_account_lifetime() {
|
|||||||
fn test_create_stake_account_from_seed() {
|
fn test_create_stake_account_from_seed() {
|
||||||
let vote_keypair = Keypair::new();
|
let vote_keypair = Keypair::new();
|
||||||
let vote_pubkey = vote_keypair.pubkey();
|
let vote_pubkey = vote_keypair.pubkey();
|
||||||
let node_pubkey = Pubkey::new_rand();
|
let identity_keypair = Keypair::new();
|
||||||
|
let identity_pubkey = identity_keypair.pubkey();
|
||||||
|
|
||||||
let GenesisConfigInfo {
|
let GenesisConfigInfo {
|
||||||
mut genesis_config,
|
mut genesis_config,
|
||||||
@ -418,7 +420,7 @@ fn test_create_stake_account_from_seed() {
|
|||||||
&mint_pubkey,
|
&mint_pubkey,
|
||||||
&vote_pubkey,
|
&vote_pubkey,
|
||||||
&VoteInit {
|
&VoteInit {
|
||||||
node_pubkey,
|
node_pubkey: identity_pubkey,
|
||||||
authorized_voter: vote_pubkey,
|
authorized_voter: vote_pubkey,
|
||||||
authorized_withdrawer: vote_pubkey,
|
authorized_withdrawer: vote_pubkey,
|
||||||
commission: 50,
|
commission: 50,
|
||||||
@ -426,7 +428,7 @@ fn test_create_stake_account_from_seed() {
|
|||||||
10,
|
10,
|
||||||
));
|
));
|
||||||
bank_client
|
bank_client
|
||||||
.send_message(&[&mint_keypair, &vote_keypair], message)
|
.send_message(&[&mint_keypair, &vote_keypair, &identity_keypair], message)
|
||||||
.expect("failed to create vote account");
|
.expect("failed to create vote account");
|
||||||
|
|
||||||
let authorized = stake_state::Authorized::auto(&mint_pubkey);
|
let authorized = stake_state::Authorized::auto(&mint_pubkey);
|
||||||
|
Reference in New Issue
Block a user