Canister A hods some state that is important to a decision on Canister B. Canister B could query Canister A for that state during an update query, but that will result in the cycle cost of a XCanister Call and a round trip for waiting for consensus.
Instead it would be nice if A could push the certified data to B once and then the client could deliver the certificate with the update call with a witness and validate any number of pieces of data on A without the XCanister call.
Example: A is a ledger of Tokens X. B awards a Token Y if you burn tokens X. A can update B on the root and all burns → mint can be executed without a XCanister call.
Specifically, if I create a canister-controlled neuron that can only be controlled via certified data from a given subnet, do I run the risk of losing control of that neuron in the future if my canister migrates to a different subnet?
I think they limit canisters from holding neurons on purpose. The t-ecdsa routes around that. Seems like it will be a silly restriction once we have t-ecdsa, so hopefully we can have it removed. I think the canister signatures are used for delegations, so maybe you could delegate to a canister your ownership of a neuron…but you’d need some way to prove you’d destroyed the private key.
Ha! Ok…so that is interesting. I’d be happy to outline that out a bit here.
I’m clearly missing something here. A canister can sign a root, but I don’t think it can sign data. Wouldn’t it need to sign the transaction? (Maybe the key here is that all that needs to be signed is a transaction hash.) If that is the case then you aren’t really signing a Merkle tree, you are just signing a root that isn’t a root, but a hash of a transaction. Maybe @bjoern can give some clarity.
Send Transaction hash and candid to the canister. Have the hash written to the certified data.
Have the canister submit a query via the new HTTP interface to get the signature
Do a second HTTP call to send the call to the management canister and the signed hash to the IC.
I wish I’d thought of that before because we could have been doing this manually for a while…now with HTTP requests, we can automate it.
The canister would create the ingress message and would put the request id into a Merkle tree structure as described in the section on canister signatures. In a subsequent query call to that canister, one can request the signature on the root of the Merkle tree, and the canister can also return the path in the Merkle tree. Together, those form the “canister signature”. This is exactly what we do in Internet Identity; well, we “sign” a delegation not an actual request id, but that doesn’t really matter, just do what II does but “sign” the request id instead.
That said, as @skilesare pointed out, canister signatures (and the tECDSA feature as well) together with the HTTP request feature make the restriction that canisters cannot hold neurons somewhat artificial. So maybe there is a discussion to be had (maybe first in a dedicated thread here in the forum, and maybe that could lead to an NNS proposal) about lifting that restriction.
Do you know if I risk losing control of the neuron in the scenario described above?
Do you have a reference for doing this? I’m still learning the ins/outs of Motoko. I thought only external actors could create ingress messages.
So does this mean that the canister itself would not be submitting the neuron management calls to the NNS? I would need some authorized third party to retrieve these variables and then pass them to the NNS indirectly?
That is not a risk. Let us look at the spec, in particular the part that defines the “public key” for canister signatures:
The BIT STRING field subjectPublicKey is the blob |signing_canister_id| · signing_canister_id · seed, where |signing_canister_id| is the one-byte encoding of the the length of the signing_canister_id and · denotes blob concatenation.
The key only depends on the signing_canister_id and a canister-chosen seed. No information about the subnet is used. In fact, we will be moving the Internet Identity canister to a new subnet soon, which is only possible due to the described property.
I don’t, unfortunately. It’s a mess, since you have to first encode the argument as Candid, then you have to assemble the ingress message as CBOR and compute the request id. I was saying that it’s possible, not that it’s easy…
Well the canister can use the HTTP request API to make a query call to itself. And then it could use the HTTP request API to submit the request to the boundary node. So once we have HTTP queries, the canister can do this.
But yeah, all this wouldn’t be necessary if canisters could control neurons directly.
Thank you! This is good to know. I misunderstood the video when it said the subnet would sign the certificate and had not taken a look at the spec yet.
Copy that. I may still try to build this just to learn from the experience.
I would like to draft a governance proposal requesting that DFINITY add this feature to their roadmap, or at least consider it in their horizon planning. I’m just not sure how that process works now given recent discussions on the topic. I want to respect y’alls processes.
If you’re referring to the recent discussion on priorities: I think the proposal you have in mind is clearly a (technically straightforward) proposed change to the IC governance system. Especially if it is phrased like that (a proposal to change the governance system, not necessarily about who implements it and when), I think it is clearly suitable and expect that fact to be uncontroversial. That said, it may make sense to describe the intent in a forum thread first.