Safety of Motoko stable variables in upgrades

As we know, upgrades can fail if we hit the cycle limit in the pre_upgrade or post_upgrade hooks. Does anyone have an example where this happens with stable variable declarations alone? What I mean is a Motoko canister with stable let or stable var declarations but no pre_upgrade or post_upgrade function defined in the source code.

I can make an upgrade fail with stable vars if their size is too large. If their size reaches close to 2 GB then there isn’t enough space to serialize them pre upgrade. That will make the upgrade fail regardless of cycles. I can also make an upgrade fail by defining an expensive pre_upgrade function that exceeds the cycle limit. That will make an upgrade fail regardless of memory. I am looking for an example where the upgrade fails with the cycle limit, not due to memory. But I want it to fail due to stable variable declaration alone, not due to having an expensive explicit pre_upgrade function. Is that possible? Can the serialization/deserialization be made so expensive that it exceeds the cycle limit?

2 Likes

Have you tried something along the lines of

let large_array: Vec<MyStruct> = vec![MyStruct::new(...); 10000];

where MyStruct is defined as:

struct MyStruct {
    x: u64,
    y: u64,
    name: String, // 10 characters average
    data: Vec<u8>, // 100 bytes average
}

to make it complex to (de)serialise but still keep it under 2MB? Or something similar with more nested layers.

Just a thought.

I have tried a 2-dimensional array of small primitive type (Nat32). That creates the highest number of memory accesses. I don’t see why records or nesting levels would increase the amount of cycles needed. Larger value types like Blob should also be cheaper to serialize than multiple accesses to smaller types. I can experiment, but maybe someone already knows the answer.

1 Like

I came back sort of worried about a 2MB variable limit thinking “that’s not many user records”. Glad to see it was always 2GB.

I’d be curious to know the answer to your question if it pops up.