diff --git a/src/providers/retryProvider.ts b/src/providers/retryProvider.ts index 436be844..f77330fd 100644 --- a/src/providers/retryProvider.ts +++ b/src/providers/retryProvider.ts @@ -125,9 +125,38 @@ export class RetryProvider extends ethers.providers.StaticJsonRpcProvider { return values[0][1]; } - const throwQuorumError = () => { + const getMismatchedProviders = (values: [ethers.providers.StaticJsonRpcProvider, unknown][]) => { + return Object.fromEntries( + values + .filter(([, result]) => !compareRpcResults(method, result, quorumResult)) + .map(([provider, result]) => [provider.connection.url, result]) + ); + }; + + const logQuorumMismatchOrFailureDetails = ( + method: string, + params: Array, + quorumProviders: string[], + mismatchedProviders: { [k: string]: unknown }, + errors: [ethers.providers.StaticJsonRpcProvider, string][] + ) => { + logger.warn({ + at: "ProviderUtils", + message: "Some providers mismatched with the quorum result or failed 🚸", + notificationPath: "across-warn", + method, + params: JSON.stringify(params), + quorumProviders, + mismatchedProviders: JSON.stringify(mismatchedProviders), + erroringProviders: errors.map(([provider, errorText]) => formatProviderError(provider, errorText)), + }); + }; + + const throwQuorumError = (fallbackValues?: [ethers.providers.StaticJsonRpcProvider, unknown][]) => { const errorTexts = errors.map(([provider, errorText]) => formatProviderError(provider, errorText)); const successfulProviderUrls = values.map(([provider]) => provider.connection.url); + const mismatchedProviders = getMismatchedProviders([...values, ...(fallbackValues || [])]); + logQuorumMismatchOrFailureDetails(method, params, successfulProviderUrls, mismatchedProviders, errors); throw new Error( "Not enough providers agreed to meet quorum.\n" + "Providers that errored:\n" + @@ -186,29 +215,16 @@ export class RetryProvider extends ethers.providers.StaticJsonRpcProvider { // If this count is less than we need for quorum, throw the quorum error. if (count < quorumThreshold) { - throwQuorumError(); + throwQuorumError(fallbackValues); } // If we've achieved quorum, then we should still log the providers that mismatched with the quorum result. - const mismatchedProviders = Object.fromEntries( - [...values, ...fallbackValues] - .filter(([, result]) => !compareRpcResults(method, result, quorumResult)) - .map(([provider, result]) => [provider.connection.url, result]) - ); + const mismatchedProviders = getMismatchedProviders([...values, ...fallbackValues]); const quorumProviders = [...values, ...fallbackValues] .filter(([, result]) => compareRpcResults(method, result, quorumResult)) .map(([provider]) => provider.connection.url); if (Object.keys(mismatchedProviders).length > 0 || errors.length > 0) { - logger.warn({ - at: "ProviderUtils", - message: "Some providers mismatched with the quorum result or failed 🚸", - notificationPath: "across-warn", - method, - params, - quorumProviders, - mismatchedProviders, - erroringProviders: errors.map(([provider, errorText]) => formatProviderError(provider, errorText)), - }); + logQuorumMismatchOrFailureDetails(method, params, quorumProviders, mismatchedProviders, errors); } return quorumResult;