From 1c4ac56e56dc940276e5b6fc21b26a4c6aa60b11 Mon Sep 17 00:00:00 2001 From: kirill lykov Date: Fri, 21 Oct 2022 09:29:37 +0200 Subject: [PATCH] Remove immutable deploy (#28399) * remove Deploy option from cli * remove solana deploy from comments * introduce dummy deploy command to improve user experience --- cli/src/cli.rs | 158 ++-------------------- cli/src/program.rs | 84 +----------- sdk/program/src/bpf_loader.rs | 2 +- sdk/program/src/bpf_loader_upgradeable.rs | 2 +- 4 files changed, 15 insertions(+), 231 deletions(-) diff --git a/cli/src/cli.rs b/cli/src/cli.rs index 8a2600a981..d681308369 100644 --- a/cli/src/cli.rs +++ b/cli/src/cli.rs @@ -167,13 +167,7 @@ pub enum CliCommand { compute_unit_price: Option, }, // Program Deployment - Deploy { - program_location: String, - address: Option, - use_deprecated_loader: bool, - allow_excessive_balance: bool, - skip_fee_check: bool, - }, + Deploy, Program(ProgramCliCommand), // Stake Commands CreateStakeAccount { @@ -679,26 +673,11 @@ pub fn parse_command( } ("upgrade-nonce-account", Some(matches)) => parse_upgrade_nonce_account(matches), // Program Deployment - ("deploy", Some(matches)) => { - let (address_signer, _address) = signer_of(matches, "address_signer", wallet_manager)?; - let mut signers = vec![default_signer.signer_from_path(matches, wallet_manager)?]; - let address = address_signer.map(|signer| { - signers.push(signer); - 1 - }); - let skip_fee_check = matches.is_present("skip_fee_check"); - - Ok(CliCommandInfo { - command: CliCommand::Deploy { - program_location: matches.value_of("program_location").unwrap().to_string(), - address, - use_deprecated_loader: matches.is_present("use_deprecated_loader"), - allow_excessive_balance: matches.is_present("allow_excessive_balance"), - skip_fee_check, - }, - signers, - }) - } + ("deploy", Some(_matches)) => clap::Error::with_description( + "`solana deploy` has been replaced with `solana program deploy`", + clap::ErrorKind::UnrecognizedSubcommand, + ) + .exit(), ("program", Some(matches)) => { parse_program_subcommand(matches, default_signer, wallet_manager) } @@ -1101,23 +1080,13 @@ pub fn process_command(config: &CliConfig) -> ProcessResult { ), // Program Deployment + CliCommand::Deploy => { + // This command is not supported any longer + // Error message is printed on the previous stage + std::process::exit(1); + } // Deploy a custom program to the chain - CliCommand::Deploy { - program_location, - address, - use_deprecated_loader, - allow_excessive_balance, - skip_fee_check, - } => process_deploy( - rpc_client, - config, - program_location, - *address, - *use_deprecated_loader, - *allow_excessive_balance, - *skip_fee_check, - ), CliCommand::Program(program_subcommand) => { process_program_subcommand(rpc_client, config, program_subcommand) } @@ -1736,7 +1705,7 @@ where mod tests { use { super::*, - serde_json::{json, Value}, + serde_json::json, solana_rpc_client::mock_sender_for_cli::SIGNATURE, solana_rpc_client_api::{ request::RpcRequest, @@ -1752,7 +1721,6 @@ mod tests { transaction::TransactionError, }, solana_transaction_status::TransactionConfirmationStatus, - std::path::PathBuf, }; fn make_tmp_path(name: &str) -> String { @@ -1984,51 +1952,6 @@ mod tests { } ); - // Test Deploy Subcommand - let test_command = - test_commands - .clone() - .get_matches_from(vec!["test", "deploy", "/Users/test/program.o"]); - assert_eq!( - parse_command(&test_command, &default_signer, &mut None).unwrap(), - CliCommandInfo { - command: CliCommand::Deploy { - program_location: "/Users/test/program.o".to_string(), - address: None, - use_deprecated_loader: false, - allow_excessive_balance: false, - skip_fee_check: false, - }, - signers: vec![read_keypair_file(&keypair_file).unwrap().into()], - } - ); - - let custom_address = Keypair::new(); - let custom_address_file = make_tmp_path("custom_address_file"); - write_keypair_file(&custom_address, &custom_address_file).unwrap(); - let test_command = test_commands.clone().get_matches_from(vec![ - "test", - "deploy", - "/Users/test/program.o", - &custom_address_file, - ]); - assert_eq!( - parse_command(&test_command, &default_signer, &mut None).unwrap(), - CliCommandInfo { - command: CliCommand::Deploy { - program_location: "/Users/test/program.o".to_string(), - address: Some(1), - use_deprecated_loader: false, - allow_excessive_balance: false, - skip_fee_check: false, - }, - signers: vec![ - read_keypair_file(&keypair_file).unwrap().into(), - read_keypair_file(&custom_address_file).unwrap().into(), - ], - } - ); - // Test ResolveSigner Subcommand, SignerSource::Filepath let test_resolve_signer = test_commands @@ -2455,63 +2378,6 @@ mod tests { assert!(result.is_ok()); } - #[test] - fn test_cli_deploy() { - 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"); - - // Success case - let mut config = CliConfig::default(); - let account_info_response = json!(Response { - context: RpcResponseContext { - slot: 1, - api_version: None - }, - value: Value::Null, - }); - let mut mocks = HashMap::new(); - mocks.insert(RpcRequest::GetAccountInfo, account_info_response); - let rpc_client = RpcClient::new_mock_with_mocks("".to_string(), mocks); - - config.rpc_client = Some(Arc::new(rpc_client)); - let default_keypair = Keypair::new(); - config.signers = vec![&default_keypair]; - - config.command = CliCommand::Deploy { - program_location: pathbuf.to_str().unwrap().to_string(), - address: None, - use_deprecated_loader: false, - allow_excessive_balance: false, - skip_fee_check: false, - }; - config.output_format = OutputFormat::JsonCompact; - let result = process_command(&config); - let json: Value = serde_json::from_str(&result.unwrap()).unwrap(); - let program_id = json - .as_object() - .unwrap() - .get("programId") - .unwrap() - .as_str() - .unwrap(); - - assert!(program_id.parse::().is_ok()); - - // Failure case - config.command = CliCommand::Deploy { - program_location: "bad/file/location.so".to_string(), - address: None, - use_deprecated_loader: false, - allow_excessive_balance: false, - skip_fee_check: false, - }; - assert!(process_command(&config).is_err()); - } - #[test] fn test_parse_transfer_subcommand() { let test_commands = get_clap_app("test", "desc", "version"); diff --git a/cli/src/program.rs b/cli/src/program.rs index baf189372f..19876bdf96 100644 --- a/cli/src/program.rs +++ b/cli/src/program.rs @@ -405,43 +405,8 @@ impl ProgramSubCommands for App<'_, '_> { ) .subcommand( SubCommand::with_name("deploy") - .about("Deploy a non-upgradeable program. Use `solana program deploy` instead to deploy upgradeable programs") + .about("Deploy has been removed. Use `solana program deploy` instead to deploy upgradeable programs") .setting(AppSettings::Hidden) - .arg( - Arg::with_name("program_location") - .index(1) - .value_name("PROGRAM_FILEPATH") - .takes_value(true) - .required(true) - .help("/path/to/program.o"), - ) - .arg( - Arg::with_name("address_signer") - .index(2) - .value_name("PROGRAM_ADDRESS_SIGNER") - .takes_value(true) - .validator(is_valid_signer) - .help("The signer for the desired address of the program [default: new random address]") - ) - .arg( - Arg::with_name("use_deprecated_loader") - .long("use-deprecated-loader") - .takes_value(false) - .hidden(true) // Don't document this argument to discourage its use - .help("Use the deprecated BPF loader") - ) - .arg( - Arg::with_name("allow_excessive_balance") - .long("allow-excessive-deploy-account-balance") - .takes_value(false) - .help("Use the designated program id, even if the account already holds a large balance of SOL") - ) - .arg( - Arg::with_name("skip_fee_check") - .long("skip-fee-check") - .hidden(true) - .takes_value(false) - ), ) } } @@ -1695,53 +1660,6 @@ fn process_close( } } -/// Deploy using non-upgradeable loader -pub fn process_deploy( - rpc_client: Arc, - config: &CliConfig, - program_location: &str, - buffer_signer_index: Option, - use_deprecated_loader: bool, - allow_excessive_balance: bool, - skip_fee_check: bool, -) -> ProcessResult { - // Create ephemeral keypair to use for Buffer account, if not provided - let (words, mnemonic, buffer_keypair) = create_ephemeral_keypair()?; - let buffer_signer = if let Some(i) = buffer_signer_index { - config.signers[i] - } else { - &buffer_keypair - }; - - let program_data = read_and_verify_elf(program_location)?; - let minimum_balance = rpc_client.get_minimum_balance_for_rent_exemption(program_data.len())?; - let loader_id = if use_deprecated_loader { - bpf_loader_deprecated::id() - } else { - bpf_loader::id() - }; - - let result = do_process_program_write_and_deploy( - rpc_client, - config, - &program_data, - program_data.len(), - program_data.len(), - minimum_balance, - &loader_id, - Some(&[buffer_signer]), - Some(buffer_signer), - &buffer_signer.pubkey(), - Some(buffer_signer), - allow_excessive_balance, - skip_fee_check, - ); - if result.is_err() && buffer_signer_index.is_none() { - report_ephemeral_mnemonic(words, mnemonic); - } - result -} - fn calculate_max_chunk_size(create_msg: &F) -> usize where F: Fn(u32, Vec) -> Message, diff --git a/sdk/program/src/bpf_loader.rs b/sdk/program/src/bpf_loader.rs index 9613c64d21..fdfe14780f 100644 --- a/sdk/program/src/bpf_loader.rs +++ b/sdk/program/src/bpf_loader.rs @@ -14,7 +14,7 @@ //! version. An example is [`bpf_loader_deprecated`] which requires //! [`entrypoint_deprecated`]. //! -//! The `solana deploy` and `solana program deploy` CLI commands use the +//! The `solana program deploy` CLI command uses the //! [upgradeable BPF loader][ubpfl]. //! //! [`bpf_loader_deprecated`]: crate::bpf_loader_deprecated diff --git a/sdk/program/src/bpf_loader_upgradeable.rs b/sdk/program/src/bpf_loader_upgradeable.rs index a2d2aa4911..40b96583ac 100644 --- a/sdk/program/src/bpf_loader_upgradeable.rs +++ b/sdk/program/src/bpf_loader_upgradeable.rs @@ -8,7 +8,7 @@ //! upgradeable programs which still have a functioning authority. For more //! information refer to the [`loader_upgradeable_instruction`] module. //! -//! The `solana deploy` and `solana program deploy` CLI commands use the +//! The `solana program deploy` CLI command uses the //! upgradeable BPF loader. Calling `solana program deploy --final` deploys a //! program that cannot be upgraded, but it does so by revoking the authority to //! upgrade, not by using the non-upgradeable loader.