Using NnsCanisterUpgrade Proposal types

Are NNS users generally “allowed” to use the NnsCanisterUpgrade to propose to upgrade any canister on the IC? Or is this limited to canisters on the NNS subnet?

If anyone can make the proposal, How would one produce it? It looks like it may be protobuf?

Is there a tool to take the canister ID, wasm, etc and create the payload for nns_function id 4?

The use case here would be community deployed canisters that can be upgraded by the NNS, but that don’t particularly need their own SNS(and that want to utilize the security provided by the NNS). I think this is what @WaterNeuron was proposing using to give the nICP and support canisters to the NNS, but not sure…I think that is delayed for a bit? Just looking for an example and a tool to create a proposal to test locally.

Hi @skilesare,
for me the main question is whether we talk about the technical question how this can be done or the more general question whether as an NNS community we want to use the NNS in this way.

Technically, anyone can submit such a proposal.

For the more general question, I personally think the NNS should not be used in this way and that this is a potentially dangerous route to take:

  • First, any call to potentially insecure canisters puts the NNS canisters under danger in the current messaging model due to call contexts that could remain open etc. This might change with the new messaging model, but first the NNS canisters would then have to use this.
  • Second, if we want the NNS to be even more active and decentralised, I think we should be very conscious what we put under NNS control and put less rather than more there. Already today it requires quite some effort to keep up with all proposals, even just deciding who to follow on what topic, if one wants to make good informed decisions. Adding more kinds of proposals will make this harder. Maybe if there are very established known neurons for all topics one day this might shift.
  • Supporting new use cases may mean more developer and maintenance work for the NNS - we need to make sure with each change that none of the use cases break with new features etc.

For all these reasons, I think we as an NNS community should make conscious decisions which things we want to put under NNS control and for which things there are better alternatives. If someone asked me today whether I would recommend upgrading a dapp canister via the NNS, I would strongly advise against that except maybe for some very rare cases where its is urgent and where for some reason it is clear that the target canister is secure.

So I take it that the answer to my first question is: Yes. nns_function_id 4 can install a wasm for any canister(is there any technical limitation? Like does the controller need to be the nns root? Or can it just install regardless of the controller?) And this is possible for any subnet(Does this include rental subnets?)

Is there any answer to the second question as to if there is a tool to package up a request for nns_function_id 4? At this point, I just want to test things locally. I agree 100% that we should be judicious on how we handle these things and part of what I’m looking at is if there are some abstractions we can lay on top of a potential utility canister that makes it easier to manage ‘public’ canister in an array of unique and custom ways, but that has the fall back of a straightforward NNS proposal if things go sideways.

I believe the ERC20, ckBTC, ckETH canisters are already using this method and we have regular proposals to update the ERC20 canister whenever anyone wants to add a new ckERC20 token.

The general use case here is more one of simplification. If I can hand control of a canister to the NNS Root rather than a black hole, I know that my service can be upgraded in the case of an emergency(aka taggr issue) without having to shim code into the replica to hardcode change a controller. If it doesn’t matter if the controller is the NNS root, then I guess we have this already if the nns_function_id 4 can be installed on any canister regardless of the controller.

Edit: There are a number of things that would be nice to release but that don’t have their ICRC Standard finalized…this is another case where it might be nice to release something that the NNS can upgrade once the standards reach a final state…they may not change from the draft, but if they do then it would be nice to have a straight forward way to upgrade them.

Why is this? Does the upgrade for nns_function id 4 not stop the canister before upgrade? I’m searching the ic code to try to find the actual execution of this code but not quite able to find it(likely due to my poor rust skills). Could you point me to it and I might be able to answer most of my own questions?

Yes, at present, the NNS root would need to be the controller of the canister. There aren’t restrictions about where the canisters must live in terms of subnets.

But I agree with what Lara said - it’s not a great idea.

