Any way to know if a canister was updated?

I want to check if a third party canister was updated since recently and maybe did broken some of its APIs. How can I achieve this?

Is there any version info or latest update timestamp somewhere?

We don’t have version info or latest update timestamp, but you can query the SHA256 of the installed module and compare to what you observed before. You can use dfx for that

~/dfinity/nns-ifaces $ dfx canister --no-wallet --network mercury info governance
Controller: r7inp-6aaaa-aaaaa-aaabq-cai
Module hash: 0x8e8303c87e9ed91cd367d65207215cdfe46401fd81e61410b6ae7384858bbc09
3 Likes

Thanks a lot!

Any way to do this onchain?

This works if you’re querying a canister that is controlled by the current one:

type CanisterIdRecord = { canister_id : Principal };

type CanisterStatusResult = {
    controller : Principal;
    status : { #stopped; #stopping; #running };
    memory_size : Nat;
    module_hash : ?Blob;
    cycles : Nat;
    balance : [(Blob, Nat)]
};

private let ic00 = actor "aaaaa-aa" : actor {
    canister_status : CanisterIdRecord -> async CanisterStatusResult;
};

public func status(dst : Principal) : async CanisterStatusResult {
    await ic00.canister_status({canister_id = dst})
};

How do we do this for arbitrary canisters?

2 Likes

This is currently not possible on-chain if you are not the controller (although it should be), sorry.

1 Like

How can we do this off-chain in order build a canister registry as described here?

Off-chain? Using the dfx command I showed above (or the underlying read_state HTTP API function)

Oh I see, this works:
dfx canister --network ic --no-wallet info ryjl3-tyaaa-aaaaa-aaaba-cai

Can you point me to the equivalent in JS with @dfinity/agent?

1 Like

I tried to call the endpoints directly; It did not seem to respond

1 Like

Not an expert on JS, but it seems that there is a method for readState. That returns a certificate which you can parse, validate and read from using Certificate.

I’d need more information about what you tried to do to help you here.

1 Like

I tried this

https://h5aet-waaaa-aaaab-qaamq-cai.raw.ic0.app/api/v2/canister/h2bch-3yaaa-aaaab-qaama-cai/module_hash

But it seems it’s 404

That’s not how it works, sorry :slight_smile:

You have to POST a suitable read_state request to https://h5aet-waaaa-aaaab-qaamq-cai.raw.ic0.app/api/v2/canister/read_state, and then decode the resulting certificate. Will take a while to implement from scratch, so I encourage using the agents. But if you want to learn more, maybe start reading from The Internet Computer Interface Specification :: Internet Computer

1 Like

Ha i misunderstood the specs :slight_smile:

Information is very close; I will use the agent;

This works for me:

import {
  HttpAgent,
  Principal,
  Certificate,
  blobFromText,
} from "@dfinity/agent";

const agent = new HttpAgent({ host: "https://ic0.app" });
const canisterId = Principal.fromText("a4gq6-oaaaa-aaaab-qaa4q-cai");
const path = [
  blobFromText("canister"),
  canisterId.toBlob(),
  blobFromText("module_hash"),
];
const res = await agent.readState(canisterId, {
  paths: [path],
});
const cert = new Certificate(res, agent);
await cert.verify();
const module_hash = cert.lookup(path);
2 Likes