Compare commits

..

1 Commits

Author SHA1 Message Date
Alexander Kolotov
d229840830 temporary solution for insufficient gas issue for AMB oracles 2020-08-05 14:43:14 +03:00
12 changed files with 26 additions and 82 deletions

View File

@@ -64,6 +64,10 @@ export const StatusContainer = ({ onBackToMain, setNetworkFromParams, receiptPar
const displayReference = multiMessageSelected ? messages[selectedMessageId].id : txHash const displayReference = multiMessageSelected ? messages[selectedMessageId].id : txHash
const formattedMessageId = formatTxHash(displayReference) const formattedMessageId = formatTxHash(displayReference)
const displayedDescription = multiMessageSelected
? getTransactionStatusDescription(TRANSACTION_STATUS.SUCCESS_ONE_MESSAGE, timestamp)
: description
const isHome = chainId === home.chainId.toString() const isHome = chainId === home.chainId.toString()
const txExplorerLink = getExplorerTxUrl(txHash, isHome) const txExplorerLink = getExplorerTxUrl(txHash, isHome)
const displayExplorerLink = status !== TRANSACTION_STATUS.NOT_FOUND const displayExplorerLink = status !== TRANSACTION_STATUS.NOT_FOUND
@@ -71,32 +75,17 @@ export const StatusContainer = ({ onBackToMain, setNetworkFromParams, receiptPar
const displayConfirmations = status === TRANSACTION_STATUS.SUCCESS_ONE_MESSAGE || multiMessageSelected const displayConfirmations = status === TRANSACTION_STATUS.SUCCESS_ONE_MESSAGE || multiMessageSelected
const messageToConfirm = const messageToConfirm =
messages.length > 1 ? messages[selectedMessageId] : messages.length > 0 ? messages[0] : { id: '', data: '' } messages.length > 1 ? messages[selectedMessageId] : messages.length > 0 ? messages[0] : { id: '', data: '' }
let displayedDescription: string = multiMessageSelected
? getTransactionStatusDescription(TRANSACTION_STATUS.SUCCESS_ONE_MESSAGE, timestamp)
: description
let link
const descArray = displayedDescription.split('%link')
if (descArray.length > 1) {
displayedDescription = descArray[0]
link = (
<ExplorerTxLink href={descArray[1]} target="_blank" rel="noopener noreferrer">
{descArray[1]}
</ExplorerTxLink>
)
}
return ( return (
<div> <div>
{status && ( {status && (
<p> <p>
The transaction{' '} The request{' '}
{displayExplorerLink && ( {displayExplorerLink && (
<ExplorerTxLink href={txExplorerLink} target="_blank"> <ExplorerTxLink href={txExplorerLink} target="_blank">
{formattedMessageId} {formattedMessageId}
</ExplorerTxLink> </ExplorerTxLink>
)} )}
{!displayExplorerLink && <label>{formattedMessageId}</label>} {displayedDescription} {link} {!displayExplorerLink && <label>{formattedMessageId}</label>} {displayedDescription}
</p> </p>
)} )}
{displayMessageSelector && <MessageSelector messages={messages} onMessageSelected={onMessageSelected} />} {displayMessageSelector && <MessageSelector messages={messages} onMessageSelected={onMessageSelected} />}

View File

@@ -2,8 +2,7 @@
export const TRANSACTION_STATUS_DESCRIPTION: { [key: string]: string } = { export const TRANSACTION_STATUS_DESCRIPTION: { [key: string]: string } = {
SUCCESS_MULTIPLE_MESSAGES: 'was initiated %t and contains several bridge messages. Specify one of them:', SUCCESS_MULTIPLE_MESSAGES: 'was initiated %t and contains several bridge messages. Specify one of them:',
SUCCESS_ONE_MESSAGE: 'was initiated %t', SUCCESS_ONE_MESSAGE: 'was initiated %t',
SUCCESS_NO_MESSAGES: SUCCESS_NO_MESSAGES: 'execution succeeded %t but it does not contain any bridge messages',
'successfully mined %t but it does not seem to contain any request to the bridge, \nso nothing needs to be confirmed by the validators. \nIf you are sure that the transaction should contain a request to the bridge,\ncontact to the validators by \nmessaging on %linkhttps://forum.poa.network/c/support',
FAILED: 'failed %t', FAILED: 'failed %t',
NOT_FOUND: NOT_FOUND:
'Transaction not found. \n1. Check that the transaction hash is correct. \n2. Wait several blocks for the transaction to be\nmined, gas price affects mining speed.' 'Transaction not found. \n1. Check that the transaction hash is correct. \n2. Wait several blocks for the transaction to be\nmined, gas price affects mining speed.'

View File

@@ -7,7 +7,7 @@ const rpcUrlsManager = require('./services/getRpcUrlsManager')
const { getNonce, getChainId, getEventsFromTx } = require('./tx/web3') const { getNonce, getChainId, getEventsFromTx } = require('./tx/web3')
const { sendTx } = require('./tx/sendTx') const { sendTx } = require('./tx/sendTx')
const { checkHTTPS, watchdog, syncForEach, addExtraGas } = require('./utils/utils') const { checkHTTPS, watchdog, syncForEach, addExtraGas } = require('./utils/utils')
const { EXIT_CODES, EXTRA_GAS_PERCENTAGE, MAX_GAS_LIMIT } = require('./utils/constants') const { EXIT_CODES, EXTRA_GAS_PERCENTAGE } = require('./utils/constants')
const { ORACLE_VALIDATOR_ADDRESS, ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY, ORACLE_ALLOW_HTTP_FOR_RPC } = process.env const { ORACLE_VALIDATOR_ADDRESS, ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY, ORACLE_ALLOW_HTTP_FOR_RPC } = process.env
@@ -143,12 +143,7 @@ async function sendJobTx(jobs) {
let nonce = await getNonce(web3Instance, ORACLE_VALIDATOR_ADDRESS) let nonce = await getNonce(web3Instance, ORACLE_VALIDATOR_ADDRESS)
await syncForEach(jobs, async job => { await syncForEach(jobs, async job => {
let gasLimit const gasLimit = addExtraGas(job.gasEstimate, EXTRA_GAS_PERCENTAGE)
if (typeof job.extraGas === 'number') {
gasLimit = addExtraGas(job.gasEstimate + job.extraGas, 0, MAX_GAS_LIMIT)
} else {
gasLimit = addExtraGas(job.gasEstimate, EXTRA_GAS_PERCENTAGE, MAX_GAS_LIMIT)
}
try { try {
logger.info(`Sending transaction with nonce ${nonce}`) logger.info(`Sending transaction with nonce ${nonce}`)

View File

@@ -4,11 +4,6 @@ const logger = require('../../services/logger').child({
module: 'processAffirmationRequests:estimateGas' module: 'processAffirmationRequests:estimateGas'
}) })
const { parseAMBHeader } = require('../../utils/message') const { parseAMBHeader } = require('../../utils/message')
const { strip0x } = require('../../../../commons')
const {
AMB_AFFIRMATION_REQUEST_EXTRA_GAS_ESTIMATOR: estimateExtraGas,
MIN_AMB_HEADER_LENGTH
} = require('../../utils/constants')
async function estimateGas({ web3, homeBridge, validatorContract, message, address }) { async function estimateGas({ web3, homeBridge, validatorContract, message, address }) {
try { try {
@@ -16,10 +11,10 @@ async function estimateGas({ web3, homeBridge, validatorContract, message, addre
from: address from: address
}) })
const msgGasLimit = parseAMBHeader(message).gasLimit const msgGasLimit = parseAMBHeader(message).gasLimit
// message length in bytes
const len = strip0x(message).length / 2 - MIN_AMB_HEADER_LENGTH
return gasEstimate + msgGasLimit + estimateExtraGas(len) logger.info({ gasEstimate, msgGasLimit }, 'Gas consumption parameters')
return gasEstimate + msgGasLimit + ( message.length * 32 )
} catch (e) { } catch (e) {
if (e instanceof HttpListProviderError) { if (e instanceof HttpListProviderError) {
throw e throw e

View File

@@ -4,7 +4,7 @@ const promiseLimit = require('promise-limit')
const rootLogger = require('../../services/logger') const rootLogger = require('../../services/logger')
const { web3Home } = require('../../services/web3') const { web3Home } = require('../../services/web3')
const bridgeValidatorsABI = require('../../../../contracts/build/contracts/BridgeValidators').abi const bridgeValidatorsABI = require('../../../../contracts/build/contracts/BridgeValidators').abi
const { EXIT_CODES, MAX_CONCURRENT_EVENTS, EXTRA_GAS_ABSOLUTE } = require('../../utils/constants') const { EXIT_CODES, MAX_CONCURRENT_EVENTS } = require('../../utils/constants')
const estimateGas = require('./estimateGas') const estimateGas = require('./estimateGas')
const { parseAMBMessage } = require('../../../../commons') const { parseAMBMessage } = require('../../../../commons')
const { AlreadyProcessedError, AlreadySignedError, InvalidValidatorError } = require('../../utils/errors') const { AlreadyProcessedError, AlreadySignedError, InvalidValidatorError } = require('../../utils/errors')
@@ -75,7 +75,6 @@ function processAffirmationRequestsBuilder(config) {
txToSend.push({ txToSend.push({
data, data,
gasEstimate, gasEstimate,
extraGas: EXTRA_GAS_ABSOLUTE,
transactionReference: affirmationRequest.transactionHash, transactionReference: affirmationRequest.transactionHash,
to: config.homeBridgeAddress to: config.homeBridgeAddress
}) })

View File

@@ -27,10 +27,9 @@ async function estimateGas({
}) })
const msgGasLimit = parseAMBHeader(message).gasLimit const msgGasLimit = parseAMBHeader(message).gasLimit
// + estimateExtraGas(len) logger.info({ gasEstimate, msgGasLimit }, 'Gas consumption parameters')
// is not needed here, since estimateGas will already take into account gas
// needed for memory expansion, message processing, etc. return gasEstimate + msgGasLimit + ( message.length * 32 )
return gasEstimate + msgGasLimit
} catch (e) { } catch (e) {
if (e instanceof HttpListProviderError) { if (e instanceof HttpListProviderError) {
throw e throw e

View File

@@ -8,7 +8,7 @@ const { signatureToVRS, packSignatures } = require('../../utils/message')
const { parseAMBMessage } = require('../../../../commons') const { parseAMBMessage } = require('../../../../commons')
const estimateGas = require('./estimateGas') const estimateGas = require('./estimateGas')
const { AlreadyProcessedError, IncompatibleContractError, InvalidValidatorError } = require('../../utils/errors') const { AlreadyProcessedError, IncompatibleContractError, InvalidValidatorError } = require('../../utils/errors')
const { MAX_CONCURRENT_EVENTS, EXTRA_GAS_ABSOLUTE } = require('../../utils/constants') const { MAX_CONCURRENT_EVENTS } = require('../../utils/constants')
const limit = promiseLimit(MAX_CONCURRENT_EVENTS) const limit = promiseLimit(MAX_CONCURRENT_EVENTS)
@@ -107,7 +107,6 @@ function processCollectedSignaturesBuilder(config) {
txToSend.push({ txToSend.push({
data, data,
gasEstimate, gasEstimate,
extraGas: EXTRA_GAS_ABSOLUTE,
transactionReference: colSignature.transactionHash, transactionReference: colSignature.transactionHash,
to: config.foreignBridgeAddress to: config.foreignBridgeAddress
}) })

View File

@@ -16,7 +16,7 @@ const {
watchdog, watchdog,
nonceError nonceError
} = require('./utils/utils') } = require('./utils/utils')
const { EXIT_CODES, EXTRA_GAS_PERCENTAGE, MAX_GAS_LIMIT } = require('./utils/constants') const { EXIT_CODES, EXTRA_GAS_ABSOLUTE } = require('./utils/constants')
const { ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY } = process.env const { ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY } = process.env
@@ -106,12 +106,7 @@ async function main({ msg, ackMsg, nackMsg, channel, scheduleForRetry }) {
logger.debug(`Sending ${txArray.length} transactions`) logger.debug(`Sending ${txArray.length} transactions`)
await syncForEach(txArray, async job => { await syncForEach(txArray, async job => {
let gasLimit const gasLimit = addExtraGas(job.gasEstimate, EXTRA_GAS_ABSOLUTE, logger)
if (typeof job.extraGas === 'number') {
gasLimit = addExtraGas(job.gasEstimate + job.extraGas, 0, MAX_GAS_LIMIT)
} else {
gasLimit = addExtraGas(job.gasEstimate, EXTRA_GAS_PERCENTAGE, MAX_GAS_LIMIT)
}
try { try {
logger.info(`Sending transaction with nonce ${nonce}`) logger.info(`Sending transaction with nonce ${nonce}`)

View File

@@ -1,9 +1,6 @@
module.exports = { module.exports = {
EXTRA_GAS_PERCENTAGE: 4, EXTRA_GAS_PERCENTAGE: 2,
EXTRA_GAS_ABSOLUTE: 200000, EXTRA_GAS_ABSOLUTE: 500000,
AMB_AFFIRMATION_REQUEST_EXTRA_GAS_ESTIMATOR: len => Math.floor(0.0035 * len ** 2 + 40 * len),
MIN_AMB_HEADER_LENGTH: 32 + 20 + 20 + 4 + 2 + 1 + 2,
MAX_GAS_LIMIT: 10000000,
MAX_CONCURRENT_EVENTS: 50, MAX_CONCURRENT_EVENTS: 50,
RETRY_CONFIG: { RETRY_CONFIG: {
retries: 20, retries: 20,

View File

@@ -48,13 +48,13 @@ async function waitForFunds(web3, address, minimumBalance, cb, logger) {
) )
} }
function addExtraGas(gas, extraPercentage, maxGasLimit = Infinity) { function addExtraGas(gas, extra, logger) {
gas = BigNumber(gas) gas = BigNumber(gas)
extraPercentage = BigNumber(1 + extraPercentage) const gasWithExtra = gas.plus(extra).toFixed(0)
const gasWithExtra = gas.multipliedBy(extraPercentage).toFixed(0) logger.info({ gasEstimated: gasWithExtra }, 'Gas Limit used')
return BigNumber.min(maxGasLimit, gasWithExtra) return BigNumber(gasWithExtra)
} }
function setIntervalAndRun(f, interval) { function setIntervalAndRun(f, interval) {

View File

@@ -1,6 +1,6 @@
const { BN, toBN } = require('web3').utils const { BN, toBN } = require('web3').utils
const { expect } = require('chai').use(require('bn-chai')(BN)) const { expect } = require('chai').use(require('bn-chai')(BN))
const { createMessage, parseMessage, signatureToVRS, parseAMBHeader } = require('../src/utils/message') const { createMessage, parseMessage, signatureToVRS } = require('../src/utils/message')
describe('message utils', () => { describe('message utils', () => {
const expectedMessageLength = 104 const expectedMessageLength = 104
@@ -288,19 +288,4 @@ describe('message utils', () => {
expect(signatureThunk).to.throw() expect(signatureThunk).to.throw()
}) })
}) })
describe('parseAMBHeader', () => {
it('should return correct values for parsed headers', () => {
// given
const message =
'0x000500009a6ff99b356dd998260582be7d95a4d08b2132600000000000000061339d0e6f308a410f18888932bdf661636a0f538f34718200957aeadd6bece186e61b95618e73a6dc000f42400101002a4d2fb102cf00000000000000000000000081c770bbe8f5f41b4642ed575e630c911c94e4070000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000002e516d543162324178466b6643456a6f715861547148734370666f724a4c66765667434853516e513847575a347662000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e516d5a7543586f693378487338486e4c325a423539316674466f4c454471516b473655746e47324d6d513147614e000000000000000000000000000000000000'
const { messageId, sender, executor, gasLimit } = parseAMBHeader(message)
// then
expect(messageId).to.equal('0x000500009a6ff99b356dd998260582be7d95a4d08b2132600000000000000061')
expect(sender).to.equal('0x339d0e6f308a410f18888932bdf661636a0f538f')
expect(executor).to.equal('0x34718200957aeadd6bece186e61b95618e73a6dc')
expect(gasLimit).to.equal(1000000)
})
})
}) })

View File

@@ -34,14 +34,6 @@ describe('utils', () => {
expect(result.toString()).to.equal('225') expect(result.toString()).to.equal('225')
}) })
it('should handle maxGasLimit', () => {
const result1 = addExtraGas(new BigNumber(100), 0.25, 110)
const result2 = addExtraGas(new BigNumber(100), 0.25, 150)
expect(result1.toString()).to.equal('110')
expect(result2.toString()).to.equal('125')
})
}) })
describe('checkHTTPS', () => { describe('checkHTTPS', () => {