From d1b23a2baef281ffc0c67146e8ad9bae174f7562 Mon Sep 17 00:00:00 2001 From: KarishmaBothara Date: Thu, 14 Jul 2022 10:27:11 +1200 Subject: [PATCH 1/4] Adding delay before submitting event proof --- scripts/subscribeEventProof.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/scripts/subscribeEventProof.js b/scripts/subscribeEventProof.js index 2c4bb54..ac8d42f 100644 --- a/scripts/subscribeEventProof.js +++ b/scripts/subscribeEventProof.js @@ -86,10 +86,12 @@ async function getEventPoofAndSubmit(api, eventId, bridge, txExecutor, newValida logger.info('percentGasPrice:',percentGasPrice.toString()); const increasedGasPrice = gasPrice.add(percentGasPrice); logger.info('Gas price nw;:', gasPrice.toString()); - - const gasEstimated = await bridge.estimateGas.setValidators(newValidators, newValidatorSetId, proof, {gasLimit: 5000000, gasPrice: increasedGasPrice}); + const timeMs = 60000; // wait for a minute + logger.info(`Wait for a minute before sending the event proof`); + await sleep(timeMs); const eventExists = await bridge.eventIds(eventId.toString()); // check storage again, before sending event proof if (!eventExists) { + const gasEstimated = await bridge.estimateGas.setValidators(newValidators, newValidatorSetId, proof, {gasLimit: 5000000, gasPrice: increasedGasPrice}); const tx = await bridge.setValidators(newValidators, newValidatorSetId, proof, { gasLimit: gasEstimated.add(BUFFER), gasPrice: increasedGasPrice @@ -113,8 +115,7 @@ async function getEventPoofAndSubmit(api, eventId, bridge, txExecutor, newValida logger.error(`IMP Error: ${e.stack}`); // send slack notification when proof submission fails const message = ` 🚨 Issue while submitting validator set on ethereum bridge - proof: ${JSON.stringify(proof)} - newValidators: ${newValidators} + event proof id: ${eventProof.eventId} newValidatorSetId: ${newValidatorSetId} on CENNZnets ${process.env.NETWORK} chain`; await sendSlackNotification(message); @@ -217,6 +218,10 @@ async function withTimeout(promise, timeoutMs) { ]); } +function sleep(ms) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} + const networkName = process.env.NETWORK; const bridgeContractAddress = process.env.BRIDGE_CONTRACT; main(networkName, bridgeContractAddress).catch((err) => console.log(err)); From 11e9d7ff45884bfcbd4bfce81ebaa5f55b9d7a67 Mon Sep 17 00:00:00 2001 From: KarishmaBothara Date: Thu, 14 Jul 2022 17:18:17 +1200 Subject: [PATCH 2/4] as discussed use flashbot to send validator set txs --- package.json | 1 + scripts/subscribeEventProof.js | 36 +++++++++++++++++++++++----------- yarn.lock | 25 +++++++++++++++++++++++ 3 files changed, 51 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 47653e9..e8b4e9b 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ }, "homepage": "https://github.com/cennznet/cennznet#readme", "dependencies": { + "@flashbots/ethers-provider-bundle": "^0.5.0", "@types/chai": "^4.2.19", "@types/mocha": "^8.2.2", "dotenv": "^8.2.0", diff --git a/scripts/subscribeEventProof.js b/scripts/subscribeEventProof.js index ac8d42f..158b9c8 100644 --- a/scripts/subscribeEventProof.js +++ b/scripts/subscribeEventProof.js @@ -7,6 +7,7 @@ const mongoose = require('mongoose'); const { EventProcessed } = require('../src/mongo/models'); const ethers = require('ethers'); const bridgeAbi = require("../abi/CENNZnetBridge.json").abi; +const { FlashbotsBundleProvider, FlashbotsTransactionResolution} = require("@flashbots/ethers-provider-bundle"); const timeoutMs = 20000; const BUFFER = 1000; @@ -88,16 +89,33 @@ async function getEventPoofAndSubmit(api, eventId, bridge, txExecutor, newValida logger.info('Gas price nw;:', gasPrice.toString()); const timeMs = 60000; // wait for a minute logger.info(`Wait for a minute before sending the event proof`); - await sleep(timeMs); const eventExists = await bridge.eventIds(eventId.toString()); // check storage again, before sending event proof if (!eventExists) { - const gasEstimated = await bridge.estimateGas.setValidators(newValidators, newValidatorSetId, proof, {gasLimit: 5000000, gasPrice: increasedGasPrice}); - const tx = await bridge.setValidators(newValidators, newValidatorSetId, proof, { - gasLimit: gasEstimated.add(BUFFER), - gasPrice: increasedGasPrice + const iface = new ethers.utils.Interface(bridgeAbi); + const data = iface.encodeFunctionData("setValidators", [newValidators, newValidatorSetId, proof]); + const flashbotsProvider = await FlashbotsBundleProvider.create(provider, txExecutor); + const transaction = { + from: txExecutor.address, + to: process.env.BRIDGE_CONTRACT, + data: data, + gasPrice: increasedGasPrice, + gasLimit: 500000, + } + const res = await flashbotsProvider.sendPrivateTransaction({ + transaction, + txExecutor, + }, { + maxBlockNumber: (await provider.getBlockNumber()) + 15, // only allow tx to be mined for the next 15 blocks }); - await tx.wait(); // wait till tx is mined - logger.info(JSON.stringify(tx)); + + const waitRes = await res.wait(); + if (waitRes === FlashbotsTransactionResolution.TransactionIncluded) { + logger.info("Private transaction successfully mined."); + logger.info(JSON.stringify(waitRes)); + } else if (waitRes === FlashbotsTransactionResolution.TransactionDropped) { + logger.info("Private transaction was not mined and has been removed from the system."); + await sendSlackNotification(`Failed to submit transaction via flashbot`); + } await updateLastEventProcessed(eventId, blockHash.toString()); const balance = await provider.getBalance(txExecutor.address); logger.info(`IMP Balance is: ${balance}`); @@ -218,10 +236,6 @@ async function withTimeout(promise, timeoutMs) { ]); } -function sleep(ms) { - return new Promise((resolve) => setTimeout(resolve, ms)); -} - const networkName = process.env.NETWORK; const bridgeContractAddress = process.env.BRIDGE_CONTRACT; main(networkName, bridgeContractAddress).catch((err) => console.log(err)); diff --git a/yarn.lock b/yarn.lock index 648d444..6b1f090 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1089,6 +1089,14 @@ dependencies: ajv "^6.12.6" +"@flashbots/ethers-provider-bundle@^0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@flashbots/ethers-provider-bundle/-/ethers-provider-bundle-0.5.0.tgz#068dd6a078066c50c36ac81b92d4726636768853" + integrity sha512-w7vc6aWDtgaHkDSgACjda0NoKYjOJ4mkr2av+u0NctvsoeNTg5dji65zeyU+98Fx3s6IbK0mfUTSGHAUtyt21A== + dependencies: + ts-node "^9.1.0" + typescript "^4.1.2" + "@humanwhocodes/config-array@^0.5.0": version "0.5.0" resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9" @@ -9782,6 +9790,18 @@ ts-node@^10.0.0: source-map-support "^0.5.17" yn "3.1.1" +ts-node@^9.1.0: + version "9.1.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-9.1.1.tgz#51a9a450a3e959401bda5f004a72d54b936d376d" + integrity sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg== + dependencies: + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + source-map-support "^0.5.17" + yn "3.1.1" + tslib@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.1.tgz#410eb0d113e5b6356490eec749603725b021b43e" @@ -9894,6 +9914,11 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= +typescript@^4.1.2: + version "4.7.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235" + integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ== + typescript@^4.3.4, typescript@^4.3.5: version "4.3.5" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4" From 5fbf5eef4e8830cc47f787e6755023a26e0d3e4c Mon Sep 17 00:00:00 2001 From: KarishmaBothara Date: Thu, 14 Jul 2022 17:21:21 +1200 Subject: [PATCH 3/4] remove unused --- scripts/subscribeEventProof.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/scripts/subscribeEventProof.js b/scripts/subscribeEventProof.js index 158b9c8..5e6f20e 100644 --- a/scripts/subscribeEventProof.js +++ b/scripts/subscribeEventProof.js @@ -10,7 +10,6 @@ const bridgeAbi = require("../abi/CENNZnetBridge.json").abi; const { FlashbotsBundleProvider, FlashbotsTransactionResolution} = require("@flashbots/ethers-provider-bundle"); const timeoutMs = 20000; -const BUFFER = 1000; // Ignore if validator public key is 0x000.. const IGNORE_KEY = '0x000000000000000000000000000000000000000000000000000000000000000000'; @@ -87,8 +86,6 @@ async function getEventPoofAndSubmit(api, eventId, bridge, txExecutor, newValida logger.info('percentGasPrice:',percentGasPrice.toString()); const increasedGasPrice = gasPrice.add(percentGasPrice); logger.info('Gas price nw;:', gasPrice.toString()); - const timeMs = 60000; // wait for a minute - logger.info(`Wait for a minute before sending the event proof`); const eventExists = await bridge.eventIds(eventId.toString()); // check storage again, before sending event proof if (!eventExists) { const iface = new ethers.utils.Interface(bridgeAbi); From 713ac97cb7846f7cf652d65ea533720be522f4a0 Mon Sep 17 00:00:00 2001 From: KarishmaBothara Date: Thu, 14 Jul 2022 17:25:41 +1200 Subject: [PATCH 4/4] wip --- scripts/subscribeEventProof.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/subscribeEventProof.js b/scripts/subscribeEventProof.js index 5e6f20e..dc11a51 100644 --- a/scripts/subscribeEventProof.js +++ b/scripts/subscribeEventProof.js @@ -10,6 +10,7 @@ const bridgeAbi = require("../abi/CENNZnetBridge.json").abi; const { FlashbotsBundleProvider, FlashbotsTransactionResolution} = require("@flashbots/ethers-provider-bundle"); const timeoutMs = 20000; +const BUFFER = 1000; // Ignore if validator public key is 0x000.. const IGNORE_KEY = '0x000000000000000000000000000000000000000000000000000000000000000000'; @@ -87,6 +88,7 @@ async function getEventPoofAndSubmit(api, eventId, bridge, txExecutor, newValida const increasedGasPrice = gasPrice.add(percentGasPrice); logger.info('Gas price nw;:', gasPrice.toString()); const eventExists = await bridge.eventIds(eventId.toString()); // check storage again, before sending event proof + const gasEstimated = await bridge.estimateGas.setValidators(newValidators, newValidatorSetId, proof, {gasLimit: 5000000, gasPrice: increasedGasPrice}); if (!eventExists) { const iface = new ethers.utils.Interface(bridgeAbi); const data = iface.encodeFunctionData("setValidators", [newValidators, newValidatorSetId, proof]); @@ -96,7 +98,7 @@ async function getEventPoofAndSubmit(api, eventId, bridge, txExecutor, newValida to: process.env.BRIDGE_CONTRACT, data: data, gasPrice: increasedGasPrice, - gasLimit: 500000, + gasLimit: gasEstimated.add(BUFFER), } const res = await flashbotsProvider.sendPrivateTransaction({ transaction,