Skip to content

Commit

Permalink
feat!: support getting certificate back from call (#892)
Browse files Browse the repository at this point in the history
* feat: adds createActorWithExtendedDetails method
* feat!: changes return types of HttpAgent.call

Co-authored-by: Jason <[email protected]>
  • Loading branch information
krpeacock and Jason authored Jun 26, 2024
1 parent 158d9b4 commit 972e3cb
Show file tree
Hide file tree
Showing 15 changed files with 6,670 additions and 8,277 deletions.
41 changes: 41 additions & 0 deletions e2e/node/basic/__snapshots__/mainnet.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`certified query > should verify lots of query certificates > whoami seed 0 1`] = `"535yc-uxytb-gfk7h-tny7p-vjkoe-i4krp-3qmcl-uqfgr-cpgej-yqtjq-rqe"`;

exports[`certified query > should verify lots of query certificates > whoami seed 1 1`] = `"wf3fv-4c4nr-7ks2b-xa4u7-kf3no-32glf-lf7e4-4ng4a-wwtlu-a2vnq-nae"`;

exports[`certified query > should verify lots of query certificates > whoami seed 2 1`] = `"52mr2-fw2ng-2ofst-7jekz-xbymo-3ysz7-itwdk-bgstz-r7g4g-oz5vi-pqe"`;

exports[`certified query > should verify lots of query certificates > whoami seed 3 1`] = `"skpwg-42fe4-eyep5-nfyz7-66wvg-hthea-q3eek-vonbv-5wpxs-nxhmh-fqe"`;

exports[`certified query > should verify lots of query certificates > whoami seed 4 1`] = `"ghaya-cncjm-ntxgt-af5pp-6hzsz-tvwlv-hrlfc-ocq3t-ai7vk-vyixr-cqe"`;

exports[`certified query > should verify lots of query certificates > whoami seed 5 1`] = `"ebtho-zkeqd-ebs74-f5if3-lk6js-3a5q5-37xt4-3ylns-h7r4n-tkhly-aqe"`;

exports[`certified query > should verify lots of query certificates > whoami seed 6 1`] = `"5zqn5-627q2-spx2w-mt6bm-llsnz-gipvv-5femn-3box4-vzuh6-bn723-sae"`;

exports[`certified query > should verify lots of query certificates > whoami seed 7 1`] = `"tek7g-2zmny-nzjwg-ansf7-rkxv6-z32x6-3flbb-ous5d-pygjx-wkhlc-jae"`;

exports[`certified query > should verify lots of query certificates > whoami seed 8 1`] = `"jjn6g-sh75l-r3cxb-wxrkl-frqld-6p6qq-d4ato-wske5-op7s5-n566f-bqe"`;

exports[`certified query > should verify lots of query certificates > whoami seed 9 1`] = `"447dk-byguq-fqkfn-7h4r6-lpk74-itbnh-mkutj-m6tmy-igaff-hmfel-cqe"`;

exports[`certified query > should verify lots of query certificates > whoami seed 10 1`] = `"muo3f-ines5-bxbwm-6wi5e-z663m-3zte2-r7d4x-pleey-xqvxt-scwc5-jae"`;

exports[`certified query > should verify lots of query certificates > whoami seed 11 1`] = `"snzff-yj2qd-fjns7-lqhvw-rsgq7-tohk2-fjnw4-uq3d6-wtk56-pxgry-mqe"`;

exports[`certified query > should verify lots of query certificates > whoami seed 12 1`] = `"pb54o-aqais-24v7j-msopl-bqeuv-paefp-vuoqc-gkezk-grujb-oetl6-sae"`;

exports[`certified query > should verify lots of query certificates > whoami seed 13 1`] = `"bf37n-7ybos-wmqt6-yiov5-24q4m-ajpjk-madkr-snuj2-ngruk-tspnh-aqe"`;

exports[`certified query > should verify lots of query certificates > whoami seed 14 1`] = `"tbjmy-vay5e-hqvv6-sval4-zfxmm-aii6f-b7p55-hwtz5-dejtl-qcuh2-aqe"`;

