(Fix) Geth nodes gas estimation errors (#1635)

* Replaces getNonGETHErrorDataResult with getDataFromNodeErrorMessage
Updates the extraction of data from the error message to include new GETH nodes version

* Add tests for new GETH nodes
This commit is contained in:
Agustin Pane 2020-11-20 13:56:29 -03:00 committed by Daniel Sanchez
parent c36a610cbe
commit 7e2bd37647
2 changed files with 29 additions and 10 deletions

View File

@ -93,19 +93,40 @@ export const estimateTxGasCosts = async (
} }
} }
// Parses the result of OpenEthereum/Parity and Nethermind error messages and returns the value // Parses the result from the error message (GETH, OpenEthereum/Parity and Nethermind) and returns the data value
export const getNonGETHErrorDataResult = (errorMessage: string): string | undefined => { export const getDataFromNodeErrorMessage = (errorMessage: string): string | undefined => {
// Extracts JSON object from the error message // Extracts JSON object from the error message
const [, ...error] = errorMessage.split('\n') const [, ...error] = errorMessage.split('\n')
try { try {
const errorAsJSON = JSON.parse(error.join('')) const errorAsJSON = JSON.parse(error.join(''))
// For new GETH nodes they will return the data as error in the format:
// {
// "originalError": {
// "code": number,
// "data": string,
// "message": "execution reverted: ..."
// }
// }
if (errorAsJSON.originalError && errorAsJSON.originalError.data) {
return errorAsJSON.originalError.data
}
// OpenEthereum/Parity nodes will return the data as error in the format:
// {
// "error": {
// "code": number,
// "message": string,
// "data": "revert: 0x..." -> this is the result data that should be extracted from the message
// },
// "id": number
// }
if (errorAsJSON?.data) { if (errorAsJSON?.data) {
const [, dataResult] = errorAsJSON.data.split(' ') const [, dataResult] = errorAsJSON.data.split(' ')
return dataResult return dataResult
} }
} catch (error) { } catch (error) {
console.error(`Error trying to extract data from openEthereum/Nethermind error message: ${errorMessage}`) console.error(`Error trying to extract data from node error message: ${errorMessage}`)
} }
} }
@ -120,18 +141,16 @@ const getGasEstimationTxResponse = async (txConfig: {
try { try {
const result = await web3.eth.call(txConfig) const result = await web3.eth.call(txConfig)
// GETH Nodes // GETH Nodes (geth version < v1.9.24)
// In case that the gas is not enough we will receive an EMPTY data // In case that the gas is not enough we will receive an EMPTY data
// Otherwise we will receive the gas amount as hash data // Otherwise we will receive the gas amount as hash data -> this is valid for old versions of GETH nodes ( < v1.9.24)
if (!sameString(result, EMPTY_DATA)) { if (!sameString(result, EMPTY_DATA)) {
return new BigNumber(result.substring(138), 16).toNumber() return new BigNumber(result.substring(138), 16).toNumber()
} }
} catch (error) { } catch (error) {
// OpenEthereum/Parity nodes
// Parity/OpenEthereum nodes always returns the response as an error
// So we try to extract the estimation result within the error in case is possible // So we try to extract the estimation result within the error in case is possible
const estimationData = getNonGETHErrorDataResult(error.message) const estimationData = getDataFromNodeErrorMessage(error.message)
if (!estimationData || sameString(estimationData, EMPTY_DATA)) { if (!estimationData || sameString(estimationData, EMPTY_DATA)) {
throw error throw error
@ -140,8 +159,8 @@ const getGasEstimationTxResponse = async (txConfig: {
return new BigNumber(estimationData.substring(138), 16).toNumber() return new BigNumber(estimationData.substring(138), 16).toNumber()
} }
// This will fail in case that we receive an EMPTY_DATA on the GETH node gas estimation // This will fail in case that we receive an EMPTY_DATA on the GETH node gas estimation (for version < v1.9.24 of geth nodes)
// We cannot throw this error above because it will be captured again on the OpenEthereum code bellow // We cannot throw this error above because it will be captured again on the catch block bellow
throw new Error('Error while estimating the gas required for tx') throw new Error('Error while estimating the gas required for tx')
} }