Update watcher to be able to skip events
This commit is contained in:
parent
0eeae74ffa
commit
3cd53f7bda
@ -32,7 +32,7 @@ FOREIGN_GAS_PRICE=10000000000
|
||||
FOREIGN_REWARDABLE=false
|
||||
|
||||
BLOCK_REWARD_ADDRESS=0xF9698Eb93702dfdd0e2d802088d4c21822a8A977
|
||||
ERC20_TOKEN_ADDRESS=0x7cc4b1851c35959d34e635a470f6b5c43ba3c9c9
|
||||
ERC20_TOKEN_ADDRESS=0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359
|
||||
|
||||
REQUIRED_NUMBER_OF_VALIDATORS=1
|
||||
VALIDATORS="0xaaB52d66283F7A1D5978bcFcB55721ACB467384b"
|
||||
|
@ -33,12 +33,122 @@ describe('erc to native', () => {
|
||||
before(async () => {
|
||||
halfDuplexTokenAddress = await foreignBridge.methods.halfDuplexErc20token().call()
|
||||
halfDuplexToken = new foreignWeb3.eth.Contract(ERC677_BRIDGE_TOKEN_ABI, halfDuplexTokenAddress)
|
||||
})
|
||||
it('should continue working after migration', async () => {
|
||||
const originalBalanceOnHome = await homeWeb3.eth.getBalance(user.address)
|
||||
|
||||
// set min threshold for swap
|
||||
const transferValue = homeWeb3.utils.toWei('0.01')
|
||||
|
||||
// erc20 token address and half duplex address are the same before migration
|
||||
const tokenAddress = await foreignBridge.methods.erc20token().call()
|
||||
|
||||
const erc20AndhalfDuplexToken = new foreignWeb3.eth.Contract(ERC677_BRIDGE_TOKEN_ABI, tokenAddress)
|
||||
|
||||
// send tokens to foreign bridge
|
||||
await erc20AndhalfDuplexToken.methods
|
||||
.transfer(COMMON_FOREIGN_BRIDGE_ADDRESS, transferValue)
|
||||
.send({
|
||||
from: user.address,
|
||||
gas: '1000000'
|
||||
})
|
||||
.catch(e => {
|
||||
console.error(e)
|
||||
})
|
||||
|
||||
// Send a trivial transaction to generate a new block since the watcher
|
||||
// is configured to wait 1 confirmation block
|
||||
await generateNewBlock(foreignWeb3, user.address)
|
||||
|
||||
// check that balance increases
|
||||
await promiseRetry(async (retry, number) => {
|
||||
const balance = await homeWeb3.eth.getBalance(user.address)
|
||||
await generateNewBlock(foreignWeb3, user.address)
|
||||
// retry at least 4 times to check transfer is not double processed by the two watchers
|
||||
if (toBN(balance).lte(toBN(originalBalanceOnHome)) || number < 4) {
|
||||
retry()
|
||||
} else {
|
||||
assert(
|
||||
toBN(balance).eq(toBN(originalBalanceOnHome).add(toBN(transferValue))),
|
||||
'User balance should be increased only by second transfer'
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
// call migration
|
||||
await foreignBridge.methods.migrateToMCD().send({
|
||||
from: validator.address,
|
||||
gas: '4000000'
|
||||
})
|
||||
|
||||
// update min threshold for swap
|
||||
await foreignBridge.methods.setMinHDTokenBalance(foreignWeb3.utils.toWei('1', 'ether')).send({
|
||||
from: validator.address,
|
||||
gas: '1000000'
|
||||
})
|
||||
|
||||
const AfterMigrateBalance = await homeWeb3.eth.getBalance(user.address)
|
||||
|
||||
// send tokens to foreign bridge
|
||||
await erc20Token.methods
|
||||
.transfer(COMMON_FOREIGN_BRIDGE_ADDRESS, transferValue)
|
||||
.send({
|
||||
from: user.address,
|
||||
gas: '1000000'
|
||||
})
|
||||
.catch(e => {
|
||||
console.error(e)
|
||||
})
|
||||
|
||||
// Send a trivial transaction to generate a new block since the watcher
|
||||
// is configured to wait 1 confirmation block
|
||||
await generateNewBlock(foreignWeb3, user.address)
|
||||
|
||||
// check that balance increases
|
||||
await promiseRetry(async (retry, number) => {
|
||||
const balance = await homeWeb3.eth.getBalance(user.address)
|
||||
await generateNewBlock(foreignWeb3, user.address)
|
||||
// retry at least 4 times to check transfer is not double processed by the two watchers
|
||||
if (toBN(balance).lte(toBN(AfterMigrateBalance)) || number < 4) {
|
||||
retry()
|
||||
} else {
|
||||
assert(
|
||||
toBN(balance).eq(toBN(AfterMigrateBalance).add(toBN(transferValue))),
|
||||
'User balance should be increased only by second transfer'
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
const afterMigrateAndTransferBalance = await homeWeb3.eth.getBalance(user.address)
|
||||
|
||||
// send tokens to foreign bridge
|
||||
await halfDuplexToken.methods
|
||||
.transfer(COMMON_FOREIGN_BRIDGE_ADDRESS, transferValue)
|
||||
.send({
|
||||
from: user.address,
|
||||
gas: '1000000'
|
||||
})
|
||||
.catch(e => {
|
||||
console.error(e)
|
||||
})
|
||||
|
||||
// Send a trivial transaction to generate a new block since the watcher
|
||||
// is configured to wait 1 confirmation block
|
||||
await generateNewBlock(foreignWeb3, user.address)
|
||||
|
||||
// check that balance increases
|
||||
await promiseRetry(async (retry, number) => {
|
||||
const balance = await homeWeb3.eth.getBalance(user.address)
|
||||
await generateNewBlock(foreignWeb3, user.address)
|
||||
// retry at least 4 times to check transfer is not double processed by the two watchers
|
||||
if (toBN(balance).lte(toBN(afterMigrateAndTransferBalance)) || number < 4) {
|
||||
retry()
|
||||
} else {
|
||||
assert(
|
||||
toBN(balance).eq(toBN(afterMigrateAndTransferBalance).add(toBN(transferValue))),
|
||||
'User balance should be increased only by second transfer'
|
||||
)
|
||||
}
|
||||
})
|
||||
})
|
||||
it('should convert tokens in foreign to coins in home', async () => {
|
||||
const balance = await erc20Token.methods.balanceOf(user.address).call()
|
||||
@ -116,7 +226,6 @@ describe('erc to native', () => {
|
||||
const originalBalanceOnHome = await homeWeb3.eth.getBalance(user.address)
|
||||
const bridgeErc20TokenBalance = await erc20Token.methods.balanceOf(COMMON_FOREIGN_BRIDGE_ADDRESS).call()
|
||||
const bridgeHalfDuplexBalance = await halfDuplexToken.methods.balanceOf(COMMON_FOREIGN_BRIDGE_ADDRESS).call()
|
||||
assert(toBN(bridgeHalfDuplexBalance).isZero(), 'Bridge balance should be zero')
|
||||
|
||||
const valueToTransfer = foreignWeb3.utils.toWei('1', 'ether')
|
||||
|
||||
@ -176,7 +285,9 @@ describe('erc to native', () => {
|
||||
assert(toBN(updatedBalance).isZero(), 'Half duplex bridge balance should be zero')
|
||||
assert(
|
||||
toBN(updatedBridgeErc20TokenBalance).eq(
|
||||
toBN(bridgeErc20TokenBalance).add(toBN(foreignWeb3.utils.toWei('2', 'ether')))
|
||||
toBN(bridgeErc20TokenBalance)
|
||||
.add(toBN(bridgeHalfDuplexBalance))
|
||||
.add(toBN(foreignWeb3.utils.toWei('2', 'ether')))
|
||||
),
|
||||
'Erc20 token balance should be correctly increased by the token swap'
|
||||
)
|
||||
|
@ -1,5 +1,6 @@
|
||||
require('../env')
|
||||
const Web3 = require('web3')
|
||||
const { getTokensState } = require('../src/events/processTransfers/tokenState')
|
||||
const {
|
||||
ERC677_BRIDGE_TOKEN_ABI,
|
||||
FOREIGN_ERC_TO_ERC_ABI,
|
||||
@ -9,7 +10,7 @@ const {
|
||||
|
||||
async function initialChecks() {
|
||||
const { ORACLE_BRIDGE_MODE, COMMON_FOREIGN_RPC_URL, COMMON_FOREIGN_BRIDGE_ADDRESS } = process.env
|
||||
const result = {}
|
||||
let result = {}
|
||||
const foreignWeb3 = new Web3(new Web3.providers.HttpProvider(COMMON_FOREIGN_RPC_URL))
|
||||
|
||||
if (ORACLE_BRIDGE_MODE === 'ERC_TO_ERC') {
|
||||
@ -17,17 +18,7 @@ async function initialChecks() {
|
||||
result.bridgeableTokenAddress = await bridge.methods.erc20token().call()
|
||||
} else if (ORACLE_BRIDGE_MODE === 'ERC_TO_NATIVE') {
|
||||
const bridge = new foreignWeb3.eth.Contract(FOREIGN_ERC_TO_NATIVE_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS)
|
||||
result.bridgeableTokenAddress = await bridge.methods.erc20token().call()
|
||||
try {
|
||||
const halfDuplexErc20tokenAddress = await bridge.methods.halfDuplexErc20token().call()
|
||||
if (halfDuplexErc20tokenAddress !== result.bridgeableTokenAddress) {
|
||||
result.halfDuplexTokenAddress = halfDuplexErc20tokenAddress
|
||||
} else {
|
||||
result.idle = true
|
||||
}
|
||||
} catch (e) {
|
||||
result.idle = true
|
||||
}
|
||||
result = await getTokensState(bridge)
|
||||
}
|
||||
|
||||
if (ORACLE_BRIDGE_MODE === 'ERC_TO_ERC') {
|
||||
|
20
oracle/src/events/processTransfers/tokenState.js
Normal file
20
oracle/src/events/processTransfers/tokenState.js
Normal file
@ -0,0 +1,20 @@
|
||||
async function getTokensState(bridgeContract) {
|
||||
const context = {}
|
||||
context.bridgeableTokenAddress = await bridgeContract.methods.erc20token().call()
|
||||
try {
|
||||
const halfDuplexErc20tokenAddress = await bridgeContract.methods.halfDuplexErc20token().call()
|
||||
if (halfDuplexErc20tokenAddress !== context.bridgeableTokenAddress) {
|
||||
context.halfDuplexTokenAddress = halfDuplexErc20tokenAddress
|
||||
} else {
|
||||
context.idle = true
|
||||
}
|
||||
} catch (e) {
|
||||
context.idle = true
|
||||
}
|
||||
|
||||
return context
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getTokensState
|
||||
}
|
@ -26,12 +26,16 @@ const processAMBSignatureRequests = require('./events/processAMBSignatureRequest
|
||||
const processAMBCollectedSignatures = require('./events/processAMBCollectedSignatures')(config)
|
||||
const processAMBAffirmationRequests = require('./events/processAMBAffirmationRequests')(config)
|
||||
|
||||
const { getTokensState } = require('./events/processTransfers/tokenState')
|
||||
|
||||
const ZERO = toBN(0)
|
||||
const ONE = toBN(1)
|
||||
|
||||
const web3Instance = config.web3
|
||||
const bridgeContract = new web3Instance.eth.Contract(config.bridgeAbi, config.bridgeContractAddress)
|
||||
const eventContract = new web3Instance.eth.Contract(config.eventAbi, config.eventContractAddress)
|
||||
let { eventContractAddress } = config
|
||||
let eventContract = new web3Instance.eth.Contract(config.eventAbi, eventContractAddress)
|
||||
let skipEvents = config.idle
|
||||
const lastBlockRedisKey = `${config.id}:lastProcessedBlock`
|
||||
let lastProcessedBlock = BN.max(config.startBlock.sub(ONE), ZERO)
|
||||
|
||||
@ -117,6 +121,29 @@ function processEvents(events, blockNumber) {
|
||||
}
|
||||
}
|
||||
|
||||
async function checkConditions() {
|
||||
let state
|
||||
switch (config.id) {
|
||||
case 'erc-native-transfer':
|
||||
state = await getTokensState(bridgeContract)
|
||||
updateEventContract(state.bridgeableTokenAddress)
|
||||
break
|
||||
case 'erc-native-half-duplex-transfer':
|
||||
state = await getTokensState(bridgeContract)
|
||||
skipEvents = state.idle
|
||||
updateEventContract(state.halfDuplexTokenAddress)
|
||||
break
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
function updateEventContract(address) {
|
||||
if (eventContractAddress !== address) {
|
||||
eventContractAddress = address
|
||||
eventContract = new web3Instance.eth.Contract(config.eventAbi, eventContractAddress)
|
||||
}
|
||||
}
|
||||
|
||||
async function getLastBlockToProcess() {
|
||||
const lastBlockNumberPromise = getBlockNumber(web3Instance).then(toBN)
|
||||
const requiredBlockConfirmationsPromise = getRequiredBlockConfirmations(bridgeContract).then(toBN)
|
||||
@ -130,7 +157,9 @@ async function getLastBlockToProcess() {
|
||||
|
||||
async function main({ sendToQueue, sendToWorker }) {
|
||||
try {
|
||||
if (config.idle) {
|
||||
await checkConditions()
|
||||
|
||||
if (skipEvents) {
|
||||
logger.debug('Watcher in idle mode, skipping getting events')
|
||||
return
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user