TL;DR: The Foundation will resubmit the proposal to upgrade the ledger and enable canisters to transfer ICP. The Foundation will vote for adopting the proposal.
Yesterday, voting on proposal 30496 to upgrade the Ledger and enable canisters to transfer ICP saw 18.9% votes for adoption and less than 0.1% for rejection with only half an hour to the deadline. Unfortunately, a technical issue in application subnet “pljlw” made it risky to perform the upgrade to the Ledger canister at the same time. Important to note, the issue with subnet “pljlw” is unrelated to the ICP transferability upgrade. Fortunately, the subnet is back to running normally. As promised, the Foundation is resubmitting the upgrade proposal to update the Ledger canister and enable ICP transferability. Given the majority of the community was in favour of adoption, this time, the Foundation will vote in favor of the upgrade proposal.
I am confused why this has to do so like this, which sounds like a waste of time. You said that “the issue with subnet ‘pljlw’ is unrelated to the ICP transferability upgrade.” Why cannot jut let the ICP transferability upgrade? As per this saying, if one day there are millions of subsets and if one subset has this kind of issue and we will not be able to do any of this kind of upgrade things? Is my understanding right?
Currently, converting ICP to Cycles to top-up a canister triggers a call-tree involving the ledger and the canister to be topped up. If the canister to be topped up is on an unresponsive subnetwork, then the call-tree may not terminate and the ledger cannot be upgraded (since atm, to safely upgrade a canister the canister needs to be stopped).
We will remove this dependency (either by eliminating the need to stop the canister, or via different flows for ICP conversion to cycles so that the dependency is removed). So, upgrading the ledger will be completely independent of the behavior of other canisters/subnetworks.
I wonder is the phase of the nns ICP wallet when we accidentally delete it, although we still save the phase, but we can’t backup the wallet, is there any way to recreate it?
If you have accidentally deleted the recovery phrase then you can simply create a new recovery phrase which will be different from the phrase you had before. Is your question if you can somehow re-install the old recovery phrase into your internet identity instead of getting a new, different one?
The Replica returned an error: code 4, message: "IC0503: Canister ryjl3-tyaaa-aaaaa-aaaba-cai trapped explicitly: Panicked at 'Deserialization Failed: "Fail to decode argument 0 from table0 to record { account : vec nat8 }"', /builds/dfinity/ic/rs/rust_canisters/dfn_core/src/endpoint.rs:34:41"
Context: a canister that tries to get its own balance.
You can find the code here.
EDIT: it is now fixed, the account id hash was missing.
I believe the problems you’re facing with ledger interface are caused by the fact that you’re trying to use canister principals as ledger account identifiers. Principals and ledger account identifiers are different identifiers (even though the ledger account id is derived from the principal of the owner and a subaccount):
I know this is very confusing, but it’s how the ledger was originally designed, and there is some reasoning behind this.
We’re planning to release a few support libraries and examples demonstrating how to correctly talk to the Ledger, a formal specification for the Ledger canister, and a reference implementation in Motoko. This will happen in the next few weeks. I’ll also give a community conversation talk on these topics.
If you’re already eager to start building things, you can use the following draft PRs as your point of departure:
Thanks for the response! Just to clarify, the example above uses account ids.
Not really:
public type AccountIdentifier = Blob;
public func balance() : async Ledger.ICP {
await ledger.account_balance({
// same as Blob.fromArray(Blob.fromPrincipal(Principal.fromActor(this), null));
account = Blob.fromArray(AccountIdentifier.fromPrincipal(Principal.fromActor(this), null));
});
};
It uses this package to convert a principal to an account ids, not Blob, am I missing something?..
How are these the same?
// same as Blob.fromArray(Blob.fromPrincipal(Principal.fromActor(this), null));
account = Blob.fromArray(AccountIdentifier.fromPrincipal(Principal.fromActor(this), null));
Ah, thanks for the clarification, I missed the fact that an external package is used. Unfortunately, this package doesn’t include the extra 4 bytes (CRC32 of the hash) into the account identifier as indicated in the ledger candid interface docs. So the ledger canister fails to decode a 32 byte array from the message.
Thanks a lot for spotting the issue, @hhanh00! I fixed the issue in this commit.
The id and interface differs from what the rust code uses but I was able to query the balance of my canister after updating them.
That’s a very good point!
The canister provides multiple interfaces for various use-cases, and the .did file returned by __get_candid_interface_tmp_hack endpoint still describes the old interface. Since the methods exposed by the old interface weren’t designed for general public use, and mixing two interfaces together will be very confusing, we can change the interface endpoint to return the new .did file in the next release of the ledger canister.
so what do i need to do to generate a new phase code on my old nns wallet address i need to back it up on my laptop now i’m praying my phone doesn’t break
Go to https://identity.ic0.app/ on your phone
Type in your identity anchor number
Authenticate with your phone
Click on “Add recovery key” or “Add recovery mechanism” (whatever appears)
Click on “Seed phrase”
Copy the whole thing including the identity anchor number in the beginning and write it down