Compare commits
13 Commits
2.6.0-rc0
...
allow-rela
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
60b45faa6c | ||
|
|
48752e8575 | ||
|
|
86a47f4a0b | ||
|
|
7af04fa0e8 | ||
|
|
bc871a6844 | ||
|
|
4198b092a6 | ||
|
|
30208b4f8e | ||
|
|
d5946f7df1 | ||
|
|
4efda98f2b | ||
|
|
9e309db876 | ||
|
|
aff8b777c5 | ||
|
|
74293959f3 | ||
|
|
46daeb6815 |
@@ -77,4 +77,4 @@ MONITOR_VALIDATOR_FOREIGN_TX_LIMIT | Average gas usage of a transaction sent by
|
||||
MONITOR_TX_NUMBER_THRESHOLD | If estimated number of transaction is equal to or below this value, the monitor will report that the validator has less funds than it is required. | integer
|
||||
MONITOR_PORT | The port for the Monitor. | integer
|
||||
MONITOR_BRIDGE_NAME | The name to be used in the url path for the bridge | string
|
||||
MONITOR_CACHE_EVENTS | If set to true, monitor will cache obtained events for other workers runs
|
||||
MONITOR_CACHE_EVENTS | If set to true, monitor will cache obtained events for other workers runs | `true` / `false`
|
||||
|
||||
@@ -169,13 +169,13 @@ const getPastEvents = async (
|
||||
const middlePlusOne = middle.add(toBN(1))
|
||||
|
||||
const firstHalfEvents = await getPastEvents(contract, {
|
||||
...options,
|
||||
options,
|
||||
event,
|
||||
fromBlock,
|
||||
toBlock: middle
|
||||
})
|
||||
const secondHalfEvents = await getPastEvents(contract, {
|
||||
...options,
|
||||
options,
|
||||
event,
|
||||
fromBlock: middlePlusOne,
|
||||
toBlock
|
||||
|
||||
@@ -65,6 +65,20 @@ const homeV1Abi = [
|
||||
payable: false,
|
||||
stateMutability: 'view',
|
||||
type: 'function'
|
||||
},
|
||||
{
|
||||
constant: true,
|
||||
inputs: [],
|
||||
name: 'requiredBlockConfirmations',
|
||||
outputs: [
|
||||
{
|
||||
name: '',
|
||||
type: 'uint256'
|
||||
}
|
||||
],
|
||||
payable: false,
|
||||
stateMutability: 'view',
|
||||
type: 'function'
|
||||
}
|
||||
]
|
||||
|
||||
@@ -154,6 +168,20 @@ const foreignViAbi = [
|
||||
payable: false,
|
||||
stateMutability: 'view',
|
||||
type: 'function'
|
||||
},
|
||||
{
|
||||
constant: true,
|
||||
inputs: [],
|
||||
name: 'requiredBlockConfirmations',
|
||||
outputs: [
|
||||
{
|
||||
name: '',
|
||||
type: 'uint256'
|
||||
}
|
||||
],
|
||||
payable: false,
|
||||
stateMutability: 'view',
|
||||
type: 'function'
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@@ -74,6 +74,11 @@ async function main(mode) {
|
||||
|
||||
logger.debug('getting last block numbers')
|
||||
const [homeBlockNumber, foreignBlockNumber] = await getBlockNumber(web3Home, web3Foreign)
|
||||
const homeConfirmations = toBN(await homeBridge.methods.requiredBlockConfirmations().call())
|
||||
const foreignConfirmations = toBN(await foreignBridge.methods.requiredBlockConfirmations().call())
|
||||
const homeDelayedBlockNumber = homeBlockNumber.sub(homeConfirmations)
|
||||
const foreignDelayedBlockNumber = foreignBlockNumber.sub(foreignConfirmations)
|
||||
|
||||
let homeToForeignRequests = []
|
||||
let foreignToHomeRequests = []
|
||||
let homeMigrationBlock = MONITOR_HOME_START_BLOCK
|
||||
@@ -90,7 +95,7 @@ async function main(mode) {
|
||||
homeToForeignRequests = (await getPastEvents(oldHomeBridge, {
|
||||
event: 'UserRequestForSignature',
|
||||
fromBlock: MONITOR_HOME_START_BLOCK,
|
||||
toBlock: homeBlockNumber
|
||||
toBlock: homeDelayedBlockNumber
|
||||
})).map(normalizeEvent)
|
||||
logger.debug(`found ${homeToForeignRequests.length} events`)
|
||||
if (homeToForeignRequests.length > 0) {
|
||||
@@ -101,7 +106,7 @@ async function main(mode) {
|
||||
foreignToHomeRequests = (await getPastEvents(oldForeignBridge, {
|
||||
event: 'UserRequestForAffirmation',
|
||||
fromBlock: MONITOR_FOREIGN_START_BLOCK,
|
||||
toBlock: foreignBlockNumber
|
||||
toBlock: foreignDelayedBlockNumber
|
||||
})).map(normalizeEvent)
|
||||
logger.debug(`found ${foreignToHomeRequests.length} events`)
|
||||
if (foreignToHomeRequests.length > 0) {
|
||||
@@ -113,7 +118,7 @@ async function main(mode) {
|
||||
const homeToForeignRequestsNew = (await getPastEvents(homeBridge, {
|
||||
event: v1Bridge ? 'Deposit' : 'UserRequestForSignature',
|
||||
fromBlock: homeMigrationBlock,
|
||||
toBlock: homeBlockNumber
|
||||
toBlock: homeDelayedBlockNumber
|
||||
})).map(normalizeEvent)
|
||||
homeToForeignRequests = [...homeToForeignRequests, ...homeToForeignRequestsNew]
|
||||
|
||||
@@ -135,7 +140,7 @@ async function main(mode) {
|
||||
const foreignToHomeRequestsNew = (await getPastEvents(foreignBridge, {
|
||||
event: v1Bridge ? 'Withdraw' : 'UserRequestForAffirmation',
|
||||
fromBlock: foreignMigrationBlock,
|
||||
toBlock: foreignBlockNumber
|
||||
toBlock: foreignDelayedBlockNumber
|
||||
})).map(normalizeEvent)
|
||||
foreignToHomeRequests = [...foreignToHomeRequests, ...foreignToHomeRequestsNew]
|
||||
|
||||
@@ -144,7 +149,7 @@ async function main(mode) {
|
||||
let transferEvents = (await getPastEvents(erc20Contract, {
|
||||
event: 'Transfer',
|
||||
fromBlock: MONITOR_FOREIGN_START_BLOCK,
|
||||
toBlock: foreignBlockNumber,
|
||||
toBlock: foreignDelayedBlockNumber,
|
||||
options: {
|
||||
filter: { to: COMMON_FOREIGN_BRIDGE_ADDRESS }
|
||||
}
|
||||
@@ -194,7 +199,7 @@ async function main(mode) {
|
||||
const halfDuplexTransferEvents = (await getPastEvents(halfDuplexTokenContract, {
|
||||
event: 'Transfer',
|
||||
fromBlock: MONITOR_FOREIGN_START_BLOCK,
|
||||
toBlock: foreignBlockNumber,
|
||||
toBlock: foreignDelayedBlockNumber,
|
||||
options: {
|
||||
filter: { to: COMMON_FOREIGN_BRIDGE_ADDRESS }
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
const Web3 = require('web3')
|
||||
const { BRIDGE_MODES, getBridgeMode, HOME_ERC_TO_ERC_ABI } = require('../../commons')
|
||||
|
||||
const { COMMON_HOME_BRIDGE_ADDRESS, COMMON_HOME_RPC_URL } = process.env
|
||||
const homeProvider = new Web3.providers.HttpProvider(COMMON_HOME_RPC_URL)
|
||||
const web3Home = new Web3(homeProvider)
|
||||
|
||||
async function isV1Bridge() {
|
||||
const homeBridge = new web3Home.eth.Contract(HOME_ERC_TO_ERC_ABI, COMMON_HOME_BRIDGE_ADDRESS)
|
||||
const bridgeMode = await getBridgeMode(homeBridge)
|
||||
return bridgeMode === BRIDGE_MODES.NATIVE_TO_ERC_V1
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
isV1Bridge
|
||||
}
|
||||
@@ -66,8 +66,12 @@ function processCollectedSignaturesBuilder(config) {
|
||||
if (allowanceList.indexOf(recipient) === -1) {
|
||||
if (ORACLE_HOME_TO_FOREIGN_CHECK_SENDER === 'true') {
|
||||
logger.debug({ txHash: originalTxHash }, 'Requested sender of an original withdrawal transaction')
|
||||
const sender = (await web3Home.eth.getTransaction(originalTxHash)).from.toLowerCase()
|
||||
if (allowanceList.indexOf(sender) === -1) {
|
||||
const originalTx = await web3Home.eth.getTransaction(originalTxHash)
|
||||
logger.debug(`Tx data of an original withdrawal transaction ${originalTx.input}`)
|
||||
const isRelayTokens = originalTx.input.slice(2, 10) === '5d1e9307'
|
||||
logger.info(`Is the relayTokens method invoked: ${isRelayTokens}`)
|
||||
const sender = originalTx.from.toLowerCase()
|
||||
if (allowanceList.indexOf(sender) === -1 && !isRelayTokens) {
|
||||
logger.info(
|
||||
{ sender, recipient },
|
||||
'Validator skips a transaction. Neither sender nor recipient addresses are in the allowance list.'
|
||||
|
||||
@@ -80,13 +80,17 @@ async function readNonce(forceUpdate) {
|
||||
logger.debug({ nonce }, 'Nonce found in the DB')
|
||||
return Number(nonce)
|
||||
} else {
|
||||
logger.debug("Nonce wasn't found in the DB")
|
||||
logger.warn("Nonce wasn't found in the DB")
|
||||
return getNonce(web3Instance, ORACLE_VALIDATOR_ADDRESS)
|
||||
}
|
||||
}
|
||||
|
||||
function updateNonce(nonce) {
|
||||
return redis.set(nonceKey, nonce)
|
||||
if (typeof nonce !== 'number') {
|
||||
logger.warn('Given nonce value is not a valid number. Nothing will be updated in the DB.')
|
||||
} else {
|
||||
redis.set(nonceKey, nonce)
|
||||
}
|
||||
}
|
||||
|
||||
async function main({ msg, ackMsg, nackMsg, channel, scheduleForRetry, scheduleTransactionResend }) {
|
||||
@@ -98,13 +102,13 @@ async function main({ msg, ackMsg, nackMsg, channel, scheduleForRetry, scheduleT
|
||||
|
||||
const txArray = JSON.parse(msg.content)
|
||||
logger.debug(`Msg received with ${txArray.length} Tx to send`)
|
||||
const gasPrice = GasPrice.getPrice()
|
||||
const gasPrice = GasPrice.getPrice().toString(10)
|
||||
|
||||
let nonce
|
||||
let insufficientFunds = false
|
||||
let minimumBalance = null
|
||||
const failedTx = []
|
||||
const sentTx = []
|
||||
const resendJobs = []
|
||||
|
||||
const isResend = txArray.length > 0 && !!txArray[0].txHash
|
||||
|
||||
@@ -136,17 +140,14 @@ async function main({ msg, ackMsg, nackMsg, channel, scheduleForRetry, scheduleT
|
||||
nonce = await readNonce(true)
|
||||
}
|
||||
|
||||
logger.info(
|
||||
`Transaction ${job.txHash} was not mined, updating gasPrice: ${job.gasPrice} -> ${gasPrice.toString(10)}`
|
||||
)
|
||||
logger.info(`Transaction ${job.txHash} was not mined, updating gasPrice: ${job.gasPrice} -> ${gasPrice}`)
|
||||
}
|
||||
logger.info(`Sending transaction with nonce ${nonce}`)
|
||||
job.gasPrice = gasPrice.toString(10)
|
||||
job.txHash = await sendTx({
|
||||
const txHash = await sendTx({
|
||||
chain: config.id,
|
||||
data: job.data,
|
||||
nonce,
|
||||
gasPrice: job.gasPrice,
|
||||
gasPrice,
|
||||
amount: '0',
|
||||
gasLimit,
|
||||
privateKey: ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY,
|
||||
@@ -154,12 +155,17 @@ async function main({ msg, ackMsg, nackMsg, channel, scheduleForRetry, scheduleT
|
||||
chainId,
|
||||
web3: web3Instance
|
||||
})
|
||||
sentTx.push(job)
|
||||
const resendJob = {
|
||||
...job,
|
||||
txHash,
|
||||
gasPrice
|
||||
}
|
||||
resendJobs.push(resendJob)
|
||||
|
||||
nonce++
|
||||
logger.info(
|
||||
{ eventTransactionHash: job.transactionReference, generatedTransactionHash: job.txHash },
|
||||
`Tx generated ${job.txHash} for event Tx ${job.transactionReference}`
|
||||
{ eventTransactionHash: job.transactionReference, generatedTransactionHash: txHash },
|
||||
`Tx generated ${txHash} for event Tx ${job.transactionReference}`
|
||||
)
|
||||
} catch (e) {
|
||||
logger.error(
|
||||
@@ -168,7 +174,11 @@ async function main({ msg, ackMsg, nackMsg, channel, scheduleForRetry, scheduleT
|
||||
e.message
|
||||
)
|
||||
if (!e.message.toLowerCase().includes('transaction with the same hash was already imported')) {
|
||||
failedTx.push(job)
|
||||
if (isResend) {
|
||||
resendJobs.push(job)
|
||||
} else {
|
||||
failedTx.push(job)
|
||||
}
|
||||
}
|
||||
|
||||
if (e.message.toLowerCase().includes('insufficient funds')) {
|
||||
@@ -184,16 +194,18 @@ async function main({ msg, ackMsg, nackMsg, channel, scheduleForRetry, scheduleT
|
||||
}
|
||||
})
|
||||
|
||||
logger.debug('Updating nonce')
|
||||
await updateNonce(nonce)
|
||||
if (typeof nonce === 'number') {
|
||||
logger.debug('Updating nonce')
|
||||
await updateNonce(nonce)
|
||||
}
|
||||
|
||||
if (failedTx.length) {
|
||||
logger.info(`Sending ${failedTx.length} Failed Tx to Queue`)
|
||||
await scheduleForRetry(failedTx, msg.properties.headers['x-retries'])
|
||||
}
|
||||
if (sentTx.length) {
|
||||
logger.info(`Sending ${sentTx.length} Tx Delayed Resend Requests to Queue`)
|
||||
await scheduleTransactionResend(sentTx)
|
||||
if (resendJobs.length) {
|
||||
logger.info(`Sending ${resendJobs.length} Tx Delayed Resend Requests to Queue`)
|
||||
await scheduleTransactionResend(resendJobs)
|
||||
}
|
||||
ackMsg(msg)
|
||||
logger.debug(`Finished processing msg`)
|
||||
|
||||
Reference in New Issue
Block a user