Add statistics about used AMB information requests (#577)
This commit is contained in:
parent
8f72516374
commit
3cf184c391
@ -1,3 +1,5 @@
|
|||||||
|
const { soliditySha3 } = require('web3-utils')
|
||||||
|
|
||||||
function strip0x(input) {
|
function strip0x(input) {
|
||||||
return input.replace(/^0x/, '')
|
return input.replace(/^0x/, '')
|
||||||
}
|
}
|
||||||
@ -39,8 +41,35 @@ const normalizeAMBMessageEvent = e => {
|
|||||||
return parseAMBMessage(msgData)
|
return parseAMBMessage(msgData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ambInformationSignatures = [
|
||||||
|
'eth_call(address,bytes)',
|
||||||
|
'eth_call(address,bytes,uint256)',
|
||||||
|
'eth_call(address,address,uint256,bytes)',
|
||||||
|
'eth_blockNumber()',
|
||||||
|
'eth_getBlockByNumber()',
|
||||||
|
'eth_getBlockByNumber(uint256)',
|
||||||
|
'eth_getBlockByHash(bytes32)',
|
||||||
|
'eth_getBalance(address)',
|
||||||
|
'eth_getBalance(address,uint256)',
|
||||||
|
'eth_getTransactionCount(address)',
|
||||||
|
'eth_getTransactionCount(address,uint256)',
|
||||||
|
'eth_getTransactionByHash(bytes32)',
|
||||||
|
'eth_getTransactionReceipt(bytes32)',
|
||||||
|
'eth_getStorageAt(address,bytes32)',
|
||||||
|
'eth_getStorageAt(address,bytes32,uint256)'
|
||||||
|
]
|
||||||
|
const ambInformationSelectors = Object.fromEntries(ambInformationSignatures.map(sig => [soliditySha3(sig), sig]))
|
||||||
|
const normalizeAMBInfoRequest = e => ({
|
||||||
|
messageId: e.returnValues.messageId,
|
||||||
|
sender: e.returnValues.sender,
|
||||||
|
requestSelector: ambInformationSelectors[e.returnValues.requestSelector] || 'unknown',
|
||||||
|
data: e.returnValues.data
|
||||||
|
})
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
strip0x,
|
strip0x,
|
||||||
parseAMBMessage,
|
parseAMBMessage,
|
||||||
normalizeAMBMessageEvent
|
normalizeAMBMessageEvent,
|
||||||
|
ambInformationSignatures,
|
||||||
|
normalizeAMBInfoRequest
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
const logger = require('./logger')('detectMediators.js')
|
const logger = require('./logger')('detectMediators.js')
|
||||||
const { isHomeContract, isForeignContract } = require('./utils/web3Cache')
|
|
||||||
const eventsInfo = require('./utils/events')
|
const eventsInfo = require('./utils/events')
|
||||||
const { getHomeTxSender, getForeignTxSender } = require('./utils/web3Cache')
|
const { getHomeTxSender, getForeignTxSender, isHomeContract, isForeignContract } = require('./utils/web3Cache')
|
||||||
const { addExecutionStatus } = require('./utils/message')
|
const { addExecutionStatus, addRetrievalStatus } = require('./utils/message')
|
||||||
const { normalizeAMBMessageEvent } = require('../commons')
|
const { normalizeAMBMessageEvent, normalizeAMBInfoRequest } = require('../commons')
|
||||||
|
|
||||||
function countInteractions(requests) {
|
function countInteractions(requests) {
|
||||||
const stats = {}
|
const stats = {}
|
||||||
@ -30,6 +29,41 @@ function countInteractions(requests) {
|
|||||||
return stats
|
return stats
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function countInfoRequests(requests) {
|
||||||
|
const stats = {}
|
||||||
|
requests.forEach(msg => {
|
||||||
|
if (!stats[msg.sender]) {
|
||||||
|
stats[msg.sender] = {}
|
||||||
|
}
|
||||||
|
if (!stats[msg.sender][msg.requestSelector]) {
|
||||||
|
stats[msg.sender][msg.requestSelector] = {
|
||||||
|
callSucceeded: {
|
||||||
|
callbackSucceeded: 0,
|
||||||
|
callbackFailed: 0
|
||||||
|
},
|
||||||
|
callFailed: {
|
||||||
|
callbackSucceeded: 0,
|
||||||
|
callbackFailed: 0
|
||||||
|
},
|
||||||
|
pending: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const stat = stats[msg.sender][msg.requestSelector]
|
||||||
|
if (msg.callStatus === true && msg.callbackStatus === true) {
|
||||||
|
stat.callSucceeded.callbackSucceeded += 1
|
||||||
|
} else if (msg.callStatus === true && msg.callbackStatus === false) {
|
||||||
|
stat.callSucceeded.callbackFailed += 1
|
||||||
|
} else if (msg.callStatus === false && msg.callbackStatus === true) {
|
||||||
|
stat.callFailed.callbackSucceeded += 1
|
||||||
|
} else if (msg.callStatus === false && msg.callbackStatus === false) {
|
||||||
|
stat.callFailed.callbackFailed += 1
|
||||||
|
} else {
|
||||||
|
stat.pending += 1
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return stats
|
||||||
|
}
|
||||||
|
|
||||||
const normalize = event => ({
|
const normalize = event => ({
|
||||||
...normalizeAMBMessageEvent(event),
|
...normalizeAMBMessageEvent(event),
|
||||||
txHash: event.transactionHash,
|
txHash: event.transactionHash,
|
||||||
@ -88,10 +122,13 @@ async function main(mode) {
|
|||||||
homeToForeignRequests,
|
homeToForeignRequests,
|
||||||
foreignToHomeRequests,
|
foreignToHomeRequests,
|
||||||
homeToForeignConfirmations,
|
homeToForeignConfirmations,
|
||||||
foreignToHomeConfirmations
|
foreignToHomeConfirmations,
|
||||||
|
informationRequests,
|
||||||
|
informationResponses
|
||||||
} = await eventsInfo(mode)
|
} = await eventsInfo(mode)
|
||||||
const homeToForeign = homeToForeignRequests.map(normalize).map(addExecutionStatus(homeToForeignConfirmations))
|
const homeToForeign = homeToForeignRequests.map(normalize).map(addExecutionStatus(homeToForeignConfirmations))
|
||||||
const foreignToHome = foreignToHomeRequests.map(normalize).map(addExecutionStatus(foreignToHomeConfirmations))
|
const foreignToHome = foreignToHomeRequests.map(normalize).map(addExecutionStatus(foreignToHomeConfirmations))
|
||||||
|
const infoRequests = informationRequests.map(normalizeAMBInfoRequest).map(addRetrievalStatus(informationResponses))
|
||||||
|
|
||||||
for (const event of homeToForeign) {
|
for (const event of homeToForeign) {
|
||||||
// AMB contract emits a single UserRequestForSignature event for every home->foreign request.
|
// AMB contract emits a single UserRequestForSignature event for every home->foreign request.
|
||||||
@ -146,6 +183,7 @@ async function main(mode) {
|
|||||||
floatingMediators,
|
floatingMediators,
|
||||||
remotelyControlledMediators,
|
remotelyControlledMediators,
|
||||||
unknown,
|
unknown,
|
||||||
|
informationReceivers: countInfoRequests(infoRequests),
|
||||||
lastChecked: Math.floor(Date.now() / 1000)
|
lastChecked: Math.floor(Date.now() / 1000)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,9 @@ async function main(bridgeMode, eventsInfo) {
|
|||||||
homeToForeignConfirmations,
|
homeToForeignConfirmations,
|
||||||
homeToForeignRequests,
|
homeToForeignRequests,
|
||||||
foreignToHomeConfirmations,
|
foreignToHomeConfirmations,
|
||||||
foreignToHomeRequests
|
foreignToHomeRequests,
|
||||||
|
informationRequests,
|
||||||
|
informationResponses
|
||||||
} = eventsInfo
|
} = eventsInfo
|
||||||
|
|
||||||
if (bridgeMode === BRIDGE_MODES.ARBITRARY_MESSAGE) {
|
if (bridgeMode === BRIDGE_MODES.ARBITRARY_MESSAGE) {
|
||||||
@ -34,7 +36,9 @@ async function main(bridgeMode, eventsInfo) {
|
|||||||
fromForeignToHomeDiff: foreignToHomeConfirmations.length - foreignToHomeRequests.length,
|
fromForeignToHomeDiff: foreignToHomeConfirmations.length - foreignToHomeRequests.length,
|
||||||
home: {
|
home: {
|
||||||
toForeign: homeToForeignRequests.length,
|
toForeign: homeToForeignRequests.length,
|
||||||
fromForeign: foreignToHomeConfirmations.length
|
fromForeign: foreignToHomeConfirmations.length,
|
||||||
|
informationRequests: informationRequests.length,
|
||||||
|
informationResponses: informationResponses.length
|
||||||
},
|
},
|
||||||
foreign: {
|
foreign: {
|
||||||
fromHome: homeToForeignConfirmations.length,
|
fromHome: homeToForeignConfirmations.length,
|
||||||
|
@ -129,6 +129,27 @@ async function main(mode) {
|
|||||||
})).map(normalizeEvent)
|
})).map(normalizeEvent)
|
||||||
foreignToHomeRequests = [...foreignToHomeRequests, ...foreignToHomeRequestsNew]
|
foreignToHomeRequests = [...foreignToHomeRequests, ...foreignToHomeRequestsNew]
|
||||||
|
|
||||||
|
let informationRequests
|
||||||
|
let informationResponses
|
||||||
|
if (bridgeMode === BRIDGE_MODES.ARBITRARY_MESSAGE) {
|
||||||
|
logger.debug("calling homeBridge.getPastEvents('UserRequestForInformation')")
|
||||||
|
informationRequests = (await getPastEvents(homeBridge, {
|
||||||
|
event: 'UserRequestForInformation',
|
||||||
|
fromBlock: MONITOR_HOME_START_BLOCK,
|
||||||
|
toBlock: homeDelayedBlockNumber,
|
||||||
|
chain: 'home'
|
||||||
|
})).map(normalizeEvent)
|
||||||
|
|
||||||
|
logger.debug("calling foreignBridge.getPastEvents('InformationRetrieved')")
|
||||||
|
informationResponses = (await getPastEvents(homeBridge, {
|
||||||
|
event: 'InformationRetrieved',
|
||||||
|
fromBlock: MONITOR_HOME_START_BLOCK,
|
||||||
|
toBlock: homeBlockNumber,
|
||||||
|
safeToBlock: homeDelayedBlockNumber,
|
||||||
|
chain: 'home'
|
||||||
|
})).map(normalizeEvent)
|
||||||
|
}
|
||||||
|
|
||||||
if (isExternalErc20) {
|
if (isExternalErc20) {
|
||||||
logger.debug("calling erc20Contract.getPastEvents('Transfer')")
|
logger.debug("calling erc20Contract.getPastEvents('Transfer')")
|
||||||
let transferEvents = (await getPastEvents(erc20Contract, {
|
let transferEvents = (await getPastEvents(erc20Contract, {
|
||||||
@ -225,6 +246,8 @@ async function main(mode) {
|
|||||||
homeToForeignConfirmations,
|
homeToForeignConfirmations,
|
||||||
foreignToHomeConfirmations,
|
foreignToHomeConfirmations,
|
||||||
foreignToHomeRequests,
|
foreignToHomeRequests,
|
||||||
|
informationRequests,
|
||||||
|
informationResponses,
|
||||||
isExternalErc20,
|
isExternalErc20,
|
||||||
bridgeMode,
|
bridgeMode,
|
||||||
homeBlockNumber,
|
homeBlockNumber,
|
||||||
|
@ -28,6 +28,21 @@ function addExecutionStatus(processedList) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function addRetrievalStatus(retrievedInfoList) {
|
||||||
|
const statuses = {}
|
||||||
|
retrievedInfoList.forEach(e => {
|
||||||
|
statuses[e.returnValues.messageId] = {
|
||||||
|
callStatus: e.returnValues.status,
|
||||||
|
callbackStatus: e.returnValues.callbackStatus
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return deliveredMsg => {
|
||||||
|
deliveredMsg.callStatus = statuses[deliveredMsg.messageId].callStatus
|
||||||
|
deliveredMsg.callbackStatus = statuses[deliveredMsg.messageId].callbackStatus
|
||||||
|
return deliveredMsg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Normalizes the different event objects to facilitate data processing
|
* Normalizes the different event objects to facilitate data processing
|
||||||
* @param {Object} event
|
* @param {Object} event
|
||||||
@ -89,6 +104,7 @@ module.exports = {
|
|||||||
deliveredMsgNotProcessed,
|
deliveredMsgNotProcessed,
|
||||||
processedMsgNotDelivered,
|
processedMsgNotDelivered,
|
||||||
addExecutionStatus,
|
addExecutionStatus,
|
||||||
|
addRetrievalStatus,
|
||||||
normalizeEventInformation,
|
normalizeEventInformation,
|
||||||
eventWithoutReference,
|
eventWithoutReference,
|
||||||
unclaimedHomeToForeignRequests,
|
unclaimedHomeToForeignRequests,
|
||||||
|
@ -2,7 +2,7 @@ const Web3 = require('web3')
|
|||||||
const assert = require('assert')
|
const assert = require('assert')
|
||||||
const { user, homeRPC, foreignRPC, amb, validator } = require('../../e2e-commons/constants.json')
|
const { user, homeRPC, foreignRPC, amb, validator } = require('../../e2e-commons/constants.json')
|
||||||
const { uniformRetry } = require('../../e2e-commons/utils')
|
const { uniformRetry } = require('../../e2e-commons/utils')
|
||||||
const { BOX_ABI, HOME_AMB_ABI, FOREIGN_AMB_ABI } = require('../../commons')
|
const { BOX_ABI, HOME_AMB_ABI, FOREIGN_AMB_ABI, ambInformationSignatures } = require('../../commons')
|
||||||
const { delay, setRequiredSignatures } = require('./utils')
|
const { delay, setRequiredSignatures } = require('./utils')
|
||||||
|
|
||||||
const { toBN } = Web3.utils
|
const { toBN } = Web3.utils
|
||||||
@ -29,24 +29,7 @@ const foreignBridge = new foreignWeb3.eth.Contract(FOREIGN_AMB_ABI, amb.foreign,
|
|||||||
describe('arbitrary message bridging', () => {
|
describe('arbitrary message bridging', () => {
|
||||||
let requiredSignatures = 1
|
let requiredSignatures = 1
|
||||||
before(async () => {
|
before(async () => {
|
||||||
const allowedMethods = [
|
for (const method of ambInformationSignatures) {
|
||||||
'eth_call(address,bytes)',
|
|
||||||
'eth_call(address,bytes,uint256)',
|
|
||||||
'eth_call(address,address,uint256,bytes)',
|
|
||||||
'eth_blockNumber()',
|
|
||||||
'eth_getBlockByNumber()',
|
|
||||||
'eth_getBlockByNumber(uint256)',
|
|
||||||
'eth_getBlockByHash(bytes32)',
|
|
||||||
'eth_getBalance(address)',
|
|
||||||
'eth_getBalance(address,uint256)',
|
|
||||||
'eth_getTransactionCount(address)',
|
|
||||||
'eth_getTransactionCount(address,uint256)',
|
|
||||||
'eth_getTransactionByHash(bytes32)',
|
|
||||||
'eth_getTransactionReceipt(bytes32)',
|
|
||||||
'eth_getStorageAt(address,bytes32)',
|
|
||||||
'eth_getStorageAt(address,bytes32,uint256)'
|
|
||||||
]
|
|
||||||
for (const method of allowedMethods) {
|
|
||||||
const selector = homeWeb3.utils.soliditySha3(method)
|
const selector = homeWeb3.utils.soliditySha3(method)
|
||||||
await homeBridge.methods.enableAsyncRequestSelector(selector, true).send({ from: validator.address })
|
await homeBridge.methods.enableAsyncRequestSelector(selector, true).send({ from: validator.address })
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user