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?
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
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?
This is currently not possible on-chain if you are not the controller (although it should be), sorry.
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
?
I tried to call the endpoints directly; It did not seem to respond
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.
I tried this
But it seems it’s 404
That’s not how it works, sorry
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
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);
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?