Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: update ic-mgmt candid and log_visibility support #638

Merged
merged 5 commits into from
May 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions packages/ic-management/candid/ic-management.certified.idl.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,15 @@ export const idlFactory = ({ IDL }) => {
'total_num_changes' : IDL.Nat64,
});
const canister_status_args = IDL.Record({ 'canister_id' : canister_id });
const log_visibility = IDL.Variant({
'controllers' : IDL.Null,
'public' : IDL.Null,
});
const definite_canister_settings = IDL.Record({
'freezing_threshold' : IDL.Nat,
'controllers' : IDL.Vec(IDL.Principal),
'reserved_cycles_limit' : IDL.Nat,
'log_visibility' : log_visibility,
'memory_allocation' : IDL.Nat,
'compute_allocation' : IDL.Nat,
});
Expand Down Expand Up @@ -142,6 +147,7 @@ export const idlFactory = ({ IDL }) => {
'freezing_threshold' : IDL.Opt(IDL.Nat),
'controllers' : IDL.Opt(IDL.Vec(IDL.Principal)),
'reserved_cycles_limit' : IDL.Opt(IDL.Nat),
'log_visibility' : IDL.Opt(log_visibility),
'memory_allocation' : IDL.Opt(IDL.Nat),
'compute_allocation' : IDL.Opt(IDL.Nat),
});
Expand All @@ -162,6 +168,15 @@ export const idlFactory = ({ IDL }) => {
'public_key' : IDL.Vec(IDL.Nat8),
'chain_code' : IDL.Vec(IDL.Nat8),
});
const fetch_canister_logs_args = IDL.Record({ 'canister_id' : canister_id });
const canister_log_record = IDL.Record({
'idx' : IDL.Nat64,
'timestamp_nanos' : IDL.Nat64,
'content' : IDL.Vec(IDL.Nat8),
});
const fetch_canister_logs_result = IDL.Record({
'canister_log_records' : IDL.Vec(canister_log_record),
});
const http_header = IDL.Record({ 'value' : IDL.Text, 'name' : IDL.Text });
const http_request_result = IDL.Record({
'status' : IDL.Nat,
Expand Down Expand Up @@ -333,6 +348,11 @@ export const idlFactory = ({ IDL }) => {
[ecdsa_public_key_result],
[],
),
'fetch_canister_logs' : IDL.Func(
[fetch_canister_logs_args],
[fetch_canister_logs_result],
[],
),
'http_request' : IDL.Func([http_request_args], [http_request_result], []),
'install_chunked_code' : IDL.Func([install_chunked_code_args], [], []),
'install_code' : IDL.Func([install_code_args], [], []),
Expand Down
18 changes: 18 additions & 0 deletions packages/ic-management/candid/ic-management.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,16 @@ export type canister_install_mode =
];
}
| { install: null };
export interface canister_log_record {
idx: bigint;
timestamp_nanos: bigint;
content: Uint8Array | number[];
}
export interface canister_settings {
freezing_threshold: [] | [bigint];
controllers: [] | [Array<Principal>];
reserved_cycles_limit: [] | [bigint];
log_visibility: [] | [log_visibility];
memory_allocation: [] | [bigint];
compute_allocation: [] | [bigint];
}
Expand Down Expand Up @@ -147,6 +153,7 @@ export interface definite_canister_settings {
freezing_threshold: bigint;
controllers: Array<Principal>;
reserved_cycles_limit: bigint;
log_visibility: log_visibility;
memory_allocation: bigint;
compute_allocation: bigint;
}
Expand All @@ -166,6 +173,12 @@ export interface ecdsa_public_key_result {
public_key: Uint8Array | number[];
chain_code: Uint8Array | number[];
}
export interface fetch_canister_logs_args {
canister_id: canister_id;
}
export interface fetch_canister_logs_result {
canister_log_records: Array<canister_log_record>;
}
export interface http_header {
value: string;
name: string;
Expand Down Expand Up @@ -201,6 +214,7 @@ export interface install_code_args {
canister_id: canister_id;
sender_canister_version: [] | [bigint];
}
export type log_visibility = { controllers: null } | { public: null };
export type millisatoshi_per_byte = bigint;
export interface node_metrics {
num_block_failures_total: bigint;
Expand Down Expand Up @@ -307,6 +321,10 @@ export interface _SERVICE {
[ecdsa_public_key_args],
ecdsa_public_key_result
>;
fetch_canister_logs: ActorMethod<
[fetch_canister_logs_args],
fetch_canister_logs_result
>;
http_request: ActorMethod<[http_request_args], http_request_result>;
install_chunked_code: ActorMethod<[install_chunked_code_args], undefined>;
install_code: ActorMethod<[install_code_args], undefined>;
Expand Down
24 changes: 24 additions & 0 deletions packages/ic-management/candid/ic-management.did
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
type canister_id = principal;
type wasm_module = blob;

type log_visibility = variant {
controllers;
public;
};

type canister_settings = record {
controllers : opt vec principal;
compute_allocation : opt nat;
memory_allocation : opt nat;
freezing_threshold : opt nat;
reserved_cycles_limit : opt nat;
log_visibility : opt log_visibility;
};

type definite_canister_settings = record {
Expand All @@ -15,6 +21,7 @@ type definite_canister_settings = record {
memory_allocation : nat;
freezing_threshold : nat;
reserved_cycles_limit : nat;
log_visibility : log_visibility;
};

type change_origin = variant {
Expand Down Expand Up @@ -332,6 +339,20 @@ type bitcoin_get_balance_query_result = satoshi;

type bitcoin_get_current_fee_percentiles_result = vec millisatoshi_per_byte;

type fetch_canister_logs_args = record {
canister_id : canister_id;
};

type canister_log_record = record {
idx: nat64;
timestamp_nanos: nat64;
content: blob;
};

type fetch_canister_logs_result = record {
canister_log_records: vec canister_log_record;
};

service ic : {
create_canister : (create_canister_args) -> (create_canister_result);
update_settings : (update_settings_args) -> ();
Expand Down Expand Up @@ -368,4 +389,7 @@ service ic : {
// provisional interfaces for the pre-ledger world
provisional_create_canister_with_cycles : (provisional_create_canister_with_cycles_args) -> (provisional_create_canister_with_cycles_result);
provisional_top_up_canister : (provisional_top_up_canister_args) -> ();

// canister logging
fetch_canister_logs : (fetch_canister_logs_args) -> (fetch_canister_logs_result) query;
};
20 changes: 20 additions & 0 deletions packages/ic-management/candid/ic-management.idl.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,15 @@ export const idlFactory = ({ IDL }) => {
'total_num_changes' : IDL.Nat64,
});
const canister_status_args = IDL.Record({ 'canister_id' : canister_id });
const log_visibility = IDL.Variant({
'controllers' : IDL.Null,
'public' : IDL.Null,
});
const definite_canister_settings = IDL.Record({
'freezing_threshold' : IDL.Nat,
'controllers' : IDL.Vec(IDL.Principal),
'reserved_cycles_limit' : IDL.Nat,
'log_visibility' : log_visibility,
'memory_allocation' : IDL.Nat,
'compute_allocation' : IDL.Nat,
});
Expand Down Expand Up @@ -142,6 +147,7 @@ export const idlFactory = ({ IDL }) => {
'freezing_threshold' : IDL.Opt(IDL.Nat),
'controllers' : IDL.Opt(IDL.Vec(IDL.Principal)),
'reserved_cycles_limit' : IDL.Opt(IDL.Nat),
'log_visibility' : IDL.Opt(log_visibility),
'memory_allocation' : IDL.Opt(IDL.Nat),
'compute_allocation' : IDL.Opt(IDL.Nat),
});
Expand All @@ -162,6 +168,15 @@ export const idlFactory = ({ IDL }) => {
'public_key' : IDL.Vec(IDL.Nat8),
'chain_code' : IDL.Vec(IDL.Nat8),
});
const fetch_canister_logs_args = IDL.Record({ 'canister_id' : canister_id });
const canister_log_record = IDL.Record({
'idx' : IDL.Nat64,
'timestamp_nanos' : IDL.Nat64,
'content' : IDL.Vec(IDL.Nat8),
});
const fetch_canister_logs_result = IDL.Record({
'canister_log_records' : IDL.Vec(canister_log_record),
});
const http_header = IDL.Record({ 'value' : IDL.Text, 'name' : IDL.Text });
const http_request_result = IDL.Record({
'status' : IDL.Nat,
Expand Down Expand Up @@ -333,6 +348,11 @@ export const idlFactory = ({ IDL }) => {
[ecdsa_public_key_result],
[],
),
'fetch_canister_logs' : IDL.Func(
[fetch_canister_logs_args],
[fetch_canister_logs_result],
['query'],
),
'http_request' : IDL.Func([http_request_args], [http_request_result], []),
'install_chunked_code' : IDL.Func([install_chunked_code_args], [], []),
'install_code' : IDL.Func([install_code_args], [], []),
Expand Down
70 changes: 70 additions & 0 deletions packages/ic-management/src/ic-management.canister.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import {
CanisterSettings,
InstallCodeParams,
InstallMode,
LogVisibility,
UnsupportedLogVisibility,
toInstallMode,
type BitcoinGetUtxosParams,
type ClearChunkStoreParams,
Expand Down Expand Up @@ -116,10 +118,77 @@ describe("ICManagementCanister", () => {
freezing_threshold: [],
memory_allocation: [],
reserved_cycles_limit: [],
log_visibility: [],
},
});
});

it("calls update_settings with mapped log_visibility controllers", async () => {
const service = mock<IcManagementService>();
service.update_settings.mockResolvedValue(undefined);

const icManagement = await createICManagement(service);

await icManagement.updateSettings({
canisterId: mockCanisterId,
settings: {
...mockCanisterSettings,
logVisibility: LogVisibility.Controllers,
},
});

expect(service.update_settings).toHaveBeenCalledWith({
canister_id: mockCanisterId,
settings: {
...mappedMockCanisterSettings,
log_visibility: [{ controllers: null }],
},
sender_canister_version: [],
});
});

it("calls update_settings with mapped log_visibility public", async () => {
const service = mock<IcManagementService>();
service.update_settings.mockResolvedValue(undefined);

const icManagement = await createICManagement(service);

await icManagement.updateSettings({
canisterId: mockCanisterId,
settings: {
...mockCanisterSettings,
logVisibility: LogVisibility.Public,
},
});

expect(service.update_settings).toHaveBeenCalledWith({
canister_id: mockCanisterId,
settings: {
...mappedMockCanisterSettings,
log_visibility: [{ public: null }],
},
sender_canister_version: [],
});
});

it("throws Error for unsupported log visibility", async () => {
const service = mock<IcManagementService>();
service.update_settings.mockResolvedValue(undefined);

const icManagement = await createICManagement(service);

const call = () =>
icManagement.updateSettings({
canisterId: mockCanisterId,
settings: {
...mockCanisterSettings,
logVisibility: 2 as unknown as LogVisibility,
},
});

expect(call).toThrow(UnsupportedLogVisibility);
});

it("throws Error", async () => {
const error = new Error("Test");
const service = mock<IcManagementService>();
Expand Down Expand Up @@ -274,6 +343,7 @@ describe("ICManagementCanister", () => {
memory_allocation: BigInt(4),
compute_allocation: BigInt(10),
reserved_cycles_limit: BigInt(11),
log_visibility: { controllers: null },
};
const response: CanisterStatusResponse = {
status: { running: null },
Expand Down
24 changes: 23 additions & 1 deletion packages/ic-management/src/types/ic-management.params.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,57 @@
import { Principal } from "@dfinity/principal";
import { toNullable } from "@dfinity/utils";
import { isNullish, toNullable } from "@dfinity/utils";
import type {
bitcoin_get_utxos_args,
bitcoin_get_utxos_query_args,
canister_install_mode,
canister_settings,
chunk_hash,
log_visibility,
upload_chunk_args,
} from "../../candid/ic-management";

export enum LogVisibility {
Controllers,
Public,
}

export interface CanisterSettings {
controllers?: string[];
freezingThreshold?: bigint;
memoryAllocation?: bigint;
computeAllocation?: bigint;
reservedCyclesLimit?: bigint;
logVisibility?: LogVisibility;
}

export class UnsupportedLogVisibility extends Error {}

export const toCanisterSettings = ({
controllers,
freezingThreshold,
memoryAllocation,
computeAllocation,
reservedCyclesLimit,
logVisibility,
}: CanisterSettings = {}): canister_settings => {
const toLogVisibility = (): log_visibility => {
switch (logVisibility) {
case LogVisibility.Controllers:
return { controllers: null };
case LogVisibility.Public:
return { public: null };
default:
throw new UnsupportedLogVisibility();
}
};

return {
controllers: toNullable(controllers?.map((c) => Principal.fromText(c))),
freezing_threshold: toNullable(freezingThreshold),
memory_allocation: toNullable(memoryAllocation),
compute_allocation: toNullable(computeAllocation),
reserved_cycles_limit: toNullable(reservedCyclesLimit),
log_visibility: isNullish(logVisibility) ? [] : [toLogVisibility()],
};
};

Expand Down
Loading