Merge the develop branch to the master branch, preparation to v2.3.1
This commit is contained in:
commit
c2f6b5e8ba
@ -64,10 +64,6 @@ 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
|
||||||
@ -75,17 +71,32 @@ 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 request{' '}
|
The transaction{' '}
|
||||||
{displayExplorerLink && (
|
{displayExplorerLink && (
|
||||||
<ExplorerTxLink href={txExplorerLink} target="_blank">
|
<ExplorerTxLink href={txExplorerLink} target="_blank">
|
||||||
{formattedMessageId}
|
{formattedMessageId}
|
||||||
</ExplorerTxLink>
|
</ExplorerTxLink>
|
||||||
)}
|
)}
|
||||||
{!displayExplorerLink && <label>{formattedMessageId}</label>} {displayedDescription}
|
{!displayExplorerLink && <label>{formattedMessageId}</label>} {displayedDescription} {link}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
{displayMessageSelector && <MessageSelector messages={messages} onMessageSelected={onMessageSelected} />}
|
{displayMessageSelector && <MessageSelector messages={messages} onMessageSelected={onMessageSelected} />}
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
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: 'execution succeeded %t but it does not contain any bridge messages',
|
SUCCESS_NO_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.'
|
||||||
|
@ -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 } = require('./utils/constants')
|
const { EXIT_CODES, EXTRA_GAS_PERCENTAGE, MAX_GAS_LIMIT } = 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,7 +143,12 @@ 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 => {
|
||||||
const gasLimit = addExtraGas(job.gasEstimate, EXTRA_GAS_PERCENTAGE)
|
let gasLimit
|
||||||
|
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}`)
|
||||||
|
@ -3,14 +3,23 @@ const { AlreadyProcessedError, AlreadySignedError, InvalidValidatorError } = req
|
|||||||
const logger = require('../../services/logger').child({
|
const logger = require('../../services/logger').child({
|
||||||
module: 'processAffirmationRequests:estimateGas'
|
module: 'processAffirmationRequests:estimateGas'
|
||||||
})
|
})
|
||||||
|
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 {
|
||||||
const gasEstimate = await homeBridge.methods.executeAffirmation(message).estimateGas({
|
const gasEstimate = await homeBridge.methods.executeAffirmation(message).estimateGas({
|
||||||
from: address
|
from: address
|
||||||
})
|
})
|
||||||
|
const msgGasLimit = parseAMBHeader(message).gasLimit
|
||||||
|
// message length in bytes
|
||||||
|
const len = strip0x(message).length / 2 - MIN_AMB_HEADER_LENGTH
|
||||||
|
|
||||||
return gasEstimate
|
return gasEstimate + msgGasLimit + estimateExtraGas(len)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof HttpListProviderError) {
|
if (e instanceof HttpListProviderError) {
|
||||||
throw e
|
throw e
|
||||||
|
@ -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 } = require('../../utils/constants')
|
const { EXIT_CODES, MAX_CONCURRENT_EVENTS, EXTRA_GAS_ABSOLUTE } = 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,6 +75,7 @@ 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
|
||||||
})
|
})
|
||||||
|
@ -4,6 +4,7 @@ const { AlreadyProcessedError, IncompatibleContractError, InvalidValidatorError
|
|||||||
const logger = require('../../services/logger').child({
|
const logger = require('../../services/logger').child({
|
||||||
module: 'processCollectedSignatures:estimateGas'
|
module: 'processCollectedSignatures:estimateGas'
|
||||||
})
|
})
|
||||||
|
const { parseAMBHeader } = require('../../utils/message')
|
||||||
|
|
||||||
const web3 = new Web3()
|
const web3 = new Web3()
|
||||||
const { toBN } = Web3.utils
|
const { toBN } = Web3.utils
|
||||||
@ -24,7 +25,12 @@ async function estimateGas({
|
|||||||
const gasEstimate = await foreignBridge.methods.executeSignatures(message, signatures).estimateGas({
|
const gasEstimate = await foreignBridge.methods.executeSignatures(message, signatures).estimateGas({
|
||||||
from: address
|
from: address
|
||||||
})
|
})
|
||||||
return gasEstimate
|
const msgGasLimit = parseAMBHeader(message).gasLimit
|
||||||
|
|
||||||
|
// + estimateExtraGas(len)
|
||||||
|
// is not needed here, since estimateGas will already take into account gas
|
||||||
|
// needed for memory expansion, message processing, etc.
|
||||||
|
return gasEstimate + msgGasLimit
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof HttpListProviderError) {
|
if (e instanceof HttpListProviderError) {
|
||||||
throw e
|
throw e
|
||||||
|
@ -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 } = require('../../utils/constants')
|
const { MAX_CONCURRENT_EVENTS, EXTRA_GAS_ABSOLUTE } = require('../../utils/constants')
|
||||||
|
|
||||||
const limit = promiseLimit(MAX_CONCURRENT_EVENTS)
|
const limit = promiseLimit(MAX_CONCURRENT_EVENTS)
|
||||||
|
|
||||||
@ -107,6 +107,7 @@ 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
|
||||||
})
|
})
|
||||||
|
@ -16,7 +16,7 @@ const {
|
|||||||
watchdog,
|
watchdog,
|
||||||
nonceError
|
nonceError
|
||||||
} = require('./utils/utils')
|
} = require('./utils/utils')
|
||||||
const { EXIT_CODES, EXTRA_GAS_PERCENTAGE } = require('./utils/constants')
|
const { EXIT_CODES, EXTRA_GAS_PERCENTAGE, MAX_GAS_LIMIT } = require('./utils/constants')
|
||||||
|
|
||||||
const { ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY } = process.env
|
const { ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY } = process.env
|
||||||
|
|
||||||
@ -106,7 +106,12 @@ 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 => {
|
||||||
const gasLimit = addExtraGas(job.gasEstimate, EXTRA_GAS_PERCENTAGE)
|
let gasLimit
|
||||||
|
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}`)
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
EXTRA_GAS_PERCENTAGE: 4,
|
EXTRA_GAS_PERCENTAGE: 4,
|
||||||
|
EXTRA_GAS_ABSOLUTE: 200000,
|
||||||
|
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,
|
||||||
|
@ -73,9 +73,37 @@ function packSignatures(array) {
|
|||||||
return `0x${msgLength}${v}${r}${s}`
|
return `0x${msgLength}${v}${r}${s}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function parseAMBHeader(message) {
|
||||||
|
message = strip0x(message)
|
||||||
|
|
||||||
|
const messageIdStart = 0
|
||||||
|
const messageIdLength = 32 * 2
|
||||||
|
const messageId = `0x${message.slice(messageIdStart, messageIdStart + messageIdLength)}`
|
||||||
|
|
||||||
|
const senderStart = messageIdStart + messageIdLength
|
||||||
|
const senderLength = 20 * 2
|
||||||
|
const sender = `0x${message.slice(senderStart, senderStart + senderLength)}`
|
||||||
|
|
||||||
|
const executorStart = senderStart + senderLength
|
||||||
|
const executorLength = 20 * 2
|
||||||
|
const executor = `0x${message.slice(executorStart, executorStart + executorLength)}`
|
||||||
|
|
||||||
|
const gasLimitStart = executorStart + executorLength
|
||||||
|
const gasLimitLength = 4 * 2
|
||||||
|
const gasLimit = parseInt(message.slice(gasLimitStart, gasLimitStart + gasLimitLength), 16)
|
||||||
|
|
||||||
|
return {
|
||||||
|
messageId,
|
||||||
|
sender,
|
||||||
|
executor,
|
||||||
|
gasLimit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
createMessage,
|
createMessage,
|
||||||
parseMessage,
|
parseMessage,
|
||||||
signatureToVRS,
|
signatureToVRS,
|
||||||
packSignatures
|
packSignatures,
|
||||||
|
parseAMBHeader
|
||||||
}
|
}
|
||||||
|
@ -48,13 +48,13 @@ async function waitForFunds(web3, address, minimumBalance, cb, logger) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function addExtraGas(gas, extraPercentage) {
|
function addExtraGas(gas, extraPercentage, maxGasLimit = Infinity) {
|
||||||
gas = BigNumber(gas)
|
gas = BigNumber(gas)
|
||||||
extraPercentage = BigNumber(1 + extraPercentage)
|
extraPercentage = BigNumber(1 + extraPercentage)
|
||||||
|
|
||||||
const gasWithExtra = gas.multipliedBy(extraPercentage).toFixed(0)
|
const gasWithExtra = gas.multipliedBy(extraPercentage).toFixed(0)
|
||||||
|
|
||||||
return BigNumber(gasWithExtra)
|
return BigNumber.min(maxGasLimit, gasWithExtra)
|
||||||
}
|
}
|
||||||
|
|
||||||
function setIntervalAndRun(f, interval) {
|
function setIntervalAndRun(f, interval) {
|
||||||
|
@ -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 } = require('../src/utils/message')
|
const { createMessage, parseMessage, signatureToVRS, parseAMBHeader } = require('../src/utils/message')
|
||||||
|
|
||||||
describe('message utils', () => {
|
describe('message utils', () => {
|
||||||
const expectedMessageLength = 104
|
const expectedMessageLength = 104
|
||||||
@ -288,4 +288,19 @@ 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)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -34,6 +34,14 @@ 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', () => {
|
||||||
|
Loading…
Reference in New Issue
Block a user