exports[`certified query > should verify lots of query certificates > whoami seed 15 1`] = `"7d3pe-dh4ov-fp5xz-nctjc-5rduh-gzv3t-5ioyh-4dvx3-x4lgj-hz63t-dqe"`;

exports[`certified query > should verify lots of query certificates > whoami seed 16 1`] = `"37axv-sazcg-75pi3-owhxr-kollq-xnzjz-zfxsv-nzdbp-yaelp-shcul-jae"`;

exports[`certified query > should verify lots of query certificates > whoami seed 17 1`] = `"r772c-4dz5f-rpg4e-qzxgg-7bxlb-67zpu-bitgb-vsx7k-mmagd-6zk3d-4qe"`;

exports[`certified query > should verify lots of query certificates > whoami seed 18 1`] = `"knkon-d3kx7-du4wt-r2fo6-uwc5a-hwhkk-m7snf-nxfhu-6bhgb-k6dn5-wae"`;

exports[`certified query > should verify lots of query certificates > whoami seed 19 1`] = `"entn3-mas6a-37smu-vadtg-wgsno-zokif-vyphu-umase-lfwqe-dmcrk-kae"`;
135 changes: 57 additions & 78 deletions e2e/node/basic/mainnet.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
import { Actor, AnonymousIdentity, HttpAgent, Identity, CanisterStatus } from '@dfinity/agent';
import {
Actor,
AnonymousIdentity,
HttpAgent,
Identity,
CanisterStatus,
fromHex,
polling,
requestIdOf,
} from '@dfinity/agent';
import { IDL } from '@dfinity/candid';
import { Ed25519KeyIdentity } from '@dfinity/identity';
import { Principal } from '@dfinity/principal';
import { describe, it, expect, vi } from 'vitest';
import { describe, it, expect, vi, test } from 'vitest';
import { makeAgent } from '../utils/agent';

const { defaultStrategy, pollForResponse } = polling;

