diff --git a/apps/provider-proxy/src/services/CertificateValidator.ts b/apps/provider-proxy/src/services/CertificateValidator.ts index 304bb8f92..99ac57df1 100644 --- a/apps/provider-proxy/src/services/CertificateValidator.ts +++ b/apps/provider-proxy/src/services/CertificateValidator.ts @@ -59,8 +59,10 @@ export class CertificateValidator { return this.knownCertificatesCache.get(key); } finally { - this.locks[key].release(); - delete this.locks[key]; + if (this.locks[key]) { + this.locks[key].release(); + delete this.locks[key]; + } } } } diff --git a/apps/provider-proxy/test/services/CertificateValidator.spec.ts b/apps/provider-proxy/test/services/CertificateValidator.spec.ts index 5aa580717..cd54d386d 100644 --- a/apps/provider-proxy/test/services/CertificateValidator.spec.ts +++ b/apps/provider-proxy/test/services/CertificateValidator.spec.ts @@ -152,6 +152,23 @@ describe(CertificateValidator.name, () => { expect(result.ok).toBe(true); }); + it("fetches provider certificate only once for concurrent validation of the same certificate", async () => { + const { cert } = createX509CertPair({ + validFrom: new Date(), + validTo: new Date(Date.now() + ONE_MINUTE), + commonName: "akash1rk090a6mq9gvm0h6ljf8kz8mrxglwwxsk4srxh", + serialNumber: "177831BE7F249E66" + }); + const getCertificate = jest.fn(() => Promise.resolve(cert)); + const validator = setup({ getCertificate }); + + const results = await Promise.all([validator.validate(cert, "mainnet", "provider"), validator.validate(cert, "mainnet", "provider")]); + + expect(getCertificate).toHaveBeenCalledTimes(1); + expect(results[0].ok).toBe(true); + expect(results[1].ok).toBe(true); + }); + function setup(params?: Params) { return new CertificateValidator( () => params?.now ?? Date.now(),