From bb52652fc2a1cf0dc9cf9456e1ca60f4de2f28e5 Mon Sep 17 00:00:00 2001 From: Kyle Peacock Date: Thu, 18 Jul 2024 10:59:44 -0700 Subject: [PATCH] feat: allow for setting HttpAgent ingress expiry using `ingressExpiryInMinutes` option --- docs/CHANGELOG.md | 4 ++ e2e/node/basic/mainnet.test.ts | 46 ++++++++++++++++++++++ packages/agent/src/agent/http/http.test.ts | 25 ++++-------- packages/agent/src/agent/http/index.ts | 5 +++ 4 files changed, 63 insertions(+), 17 deletions(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 48f2a12f..94c0f938 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Added + +- feat: allow for setting HttpAgent ingress expiry using `ingressExpiryInMinutes` option + ## [2.0.0] - 2024-07-16 ### Changed diff --git a/e2e/node/basic/mainnet.test.ts b/e2e/node/basic/mainnet.test.ts index 3692d233..fd844f6a 100644 --- a/e2e/node/basic/mainnet.test.ts +++ b/e2e/node/basic/mainnet.test.ts @@ -140,3 +140,49 @@ describe('call forwarding', () => { reply; // ArrayBuffer }, 15_000); }); + +// TODO: change Expiry logic rounding to make <= 1 minute expiry work +test.skip('it should succeed when setting an expiry in the near future', async () => { + ``; + const agent = await HttpAgent.create({ + host: 'https://icp-api.io', + ingressExpiryInMinutes: 1, + }); + + await agent.syncTime(); + + expect( + agent.call('tnnnb-2yaaa-aaaab-qaiiq-cai', { + methodName: 'inc_read', + arg: fromHex('4449444c0000'), + effectiveCanisterId: 'tnnnb-2yaaa-aaaab-qaiiq-cai', + }), + ).rejects.toThrowError(`Specified ingress_expiry not within expected range`); +}); + +test('it should succeed when setting an expiry in the future', async () => { + ``; + const agent = await HttpAgent.create({ + host: 'https://icp-api.io', + ingressExpiryInMinutes: 5, + }); + + await agent.syncTime(); + + expect( + agent.call('tnnnb-2yaaa-aaaab-qaiiq-cai', { + methodName: 'inc_read', + arg: fromHex('4449444c0000'), + effectiveCanisterId: 'tnnnb-2yaaa-aaaab-qaiiq-cai', + }), + ).resolves.toBeDefined(); +}); + +test('it should fail when setting an expiry in the far future', async () => { + expect( + HttpAgent.create({ + host: 'https://icp-api.io', + ingressExpiryInMinutes: 100, + }), + ).rejects.toThrowError(`The maximum ingress expiry time is 5 minutes`); +}); diff --git a/packages/agent/src/agent/http/http.test.ts b/packages/agent/src/agent/http/http.test.ts index 9b1b4beb..04256f6e 100644 --- a/packages/agent/src/agent/http/http.test.ts +++ b/packages/agent/src/agent/http/http.test.ts @@ -811,21 +811,12 @@ test('it should log errors to console if the option is set', async () => { }); -test.only('it should allow for configuring a max age in minutes for the ingress expiry', async () => { - const mockFetch = jest.fn(); - - const agent = await HttpAgent.create({ - host: HTTP_AGENT_HOST, - fetch: mockFetch, - ingressExpiryInMinutes: 5, - }); - - await agent.syncTime(); - - await agent.call(Principal.managementCanister(), { - methodName: 'test', - arg: new Uint8Array().buffer, - }); - - const requestBody: any = cbor.decode(mockFetch.mock.calls[0][1].body); +test('it should fail when setting an expiry in the past', async () => { + expect(() => + HttpAgent.createSync({ + host: 'https://icp-api.io', + ingressExpiryInMinutes: -1, + fetch: jest.fn(), + }), + ).toThrow(`Ingress expiry time must be greater than 0`); }); diff --git a/packages/agent/src/agent/http/index.ts b/packages/agent/src/agent/http/index.ts index edd2dfb4..366773ea 100644 --- a/packages/agent/src/agent/http/index.ts +++ b/packages/agent/src/agent/http/index.ts @@ -315,6 +315,11 @@ export class HttpAgent implements Agent { `The maximum ingress expiry time is 5 minutes. Provided ingress expiry time is ${options.ingressExpiryInMinutes} minutes.`, ); } + if (options.ingressExpiryInMinutes && options.ingressExpiryInMinutes <= 0) { + throw new AgentError( + `Ingress expiry time must be greater than 0. Provided ingress expiry time is ${options.ingressExpiryInMinutes} minutes.`, + ); + } this.#maxIngressExpiryInMinutes = options.ingressExpiryInMinutes || 5;