Pocket IC CanisterInstallCodeRateLimited

I’m using pocket-ic for integration testing of my Rust canister and ran into the following problem.

I want to install canister code and directly after upgrade the canister code. So basically I’m doing the following

let pic = PocketIc:new()
let can_id = pic.create_canister();
pic.add_cycles(can_id, 2_000_000_000_000);
let wasm = load_wasm(); // fetches my wasm
pic.install_canister(can_id, wasm.clone(), encode_one(()).unwrap(), None)
// works until here
pic.upgrade_canister(can_id, wasm, encode_one(()).unwrap(), None)
// fails here

The pic.upgrade_canister(...) step fails with the error

Err(UserError(UserError { code: CanisterInstallCodeRateLimited, description: "Canister lxzze-o7777-77777-aaaaa-cai is rate limited because it executed too many instructions in the previous install_code messages. Please retry installation after several minutes." })).

How can I fix this? Is this the correct approach to install a canister and upgrade it directly afterwards?

@dsharifi @mraszyk @berestovskyy (tagging you as I saw you committed to the pocket-ic repo)

Was able to solve it by letting ic-pocket process one block by adding pic.tick() in between install and upgrade. Works for me but would still like to understand what the underlying problem is.

The reason why you need to tick in between is that all install code messages on a subnet are executed on a single thread and thus the IC prevents a single canister from using that single thread all the time by rate-limiting instruction-heavy install code messages.

Why do you want to upgrade right after installing? To test if the canister doesn’t trap in upgrade hooks?

2 Likes

Thanks for that info!
Yeah, we were testing a call during the post_upgrade hook.