Buffer authority must match upgrade authority for deploys and upgrades (#14923)

This commit is contained in:
Jack May
2021-01-29 12:43:42 -08:00
committed by GitHub
parent 65315fa4c2
commit 07cef5a557
8 changed files with 767 additions and 572 deletions

View File

@ -62,8 +62,7 @@ pub enum ProgramCliCommand {
program_pubkey: Option<Pubkey>,
buffer_signer_index: Option<SignerIndex>,
buffer_pubkey: Option<Pubkey>,
upgrade_authority_signer_index: Option<SignerIndex>,
upgrade_authority_pubkey: Option<Pubkey>,
upgrade_authority_signer_index: SignerIndex,
is_final: bool,
max_len: Option<usize>,
allow_excessive_balance: bool,
@ -73,13 +72,12 @@ pub enum ProgramCliCommand {
buffer_signer_index: Option<SignerIndex>,
buffer_pubkey: Option<Pubkey>,
buffer_authority_signer_index: Option<SignerIndex>,
is_final: bool,
max_len: Option<usize>,
},
SetBufferAuthority {
buffer_pubkey: Pubkey,
buffer_authority_index: Option<SignerIndex>,
new_buffer_authority: Option<Pubkey>,
new_buffer_authority: Pubkey,
},
SetUpgradeAuthority {
program_pubkey: Pubkey,
@ -122,10 +120,12 @@ impl ProgramSubCommands for App<'_, '_> {
[default: random address]")
)
.arg(
pubkey!(Arg::with_name("upgrade_authority")
Arg::with_name("upgrade_authority")
.long("upgrade-authority")
.value_name("UPGRADE_AUTHORITY"),
"Upgrade authority [default: the default configured keypair]"),
.value_name("UPGRADE_AUTHORITY_SIGNER")
.takes_value(true)
.validator(is_valid_signer)
.help("Upgrade authority [default: the default configured keypair]")
)
.arg(
pubkey!(Arg::with_name("program_id")
@ -182,11 +182,6 @@ impl ProgramSubCommands for App<'_, '_> {
.validator(is_valid_signer)
.help("Buffer authority [default: the default configured keypair]")
)
.arg(
Arg::with_name("final")
.long("final")
.help("The program will not be upgradeable")
)
.arg(
Arg::with_name("max_len")
.long("max-len")
@ -220,15 +215,9 @@ impl ProgramSubCommands for App<'_, '_> {
pubkey!(Arg::with_name("new_buffer_authority")
.long("new-buffer-authority")
.value_name("NEW_BUFFER_AUTHORITY")
.required_unless("final"),
.required(true),
"Address of the new buffer authority"),
)
.arg(
Arg::with_name("final")
.long("final")
.conflicts_with("new_buffer_authority")
.help("The buffer will be immutable")
)
)
.subcommand(
SubCommand::with_name("set-upgrade-authority")
@ -327,10 +316,6 @@ pub fn parse_program_subcommand(
{
bulk_signers.push(upgrade_authority_signer);
Some(upgrade_authority_pubkey)
} else if let Some(upgrade_authority_pubkey) =
pubkey_of_signer(matches, "upgrade_authority", wallet_manager)?
{
Some(upgrade_authority_pubkey)
} else {
Some(
default_signer
@ -352,8 +337,8 @@ pub fn parse_program_subcommand(
buffer_signer_index: signer_info.index_of_or_none(buffer_pubkey),
buffer_pubkey,
upgrade_authority_signer_index: signer_info
.index_of_or_none(upgrade_authority_pubkey),
upgrade_authority_pubkey,
.index_of(upgrade_authority_pubkey)
.unwrap(),
is_final: matches.is_present("final"),
max_len,
allow_excessive_balance: matches.is_present("allow_excessive_balance"),
@ -404,7 +389,6 @@ pub fn parse_program_subcommand(
buffer_pubkey,
buffer_authority_signer_index: signer_info
.index_of_or_none(buffer_authority_pubkey),
is_final: matches.is_present("final"),
max_len,
}),
signers: signer_info.signers,
@ -415,16 +399,14 @@ pub fn parse_program_subcommand(
let (buffer_authority_signer, buffer_authority_pubkey) =
signer_of(matches, "buffer_authority", wallet_manager)?;
let new_buffer_authority = if matches.is_present("final") {
None
} else if let Some(new_buffer_authority) =
let new_buffer_authority = if let Some(new_buffer_authority) =
pubkey_of_signer(matches, "new_buffer_authority", wallet_manager)?
{
Some(new_buffer_authority)
new_buffer_authority
} else {
let (_, new_buffer_authority) =
signer_of(matches, "new_buffer_authority", wallet_manager)?;
new_buffer_authority
new_buffer_authority.unwrap()
};
let signer_info = default_signer.generate_unique_signers(
@ -503,7 +485,6 @@ pub fn process_program_subcommand(
buffer_signer_index,
buffer_pubkey,
upgrade_authority_signer_index,
upgrade_authority_pubkey,
is_final,
max_len,
allow_excessive_balance,
@ -516,7 +497,6 @@ pub fn process_program_subcommand(
*buffer_signer_index,
*buffer_pubkey,
*upgrade_authority_signer_index,
*upgrade_authority_pubkey,
*is_final,
*max_len,
*allow_excessive_balance,
@ -526,7 +506,6 @@ pub fn process_program_subcommand(
buffer_signer_index,
buffer_pubkey,
buffer_authority_signer_index,
is_final,
max_len,
} => process_write_buffer(
&rpc_client,
@ -535,7 +514,6 @@ pub fn process_program_subcommand(
*buffer_signer_index,
*buffer_pubkey,
*buffer_authority_signer_index,
*is_final,
*max_len,
),
ProgramCliCommand::SetBufferAuthority {
@ -548,7 +526,7 @@ pub fn process_program_subcommand(
None,
Some(*buffer_pubkey),
*buffer_authority_index,
*new_buffer_authority,
Some(*new_buffer_authority),
),
ProgramCliCommand::SetUpgradeAuthority {
program_pubkey,
@ -599,8 +577,7 @@ fn process_program_deploy(
program_pubkey: Option<Pubkey>,
buffer_signer_index: Option<SignerIndex>,
buffer_pubkey: Option<Pubkey>,
upgrade_authority_signer_index: Option<SignerIndex>,
upgrade_authority_pubkey: Option<Pubkey>,
upgrade_authority_signer_index: SignerIndex,
is_final: bool,
max_len: Option<usize>,
allow_excessive_balance: bool,
@ -616,6 +593,7 @@ fn process_program_deploy(
buffer_keypair.pubkey(),
)
};
let upgrade_authority_signer = config.signers[upgrade_authority_signer_index];
let default_program_keypair = get_default_program_keypair(&program_location);
let (program_signer, program_pubkey) = if let Some(i) = program_signer_index {
@ -652,10 +630,11 @@ fn process_program_deploy(
if program_authority_pubkey.is_none() {
return Err("Program is no longer upgradeable".into());
}
if program_authority_pubkey != upgrade_authority_pubkey {
if program_authority_pubkey != Some(upgrade_authority_signer.pubkey()) {
return Err(format!(
"Program's authority {:?} does not match authority provided {:?}",
program_authority_pubkey, upgrade_authority_pubkey,
program_authority_pubkey,
upgrade_authority_signer.pubkey(),
)
.into());
}
@ -717,25 +696,22 @@ fn process_program_deploy(
buffer_data_len,
minimum_balance,
&bpf_loader_upgradeable::id(),
Some(program_signer.unwrap()),
Some(&[program_signer.unwrap(), upgrade_authority_signer]),
buffer_signer,
&buffer_pubkey,
buffer_signer,
upgrade_authority_pubkey,
Some(upgrade_authority_signer),
allow_excessive_balance,
)
} else if let Some(upgrade_authority_index) = upgrade_authority_signer_index {
} else {
do_process_program_upgrade(
rpc_client,
config,
&program_data,
&program_pubkey,
config.signers[upgrade_authority_index],
config.signers[upgrade_authority_signer_index],
&buffer_pubkey,
buffer_signer,
)
} else {
return Err("Program upgrade requires an authority".into());
};
if result.is_ok() && is_final {
process_set_authority(
@ -743,7 +719,7 @@ fn process_program_deploy(
config,
Some(program_pubkey),
None,
upgrade_authority_signer_index,
Some(upgrade_authority_signer_index),
None,
)?;
}
@ -760,7 +736,6 @@ fn process_write_buffer(
buffer_signer_index: Option<SignerIndex>,
buffer_pubkey: Option<Pubkey>,
buffer_authority_signer_index: Option<SignerIndex>,
is_final: bool,
max_len: Option<usize>,
) -> ProcessResult {
// Create ephemeral keypair to use for Buffer account, if not provided
@ -823,21 +798,9 @@ fn process_write_buffer(
buffer_signer,
&buffer_pubkey,
Some(buffer_authority),
None,
true,
);
if result.is_ok() && is_final {
process_set_authority(
rpc_client,
config,
None,
Some(buffer_pubkey),
buffer_authority_signer_index,
None,
)?;
}
if result.is_err() && buffer_signer_index.is_none() && buffer_signer.is_some() {
report_ephemeral_mnemonic(words, mnemonic);
}
@ -861,24 +824,28 @@ fn process_set_authority(
trace!("Set a new authority");
let (blockhash, _) = rpc_client.get_recent_blockhash()?;
let mut tx = if let Some(pubkey) = program_pubkey {
let mut tx = if let Some(ref pubkey) = program_pubkey {
Transaction::new_unsigned(Message::new(
&[bpf_loader_upgradeable::set_upgrade_authority(
&pubkey,
pubkey,
&authority_signer.pubkey(),
new_authority.as_ref(),
)],
Some(&config.signers[0].pubkey()),
))
} else if let Some(pubkey) = buffer_pubkey {
Transaction::new_unsigned(Message::new(
&[bpf_loader_upgradeable::set_buffer_authority(
&pubkey,
&authority_signer.pubkey(),
new_authority.as_ref(),
)],
Some(&config.signers[0].pubkey()),
))
if let Some(ref new_authority) = new_authority {
Transaction::new_unsigned(Message::new(
&[bpf_loader_upgradeable::set_buffer_authority(
&pubkey,
&authority_signer.pubkey(),
new_authority,
)],
Some(&config.signers[0].pubkey()),
))
} else {
return Err("Buffer authority cannot be None".into());
}
} else {
return Err("Program or Buffer not provided".into());
};
@ -984,11 +951,10 @@ pub fn process_deploy(
program_data.len(),
minimum_balance,
&loader_id,
Some(buffer_signer),
Some(&[buffer_signer]),
Some(buffer_signer),
&buffer_signer.pubkey(),
Some(buffer_signer),
None,
allow_excessive_balance,
);
if result.is_err() && buffer_signer_index.is_none() {
@ -1005,11 +971,10 @@ fn do_process_program_write_and_deploy(
buffer_data_len: usize,
minimum_balance: u64,
loader_id: &Pubkey,
program_signer: Option<&dyn Signer>,
program_signers: Option<&[&dyn Signer]>,
buffer_signer: Option<&dyn Signer>,
buffer_pubkey: &Pubkey,
buffer_authority_signer: Option<&dyn Signer>,
upgrade_authority: Option<Pubkey>,
allow_excessive_balance: bool,
) -> ProcessResult {
// Build messages to calculate fees
@ -1040,7 +1005,7 @@ fn do_process_program_write_and_deploy(
bpf_loader_upgradeable::create_buffer(
&config.signers[0].pubkey(),
buffer_pubkey,
Some(&buffer_authority_signer.pubkey()),
&buffer_authority_signer.pubkey(),
minimum_balance,
buffer_data_len,
)?,
@ -1074,7 +1039,7 @@ fn do_process_program_write_and_deploy(
let instruction = if loader_id == &bpf_loader_upgradeable::id() {
bpf_loader_upgradeable::write(
buffer_pubkey,
Some(&buffer_authority_signer.pubkey()),
&buffer_authority_signer.pubkey(),
(i * DATA_CHUNK_SIZE) as u32,
chunk.to_vec(),
)
@ -1108,14 +1073,14 @@ fn do_process_program_write_and_deploy(
// Create and add final message
let final_message = if let Some(program_signer) = program_signer {
let final_message = if let Some(program_signers) = program_signers {
let message = if loader_id == &bpf_loader_upgradeable::id() {
Message::new(
&bpf_loader_upgradeable::deploy_with_max_program_len(
&config.signers[0].pubkey(),
&program_signer.pubkey(),
&program_signers[0].pubkey(),
buffer_pubkey,
upgrade_authority.as_ref(),
&program_signers[1].pubkey(),
rpc_client.get_minimum_balance_for_rent_exemption(
UpgradeableLoaderState::program_len()?,
)?,
@ -1147,12 +1112,12 @@ fn do_process_program_write_and_deploy(
&final_message,
buffer_signer,
buffer_authority_signer,
program_signer,
program_signers,
)?;
if let Some(program_signer) = program_signer {
if let Some(program_signers) = program_signers {
Ok(json!({
"ProgramId": format!("{}", program_signer.pubkey()),
"ProgramId": format!("{}", program_signers[0].pubkey()),
})
.to_string())
} else {
@ -1202,7 +1167,7 @@ fn do_process_program_upgrade(
bpf_loader_upgradeable::create_buffer(
&config.signers[0].pubkey(),
buffer_pubkey,
Some(&buffer_signer.pubkey()),
&upgrade_authority.pubkey(),
minimum_balance,
data_len,
)?,
@ -1224,7 +1189,7 @@ fn do_process_program_upgrade(
for (chunk, i) in program_data.chunks(DATA_CHUNK_SIZE).zip(0..) {
let instruction = bpf_loader_upgradeable::write(
&buffer_signer.pubkey(),
None,
&upgrade_authority.pubkey(),
(i * DATA_CHUNK_SIZE) as u32,
chunk.to_vec(),
);
@ -1268,8 +1233,8 @@ fn do_process_program_upgrade(
&write_messages,
&Some(final_message),
buffer_signer,
buffer_signer,
Some(upgrade_authority),
Some(&[upgrade_authority]),
)?;
Ok(json!({
@ -1372,9 +1337,10 @@ fn send_deploy_messages(
final_message: &Option<Message>,
initial_signer: Option<&dyn Signer>,
write_signer: Option<&dyn Signer>,
final_signer: Option<&dyn Signer>,
final_signers: Option<&[&dyn Signer]>,
) -> Result<(), Box<dyn std::error::Error>> {
let payer_signer = config.signers[0];
if let Some(message) = initial_message {
if let Some(initial_signer) = initial_signer {
trace!("Preparing the required accounts");
@ -1423,12 +1389,14 @@ fn send_deploy_messages(
}
if let Some(message) = final_message {
if let Some(final_signer) = final_signer {
if let Some(final_signers) = final_signers {
trace!("Deploying program");
let (blockhash, _) = rpc_client.get_recent_blockhash()?;
let mut final_tx = Transaction::new_unsigned(message.clone());
final_tx.try_sign(&[payer_signer, final_signer], blockhash)?;
let mut signers = final_signers.to_vec();
signers.push(payer_signer);
final_tx.try_sign(&signers, blockhash)?;
rpc_client
.send_and_confirm_transaction_with_spinner_and_config(
&final_tx,
@ -1700,8 +1668,7 @@ mod tests {
buffer_pubkey: None,
program_signer_index: None,
program_pubkey: None,
upgrade_authority_signer_index: Some(0),
upgrade_authority_pubkey: Some(default_keypair.pubkey()),
upgrade_authority_signer_index: 0,
is_final: false,
max_len: None,
allow_excessive_balance: false,
@ -1727,8 +1694,7 @@ mod tests {
buffer_pubkey: None,
program_signer_index: None,
program_pubkey: None,
upgrade_authority_signer_index: Some(0),
upgrade_authority_pubkey: Some(default_keypair.pubkey()),
upgrade_authority_signer_index: 0,
is_final: false,
max_len: Some(42),
allow_excessive_balance: false,
@ -1756,8 +1722,7 @@ mod tests {
buffer_pubkey: Some(buffer_keypair.pubkey()),
program_signer_index: None,
program_pubkey: None,
upgrade_authority_signer_index: Some(0),
upgrade_authority_pubkey: Some(default_keypair.pubkey()),
upgrade_authority_signer_index: 0,
is_final: false,
max_len: None,
allow_excessive_balance: false,
@ -1787,8 +1752,7 @@ mod tests {
buffer_pubkey: None,
program_signer_index: None,
program_pubkey: Some(program_pubkey),
upgrade_authority_signer_index: Some(0),
upgrade_authority_pubkey: Some(default_keypair.pubkey()),
upgrade_authority_signer_index: 0,
is_final: false,
max_len: None,
allow_excessive_balance: false,
@ -1817,8 +1781,7 @@ mod tests {
buffer_pubkey: None,
program_signer_index: Some(1),
program_pubkey: Some(program_keypair.pubkey()),
upgrade_authority_signer_index: Some(0),
upgrade_authority_pubkey: Some(default_keypair.pubkey()),
upgrade_authority_signer_index: 0,
is_final: false,
max_len: None,
allow_excessive_balance: false,
@ -1830,34 +1793,6 @@ mod tests {
}
);
let authority_pubkey = Pubkey::new_unique();
let test_deploy = test_commands.clone().get_matches_from(vec![
"test",
"program",
"deploy",
"/Users/test/program.so",
"--upgrade-authority",
&authority_pubkey.to_string(),
]);
assert_eq!(
parse_command(&test_deploy, &default_signer, &mut None).unwrap(),
CliCommandInfo {
command: CliCommand::Program(ProgramCliCommand::Deploy {
program_location: Some("/Users/test/program.so".to_string()),
buffer_signer_index: None,
buffer_pubkey: None,
program_signer_index: None,
program_pubkey: None,
upgrade_authority_signer_index: None,
upgrade_authority_pubkey: Some(authority_pubkey),
is_final: false,
max_len: None,
allow_excessive_balance: false,
}),
signers: vec![read_keypair_file(&keypair_file).unwrap().into()],
}
);
let authority_keypair = Keypair::new();
let authority_keypair_file = make_tmp_path("authority_keypair_file");
write_keypair_file(&authority_keypair, &authority_keypair_file).unwrap();
@ -1878,8 +1813,7 @@ mod tests {
buffer_pubkey: None,
program_signer_index: None,
program_pubkey: None,
upgrade_authority_signer_index: Some(1),
upgrade_authority_pubkey: Some(authority_keypair.pubkey()),
upgrade_authority_signer_index: 1,
is_final: false,
max_len: None,
allow_excessive_balance: false,
@ -1907,8 +1841,7 @@ mod tests {
buffer_pubkey: None,
program_signer_index: None,
program_pubkey: None,
upgrade_authority_signer_index: Some(0),
upgrade_authority_pubkey: Some(default_keypair.pubkey()),
upgrade_authority_signer_index: 0,
is_final: true,
max_len: None,
allow_excessive_balance: false,
@ -1946,7 +1879,6 @@ mod tests {
buffer_signer_index: None,
buffer_pubkey: None,
buffer_authority_signer_index: Some(0),
is_final: false,
max_len: None,
}),
signers: vec![read_keypair_file(&keypair_file).unwrap().into()],
@ -1970,7 +1902,6 @@ mod tests {
buffer_signer_index: None,
buffer_pubkey: None,
buffer_authority_signer_index: Some(0),
is_final: false,
max_len: Some(42),
}),
signers: vec![read_keypair_file(&keypair_file).unwrap().into()],
@ -1997,7 +1928,6 @@ mod tests {
buffer_signer_index: Some(1),
buffer_pubkey: Some(buffer_keypair.pubkey()),
buffer_authority_signer_index: Some(0),
is_final: false,
max_len: None,
}),
signers: vec![
@ -2027,7 +1957,6 @@ mod tests {
buffer_signer_index: None,
buffer_pubkey: None,
buffer_authority_signer_index: Some(1),
is_final: false,
max_len: None,
}),
signers: vec![
@ -2062,7 +1991,6 @@ mod tests {
buffer_signer_index: Some(1),
buffer_pubkey: Some(buffer_keypair.pubkey()),
buffer_authority_signer_index: Some(2),
is_final: false,
max_len: None,
}),
signers: vec![
@ -2072,60 +2000,6 @@ mod tests {
],
}
);
// specify authority
let test_deploy = test_commands.clone().get_matches_from(vec![
"test",
"program",
"write-buffer",
"/Users/test/program.so",
"--final",
]);
assert_eq!(
parse_command(&test_deploy, &default_signer, &mut None).unwrap(),
CliCommandInfo {
command: CliCommand::Program(ProgramCliCommand::WriteBuffer {
program_location: "/Users/test/program.so".to_string(),
buffer_signer_index: None,
buffer_pubkey: None,
buffer_authority_signer_index: Some(0),
is_final: true,
max_len: None,
}),
signers: vec![read_keypair_file(&keypair_file).unwrap().into()],
}
);
// specify both buffer and authority and final
let authority_keypair = Keypair::new();
let authority_keypair_file = make_tmp_path("authority_keypair_file");
write_keypair_file(&authority_keypair, &authority_keypair_file).unwrap();
let test_deploy = test_commands.clone().get_matches_from(vec![
"test",
"program",
"write-buffer",
"/Users/test/program.so",
"--buffer-authority",
&authority_keypair_file,
"--final",
]);
assert_eq!(
parse_command(&test_deploy, &default_signer, &mut None).unwrap(),
CliCommandInfo {
command: CliCommand::Program(ProgramCliCommand::WriteBuffer {
program_location: "/Users/test/program.so".to_string(),
buffer_signer_index: None,
buffer_pubkey: None,
buffer_authority_signer_index: Some(1),
is_final: true,
max_len: None,
}),
signers: vec![
read_keypair_file(&keypair_file).unwrap().into(),
read_keypair_file(&authority_keypair_file).unwrap().into(),
],
}
);
}
#[test]
@ -2271,7 +2145,7 @@ mod tests {
command: CliCommand::Program(ProgramCliCommand::SetBufferAuthority {
buffer_pubkey,
buffer_authority_index: Some(0),
new_buffer_authority: Some(new_authority_pubkey),
new_buffer_authority: new_authority_pubkey,
}),
signers: vec![read_keypair_file(&keypair_file).unwrap().into()],
}
@ -2295,65 +2169,11 @@ mod tests {
command: CliCommand::Program(ProgramCliCommand::SetBufferAuthority {
buffer_pubkey,
buffer_authority_index: Some(0),
new_buffer_authority: Some(new_authority_pubkey.pubkey()),
new_buffer_authority: new_authority_pubkey.pubkey(),
}),
signers: vec![read_keypair_file(&keypair_file).unwrap().into()],
}
);
let buffer_pubkey = Pubkey::new_unique();
let new_authority_pubkey = Keypair::new();
let new_authority_pubkey_file = make_tmp_path("authority_keypair_file");
write_keypair_file(&new_authority_pubkey, &new_authority_pubkey_file).unwrap();
let test_deploy = test_commands.clone().get_matches_from(vec![
"test",
"program",
"set-buffer-authority",
&buffer_pubkey.to_string(),
"--final",
]);
assert_eq!(
parse_command(&test_deploy, &default_signer, &mut None).unwrap(),
CliCommandInfo {
command: CliCommand::Program(ProgramCliCommand::SetBufferAuthority {
buffer_pubkey,
buffer_authority_index: Some(0),
new_buffer_authority: None,
}),
signers: vec![read_keypair_file(&keypair_file).unwrap().into()],
}
);
let buffer_pubkey = Pubkey::new_unique();
let authority = Keypair::new();
let authority_keypair_file = make_tmp_path("authority_keypair_file");
write_keypair_file(&authority, &authority_keypair_file).unwrap();
let new_authority_pubkey = Keypair::new();
let new_authority_pubkey_file = make_tmp_path("authority_keypair_file");
write_keypair_file(&new_authority_pubkey, &new_authority_pubkey_file).unwrap();
let test_deploy = test_commands.clone().get_matches_from(vec![
"test",
"program",
"set-buffer-authority",
&buffer_pubkey.to_string(),
"--buffer-authority",
&authority_keypair_file,
"--final",
]);
assert_eq!(
parse_command(&test_deploy, &default_signer, &mut None).unwrap(),
CliCommandInfo {
command: CliCommand::Program(ProgramCliCommand::SetBufferAuthority {
buffer_pubkey,
buffer_authority_index: Some(1),
new_buffer_authority: None,
}),
signers: vec![
read_keypair_file(&keypair_file).unwrap().into(),
read_keypair_file(&authority_keypair_file).unwrap().into(),
],
}
);
}
#[test]
@ -2415,8 +2235,7 @@ mod tests {
buffer_pubkey: None,
program_signer_index: None,
program_pubkey: None,
upgrade_authority_signer_index: None,
upgrade_authority_pubkey: Some(default_keypair.pubkey()),
upgrade_authority_signer_index: 0,
is_final: false,
max_len: None,
allow_excessive_balance: false,

View File

@ -177,8 +177,8 @@ fn test_cli_program_deploy_no_authority() {
config.signers = vec![&keypair];
process_command(&config).unwrap();
// Deploy a program with no authority
config.signers = vec![&keypair];
// Deploy a program
config.signers = vec![&keypair, &upgrade_authority];
config.command = CliCommand::Program(ProgramCliCommand::Deploy {
program_location: Some(pathbuf.to_str().unwrap().to_string()),
program_signer_index: None,
@ -186,9 +186,8 @@ fn test_cli_program_deploy_no_authority() {
buffer_signer_index: None,
buffer_pubkey: None,
allow_excessive_balance: false,
upgrade_authority_signer_index: None,
upgrade_authority_pubkey: None,
is_final: false,
upgrade_authority_signer_index: 1,
is_final: true,
max_len: None,
});
let response = process_command(&config);
@ -211,8 +210,7 @@ fn test_cli_program_deploy_no_authority() {
buffer_signer_index: None,
buffer_pubkey: None,
allow_excessive_balance: false,
upgrade_authority_signer_index: Some(1),
upgrade_authority_pubkey: Some(upgrade_authority.pubkey()),
upgrade_authority_signer_index: 1,
is_final: false,
max_len: None,
});
@ -272,8 +270,7 @@ fn test_cli_program_deploy_with_authority() {
buffer_signer_index: None,
buffer_pubkey: None,
allow_excessive_balance: false,
upgrade_authority_signer_index: Some(1),
upgrade_authority_pubkey: Some(upgrade_authority.pubkey()),
upgrade_authority_signer_index: 1,
is_final: false,
max_len: Some(max_len),
});
@ -319,8 +316,7 @@ fn test_cli_program_deploy_with_authority() {
buffer_signer_index: None,
buffer_pubkey: None,
allow_excessive_balance: false,
upgrade_authority_signer_index: Some(1),
upgrade_authority_pubkey: Some(upgrade_authority.pubkey()),
upgrade_authority_signer_index: 1,
is_final: false,
max_len: Some(max_len),
});
@ -361,8 +357,7 @@ fn test_cli_program_deploy_with_authority() {
buffer_signer_index: None,
buffer_pubkey: None,
allow_excessive_balance: false,
upgrade_authority_signer_index: Some(1),
upgrade_authority_pubkey: Some(upgrade_authority.pubkey()),
upgrade_authority_signer_index: 1,
is_final: false,
max_len: Some(max_len),
});
@ -416,8 +411,7 @@ fn test_cli_program_deploy_with_authority() {
buffer_signer_index: None,
buffer_pubkey: None,
allow_excessive_balance: false,
upgrade_authority_signer_index: Some(1),
upgrade_authority_pubkey: Some(new_upgrade_authority.pubkey()),
upgrade_authority_signer_index: 1,
is_final: false,
max_len: None,
});
@ -486,8 +480,7 @@ fn test_cli_program_deploy_with_authority() {
buffer_signer_index: None,
buffer_pubkey: None,
allow_excessive_balance: false,
upgrade_authority_signer_index: Some(1),
upgrade_authority_pubkey: Some(new_upgrade_authority.pubkey()),
upgrade_authority_signer_index: 1,
is_final: false,
max_len: None,
});
@ -502,8 +495,7 @@ fn test_cli_program_deploy_with_authority() {
buffer_signer_index: None,
buffer_pubkey: None,
allow_excessive_balance: false,
upgrade_authority_signer_index: Some(1),
upgrade_authority_pubkey: Some(new_upgrade_authority.pubkey()),
upgrade_authority_signer_index: 1,
is_final: true,
max_len: None,
});
@ -598,7 +590,6 @@ fn test_cli_program_write_buffer() {
buffer_signer_index: None,
buffer_pubkey: None,
buffer_authority_signer_index: None,
is_final: false,
max_len: None,
});
let response = process_command(&config);
@ -632,7 +623,6 @@ fn test_cli_program_write_buffer() {
buffer_signer_index: Some(1),
buffer_pubkey: Some(buffer_keypair.pubkey()),
buffer_authority_signer_index: None,
is_final: false,
max_len: Some(max_len),
});
let response = process_command(&config);
@ -689,7 +679,6 @@ fn test_cli_program_write_buffer() {
buffer_signer_index: Some(1),
buffer_pubkey: Some(buffer_keypair.pubkey()),
buffer_authority_signer_index: Some(2),
is_final: false,
max_len: None,
});
let response = process_command(&config);
@ -727,7 +716,6 @@ fn test_cli_program_write_buffer() {
buffer_signer_index: None,
buffer_pubkey: None,
buffer_authority_signer_index: Some(2),
is_final: false,
max_len: None,
});
let response = process_command(&config);
@ -753,35 +741,6 @@ fn test_cli_program_write_buffer() {
program_data[..]
);
// Specify final
let buffer_keypair = Keypair::new();
let authority_keypair = Keypair::new();
config.signers = vec![&keypair, &buffer_keypair, &authority_keypair];
config.command = CliCommand::Program(ProgramCliCommand::WriteBuffer {
program_location: pathbuf.to_str().unwrap().to_string(),
buffer_signer_index: None,
buffer_pubkey: None,
buffer_authority_signer_index: Some(2),
is_final: true,
max_len: None,
});
let response = process_command(&config);
let json: Value = serde_json::from_str(&response.unwrap()).unwrap();
let buffer_pubkey_str = json
.as_object()
.unwrap()
.get("Buffer")
.unwrap()
.as_str()
.unwrap();
let buffer_pubkey = Pubkey::from_str(&buffer_pubkey_str).unwrap();
let buffer_account = rpc_client.get_account(&buffer_pubkey).unwrap();
if let UpgradeableLoaderState::Buffer { authority_address } = buffer_account.state().unwrap() {
assert_eq!(authority_address, None);
} else {
panic!("not a buffer account");
}
// Get buffer authority
config.signers = vec![&keypair];
config.command = CliCommand::Program(ProgramCliCommand::GetAuthority {
@ -796,7 +755,10 @@ fn test_cli_program_write_buffer() {
.unwrap()
.as_str()
.unwrap();
assert_eq!("None", authority_pubkey_str);
assert_eq!(
authority_keypair.pubkey(),
Pubkey::from_str(&authority_pubkey_str).unwrap()
);
}
#[test]
@ -846,7 +808,6 @@ fn test_cli_program_set_buffer_authority() {
buffer_signer_index: Some(1),
buffer_pubkey: Some(buffer_keypair.pubkey()),
buffer_authority_signer_index: None,
is_final: false,
max_len: None,
});
process_command(&config).unwrap();
@ -863,7 +824,7 @@ fn test_cli_program_set_buffer_authority() {
config.command = CliCommand::Program(ProgramCliCommand::SetBufferAuthority {
buffer_pubkey: buffer_keypair.pubkey(),
buffer_authority_index: Some(0),
new_buffer_authority: Some(new_buffer_authority.pubkey()),
new_buffer_authority: new_buffer_authority.pubkey(),
});
let response = process_command(&config);
let json: Value = serde_json::from_str(&response.unwrap()).unwrap();
@ -890,7 +851,7 @@ fn test_cli_program_set_buffer_authority() {
config.command = CliCommand::Program(ProgramCliCommand::SetBufferAuthority {
buffer_pubkey: buffer_keypair.pubkey(),
buffer_authority_index: Some(1),
new_buffer_authority: Some(buffer_keypair.pubkey()),
new_buffer_authority: buffer_keypair.pubkey(),
});
let response = process_command(&config);
let json: Value = serde_json::from_str(&response.unwrap()).unwrap();
@ -911,28 +872,94 @@ fn test_cli_program_set_buffer_authority() {
} else {
panic!("not a buffer account");
}
}
// Set authority to None
config.signers = vec![&keypair, &buffer_keypair];
config.command = CliCommand::Program(ProgramCliCommand::SetBufferAuthority {
buffer_pubkey: buffer_keypair.pubkey(),
buffer_authority_index: Some(1),
new_buffer_authority: None,
});
let response = process_command(&config);
let json: Value = serde_json::from_str(&response.unwrap()).unwrap();
let buffer_authority_str = json
.as_object()
.unwrap()
.get("Authority")
.unwrap()
.as_str()
#[test]
fn test_cli_program_mismatch_buffer_authority() {
solana_logger::setup();
let mut pathbuf = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
pathbuf.push("tests");
pathbuf.push("fixtures");
pathbuf.push("noop");
pathbuf.set_extension("so");
let mint_keypair = Keypair::new();
let test_validator = TestValidator::with_no_fees(mint_keypair.pubkey());
let faucet_addr = run_local_faucet(mint_keypair, None);
let rpc_client =
RpcClient::new_with_commitment(test_validator.rpc_url(), CommitmentConfig::processed());
let mut file = File::open(pathbuf.to_str().unwrap()).unwrap();
let mut program_data = Vec::new();
file.read_to_end(&mut program_data).unwrap();
let max_len = program_data.len();
let minimum_balance_for_buffer = rpc_client
.get_minimum_balance_for_rent_exemption(
UpgradeableLoaderState::programdata_len(max_len).unwrap(),
)
.unwrap();
assert_eq!(buffer_authority_str, "None");
let mut config = CliConfig::recent_for_tests();
let keypair = Keypair::new();
config.json_rpc_url = test_validator.rpc_url();
config.signers = vec![&keypair];
config.command = CliCommand::Airdrop {
faucet_host: None,
faucet_port: faucet_addr.port(),
pubkey: None,
lamports: 100 * minimum_balance_for_buffer,
};
process_command(&config).unwrap();
// Write a buffer
let buffer_authority = Keypair::new();
let buffer_keypair = Keypair::new();
config.signers = vec![&keypair, &buffer_keypair, &buffer_authority];
config.command = CliCommand::Program(ProgramCliCommand::WriteBuffer {
program_location: pathbuf.to_str().unwrap().to_string(),
buffer_signer_index: Some(1),
buffer_pubkey: Some(buffer_keypair.pubkey()),
buffer_authority_signer_index: Some(2),
max_len: None,
});
process_command(&config).unwrap();
let buffer_account = rpc_client.get_account(&buffer_keypair.pubkey()).unwrap();
if let UpgradeableLoaderState::Buffer { authority_address } = buffer_account.state().unwrap() {
assert_eq!(authority_address, None);
assert_eq!(authority_address, Some(buffer_authority.pubkey()));
} else {
panic!("not a buffer account");
}
// Attempt to deploy with mismatched authority
let upgrade_authority = Keypair::new();
config.signers = vec![&keypair, &upgrade_authority];
config.command = CliCommand::Program(ProgramCliCommand::Deploy {
program_location: Some(pathbuf.to_str().unwrap().to_string()),
program_signer_index: None,
program_pubkey: None,
buffer_signer_index: None,
buffer_pubkey: Some(buffer_keypair.pubkey()),
allow_excessive_balance: false,
upgrade_authority_signer_index: 1,
is_final: true,
max_len: None,
});
process_command(&config).unwrap_err();
// Attempt to deploy matched authority
config.signers = vec![&keypair, &buffer_authority];
config.command = CliCommand::Program(ProgramCliCommand::Deploy {
program_location: Some(pathbuf.to_str().unwrap().to_string()),
program_signer_index: None,
program_pubkey: None,
buffer_signer_index: None,
buffer_pubkey: Some(buffer_keypair.pubkey()),
allow_excessive_balance: false,
upgrade_authority_signer_index: 1,
is_final: true,
max_len: None,
});
process_command(&config).unwrap();
}