(
target_canister: Principal,
install_mode: CanisterInstallMode,
module: Vec<u8>,
module_extra_chunks: Option<WasmModuleExtraChunks>,
arg: Vec<u8>,
)
| 125 | } |
| 126 | |
| 127 | pub async fn install_chunked_code( |
| 128 | target_canister: Principal, |
| 129 | install_mode: CanisterInstallMode, |
| 130 | module: Vec<u8>, |
| 131 | module_extra_chunks: Option<WasmModuleExtraChunks>, |
| 132 | arg: Vec<u8>, |
| 133 | ) -> Result<(), String> { |
| 134 | if let Some(module_extra_chunks) = module_extra_chunks { |
| 135 | // clear the ICP chunk store of the target canister |
| 136 | // to delete left-over chunks in case of a failure |
| 137 | // during a past code install |
| 138 | mgmt::clear_chunk_store(ClearChunkStoreArgument { |
| 139 | canister_id: target_canister, |
| 140 | }) |
| 141 | .await |
| 142 | .map_err(|(_, err)| format!("failed to clear chunk store: {err}"))?; |
| 143 | // upload the provided module as the first chunk |
| 144 | // to the ICP chunk store of the target canister |
| 145 | let module_hash = upload_chunk(target_canister, module).await?; |
| 146 | // fetch extra chunks from the asset canister |
| 147 | let extra_chunks = fetch_extra_chunks( |
| 148 | module_extra_chunks.store_canister, |
| 149 | module_extra_chunks.extra_chunks_key, |
| 150 | ) |
| 151 | .await?; |
| 152 | // upload extra chunks to the ICP chunk store of the target canister |
| 153 | let mut chunk_hashes_list = vec![module_hash]; |
| 154 | let chunks = extra_chunks.chunks(MAX_WASM_CHUNK_LEN); |
| 155 | for chunk in chunks { |
| 156 | let chunk_hash = upload_chunk(target_canister, chunk.to_vec()).await?; |
| 157 | chunk_hashes_list.push(chunk_hash); |
| 158 | } |
| 159 | // install target canister from chunks stored in the ICP chunk store of the target canister |
| 160 | let res = mgmt::install_chunked_code(InstallChunkedCodeArgument { |
| 161 | mode: install_mode, |
| 162 | target_canister, |
| 163 | store_canister: Some(target_canister), |
| 164 | chunk_hashes_list: chunk_hashes_list |
| 165 | .into_iter() |
| 166 | .map(|hash| ChunkHash { hash }) |
| 167 | .collect(), |
| 168 | wasm_module_hash: module_extra_chunks.wasm_module_hash, |
| 169 | arg, |
| 170 | }) |
| 171 | .await |
| 172 | .map_err(|(_, err)| format!("failed to install code from chunks: {err}")); |
| 173 | // clear the ICP chunk store of the target canister to reduce memory footprint |
| 174 | // and ignore any errors here so that a successful code install is not reported |
| 175 | // as failed only because of a failure to clear the ICP chunk store |
| 176 | let _ = mgmt::clear_chunk_store(ClearChunkStoreArgument { |
| 177 | canister_id: target_canister, |
| 178 | }) |
| 179 | .await; |
| 180 | res |
| 181 | } else { |
| 182 | mgmt::install_code(InstallCodeArgument { |
| 183 | mode: install_mode, |
| 184 | canister_id: target_canister, |
no test coverage detected