From a recent Canister source code auditing gig I extracted some general advice, which I am happy to share here with the community. If you are implementing Canisters beyond toy examples, this might be a useful list to go through:
This is incredibly helpful.
One question: when you mean reply/response handler to an inter-canister message, do you mean the code that happens after the
Also, I really hope canister upgrades are improved in the near future. I read somewhere in the forum that this is in the roadmap. Right now, it seems at best tedious and at worst quite dangerous.
Great insights! Two quick questions:
(in rust) There doesn’t seem to be a way to set a timeout when calling a canister. Are there any plans to support this in the future? Being able to handle long response times at source would be handy.
Regarding backups - I had this flow in mind: Have a canister state that goes from “live” to “maintenance”, and if it’s in maintenance drops every call in “inspect_message” except for a set of backup related calls. Would dropping any update calls in “inspect_message” guarantee that the state cannot change? How would one check if there are “in flight” calls still pending? Just wait some random amount of minutes before proceeding with backing up?
Exactly! Unfortunately, I expect serious developers won’t get around thinking of their code in the form that the compiler transforms it to, with explicit continuations. At least sometimes.
Inter-canister calls or external calls? For inter-canister calls you cannot. For external calls, your agent library has to poll for the response anyways, so there a timeout applies.
No, inspect message is only for ingress messages, and will not block inter-canister messages.
You should add this “maintenance mode” check to the beginning of each update method, then your plan is good.
I see. That’s an important distinction to make. Thanks.
Thanks for sharing that, great insights! (And a clear sign that the IC platform still has quite done way to go before it matches the vision…)
What is the destination for these backups?
Also, have you considered off chain backup where a cloud hosted cron scheduled worker takes incremental backups to a cloud hosted data store?
Asking because I’m contemplating these exact questions myself
Thank you for sharing your experience. Your post has been very helpful for me and I’m sure many others. I’m not Rust developer, but it does not look like you are doing any kind of binary serialization in that code. By chunk, do you mean an array segment?
How would you handle large blob data that exceeds the transfer limits?