const createWhoamiActor = async (identity: Identity) => {
const canisterId = 'ivcos-eqaaa-aaaab-qablq-cai';
const idlFactory = () => {
Expand All @@ -29,88 +40,24 @@ describe('certified query', () => {
const result = await actor.whoami();
expect(Principal.from(result)).toBeInstanceOf(Principal);
}, 10_000);
it('should verify lots of query certificates', async () => {
let count = 1;
describe('should verify lots of query certificates', async () => {
let count = 0;
const identities = Array.from({ length: 20 }).map(() => {
const newIdentity = Ed25519KeyIdentity.generate(new Uint8Array(32).fill(count));
count++;
return newIdentity;
});
const actors = await identities.map(async identity => await createWhoamiActor(identity));

const promises = actors.map(async actor => (await actor).whoami());
test.each(identities.map((identity, idx) => [`whoami seed ${idx}`, identity]))(
'%s',
async (_, identity) => {
const actor = await createWhoamiActor(identity);

const results = await Promise.all(promises);
results.forEach(result => {
expect(Principal.from(result)).toBeInstanceOf(Principal);
});
expect(results.length).toBe(20);

expect(results).toMatchInlineSnapshot(`
[
{
"__principal__": "wf3fv-4c4nr-7ks2b-xa4u7-kf3no-32glf-lf7e4-4ng4a-wwtlu-a2vnq-nae",
},
{
"__principal__": "52mr2-fw2ng-2ofst-7jekz-xbymo-3ysz7-itwdk-bgstz-r7g4g-oz5vi-pqe",
},
{
"__principal__": "skpwg-42fe4-eyep5-nfyz7-66wvg-hthea-q3eek-vonbv-5wpxs-nxhmh-fqe",
},
{
"__principal__": "ghaya-cncjm-ntxgt-af5pp-6hzsz-tvwlv-hrlfc-ocq3t-ai7vk-vyixr-cqe",
},
{
"__principal__": "ebtho-zkeqd-ebs74-f5if3-lk6js-3a5q5-37xt4-3ylns-h7r4n-tkhly-aqe",
},
{
"__principal__": "5zqn5-627q2-spx2w-mt6bm-llsnz-gipvv-5femn-3box4-vzuh6-bn723-sae",
},
{
"__principal__": "tek7g-2zmny-nzjwg-ansf7-rkxv6-z32x6-3flbb-ous5d-pygjx-wkhlc-jae",
},
{
"__principal__": "jjn6g-sh75l-r3cxb-wxrkl-frqld-6p6qq-d4ato-wske5-op7s5-n566f-bqe",
},
{
"__principal__": "447dk-byguq-fqkfn-7h4r6-lpk74-itbnh-mkutj-m6tmy-igaff-hmfel-cqe",
},
{
"__principal__": "muo3f-ines5-bxbwm-6wi5e-z663m-3zte2-r7d4x-pleey-xqvxt-scwc5-jae",
},
{
"__principal__": "snzff-yj2qd-fjns7-lqhvw-rsgq7-tohk2-fjnw4-uq3d6-wtk56-pxgry-mqe",
},
{
"__principal__": "pb54o-aqais-24v7j-msopl-bqeuv-paefp-vuoqc-gkezk-grujb-oetl6-sae",
},
{
"__principal__": "bf37n-7ybos-wmqt6-yiov5-24q4m-ajpjk-madkr-snuj2-ngruk-tspnh-aqe",
},
{
"__principal__": "tbjmy-vay5e-hqvv6-sval4-zfxmm-aii6f-b7p55-hwtz5-dejtl-qcuh2-aqe",
},
{
"__principal__": "7d3pe-dh4ov-fp5xz-nctjc-5rduh-gzv3t-5ioyh-4dvx3-x4lgj-hz63t-dqe",
},
{
"__principal__": "37axv-sazcg-75pi3-owhxr-kollq-xnzjz-zfxsv-nzdbp-yaelp-shcul-jae",
},
{
"__principal__": "r772c-4dz5f-rpg4e-qzxgg-7bxlb-67zpu-bitgb-vsx7k-mmagd-6zk3d-4qe",
},
{
"__principal__": "knkon-d3kx7-du4wt-r2fo6-uwc5a-hwhkk-m7snf-nxfhu-6bhgb-k6dn5-wae",
},
{
"__principal__": "entn3-mas6a-37smu-vadtg-wgsno-zokif-vyphu-umase-lfwqe-dmcrk-kae",
},
{
"__principal__": "hy3bf-xpwhn-ru6bb-lhqol-wrjew-j2xqi-gb4gb-muivw-d6bkg-q3tp4-lqe",
},
]
`);
}, 30_000);
const result = (await actor.whoami()) as Principal;
expect(Principal.from(result)).toBeInstanceOf(Principal);
expect(result.toString()).toMatchSnapshot();
},
);
});
});

describe('controllers', () => {
Expand Down Expand Up @@ -161,3 +108,35 @@ describe('controllers', () => {
});
});

describe('call forwarding', () => {
it('should handle call forwarding', async () => {
vi.useRealTimers();
const forwardedOptions = {
canisterId: 'tnnnb-2yaaa-aaaab-qaiiq-cai',
methodName: 'inc_read',
arg: '4449444c0000',
effectiveCanisterId: 'tnnnb-2yaaa-aaaab-qaiiq-cai',
};

const agent = new HttpAgent({ host: 'https://icp-api.io' });
const { requestId, requestDetails } = await agent.call(
Principal.fromText(forwardedOptions.canisterId),
{
methodName: forwardedOptions.methodName,
arg: fromHex(forwardedOptions.arg),
effectiveCanisterId: Principal.fromText(forwardedOptions.effectiveCanisterId),
},
);

expect(requestIdOf(requestDetails!)).toStrictEqual(requestId);

const { certificate, reply } = await pollForResponse(
agent,
Principal.fromText(forwardedOptions.effectiveCanisterId),
requestId,
defaultStrategy(),
);
certificate; // Certificate
reply; // ArrayBuffer
}, 15_000);
});
Loading

0 comments on commit 972e3cb

Please sign in to comment.