SNS Generic Function Interfaces

What are the expected interfaces of generic functions that are called through SNS proposals of type ExecuteGenericNervousSystemFunction?

  • Can the methods be query, or should they only be update?

  • Should the generic function return a Result<(), String>, or is the only way to communicate that a function fail by trapping?

  • If the latter, is there a common pattern or solution to persist a state within the canister targeted by the custom function while still reporting to the SNS governance that the proposal failed?

The methods can be either one, because they are called through the sns-governance-canister so it will be an inter-canister-call which can be either update or query. However as of now the sns-governance-canister does not save the response into the proposal.

As of now the generic function can return anything as long as it replies with something, it is considered a success, even if it replies with Err(String). This comment in the sns-governance-canister-code says more. It looks like there was an idea to do as you suggest but it is not implemented.

There is a way to communicate that the function fails without trapping, and that is to use the ic0.msg_reject system api, read about it in the interface spec here. This can be used to persist state while still returning a canister-error and thus reporting to the governance canister that the function failed. In the Rust cdk, you can do this using the ManualReply ManualReply in ic_cdk::api::call - Rust. In the query or update macro, you’d need to set manual_reply = true like this: #[update(manual_reply = true)] then set the return type of the method to ManualReply<YourActualReturnTypeHere>, then in the method you can return a success with return ManualReply::one(YourActualReturnTypeHere); or return a canister-reject (while still persisting state) with return ManualReply::reject("your reject message here");.

2 Likes

Absolutely awesome answer, particularly the ManualReply, which I did not know about and which is exactly what I need. Thanks a ton @levi! :pray:

1 Like