diff --git a/cli/src/program.rs b/cli/src/program.rs index f4f31b72d0e83f..4ee392f8cb9805 100644 --- a/cli/src/program.rs +++ b/cli/src/program.rs @@ -2151,11 +2151,12 @@ fn do_process_program_write_and_deploy( let blockhash = rpc_client.get_latest_blockhash()?; // Initialize buffer account or complete if already partially initialized - let (initial_instructions, balance_needed) = if let Some(account) = rpc_client - .get_account_with_commitment(buffer_pubkey, config.commitment)? - .value + let (initial_instructions, balance_needed, buffer_program_data) = if let Some(mut account) = + rpc_client + .get_account_with_commitment(buffer_pubkey, config.commitment)? + .value { - complete_partial_program_init( + let (ixs, balance_needed) = complete_partial_program_init( loader_id, &fee_payer_signer.pubkey(), buffer_pubkey, @@ -2167,7 +2168,11 @@ fn do_process_program_write_and_deploy( }, min_rent_exempt_program_data_balance, allow_excessive_balance, - )? + )?; + let buffer_program_data = account + .data + .split_off(UpgradeableLoaderState::size_of_buffer_metadata()); + (ixs, balance_needed, buffer_program_data) } else if loader_id == &bpf_loader_upgradeable::id() { ( bpf_loader_upgradeable::create_buffer( @@ -2178,6 +2183,7 @@ fn do_process_program_write_and_deploy( program_len, )?, min_rent_exempt_program_data_balance, + vec![0; program_len], ) } else { ( @@ -2189,6 +2195,7 @@ fn do_process_program_write_and_deploy( loader_id, )], min_rent_exempt_program_data_balance, + vec![0; program_len], ) }; let initial_message = if !initial_instructions.is_empty() { @@ -2219,7 +2226,10 @@ fn do_process_program_write_and_deploy( let mut write_messages = vec![]; let chunk_size = calculate_max_chunk_size(&create_msg); for (chunk, i) in program_data.chunks(chunk_size).zip(0..) { - write_messages.push(create_msg((i * chunk_size) as u32, chunk.to_vec())); + let offset = i * chunk_size; + if chunk != &buffer_program_data[offset..offset + chunk.len()] { + write_messages.push(create_msg(offset as u32, chunk.to_vec())); + } } // Create and add final message @@ -2307,31 +2317,37 @@ fn do_process_program_upgrade( let (initial_message, write_messages, balance_needed) = if let Some(buffer_signer) = buffer_signer { // Check Buffer account to see if partial initialization has occurred - let (initial_instructions, balance_needed) = if let Some(account) = rpc_client - .get_account_with_commitment(&buffer_signer.pubkey(), config.commitment)? - .value - { - complete_partial_program_init( - &bpf_loader_upgradeable::id(), - &fee_payer_signer.pubkey(), - &buffer_signer.pubkey(), - &account, - UpgradeableLoaderState::size_of_buffer(program_len), - min_rent_exempt_program_data_balance, - true, - )? - } else { - ( - bpf_loader_upgradeable::create_buffer( + let (initial_instructions, balance_needed, buffer_program_data) = + if let Some(mut account) = rpc_client + .get_account_with_commitment(&buffer_signer.pubkey(), config.commitment)? + .value + { + let (ixs, balance_needed) = complete_partial_program_init( + &bpf_loader_upgradeable::id(), &fee_payer_signer.pubkey(), - buffer_pubkey, - &upgrade_authority.pubkey(), + &buffer_signer.pubkey(), + &account, + UpgradeableLoaderState::size_of_buffer(program_len), min_rent_exempt_program_data_balance, - program_len, - )?, - min_rent_exempt_program_data_balance, - ) - }; + true, + )?; + let buffer_program_data = account + .data + .split_off(UpgradeableLoaderState::size_of_buffer_metadata()); + (ixs, balance_needed, buffer_program_data) + } else { + ( + bpf_loader_upgradeable::create_buffer( + &fee_payer_signer.pubkey(), + buffer_pubkey, + &upgrade_authority.pubkey(), + min_rent_exempt_program_data_balance, + program_len, + )?, + min_rent_exempt_program_data_balance, + vec![0; program_len], + ) + }; let initial_message = if !initial_instructions.is_empty() { Some(Message::new_with_blockhash( @@ -2363,7 +2379,10 @@ fn do_process_program_upgrade( let mut write_messages = vec![]; let chunk_size = calculate_max_chunk_size(&create_msg); for (chunk, i) in program_data.chunks(chunk_size).zip(0..) { - write_messages.push(create_msg((i * chunk_size) as u32, chunk.to_vec())); + let offset = i * chunk_size; + if chunk != &buffer_program_data[offset..offset + chunk.len()] { + write_messages.push(create_msg(offset as u32, chunk.to_vec())); + } } (initial_message, write_messages, balance_needed)