Skip to content

Commit

Permalink
feat: load canister snaptots (#763)
Browse files Browse the repository at this point in the history
# Motivation

We continue adding support for snapshots with
[load_canister_snapshot](https://internetcomputer.org/docs/current/references/ic-interface-spec#ic-load_canister_snapshot)

# Changes

- Implement `loadCanisterSnapshot`

---------

Signed-off-by: David Dal Busco <[email protected]>
Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
peterpeterparker and github-actions[bot] authored Nov 21, 2024
1 parent d8af733 commit e662b54
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 0 deletions.
18 changes: 18 additions & 0 deletions packages/ic-management/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ const { status, memory_size, ...rest } = await canisterStatus(YOUR_CANISTER_ID);
- [fetchCanisterLogs](#gear-fetchcanisterlogs)
- [takeCanisterSnapshot](#gear-takecanistersnapshot)
- [listCanisterSnapshots](#gear-listcanistersnapshots)
- [loadCanisterSnapshot](#gear-loadcanistersnapshot)

##### :gear: create

Expand Down Expand Up @@ -280,6 +281,23 @@ Parameters:

[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L405)

##### :gear: loadCanisterSnapshot

Loads a snapshot of a canister's state.

| Method | Type |
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `loadCanisterSnapshot` | `({ canisterId, snapshotId, senderCanisterVersion, }: { canisterId: Principal; snapshotId: string or snapshot_id; senderCanisterVersion?: bigint or undefined; }) => Promise<void>` |

Parameters:

- `params`: - Parameters for the snapshot loading operation.
- `params.canisterId`: - The ID of the canister for which the snapshot will be loaded.
- `params.snapshotId`: - The ID of the snapshot to load.
- `params.senderCanisterVersion`: - The optional sender canister version. If provided, its value must be equal to ic0.canister_version.

[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L431)

<!-- TSDOC_END -->

## Resources
Expand Down
79 changes: 79 additions & 0 deletions packages/ic-management/src/ic-management.canister.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -872,4 +872,83 @@ describe("ICManagementCanister", () => {
await expect(call).rejects.toThrow(error);
});
});

describe("loadCanisterSnapshot", () => {
it("should call load_canister_snapshot with Uint8Array snapshotId", async () => {
const service = mock<IcManagementService>();
service.load_canister_snapshot.mockResolvedValue(undefined);

const icManagement = await createICManagement(service);

const params = {
canisterId: mockCanisterId,
snapshotId: Uint8Array.from([1, 2, 3, 4]),
};

await icManagement.loadCanisterSnapshot(params);

expect(service.load_canister_snapshot).toHaveBeenCalledWith({
canister_id: params.canisterId,
snapshot_id: params.snapshotId,
sender_canister_version: [],
});
});

it("should call load_canister_snapshot with string snapshotId", async () => {
const service = mock<IcManagementService>();
service.load_canister_snapshot.mockResolvedValue(undefined);

const icManagement = await createICManagement(service);

const params = {
canisterId: mockCanisterId,
snapshotId: "000000000000000201010000000000000001",
};

await icManagement.loadCanisterSnapshot(params);

expect(service.load_canister_snapshot).toHaveBeenCalledWith({
canister_id: params.canisterId,
snapshot_id: decodeSnapshotId(params.snapshotId),
sender_canister_version: [],
});
});

it("should call load_canister_snapshot with senderCanisterVersion", async () => {
const service = mock<IcManagementService>();
service.load_canister_snapshot.mockResolvedValue(undefined);

const icManagement = await createICManagement(service);

const params = {
canisterId: mockCanisterId,
snapshotId: Uint8Array.from([1, 2, 3, 4]),
senderCanisterVersion: 5n,
};

await icManagement.loadCanisterSnapshot(params);

expect(service.load_canister_snapshot).toHaveBeenCalledWith({
canister_id: params.canisterId,
snapshot_id: params.snapshotId,
sender_canister_version: [params.senderCanisterVersion],
});
});

it("should throw an Error if load_canister_snapshot fails", async () => {
const error = new Error("Test");
const service = mock<IcManagementService>();
service.load_canister_snapshot.mockRejectedValue(error);

const icManagement = await createICManagement(service);

const call = () =>
icManagement.loadCanisterSnapshot({
canisterId: mockCanisterId,
snapshotId: Uint8Array.from([1, 2, 3, 4]),
});

await expect(call).rejects.toThrow(error);
});
});
});
32 changes: 32 additions & 0 deletions packages/ic-management/src/ic-management.canister.ts
Original file line number Diff line number Diff line change
Expand Up @@ -413,4 +413,36 @@ export class ICManagementCanister {
canister_id: canisterId,
});
};

/**
* Loads a snapshot of a canister's state.
*
* @link https://internetcomputer.org/docs/current/references/ic-interface-spec#ic-load_canister_snapshot
*
* @param {Object} params - Parameters for the snapshot loading operation.
* @param {Principal} params.canisterId - The ID of the canister for which the snapshot will be loaded.
* @param {snapshot_id} params.snapshotId - The ID of the snapshot to load.
* @param {BigInt} [params.senderCanisterVersion] - The optional sender canister version. If provided, its value must be equal to ic0.canister_version.
*
* @returns {Promise<void>} A promise that resolves when the snapshot is successfully loaded.
*
* @throws {Error} If the snapshot loading operation fails.
*/
loadCanisterSnapshot = async ({
canisterId,
snapshotId,
senderCanisterVersion,
}: {
canisterId: Principal;
snapshotId: SnapshotIdText | snapshot_id;
senderCanisterVersion?: bigint;
}): Promise<void> => {
const { load_canister_snapshot } = this.service;

await load_canister_snapshot({
canister_id: canisterId,
snapshot_id: mapSnapshotId(snapshotId),
sender_canister_version: toNullable(senderCanisterVersion),
});
};
}

0 comments on commit e662b54

Please sign in to comment.