2019-11-22 02:39:30 -08:00
|
|
|
const ethers = require('ethers')
|
|
|
|
|
|
|
|
const {
|
|
|
|
HOME_PRIVATE_KEY, HOME_RPC_URL, HOME_BRIDGE_ADDRESS, SIDE_RPC_URL, SIDE_SHARED_DB_ADDRESS
|
|
|
|
} = process.env
|
|
|
|
const SIDE_MAX_FETCH_RANGE_SIZE = parseInt(process.env.SIDE_MAX_FETCH_RANGE_SIZE, 10)
|
|
|
|
|
|
|
|
const bridgeAbi = [
|
|
|
|
'function applyMessage(bytes message, bytes signatures)',
|
|
|
|
'function getThreshold(uint epoch) view returns (uint)',
|
2019-11-24 07:19:53 -08:00
|
|
|
'function getValidators(uint epoch) view returns (address[])'
|
2019-11-22 02:39:30 -08:00
|
|
|
]
|
|
|
|
const sharedDbAbi = [
|
|
|
|
'event NewMessage(bytes32 msgHash)',
|
2019-11-24 07:19:53 -08:00
|
|
|
'function signedMessages(bytes32 hash) view returns (bytes)',
|
2019-11-22 02:39:30 -08:00
|
|
|
'function getSignatures(bytes32 msgHash, address[] validators) view returns (bytes)'
|
|
|
|
]
|
|
|
|
|
|
|
|
let homeProvider
|
|
|
|
let sideProvider
|
|
|
|
let bridge
|
|
|
|
let sharedDb
|
|
|
|
let homeWallet
|
|
|
|
let nonce
|
|
|
|
let blockNumber = 0
|
|
|
|
|
|
|
|
async function delay(ms) {
|
|
|
|
await new Promise((res) => setTimeout(res, ms))
|
|
|
|
}
|
|
|
|
|
|
|
|
async function handleNewMessage(event) {
|
|
|
|
const { msgHash } = event.values
|
2019-11-24 07:19:53 -08:00
|
|
|
const message = await sharedDb.signedMessages(msgHash)
|
|
|
|
const epoch = parseInt(message.slice(4, 68), 16)
|
2019-11-22 02:39:30 -08:00
|
|
|
const [threshold, validators] = await Promise.all([
|
|
|
|
bridge.getThreshold(epoch),
|
2019-11-24 07:19:53 -08:00
|
|
|
bridge.getValidators(epoch)
|
2019-11-22 02:39:30 -08:00
|
|
|
])
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
const signatures = await sharedDb.getSignatures(msgHash, validators)
|
2019-11-24 07:19:53 -08:00
|
|
|
if (signatures.length === 2) {
|
|
|
|
console.log('Skipping event')
|
|
|
|
break
|
|
|
|
}
|
|
|
|
if ((signatures.length - 2) / 130 >= threshold) {
|
|
|
|
console.log('Sending applyMessage request')
|
2019-11-22 02:39:30 -08:00
|
|
|
const tx = await bridge.applyMessage(message, signatures, {
|
|
|
|
gasLimit: 1000000,
|
|
|
|
nonce
|
|
|
|
})
|
|
|
|
await tx.wait()
|
|
|
|
nonce += 1
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function initialize() {
|
|
|
|
await delay(5000)
|
|
|
|
sideProvider = new ethers.providers.JsonRpcProvider(SIDE_RPC_URL)
|
|
|
|
homeProvider = new ethers.providers.JsonRpcProvider(HOME_RPC_URL)
|
|
|
|
homeWallet = new ethers.Wallet(HOME_PRIVATE_KEY, homeProvider)
|
2019-11-24 07:19:53 -08:00
|
|
|
bridge = new ethers.Contract(HOME_BRIDGE_ADDRESS, bridgeAbi, homeWallet)
|
|
|
|
sharedDb = new ethers.Contract(SIDE_SHARED_DB_ADDRESS, sharedDbAbi, sideProvider)
|
2019-11-22 02:39:30 -08:00
|
|
|
|
|
|
|
nonce = await homeWallet.getTransactionCount()
|
|
|
|
}
|
|
|
|
|
|
|
|
async function loop() {
|
|
|
|
const latestBlockNumber = await sideProvider.getBlockNumber()
|
|
|
|
if (latestBlockNumber < blockNumber) {
|
|
|
|
console.log(`No block after ${latestBlockNumber}`)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
const endBlock = Math.min(latestBlockNumber, blockNumber + SIDE_MAX_FETCH_RANGE_SIZE - 1)
|
|
|
|
|
|
|
|
console.log(`Watching events in blocks #${blockNumber}-${endBlock}`)
|
|
|
|
|
|
|
|
const bridgeEvents = (await sideProvider.getLogs({
|
|
|
|
address: SIDE_SHARED_DB_ADDRESS,
|
|
|
|
fromBlock: blockNumber,
|
|
|
|
toBlock: endBlock,
|
2019-11-24 07:19:53 -08:00
|
|
|
topics: [
|
|
|
|
sharedDb.interface.events.NewMessage.topic
|
|
|
|
]
|
2019-11-22 02:39:30 -08:00
|
|
|
}))
|
|
|
|
|
|
|
|
for (let i = 0; i < bridgeEvents.length; i += 1) {
|
2019-11-24 07:19:53 -08:00
|
|
|
const event = sharedDb.interface.parseLog(bridgeEvents[i])
|
2019-11-22 02:39:30 -08:00
|
|
|
console.log('Consumed event', event, bridgeEvents[i])
|
2019-11-24 07:19:53 -08:00
|
|
|
await handleNewMessage(event)
|
2019-11-22 02:39:30 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
blockNumber = endBlock + 1
|
|
|
|
}
|
|
|
|
|
|
|
|
async function main() {
|
|
|
|
await initialize()
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
await delay(2000)
|
|
|
|
await loop()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
main()
|