diff --git a/package-lock.json b/package-lock.json index c70a464d4d..6c0ebd628c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11339,7 +11339,7 @@ }, "node_modules/ethereumjs-abi": { "version": "0.6.8", - "resolved": "git+ssh://git@github.com/ethereumjs/ethereumjs-abi.git", + "resolved": "https://git@github.com/ethereumjs/ethereumjs-abi.git", "integrity": "sha512-qs8G5KwnIO/thOQjv1RvR/4oiTsy6IaCsN+ory5dbiqFXz8sd239aWJH0wmsVNPimL5X1KzQheUpi6xAo6FU4w==", "dev": true, "license": "MIT", @@ -31766,7 +31766,7 @@ }, "node_modules/truffle-hdwallet-provider/node_modules/websocket": { "version": "1.0.29", - "resolved": "git+ssh://git@github.com/web3-js/WebSocket-Node.git", + "resolved": "https://git@github.com/web3-js/WebSocket-Node.git", "integrity": "sha512-shhW6L+V8TtEtoA+mSzg67T+v2Lo5vt8eLvPKWZk7b6L4B7hduaDEbPxuz85bgl1a5CIHpNSMtob7VPBB+lAZQ==", "dev": true, "hasInstallScript": true, @@ -44957,7 +44957,7 @@ } }, "ethereumjs-abi": { - "version": "git+ssh://git@github.com/ethereumjs/ethereumjs-abi.git", + "version": "https://git@github.com/ethereumjs/ethereumjs-abi.git", "integrity": "sha512-qs8G5KwnIO/thOQjv1RvR/4oiTsy6IaCsN+ory5dbiqFXz8sd239aWJH0wmsVNPimL5X1KzQheUpi6xAo6FU4w==", "dev": true, "from": "ethereumjs-abi@^0.6.8", @@ -61966,7 +61966,7 @@ } }, "websocket": { - "version": "git+ssh://git@github.com/web3-js/WebSocket-Node.git", + "version": "https://git@github.com/web3-js/WebSocket-Node.git", "integrity": "sha512-shhW6L+V8TtEtoA+mSzg67T+v2Lo5vt8eLvPKWZk7b6L4B7hduaDEbPxuz85bgl1a5CIHpNSMtob7VPBB+lAZQ==", "dev": true, "from": "websocket@^1.0.28", diff --git a/packages/metatransaction-broadcaster/Dockerfile b/packages/metatransaction-broadcaster/Dockerfile index 2ec973f8cf..dc8fabe731 100644 --- a/packages/metatransaction-broadcaster/Dockerfile +++ b/packages/metatransaction-broadcaster/Dockerfile @@ -3,7 +3,7 @@ COPY ./packages ./packages COPY ./package.json ./ COPY ./package-lock.json ./ COPY ./build ./build -RUN npm i +RUN npm ci RUN cd ./packages/metatransaction-broadcaster/ && npm i RUN cd ./packages/package-utils/ && npm i EXPOSE 3000 diff --git a/packages/metatransaction-broadcaster/MetatransactionBroadcaster.js b/packages/metatransaction-broadcaster/MetatransactionBroadcaster.js index b093f99961..d89547849e 100644 --- a/packages/metatransaction-broadcaster/MetatransactionBroadcaster.js +++ b/packages/metatransaction-broadcaster/MetatransactionBroadcaster.js @@ -4,7 +4,7 @@ const sqlite = require("sqlite"); const sqlite3 = require("sqlite3"); const queue = require("express-queue"); const NonceManager = require("./ExtendedNonceManager"); -const { colonyIOCors, ConsoleAdapter, updateGasEstimate } = require("../package-utils"); +const { colonyIOCors, ConsoleAdapter, getFeeData } = require("../package-utils"); const ETHEREUM_BRIDGE_ADDRESS = "0x75Df5AF045d91108662D8080fD1FEFAd6aA0bb59"; const BINANCE_BRIDGE_ADDRESS = "0x162E898bD0aacB578C8D5F8d6ca588c13d2A383F"; @@ -81,7 +81,7 @@ class MetatransactionBroadcaster { const colonyNetworkDef = await this.loader.load({ contractName: "IColonyNetwork" }, { abi: true, address: false }); this.colonyNetwork = new ethers.Contract(colonyNetworkAddress, colonyNetworkDef.abi, this.wallet); - this.gasPrice = await updateGasEstimate("safeLow", this.chainId, this.adapter); + this.feeData = await getFeeData("safeLow", this.chainId, this.adapter, this.provider); this.tokenLockingAddress = await this.colonyNetwork.getTokenLocking(); this.metaTxDef = await this.loader.load({ contractName: "IBasicMetaTransaction" }, { abi: true, address: false }); @@ -336,6 +336,10 @@ class MetatransactionBroadcaster { try { gasEstimate = await estimateGas(...args); + if (ethers.BigNumber.from(args[args.length - 1].gasLimit).gt(gasEstimate.mul(11).div(10))) { + // eslint-disable-next-line + args[args.length - 1].gasLimit = gasEstimate.mul(11).div(10); + } } catch (err) { let reason; try { @@ -441,14 +445,14 @@ class MetatransactionBroadcaster { try { const { target, userAddress, payload, r, s, v } = req.body; const contract = new ethers.Contract(target, this.metaTxDef.abi, this.nonceManager); - this.gasPrice = await updateGasEstimate("safeLow", this.chainId, this.adapter); + this.feeData = await getFeeData("safeLow", this.chainId, this.adapter, this.provider); return this.processTransactionLogic(req, res, contract.estimateGas.executeMetaTransaction, contract.executeMetaTransaction, [ userAddress, payload, r, s, v, - { gasPrice: this.gasPrice, gasLimit: this.gasLimit }, + { ...this.feeData, gasLimit: this.gasLimit }, ]); } catch (err) { return res.status(500).send({ @@ -462,7 +466,7 @@ class MetatransactionBroadcaster { try { const { target, owner, spender, value, deadline, r, s, v } = req.body; const contract = new ethers.Contract(target, this.metaTxTokenDef.abi, this.nonceManager); - this.gasPrice = await updateGasEstimate("safeLow", this.chainId, this.adapter); + this.feeData = await getFeeData("safeLow", this.chainId, this.adapter, this.provider); return this.processTransactionLogic(req, res, contract.estimateGas.permit, contract.permit, [ owner, spender, @@ -471,7 +475,7 @@ class MetatransactionBroadcaster { v, r, s, - { gasPrice: this.gasPrice, gasLimit: this.gasLimit }, + { ...this.feeData, gasLimit: this.gasLimit }, ]); } catch (err) { return res.status(500).send({ diff --git a/packages/package-utils/getFeeData.js b/packages/package-utils/getFeeData.js new file mode 100644 index 0000000000..354173bf43 --- /dev/null +++ b/packages/package-utils/getFeeData.js @@ -0,0 +1,90 @@ +const ethers = require("ethers"); +const axios = require("axios"); + +/** + * Update the gas estimate + * @param {string} Transaction speed (fastest, fast, safeLow) + * @param {number} Chain ID + * @param {object} Adapter + * @param {object} Provider + * @return {Promise} + */ +const getFeeData = async function (_type, chainId, adapter, provider) { + let defaultGasPrice; + let factor; + let feeData; + + let type = _type; + const options = { + headers: { + "User-Agent": "Request-Promise", + }, + json: true, // Automatically parses the JSON string in the response + }; + + if (chainId === 100) { + options.url = "https://blockscout.com/xdai/mainnet/api/v1/gas-price-oracle"; + defaultGasPrice = ethers.BigNumber.from(10000000000); + factor = 1; + // This oracle presents the information slightly differently from ethgasstation. + if (_type === "safeLow") { + type = "slow"; + } + } else if (chainId === 1) { + options.url = "https://ethgasstation.info/json/ethgasAPI.json"; + defaultGasPrice = ethers.BigNumber.from(10000000000); + factor = 10; + } else { + // We don't have an oracle, so just use the provided fee data + adapter.log(`During gas estimation: unknown chainid ${chainId}`); + feeData = await provider.getFeeData(); + delete feeData.lastBaseFeePerGas; + if (feeData.maxFeePerGas) { + delete feeData.gasPrice; + } + return feeData; + } + + try { + feeData = await provider.getFeeData(); + delete feeData.lastBaseFeePerGas; + if (feeData.maxFeePerGas) { + delete feeData.gasPrice; + } + // Update gas prices from whichever oracle + try { + const request = await axios.request(options); + const gasEstimates = request.data; + + if (feeData.maxFeePerGas) { + // Update the EIP1559 fee data based on the type + const ratio = gasEstimates[type] / gasEstimates.average; + // Increase the priority fee by this ratio + const newMaxPriorityFeePerGas = ethers.BigNumber.from(Math.floor(feeData.maxPriorityFeePerGas * 1000)) + .mul(Math.floor(ratio * 1000)) + .div(1000 * 1000); + // Increase the max fee per gas by the same amount (not the same ratio) + feeData.maxFeePerGas = feeData.maxFeePerGas.add(newMaxPriorityFeePerGas).sub(feeData.maxPriorityFeePerGas); + feeData.maxPriorityFeePerGas = newMaxPriorityFeePerGas; + return feeData; + } + + // If we get here, chain is not EIP1559, so just update gasPrice + if (gasEstimates[type]) { + feeData.gasPrice = ethers.BigNumber.from(gasEstimates[type] * 1e9).div(factor); + } else { + feeData.gasPrice = defaultGasPrice; + } + } catch (err) { + adapter.error(`Error during gas estimation: ${err}`); + adapter.error(`Using default fee data from node`); + } + } catch (err) { + adapter.error(`Error getting fee data from provider: ${err}`); + adapter.error(`Using default static gas fee. Hopefully it's not too low...`); + feeData = { gasPrice: defaultGasPrice }; + } + return feeData; +}; + +module.exports = getFeeData; diff --git a/packages/package-utils/index.js b/packages/package-utils/index.js index 07cc7dc990..2b5ffbf94e 100644 --- a/packages/package-utils/index.js +++ b/packages/package-utils/index.js @@ -1,5 +1,5 @@ exports.colonyIOCors = require("./colonyIOCors"); -exports.updateGasEstimate = require("./updateGasEstimate"); +exports.getFeeData = require("./getFeeData"); exports.DiscordAdapter = require("./adapters/discord"); exports.SlackAdapter = require("./adapters/slack"); exports.ConsoleAdapter = require("./adapters/console"); diff --git a/packages/package-utils/updateGasEstimate.js b/packages/package-utils/updateGasEstimate.js deleted file mode 100644 index 84c088e71e..0000000000 --- a/packages/package-utils/updateGasEstimate.js +++ /dev/null @@ -1,55 +0,0 @@ -const ethers = require("ethers"); -const axios = require("axios"); - -/** - * Update the gas estimate - * @param {string} Transaction speed (fastest, fast, safeLow) - * @return {Promise} - */ -const updateGasEstimate = async function (_type, chainId, adapter) { - let type = _type; - const options = { - headers: { - "User-Agent": "Request-Promise", - }, - json: true, // Automatically parses the JSON string in the response - }; - let defaultGasPrice; - let factor; - - if (chainId === 100) { - options.url = "https://blockscout.com/xdai/mainnet/api/v1/gas-price-oracle"; - defaultGasPrice = ethers.utils.hexlify(2000000000); - factor = 1; - // This oracle presents the information slightly differently from ethgasstation. - if (_type === "safeLow") { - type = "slow"; - } - } else if (chainId === 1) { - options.url = "https://ethgasstation.info/json/ethgasAPI.json"; - defaultGasPrice = ethers.utils.hexlify(20000000000); - factor = 10; - } else { - adapter.error(`Error during gas estimation: unknown chainid ${chainId}`); - const gasPrice = ethers.utils.hexlify(20000000000); - return gasPrice; - } - - // Get latest from whichever oracle - try { - const request = await axios.request(options); - const gasEstimates = request.data; - let gasPrice; - if (gasEstimates[type]) { - gasPrice = ethers.utils.hexlify(ethers.BigNumber.from(Math.floor((gasEstimates[type] * 1e9) / factor))); - } else { - gasPrice = defaultGasPrice; - } - return gasPrice; - } catch (err) { - adapter.error(`Error during gas estimation: ${err}`); - return defaultGasPrice; - } -}; - -module.exports = updateGasEstimate; diff --git a/packages/reputation-miner/ReputationMiner.js b/packages/reputation-miner/ReputationMiner.js index ec76812b68..b8dc3ec7ca 100644 --- a/packages/reputation-miner/ReputationMiner.js +++ b/packages/reputation-miner/ReputationMiner.js @@ -16,6 +16,8 @@ const minStake = ethers.BigNumber.from(10).pow(18).mul(2000); const DAY_IN_SECONDS = 60 * 60 * 24; +const BLOCK_PAGING_SIZE = 25000; + class ReputationMiner { /** * Constructor for ReputationMiner @@ -96,7 +98,7 @@ class ReputationMiner { this.nReputations = ethers.constants.Zero; this.reputations = {}; - this.gasPrice = ethers.utils.hexlify(20000000000); + this.feeData = {}; const repCycle = await this.getActiveRepCycle(); await this.updatePeriodLength(repCycle); this.db = new Database(this.dbPath, { }); @@ -763,7 +765,7 @@ class ReputationMiner { } // Submit that entry - return repCycle.submitRootHash(hash, nLeaves, jrh, entryIndex, { gasLimit: gasEstimate, gasPrice: this.gasPrice }); + return repCycle.submitRootHash(hash, nLeaves, jrh, entryIndex, { gasLimit: gasEstimate, ...this.feeData }); } async getEntryIndex(startIndex = 1) { @@ -1017,7 +1019,7 @@ class ReputationMiner { index, siblings1, siblings2, - { gasLimit: gasEstimate, gasPrice: this.gasPrice } + { gasLimit: gasEstimate, ...this.feeData } ); } @@ -1107,7 +1109,7 @@ class ReputationMiner { siblings, { gasLimit: gasEstimate, - gasPrice: this.gasPrice + ...this.feeData } ); } @@ -1139,7 +1141,7 @@ class ReputationMiner { return repCycle.confirmBinarySearchResult(round, index, intermediateReputationHash, siblings, { gasLimit: gasEstimate, - gasPrice: this.gasPrice + ...this.feeData }); } @@ -1243,7 +1245,7 @@ class ReputationMiner { } return repCycle.respondToChallenge(...functionArgs, - { gasLimit: gasEstimate, gasPrice: this.gasPrice } + { gasLimit: gasEstimate, ...this.feeData } ); } @@ -1263,7 +1265,7 @@ class ReputationMiner { } catch (err){ gasEstimate = ethers.BigNumber.from(4000000); } - return repCycle.confirmNewHash(round, { gasLimit: gasEstimate, gasPrice: this.gasPrice }); + return repCycle.confirmNewHash(round, { gasLimit: gasEstimate, ...this.feeData }); } @@ -1359,30 +1361,50 @@ class ReputationMiner { if (!blockNumber) { throw new Error("Block number not supplied to sync"); } - // Get the events - const filter = this.colonyNetwork.filters.ReputationMiningCycleComplete(null, null); - filter.fromBlock = blockNumber; - const events = await this.realProvider.getLogs(filter); + let localHash = await this.reputationTree.getRootHash(); + let foundKnownState = false; let applyLogs = false; + let syncFromIndex = -1; - // Run through events backwards find the most recent one that we know... - let syncFromIndex = 0; - for (let i = events.length - 1 ; i >= 0 ; i -= 1){ - const event = events[i]; - const hash = event.data.slice(0, 66); - const nLeaves = ethers.BigNumber.from(`0x${event.data.slice(66, 130)}`); - // Do we have such a state? - const res = await this.queries.getReputationStateCount.get(hash, nLeaves.toString()); - if (res.n === 1){ - // We know that state! We can just sync from the next one... - syncFromIndex = i + 1; - await this.loadState(hash); - applyLogs = true; - break; + const latestBlockNumber = await this.realProvider.getBlockNumber(); + const filter = this.colonyNetwork.filters.ReputationMiningCycleComplete(null, null); + filter.fromBlock = latestBlockNumber + 1; // +1 to accommodate the first loop iteration + filter.toBlock = filter.fromBlock; + + let events = []; + while (filter.toBlock > blockNumber && !foundKnownState ) { + // Create a span of events up to BLOCK_PAGING_SIZE in length + filter.toBlock = filter.fromBlock - 1; + filter.fromBlock = Math.max(filter.toBlock - BLOCK_PAGING_SIZE + 1, blockNumber); + + // Get new span of events, [fromBlock:oldset ... toBlock:newest] + const partialEvents = await this.realProvider.getLogs(filter); + // Build a complete reversed array of events, [newest ... oldest] + events = events.concat(partialEvents.reverse()); + + // Run through events to find the most recent one that we know... + for (let i = 0 ; i < events.length ; i += 1) { + const event = events[i]; + if (await this.cycleCompleteEventIsKnownState(event)) { + // We know that state! We can just sync from the next one... + const knownHash = event.data.slice(0, 66); + await this.loadState(knownHash); + + foundKnownState = true; + applyLogs = true; + syncFromIndex = i - 1; + + break; + } } } + // This means that we have not seen a known state, and so will have to sync from the start + if (syncFromIndex === -1 && !foundKnownState) { + syncFromIndex = events.length - 1; + } + // We're not going to apply the logs unless we're syncing from scratch (which is this if statement) // or we find a hash that we recognise as our current state, and we're going to sync from there (which // is the if statement at the end of the loop below @@ -1390,10 +1412,10 @@ class ReputationMiner { applyLogs = true; } - for (let i = syncFromIndex; i < events.length; i += 1) { - console.log(`Syncing mining cycle ${i + 1} of ${events.length}...`) + for (let i = syncFromIndex; i >= 0; i -= 1) { + console.log(`Syncing mining cycle ${syncFromIndex - i + 1} of ${syncFromIndex + 1}...`) const event = events[i]; - if (i === 0) { + if (i === events.length - 1 && !foundKnownState) { // If we are syncing from the very start of the reputation history, the block // before the very first 'ReputationMiningCycleComplete' does not have an // active reputation cycle. So we skip it if 'fromBlock' has not been judiciously @@ -1426,8 +1448,9 @@ class ReputationMiner { } // Some more cycles might have completed since we started syncing - const lastEventBlock = events[events.length - 1].blockNumber + const lastEventBlock = events[0].blockNumber filter.fromBlock = lastEventBlock; + filter.toBlock = "latest"; const sinceEvents = await this.realProvider.getLogs(filter); if (sinceEvents.length > 1){ console.log("Some more cycles have completed during the sync process. Continuing to sync...") @@ -1447,6 +1470,14 @@ class ReputationMiner { } } + async cycleCompleteEventIsKnownState(event) { + const hash = event.data.slice(0, 66); + const nLeaves = ethers.BigNumber.from(`0x${event.data.slice(66, 130)}`); + // Do we have such a state? + const res = await this.queries.getReputationStateCount.get(hash, nLeaves.toString()); + return res.n === 1; + } + async printCurrentState() { for (let i = 0; i < Object.keys(this.reputations).length; i += 1) { const key = Object.keys(this.reputations)[i]; @@ -1463,18 +1494,8 @@ class ReputationMiner { } } - // Gas price should be a hex string - async setGasPrice(_gasPrice){ - if (!ethers.utils.isHexString(_gasPrice)){ - throw new Error("Passed gas price was not a hex string") - } - const passedPrice = ethers.BigNumber.from(_gasPrice); - const minimumPrice = ethers.BigNumber.from("1100000000"); - if (passedPrice.lt(minimumPrice)){ - this.gasPrice = minimumPrice.toHexString(); - } else { - this.gasPrice = _gasPrice; - } + setFeeData(_feeData){ + this.feeData = _feeData; } async saveCurrentState() { diff --git a/packages/reputation-miner/ReputationMinerClient.js b/packages/reputation-miner/ReputationMinerClient.js index 22954dbe2a..359b34b8e9 100644 --- a/packages/reputation-miner/ReputationMinerClient.js +++ b/packages/reputation-miner/ReputationMinerClient.js @@ -4,7 +4,7 @@ const path = require("path"); const apicache = require("apicache") const ReputationMiner = require("./ReputationMiner"); -const { ConsoleAdapter, updateGasEstimate } = require("../package-utils"); +const { ConsoleAdapter, getFeeData } = require("../package-utils"); const minStake = ethers.BigNumber.from(10).pow(18).mul(2000); // eslint-disable-line prettier/prettier const MINUTE_IN_SECONDS = 60; @@ -442,8 +442,7 @@ class ReputationMinerClient { const canSubmit = await this._miner.submissionPossible(entryIndex); if (canSubmit) { this._adapter.log("⏰ Looks like it's time to submit an entry to the current cycle"); - const gasPrice = await updateGasEstimate("average", this.chainId, this._adapter); - await this._miner.setGasPrice(gasPrice); + await this.updateFeeData("average"); await this.submitEntry(entryIndex); this.submissionIndex += 1; this.endDoBlockChecks(); @@ -494,8 +493,7 @@ class ReputationMinerClient { return; } } - const gasPrice = await updateGasEstimate("fast", this.chainId, this._adapter); - await this._miner.setGasPrice(gasPrice); + await this.updateFeeData("fast"); this._adapter.log("Invalidating pseudo-opponent in dispute"); await repCycle.invalidateHash(round, oppIndex, {"gasPrice": this._miner.gasPrice}); @@ -509,8 +507,7 @@ class ReputationMinerClient { if (submission.jrhNLeaves.eq(0)) { const responsePossible = await repCycle.getResponsePossible(disputeStages.CONFIRM_JRH, entry.lastResponseTimestamp); if (responsePossible){ - const gasPrice = await updateGasEstimate("fast", this.chainId, this._adapter); - await this._miner.setGasPrice(gasPrice); + await this.updateFeeData("fast"); this._adapter.log("Confirming JRH in dispute"); const tx = await this._miner.confirmJustificationRootHash(); await tx.wait(); @@ -524,8 +521,7 @@ class ReputationMinerClient { if (oppEntry.challengeStepCompleted.gte(entry.challengeStepCompleted)) { const responsePossible = await repCycle.getResponsePossible(disputeStages.BINARY_SEARCH_RESPONSE, entry.lastResponseTimestamp); if (responsePossible){ - const gasPrice = await updateGasEstimate("fast", this.chainId, this._adapter); - await this._miner.setGasPrice(gasPrice); + await this.updateFeeData("fast"); this._adapter.log("Responding to binary search in dispute"); const tx = await this._miner.respondToBinarySearchForChallenge(); await tx.wait(); @@ -542,8 +538,7 @@ class ReputationMinerClient { { const responsePossible = await repCycle.getResponsePossible(disputeStages.BINARY_SEARCH_CONFIRM, entry.lastResponseTimestamp); if (responsePossible){ - const gasPrice = await updateGasEstimate("fast", this.chainId, this._adapter); - await this._miner.setGasPrice(gasPrice); + await this.updateFeeData("fast"); this._adapter.log("Confirming binary search in dispute"); const tx = await this._miner.confirmBinarySearchResult(); await tx.wait(); @@ -560,8 +555,7 @@ class ReputationMinerClient { { const responsePossible = await repCycle.getResponsePossible(disputeStages.RESPOND_TO_CHALLENGE, entry.lastResponseTimestamp); if (responsePossible){ - const gasPrice = await updateGasEstimate("fast", this.chainId, this._adapter); - await this._miner.setGasPrice(gasPrice); + await this.updateFeeData("fast"); this._adapter.log("Responding to challenge in dispute"); const tx = await this._miner.respondToChallenge(); await tx.wait(); @@ -578,8 +572,7 @@ class ReputationMinerClient { ); if (responsePossible) { // If so, invalidate them. - const gasPrice = await updateGasEstimate("fast", this.chainId, this._adapter); - await this._miner.setGasPrice(gasPrice); + await this.updateFeeData("fast"); this._adapter.log("Invalidating opponent in dispute"); await repCycle.invalidateHash(round, oppIndex, {"gasPrice": this._miner.gasPrice}); this.endDoBlockChecks(); @@ -764,8 +757,7 @@ class ReputationMinerClient { // Confirm hash if possible const [round] = await this._miner.getMySubmissionRoundAndIndex(); if (round && round.gte(0)) { - const gasPrice = await updateGasEstimate("average", this.chainId, this._adapter); - await this._miner.setGasPrice(gasPrice); + await this.updateFeeData("average"); const confirmNewHashTx = await this._miner.confirmNewHash(); @@ -785,6 +777,11 @@ class ReputationMinerClient { this._miningCycleConfirmationOverdue = true; } + async updateFeeData(type) { + const feeData = await getFeeData(type, this.chainId, this._adapter, this._miner.realProvider); + this._miner.setFeeData(feeData); + } + } module.exports = ReputationMinerClient; diff --git a/test/packages/metaTransactionBroadcaster.js b/test/packages/metaTransactionBroadcaster.js index 8f3a158af2..456c25bd0d 100644 --- a/test/packages/metaTransactionBroadcaster.js +++ b/test/packages/metaTransactionBroadcaster.js @@ -10,6 +10,7 @@ const axios = require("axios"); const { TruffleLoader } = require("../../packages/package-utils"); const { setupEtherRouter } = require("../../helpers/upgradable-contracts"); const { UINT256_MAX } = require("../../helpers/constants"); +const { web3GetTransaction } = require("../../helpers/test-helper"); const MetatransactionBroadcaster = require("../../packages/metatransaction-broadcaster/MetatransactionBroadcaster"); const { getMetaTransactionParameters, getPermitParameters, setupColony } = require("../../helpers/test-data-generator"); @@ -242,6 +243,9 @@ contract("Metatransaction broadcaster", (accounts) => { expect(balanceAccount1).to.eq.BN(1200000); const balanceAccount2 = await metaTxToken.balanceOf(colony.address); expect(balanceAccount2).to.eq.BN(300000); + + const tx = await web3GetTransaction(txHash); + expect(tx.gas).to.be.lt.BN(500000); }); it("valid transactions broadcast near-simultaneously are still mined", async function () { diff --git a/test/reputation-system/client-sync-functionality.js b/test/reputation-system/client-sync-functionality.js index d9929f7bb0..4d40c87b4c 100644 --- a/test/reputation-system/client-sync-functionality.js +++ b/test/reputation-system/client-sync-functionality.js @@ -262,8 +262,10 @@ process.env.SOLIDITY_COVERAGE useJsTree: true, dbPath: fileName, }); + await reputationMiner3.initialise(colonyNetwork.address); - await reputationMiner3.sync("latest"); + const latestBlock = await currentBlock(); + await reputationMiner3.sync(parseInt(latestBlock.number, 10)); const loadedState = await reputationMiner3.getRootHash(); expect(loadedState).to.equal(currentState);