fetches extra chunks from an asset canister
(
store_canister: Principal,
extra_chunks_key: String,
)
| 49 | |
| 50 | // fetches extra chunks from an asset canister |
| 51 | async fn fetch_extra_chunks( |
| 52 | store_canister: Principal, |
| 53 | extra_chunks_key: String, |
| 54 | ) -> Result<Vec<u8>, String> { |
| 55 | let asset = call::<_, (EncodedAsset,)>( |
| 56 | store_canister, |
| 57 | "get", |
| 58 | (GetArg { |
| 59 | key: extra_chunks_key.clone(), |
| 60 | accept_encodings: vec!["identity".to_string()], |
| 61 | },), |
| 62 | ) |
| 63 | .await |
| 64 | .map_err(|(_, err)| format!("failed to fetch asset: {err}"))? |
| 65 | .0; |
| 66 | let max_wasm_total_len: candid::Nat = MAX_WASM_TOTAL_LEN.into(); |
| 67 | if asset.total_length > max_wasm_total_len { |
| 68 | return Err(format!( |
| 69 | "Wasm extra chunks length {} exceeds the maximum wasm length {}", |
| 70 | asset.total_length, max_wasm_total_len, |
| 71 | )); |
| 72 | } |
| 73 | let mut res = asset.content; |
| 74 | let mut idx = 1; |
| 75 | while res.len() < asset.total_length && idx < MAX_WASM_CHUNK_CNT { |
| 76 | let mut chunk = call::<_, (GetChunkResponse,)>( |
| 77 | store_canister, |
| 78 | "get_chunk", |
| 79 | (GetChunkArg { |
| 80 | key: extra_chunks_key.clone(), |
| 81 | content_encoding: "identity".to_string(), |
| 82 | index: idx.into(), |
| 83 | sha256: asset.sha256.clone(), |
| 84 | },), |
| 85 | ) |
| 86 | .await |
| 87 | .map_err(|(_, err)| format!("failed to fetch chunk: {err}"))? |
| 88 | .0; |
| 89 | res.append(&mut chunk.content); |
| 90 | idx += 1; |
| 91 | } |
| 92 | let res_len: candid::Nat = res.len().into(); |
| 93 | match res_len.cmp(&asset.total_length) { |
| 94 | std::cmp::Ordering::Less => Err(format!( |
| 95 | "The total number of wasm chunks must not exceed {MAX_WASM_CHUNK_CNT}" |
| 96 | )), |
| 97 | std::cmp::Ordering::Equal => Ok(res), |
| 98 | std::cmp::Ordering::Greater => Err(format!( |
| 99 | "Wasm extra chunks length (at least {}) exceeds their total length claimed by the store canister ({})", |
| 100 | res_len, asset.total_length |
| 101 | )), |
| 102 | } |
| 103 | } |
| 104 | |
| 105 | // uploads a wasm chunk to the ICP chunk store |
| 106 | async fn upload_chunk(target_canister: Principal, chunk: Vec<u8>) -> Result<Vec<u8>, String> { |
no test coverage detected