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?

1 Like

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?

3 Likes

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

2 Likes

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.

2 Likes

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

2 Likes

Ha i misunderstood the specs :slight_smile:

Information is very close; I will use the agent;

1 Like

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);
4 Likes

Sorry if am asking wrong question.

Lets say a code is being deployed on canister which hosts some service to the public, and after somedays the canister owner has modified the code, how can the public know whether this is modified or not?
So based on the canister version/changelog people/public can take call whether to use the service.

If there is no way for public to know the version/modification on canister. Could anyone explain the intention behind that?

Has any progress been made on being able to get the module hash for a canister for which you are not the controller on chain?

1 Like