(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
export const getNonGETHErrorDataResult = (errorMessage: string): string | undefined => {
// Parses the result from the error message (GETH, OpenEthereum/Parity and Nethermind) and returns the data value
export const getDataFromNodeErrorMessage = (errorMessage: string): string | undefined => {
// Extracts JSON object from the error message
const [, ...error] = errorMessage.split('\n')
try {
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) {
const [, dataResult] = errorAsJSON.data.split(' ')
return dataResult
}
} 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 {
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
// 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)) {
return new BigNumber(result.substring(138), 16).toNumber()
}
} 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
const estimationData = getNonGETHErrorDataResult(error.message)
const estimationData = getDataFromNodeErrorMessage(error.message)
if (!estimationData || sameString(estimationData, EMPTY_DATA)) {
throw error
@ -140,8 +159,8 @@ const getGasEstimationTxResponse = async (txConfig: {
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
// We cannot throw this error above because it will be captured again on the OpenEthereum code bellow
// 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 catch block bellow
throw new Error('Error while estimating the gas required for tx')
}