Just to address the “how” part of the question, one can use the ic-admin (released as part of the IC repo like this) and the propose-to-change-nns-canister command. To test locally, you can use --nns-url (pointing to the local replica) and --secret-key-pem arguments.

Note that we are actually switching away from the NnsFunction=4, but using the InstallCode action type for new canister upgrade proposals, which you can achieve by passing the --use-explicit-action-type argument to ic-admin (will later become the default behavior)

Ok…nice…so InstallCode will be the InstallCode Type encoded as candid?

If you use ic-admin you don’t have to worry about encoding. But yes, under the hood it just sends a an update call to the NNS Governance canister manage_neuron method, using candid encoding.

Sorry for so many questions…

Do I need to do something to run it? After unzipping and trying to run from the command line I get: /Users/afat/Downloads/ic-admin-x86_64-darwin: command not found

Am I going to pass it candid as parameters?

What are the possible values of mode on the command line? If numbers, what do they line up with for install/reinstall/upgrade.

Can the wasm be gzipped? If so, do I need to calculate the sha256 of the zip file or the prezipped wasm?

Does the URL just need to point at github or something?

The binary for args…is it just candid as binary that I can encode with didc?

Hmm… I’m not sure about “command not found”. Please make sure that the file exist and is executable (I run chmod +x after downloading it, and macOS always complains about running unknown programs and I have to go to system settings to allow it).

Here is an example command for a local replica:

ic-admin \
  --secret-key-pem  ${HOME}/.config/dfx/identity/${IDENTITY_NAME}/identity.pem \
  --nns-url http://localhost:8080 \
  propose-to-change-nns-canister \
  --canister-id "$CANISTER_ID" \
  --mode upgrade \
  --wasm-module-path /path/to/wasm/file \
  --wasm-module-sha256 "$WASM_HASH" \
  --arg "$CANDID_ARGS_FILE" \
  --proposer "$NEURON_ID" \
  --summary "$SUMMARY"

You can either provide a .wasm.gz or .wasm. --wasm-module-sha256 just needs to be the hash of what you provide.

The CANDID_ARGS_FILE can be prepared by:

    didc encode \
        "$ARGS" \
        | xxd -r -p > "$CANDID_ARGS_FILE"

where $ARGS is the textual representation of the candid arg.

I’m not very familiar with using --wasm_module_url since I always use the --wasm_module_path option (exactly one of them should be provided). I suppose it can be any URL you can curl with, but I’m not exactly sure about that.

2 Likes

@lara,

Can I push back a bit?

First, I agree that it would be really tough to start throwing any and all apps at the NNS. We probably don’t want that kind of thing and I agree that NNS fatigue could be a real thing.

That being said, there are clearly some things that have emerged as valid utilities that it makes, at least temporary, sense to have governed by the NNS. ckBTC, ckETH, and ckERC20 seem to be in this camp. The SNS, the ExchangeRate canister, and I think the EthererumRPC canister are also utilities that have come under the control of the NNS. They are basically utilities and they are going to need some kind of upgradeability. It is unlikely that any SNS has the financial size to secure the governance of these if we want them used to their full potential. It is a really nice feature that they are able to inherit the security of the network.

As ETH moves towards things like EigenLayer there is a movement to help tools onboard to networks with the ability to inherit the security of the base layer. It is yet to be seen if this is a great idea or not, because the more you stack on top of that security the larger the fall if something breaks.

Back to the cks and SNS and other utility canisters. So far these have all been built by DFINITY and have been given pretty much default grace to move under the NNS and inherit its security. But I think it is highly unlikely that that should be the only pathway. I think(hope) the community is on the brink of a number of network-wide utilities that will need that kind of security. Also, these utilities are hopefully fairly baked, built on standards, and unlikely to need constant upgrading.

For example, I could see a canonical instance of @kristofer 's SIWE that other apps could use to provide Sign In With Ethereum and that can be only managed by the NNS.

