diff --git a/packages/agent/src/actor.ts b/packages/agent/src/actor.ts index f447da3e..25177b02 100644 --- a/packages/agent/src/actor.ts +++ b/packages/agent/src/actor.ts @@ -540,8 +540,6 @@ function _createActorMethod( ? (agent as HttpAgent).replicaTime : undefined; - certTime; - if (response.body && response.body.certificate) { const cert = response.body.certificate; certificate = await Certificate.create({ diff --git a/packages/agent/src/agent/http/index.ts b/packages/agent/src/agent/http/index.ts index c3d34f57..cbd360d1 100644 --- a/packages/agent/src/agent/http/index.ts +++ b/packages/agent/src/agent/http/index.ts @@ -428,6 +428,8 @@ export class HttpAgent implements Agent { arg: ArrayBuffer; effectiveCanisterId?: Principal | string; callSync?: boolean; + tries?: number; + systemTime?: number }, identity?: Identity | Promise, ): Promise { @@ -445,13 +447,7 @@ export class HttpAgent implements Agent { const sender: Principal = id.getPrincipal() || Principal.anonymous(); - let ingress_expiry = new Expiry(DEFAULT_INGRESS_EXPIRY_DELTA_IN_MSECS); - - // If the value is off by more than 30 seconds, reconcile system time with the network - const timeDiffMsecs = this.replicaTime && this.replicaTime.getTime() - Date.now(); - if (Math.abs(timeDiffMsecs) > 1_000 * 30) { - ingress_expiry = new Expiry(DEFAULT_INGRESS_EXPIRY_DELTA_IN_MSECS + timeDiffMsecs); - } + const ingress_expiry = new Expiry(DEFAULT_INGRESS_EXPIRY_DELTA_IN_MSECS, options.systemTime); const submit: CallRequest = { request_type: SubmitRequestType.Call, @@ -567,12 +563,15 @@ export class HttpAgent implements Agent { // If the error is due to the ingress expiry being misconfigured, // sync this instance's replica time using the value provided in // the error response and retry - if ((error as ReplicaTimeError).message.includes('ingress_expiry')) { + if ((error as ReplicaTimeError).message.includes('ingress_expiry') && (options.tries ?? 1) < this.#retryTimes) { this.log.warn('Agent time out of sync. Updating and retrying...'); - this.replicaTime = (error as ReplicaTimeError).replicaTime; return this.call( canisterId, - options, + { + ...options, + tries: (options.tries ?? 1) + 1, + systemTime: (error as ReplicaTimeError).replicaTime.getTime(), + }, identity, ); } diff --git a/packages/agent/src/agent/http/transforms.ts b/packages/agent/src/agent/http/transforms.ts index 934dfbfb..16447964 100644 --- a/packages/agent/src/agent/http/transforms.ts +++ b/packages/agent/src/agent/http/transforms.ts @@ -11,15 +11,13 @@ import { const NANOSECONDS_PER_MILLISECONDS = BigInt(1_000_000); -const REPLICA_PERMITTED_DRIFT_MILLISECONDS = 60 * 1000; - export class Expiry { private readonly _value: bigint; - constructor(deltaInMSec: number) { + constructor(deltaInMSec: number, systemTime: number = Date.now()) { // Use bigint because it can overflow the maximum number allowed in a double float. const raw_value = - BigInt(Math.floor(Date.now() + deltaInMSec - REPLICA_PERMITTED_DRIFT_MILLISECONDS)) * + BigInt(Math.floor(systemTime + deltaInMSec)) * NANOSECONDS_PER_MILLISECONDS; // round down to the nearest second