SNS: ExecuteGenericNervousSystemFunction

(Please ignore the spaces in the title; Discourse wouldn’t let me post this because “one or more words is very long”)

I’m looking for some documentation or information on the ExecuteGenericNervousSystemFunction in the SNS.

In particular, I couldn’t find anything about the expected return type of the target method (previously specified in the target_method_name field of GenericNervousSystemFunction via AddGenericNervousSystemFunction)

I suspect it’s a variant isomorphic to Result in order to communicate to the caller whether the operation was successful or not.

Something like variant { Ok : vec nat8; Err : vec nat8 }?

1 Like

Or is this effectively a oneway call?

You can find more details on executing generic functions in paragraph 7. of the SNS testflight docs.


The validation function must return a value of the Candid type variant { Ok: text; Err: text; }, e.g., Result<String, String> in Rust. If the validation function returns Ok(rendering), then the proposal is submitted and the rendering string is included into the proposal. Otherwise, the proposal submission fails.

The execution function gets the same binary payload as passed to the validation function and its code gets executed if the proposal is accepted. It should not return any value because this return value is ignored.

I think it would be useful for the execution function to have the same return type, and for it not to be ignored so that voters can be informed that whether it executed successfully or not.

Is this forum the right place to have that discussion? Who should be involved?

There’s already a TODO in the code to deserialize the reply and check if the execution was successful. I’ll follow up with the NNS team to get an estimate when this could be implemented.

Nevertheless, already now, the proposal execution would fail if the execution method explicitly traps (e.g., by calling ic_cdk::trap("error mesage")). In this case, the SNS proposal would have executed_timestamp_seconds = 0 : nat64 and

        failure_reason = opt record {
          error_message = "Canister method call to execute proposal failed: (Some(5), \"IC0503: Canister s55qq-oqaaa-aaaaa-aaakq-cai trapped explicitly: error message\")";
          error_type = 11 : int32;

Please note that ic_cdk::trap("error message") is different from return Err("error message") because the former rolls back any state changes performed before trapping.

1 Like

Yes, currently it is effectively a 1-way call, the only exception being what @mraszyk pointed out - if your function traps, it will not be marked as successful. There is the TODO item he mentioned, which would have the same return type as the validation function has, unless we find something better that can be done there.

There’s not a finalized design, and it’s also possible we would do something else, or leave it to the developers to add another way to get debug information.

One possibility might be that we just store the bytes of the response and let someone who knows the types read it back out of the executed proposal if the response is something needed, which would provide richer functionality at the cost of requiring the SNS operators to make some tooling.

If you have any suggestions, this forum post is a good place to make them. We don’t have a finalized design that I am aware of, which is why that was left as a TODO item.

1 Like

I think what you described would be the most flexible.