For reducing NNS Fatigue I could see a number of options:

  1. In the same way we have generic functions for SNS, it might be nice to have some kind of generic topic for these kinds of utilities because it is a very specific type of skill that is needed for each one of these utilities. Users would be able to follow topics at a granular level and/or known neurons would be able to declare which other neurons they follow for specific topics that they don’t have expertise in. And then of course things could degrade to an ‘All unassigned generic topics’ follow.

  2. There may be a simpler way to do this by delegating governance to a meta-utility that lets ‘councils’ upgrade these utility canisters and then the only votes need to be for when the NNS wants to replace or fire one of the people on the council. Instead of setting the controller to NNS root you could set the NNS to this council meta-canister that could do upgrades. For these actions/elections, you’d likely need to add a couple of governance topics.

A lot to think about here, but it would be nice to have some generic pathway for inheriting the financial backing and decentralization of the NNS.

1 Like

Of course you can push back :slight_smile: I think we don’t have a super clear view here as an NNS community how we want to go about this.

I think we agree on many points! I just wanted to bring up topics like “NNS fatigue” (I like this term btw :slight_smile: ) and also potential added complexity as issues. In my view, these aspects are often neglected and I just try to spread the awareness that we should think about them very well before adding more complexity and “responsibility to NNS users” - to make sure we don’t put things under NNS control just due to the lack of discussion of alternatives.

For a few applications that are for example niche and very relevant to some communities but not to others, it might for example also make sense to have new specialized DAOs or think about even other forms of governance / control. I totally get that we want to inherit the security of the NNS - but this security is only as good as the users behind the voting power being able to keep up with making good choices. What I mean: if in the extreme case there is one dapp that is just understood by one person and all users “have to” follow this one person even if it is not trusted (because no one else cares or knows about this dapp) - this is not much more secure than this person directly controlling the dapp. In this case, a lot of neurons might blindly follow this one person or choose to always vote no and then this application cannot actually be upgraded using the NNS. I know this is an extreme case, but I just use it as illustration.

That being said, I also see that we as an NNS community might still decide that other things should be added under NNS control - and probably for good reasons.
I really just want to advocate to have these conversations.
Maybe a solution is also to just having to “ask the NNS community for permission” when adding a canister to its responsibility (similarly to how one has to register a dapp in the SNS).

I think I generalised a bit and didn’t explain well.

For upgrades, the NNS root

  1. stops the target canister
  2. installs the new wasm
  3. starts the target canister again

Between 1 and 2 NNS root waits for the target canister to be stopped and report this back. I think this should be the relevant code where this answer is awaited.
These calls are made to the management canister on the subnet where the target canister is. If the target subnet was dishonest, it could decide not to return the call and NNS root would have an open call context.
Of course we can now debate how likely it is that the target subnet is malicious - but the NNS has more nodes for more security and for this aspect the security would be reduced to the security of the target canister’s subnet (which has less nodes if the target is an application canister).

Ahh! Very helpful information to know.

Obviously this makes a fiduciary subnet more attractive for these theoretical utility canisters, but we have to balance that with cost as well.

1 Like

We gave it a try. We will see how it goes: NNS Controlled Subscription Utility

Is there a different upgrade pattern that doesn’t require open call contexts?

Might this be solved with call timeouts in the upcoming scalable messaging model?

What I’m thinking is deploying a nns controlled canister that does nothing but upgrades and have it watch motion proposals…or maybe even install code proposals that target a black hole(and thus instantly fail.) and make the controller of the subscription canister that “3rd party upgrade”. Obviously this won’t work if Dfinity doesn’t abstain from those. I’ll try to pull all my thoughts together on it early next week.

Having the upgrade canister controlled by the nns is just a backup. It should be simple enough to do only one thing and one thing well, don’t should be sufficient and easy to have a few of us audit it. It shouldn’t ever have to be upgraded unless the nns breaks existing compatibility with the proposal type we pick.