From 591f57193d7a55985df49b6320d7413c7fb6b9ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaan=20Uzdo=C4=9Fan?= Date: Tue, 11 Apr 2023 14:08:01 +0300 Subject: [PATCH 1/7] Show server response when Sourcify fails --- src/verifier/SourcifyVerifier.ts | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/verifier/SourcifyVerifier.ts b/src/verifier/SourcifyVerifier.ts index c2e5e88..cec28c7 100644 --- a/src/verifier/SourcifyVerifier.ts +++ b/src/verifier/SourcifyVerifier.ts @@ -26,8 +26,17 @@ export class SourcifyVerifier extends AbstractVerifier implements Verifier { await this.checkBoundaries(); const res = await this.sendVerifyRequest(artifact); - enforceOrThrow(res.data?.result?.length === 1, `Failed to connect to Sourcify API at url ${SOURCIFY_API_URL}`); + const verificationStatus = res.data?.result[0]?.status; + if (verificationStatus !== 'perfect' || verificationStatus !== 'partial') { + throw new Error( + `Sourcify couldn't verify the contract. Server response at ${SOURCIFY_API_URL}: \n ${JSON.stringify( + res.data.result[0], + null, + 2 + )}` + ); + } const [contract] = res.data.result; if (contract.storageTimestamp) { @@ -83,9 +92,10 @@ export class SourcifyVerifier extends AbstractVerifier implements Verifier { logObject(this.logger, 'debug', postQueries, 2); return await axios.post(SOURCIFY_API_URL, postQueries); } catch (error: any) { - this.logger.debug(error.message); - this.logger.debug(error.response.data.message); - throw new Error(`Failed to connect to Sourcify API at url ${SOURCIFY_API_URL}`); + this.logger.info(error.message); + this.logger.info(`Response from ${SOURCIFY_API_URL}:`); + this.logger.info(error.response.data); + throw new Error(`Sourcify verification failed at ${SOURCIFY_API_URL}`); } } @@ -103,7 +113,7 @@ export class SourcifyVerifier extends AbstractVerifier implements Verifier { private async getSupportedChains() { if (this.supportedChainIds) return this.supportedChainIds; - const chainsUrl = `${SOURCIFY_API_URL}chains` + const chainsUrl = `${SOURCIFY_API_URL}chains`; try { this.logger.debug(`Fetching supported chains from ${chainsUrl}`); From a1fb9ba8d98df3a436540725cdb18d49ee408c55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaan=20Uzdo=C4=9Fan?= Date: Thu, 13 Apr 2023 11:28:56 +0300 Subject: [PATCH 2/7] Fix status check logic --- src/verifier/SourcifyVerifier.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/verifier/SourcifyVerifier.ts b/src/verifier/SourcifyVerifier.ts index cec28c7..dfb3aff 100644 --- a/src/verifier/SourcifyVerifier.ts +++ b/src/verifier/SourcifyVerifier.ts @@ -28,7 +28,7 @@ export class SourcifyVerifier extends AbstractVerifier implements Verifier { const res = await this.sendVerifyRequest(artifact); const verificationStatus = res.data?.result[0]?.status; - if (verificationStatus !== 'perfect' || verificationStatus !== 'partial') { + if (verificationStatus !== 'perfect' && verificationStatus !== 'partial') { throw new Error( `Sourcify couldn't verify the contract. Server response at ${SOURCIFY_API_URL}: \n ${JSON.stringify( res.data.result[0], From 73e0122ca206bcd6dcc78b494f6a8c223cd9d08d Mon Sep 17 00:00:00 2001 From: Rosco Kalis Date: Thu, 13 Apr 2023 18:12:32 +0200 Subject: [PATCH 3/7] Try to discern between failed verification errors and other errors for Sourcify API --- src/verifier/AbstractVerifier.ts | 4 +- src/verifier/EtherscanVerifier.ts | 2 +- src/verifier/SourcifyVerifier.ts | 93 ++++++++++++++++--------------- src/verifier/Verifier.ts | 4 +- 4 files changed, 53 insertions(+), 50 deletions(-) diff --git a/src/verifier/AbstractVerifier.ts b/src/verifier/AbstractVerifier.ts index 5d7d1ea..28107e3 100644 --- a/src/verifier/AbstractVerifier.ts +++ b/src/verifier/AbstractVerifier.ts @@ -8,12 +8,12 @@ export abstract class AbstractVerifier { abstract name: string; abstract getContractUrl(address: string): string | undefined; - abstract verifyContract(artifact: Artifact): Promise; + abstract verifyContract(artifact: Artifact): Promise; abstract verifyProxyContract( proxyArtifact: Artifact, implementationName: string, implementationAddress: string - ): Promise; + ): Promise; logger: Logger; diff --git a/src/verifier/EtherscanVerifier.ts b/src/verifier/EtherscanVerifier.ts index 4a1b8c0..90eb6e7 100644 --- a/src/verifier/EtherscanVerifier.ts +++ b/src/verifier/EtherscanVerifier.ts @@ -32,7 +32,7 @@ export class EtherscanVerifier extends AbstractVerifier implements Verifier { await super.verifyAll(contractNameAddressPairs); } - async verifyContract(artifact: Artifact): Promise { + async verifyContract(artifact: Artifact): Promise { this.checkBoundaries(); const res = await this.sendVerifyRequest(artifact); diff --git a/src/verifier/SourcifyVerifier.ts b/src/verifier/SourcifyVerifier.ts index dfb3aff..a7542c3 100644 --- a/src/verifier/SourcifyVerifier.ts +++ b/src/verifier/SourcifyVerifier.ts @@ -22,35 +22,65 @@ export class SourcifyVerifier extends AbstractVerifier implements Verifier { await super.verifyAll(contractNameAddressPairs); } - async verifyContract(artifact: Artifact): Promise { + // Note that Sourcify may indicate failed verification in through errors, but also through 200 responses + // This is why we check both cases + async verifyContract(artifact: Artifact): Promise { await this.checkBoundaries(); - const res = await this.sendVerifyRequest(artifact); + const inputJSON = await getInputJSON(artifact, this.options, this.logger); - const verificationStatus = res.data?.result[0]?.status; - if (verificationStatus !== 'perfect' && verificationStatus !== 'partial') { - throw new Error( - `Sourcify couldn't verify the contract. Server response at ${SOURCIFY_API_URL}: \n ${JSON.stringify( - res.data.result[0], - null, - 2 - )}` - ); - } - const [contract] = res.data.result; + const files: { [path: string]: string } = {}; + Object.keys(inputJSON.sources).forEach((path) => { + files[path.replace(/^.*[\\/]/, '')] = inputJSON.sources[path].content; + }); + files['metadata.json'] = JSON.stringify(JSON.parse(artifact.metadata)); - if (contract.storageTimestamp) { - return VerificationStatus.ALREADY_VERIFIED; - } + const postQueries = { + address: artifact.networks[`${this.options.networkId}`].address, + chain: `${this.options.chainId}`, + files, + }; + + try { + this.logger.debug('Sending verify request with POST arguments:'); + // logObject(this.logger, 'debug', postQueries, 2); + const res = await axios.post(SOURCIFY_API_URL, postQueries); + + const [result] = res?.data?.result ?? []; + this.logger.debug('Received response:'); + logObject(this.logger, 'debug', result, 2); + + if (result?.status !== 'perfect' && result?.status !== 'partial') { + return `${VerificationStatus.FAILED}: ${result?.message}` + } + + if (result.storageTimestamp) { + return VerificationStatus.ALREADY_VERIFIED; + } + + return VerificationStatus.SUCCESS; + } catch (error: any) { + const errorResponse = error?.response?.data; + const errorResponseMessage = errorResponse?.message ?? errorResponse?.error; + + this.logger.debug(`Error: ${error?.message}`); + logObject(this.logger, 'debug', error?.response?.data, 2) - return VerificationStatus.SUCCESS; + // If an error message is present in the checked response, this likely indicates a failed verification + if (errorResponseMessage) { + return `${VerificationStatus.FAILED}: ${errorResponseMessage}}` + } + + // If no message was passed in the response, this likely indicates a failed connection + throw new Error(`Could not connect to Sourcify API at url ${SOURCIFY_API_URL}`); + } } async verifyProxyContract( proxyArtifact: Artifact, implementationName: string, implementationAddress: string - ): Promise { + ): Promise { await this.checkBoundaries(); if (this.options.customProxy) { @@ -72,33 +102,6 @@ export class SourcifyVerifier extends AbstractVerifier implements Verifier { return status; } - private async sendVerifyRequest(artifact: Artifact) { - const inputJSON = await getInputJSON(artifact, this.options, this.logger); - - const files: { [path: string]: string } = {}; - Object.keys(inputJSON.sources).forEach((path) => { - files[path.replace(/^.*[\\/]/, '')] = inputJSON.sources[path].content; - }); - files['metadata.json'] = JSON.stringify(JSON.parse(artifact.metadata)); - - const postQueries = { - address: artifact.networks[`${this.options.networkId}`].address, - chain: `${this.options.chainId}`, - files, - }; - - try { - this.logger.debug('Sending verify request with POST arguments:'); - logObject(this.logger, 'debug', postQueries, 2); - return await axios.post(SOURCIFY_API_URL, postQueries); - } catch (error: any) { - this.logger.info(error.message); - this.logger.info(`Response from ${SOURCIFY_API_URL}:`); - this.logger.info(error.response.data); - throw new Error(`Sourcify verification failed at ${SOURCIFY_API_URL}`); - } - } - private async checkBoundaries() { enforceOrThrow( await this.isSupportedChain(this.options.chainId), diff --git a/src/verifier/Verifier.ts b/src/verifier/Verifier.ts index 9b5e8b7..c194414 100644 --- a/src/verifier/Verifier.ts +++ b/src/verifier/Verifier.ts @@ -5,11 +5,11 @@ export interface Verifier { name: string; options: Options; getContractUrl(address: string): string | undefined; - verifyContract(artifact: Artifact): Promise; + verifyContract(artifact: Artifact): Promise; verifyProxyContract( proxyArtifact: Artifact, implementationName: string, implementationAddress: string - ): Promise; + ): Promise; verifyAll(contractNameAddressPairs: string[]): Promise; } From 085bfd03a83814ce9dd50275227211a4223e8967 Mon Sep 17 00:00:00 2001 From: Rosco Kalis Date: Thu, 13 Apr 2023 18:17:47 +0200 Subject: [PATCH 4/7] Uncomment logger line --- src/verifier/SourcifyVerifier.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/verifier/SourcifyVerifier.ts b/src/verifier/SourcifyVerifier.ts index a7542c3..5b7940e 100644 --- a/src/verifier/SourcifyVerifier.ts +++ b/src/verifier/SourcifyVerifier.ts @@ -43,7 +43,7 @@ export class SourcifyVerifier extends AbstractVerifier implements Verifier { try { this.logger.debug('Sending verify request with POST arguments:'); - // logObject(this.logger, 'debug', postQueries, 2); + logObject(this.logger, 'debug', postQueries, 2); const res = await axios.post(SOURCIFY_API_URL, postQueries); const [result] = res?.data?.result ?? []; From 726d0799caddf7667ef4261ee0bab2657f534e71 Mon Sep 17 00:00:00 2001 From: Rosco Kalis Date: Sat, 15 Apr 2023 14:01:52 +0200 Subject: [PATCH 5/7] Update src/verifier/SourcifyVerifier.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Kaan Uzdoğan --- src/verifier/SourcifyVerifier.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/verifier/SourcifyVerifier.ts b/src/verifier/SourcifyVerifier.ts index 5b7940e..345d451 100644 --- a/src/verifier/SourcifyVerifier.ts +++ b/src/verifier/SourcifyVerifier.ts @@ -68,7 +68,7 @@ export class SourcifyVerifier extends AbstractVerifier implements Verifier { // If an error message is present in the checked response, this likely indicates a failed verification if (errorResponseMessage) { - return `${VerificationStatus.FAILED}: ${errorResponseMessage}}` + return `${VerificationStatus.FAILED}: ${errorResponseMessage}` } // If no message was passed in the response, this likely indicates a failed connection From 9bd63b44255116c7c8c2e961ddb6d02ce8fb888f Mon Sep 17 00:00:00 2001 From: Rosco Kalis Date: Wed, 19 Apr 2023 11:35:24 +0200 Subject: [PATCH 6/7] Add differentiation between perfect and partial match for sourcify --- src/constants.ts | 1 + src/verifier/SourcifyVerifier.ts | 14 +++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/constants.ts b/src/constants.ts index 758fc35..033e64e 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -81,6 +81,7 @@ export const RequestStatus = { export enum VerificationStatus { FAILED = 'Fail - Unable to verify', SUCCESS = 'Pass - Verified', + PARTIAL = 'Pass - Verified (with a metadata mismatch)', PENDING = 'Pending in queue', ALREADY_VERIFIED = 'Contract source code already verified', AUTOMATICALLY_VERIFIED = 'Already Verified', diff --git a/src/verifier/SourcifyVerifier.ts b/src/verifier/SourcifyVerifier.ts index 345d451..130e9d7 100644 --- a/src/verifier/SourcifyVerifier.ts +++ b/src/verifier/SourcifyVerifier.ts @@ -50,15 +50,15 @@ export class SourcifyVerifier extends AbstractVerifier implements Verifier { this.logger.debug('Received response:'); logObject(this.logger, 'debug', result, 2); - if (result?.status !== 'perfect' && result?.status !== 'partial') { - return `${VerificationStatus.FAILED}: ${result?.message}` + if (!result) { + // If no result was returned, there is likely an issue with the API connection + throw new Error(`Could not connect to Sourcify API at url ${SOURCIFY_API_URL}`); } - if (result.storageTimestamp) { - return VerificationStatus.ALREADY_VERIFIED; - } - - return VerificationStatus.SUCCESS; + if (result.storageTimestamp) return VerificationStatus.ALREADY_VERIFIED; + if (result.status === 'partial') return VerificationStatus.PARTIAL; + if (result.status === 'perfect') return VerificationStatus.SUCCESS; + return `${VerificationStatus.FAILED}: ${result?.message}` } catch (error: any) { const errorResponse = error?.response?.data; const errorResponseMessage = errorResponse?.message ?? errorResponse?.error; From 9474ffd1a8bb33d65163a0f0774c18de7de74f34 Mon Sep 17 00:00:00 2001 From: Rosco Kalis Date: Mon, 24 Apr 2023 16:53:58 +0200 Subject: [PATCH 7/7] Update partial verification string --- src/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/constants.ts b/src/constants.ts index 033e64e..d8996f7 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -81,7 +81,7 @@ export const RequestStatus = { export enum VerificationStatus { FAILED = 'Fail - Unable to verify', SUCCESS = 'Pass - Verified', - PARTIAL = 'Pass - Verified (with a metadata mismatch)', + PARTIAL = 'Pass - Partially Verified (with a metadata mismatch)', PENDING = 'Pending in queue', ALREADY_VERIFIED = 'Contract source code already verified', AUTOMATICALLY_VERIFIED = 'Already Verified',