embark/packages/plugins/profiler/src/gasEstimator.js

94 lines
3.9 KiB
JavaScript
Raw Normal View History

const async = require('async');
const ContractFuzzer = require('./fuzzer.js');
const Web3 = require('web3');
fix(@embark/profiler): Fix profile output and update messaging The profiler was not formatted correctly in the console as `util.inspect` was being applied to the ASCII table before being output to the console REPL. In addition, functions containing solidity assertions (require, revert, assert) that cause the function to fail when estimating gas would print an error to embark’s console log, and would show nothing as their gas estimate in the table. Do not `util.inspect` command output if the result is a string. For API commands being run, allow the command to specify whether or not the output of the command should be HTML escaped. This could pose security risks! For functions that have errors during gas estimation, add a message in the embark console explaining that the error may be due to solidity assertions in the function that prevent the gas from being estimated correctly. For functions that error, show `-ERROR-` in the gas estimation column. Additionally, show a description in the table footer explaining that the error may be due to solidity assertions in the function. For events with no gas estimate, show `-EVENT-` in the gas estimate column of the profile table, and a description in the table footer explaining that there is no gas estimate for events. ### Warnings This PR allows the console command to specify whether or not it should allow for a string result of the command to be HTML-escaped before being sent in the API response. Combining this with Cockpit’s `dangerouslySetInnerHTML`, this could allow a plugin to register a console command that injects XSS in to Cockpit. ![Imgur](https://i.imgur.com/1Rqkjyx.png) ![Imgur](https://i.imgur.com/s6Y1Ecy.png) ![Imgur](https://i.imgur.com/BhsjkBs.png)
2020-02-13 02:14:36 +00:00
export const GAS_ERROR = ' -ERROR- ';
export const EVENT_NO_GAS = ' -EVENT- ';
export class GasEstimator {
constructor(embark) {
this.embark = embark;
this.logger = embark.logger;
this.events = embark.events;
this.fuzzer = new ContractFuzzer(embark);
}
fix(@embark/profiler): Fix profile output and update messaging The profiler was not formatted correctly in the console as `util.inspect` was being applied to the ASCII table before being output to the console REPL. In addition, functions containing solidity assertions (require, revert, assert) that cause the function to fail when estimating gas would print an error to embark’s console log, and would show nothing as their gas estimate in the table. Do not `util.inspect` command output if the result is a string. For API commands being run, allow the command to specify whether or not the output of the command should be HTML escaped. This could pose security risks! For functions that have errors during gas estimation, add a message in the embark console explaining that the error may be due to solidity assertions in the function that prevent the gas from being estimated correctly. For functions that error, show `-ERROR-` in the gas estimation column. Additionally, show a description in the table footer explaining that the error may be due to solidity assertions in the function. For events with no gas estimate, show `-EVENT-` in the gas estimate column of the profile table, and a description in the table footer explaining that there is no gas estimate for events. ### Warnings This PR allows the console command to specify whether or not it should allow for a string result of the command to be HTML-escaped before being sent in the API response. Combining this with Cockpit’s `dangerouslySetInnerHTML`, this could allow a plugin to register a console command that injects XSS in to Cockpit. ![Imgur](https://i.imgur.com/1Rqkjyx.png) ![Imgur](https://i.imgur.com/s6Y1Ecy.png) ![Imgur](https://i.imgur.com/BhsjkBs.png)
2020-02-13 02:14:36 +00:00
printError(message, name, values = []) {
this.logger.error(`Error getting gas estimate for "${name}(${Object.values(values).join(",")})"`, message);
if (message.includes('always failing transaction')) {
this.logger.error(`This may mean function assertions (revert, assert, require) are preventing the estimate from completing. Gas will be listed as "${GAS_ERROR}" in the profile.`);
}
this.logger.error(''); // new line to separate likely many lines
}
estimateGas(contractName, cb) {
const self = this;
let gasMap = {};
self.events.request("blockchain:client:provider", "ethereum", (err, provider) => {
const web3 = new Web3(provider);
self.events.request('contracts:contract', contractName, (err, contract) => {
if (err) return cb(err);
let fuzzMap = self.fuzzer.generateFuzz(3, contract);
let contractObj = new web3.eth.Contract(contract.abiDefinition, contract.deployedAddress);
fix(@embark/profiler): Fix profile output and update messaging The profiler was not formatted correctly in the console as `util.inspect` was being applied to the ASCII table before being output to the console REPL. In addition, functions containing solidity assertions (require, revert, assert) that cause the function to fail when estimating gas would print an error to embark’s console log, and would show nothing as their gas estimate in the table. Do not `util.inspect` command output if the result is a string. For API commands being run, allow the command to specify whether or not the output of the command should be HTML escaped. This could pose security risks! For functions that have errors during gas estimation, add a message in the embark console explaining that the error may be due to solidity assertions in the function that prevent the gas from being estimated correctly. For functions that error, show `-ERROR-` in the gas estimation column. Additionally, show a description in the table footer explaining that the error may be due to solidity assertions in the function. For events with no gas estimate, show `-EVENT-` in the gas estimate column of the profile table, and a description in the table footer explaining that there is no gas estimate for events. ### Warnings This PR allows the console command to specify whether or not it should allow for a string result of the command to be HTML-escaped before being sent in the API response. Combining this with Cockpit’s `dangerouslySetInnerHTML`, this could allow a plugin to register a console command that injects XSS in to Cockpit. ![Imgur](https://i.imgur.com/1Rqkjyx.png) ![Imgur](https://i.imgur.com/s6Y1Ecy.png) ![Imgur](https://i.imgur.com/BhsjkBs.png)
2020-02-13 02:14:36 +00:00
async.each(contract.abiDefinition,
(abiMethod, gasCb) => {
let name = abiMethod.name;
if (abiMethod.type === "constructor") {
// already provided for us
gasMap['constructor'] = parseFloat(contract.gasEstimates.creation.totalCost.toString());
return gasCb(null, name, abiMethod.type);
fix(@embark/profiler): Fix profile output and update messaging The profiler was not formatted correctly in the console as `util.inspect` was being applied to the ASCII table before being output to the console REPL. In addition, functions containing solidity assertions (require, revert, assert) that cause the function to fail when estimating gas would print an error to embark’s console log, and would show nothing as their gas estimate in the table. Do not `util.inspect` command output if the result is a string. For API commands being run, allow the command to specify whether or not the output of the command should be HTML escaped. This could pose security risks! For functions that have errors during gas estimation, add a message in the embark console explaining that the error may be due to solidity assertions in the function that prevent the gas from being estimated correctly. For functions that error, show `-ERROR-` in the gas estimation column. Additionally, show a description in the table footer explaining that the error may be due to solidity assertions in the function. For events with no gas estimate, show `-EVENT-` in the gas estimate column of the profile table, and a description in the table footer explaining that there is no gas estimate for events. ### Warnings This PR allows the console command to specify whether or not it should allow for a string result of the command to be HTML-escaped before being sent in the API response. Combining this with Cockpit’s `dangerouslySetInnerHTML`, this could allow a plugin to register a console command that injects XSS in to Cockpit. ![Imgur](https://i.imgur.com/1Rqkjyx.png) ![Imgur](https://i.imgur.com/s6Y1Ecy.png) ![Imgur](https://i.imgur.com/BhsjkBs.png)
2020-02-13 02:14:36 +00:00
} else if (abiMethod.type === "event") {
gasMap[name] = EVENT_NO_GAS;
return gasCb(null, name, abiMethod.type);
} else if (abiMethod.type === "fallback") {
gasMap['fallback'] = parseFloat(contract.gasEstimates.external[""].toString());
return gasCb(null, name, abiMethod.type);
} else if (
(abiMethod.inputs === null || abiMethod.inputs === undefined || abiMethod.inputs.length === 0)
) {
// just run it and register it
contractObj.methods[name]
.apply(contractObj.methods[name], [])
fix(@embark/profiler): Fix profile output and update messaging The profiler was not formatted correctly in the console as `util.inspect` was being applied to the ASCII table before being output to the console REPL. In addition, functions containing solidity assertions (require, revert, assert) that cause the function to fail when estimating gas would print an error to embark’s console log, and would show nothing as their gas estimate in the table. Do not `util.inspect` command output if the result is a string. For API commands being run, allow the command to specify whether or not the output of the command should be HTML escaped. This could pose security risks! For functions that have errors during gas estimation, add a message in the embark console explaining that the error may be due to solidity assertions in the function that prevent the gas from being estimated correctly. For functions that error, show `-ERROR-` in the gas estimation column. Additionally, show a description in the table footer explaining that the error may be due to solidity assertions in the function. For events with no gas estimate, show `-EVENT-` in the gas estimate column of the profile table, and a description in the table footer explaining that there is no gas estimate for events. ### Warnings This PR allows the console command to specify whether or not it should allow for a string result of the command to be HTML-escaped before being sent in the API response. Combining this with Cockpit’s `dangerouslySetInnerHTML`, this could allow a plugin to register a console command that injects XSS in to Cockpit. ![Imgur](https://i.imgur.com/1Rqkjyx.png) ![Imgur](https://i.imgur.com/s6Y1Ecy.png) ![Imgur](https://i.imgur.com/BhsjkBs.png)
2020-02-13 02:14:36 +00:00
.estimateGas({ from: web3.eth.defaultAccount }, (err, gasAmount) => {
if (err) {
fix(@embark/profiler): Fix profile output and update messaging The profiler was not formatted correctly in the console as `util.inspect` was being applied to the ASCII table before being output to the console REPL. In addition, functions containing solidity assertions (require, revert, assert) that cause the function to fail when estimating gas would print an error to embark’s console log, and would show nothing as their gas estimate in the table. Do not `util.inspect` command output if the result is a string. For API commands being run, allow the command to specify whether or not the output of the command should be HTML escaped. This could pose security risks! For functions that have errors during gas estimation, add a message in the embark console explaining that the error may be due to solidity assertions in the function that prevent the gas from being estimated correctly. For functions that error, show `-ERROR-` in the gas estimation column. Additionally, show a description in the table footer explaining that the error may be due to solidity assertions in the function. For events with no gas estimate, show `-EVENT-` in the gas estimate column of the profile table, and a description in the table footer explaining that there is no gas estimate for events. ### Warnings This PR allows the console command to specify whether or not it should allow for a string result of the command to be HTML-escaped before being sent in the API response. Combining this with Cockpit’s `dangerouslySetInnerHTML`, this could allow a plugin to register a console command that injects XSS in to Cockpit. ![Imgur](https://i.imgur.com/1Rqkjyx.png) ![Imgur](https://i.imgur.com/s6Y1Ecy.png) ![Imgur](https://i.imgur.com/BhsjkBs.png)
2020-02-13 02:14:36 +00:00
self.printError(err.message || err, name);
return gasCb(null, name, abiMethod.type);
}
gasMap[name] = gasAmount;
return gasCb(null, name, abiMethod.type);
});
} else {
// async concatenate all the fuzz values and their gas cost outputs and check for equality
async.concat(fuzzMap[name], (values, getVarianceCb) => {
contractObj.methods[name].apply(contractObj.methods[name], values)
.estimateGas((err, gasAmount) => {
if (err) {
fix(@embark/profiler): Fix profile output and update messaging The profiler was not formatted correctly in the console as `util.inspect` was being applied to the ASCII table before being output to the console REPL. In addition, functions containing solidity assertions (require, revert, assert) that cause the function to fail when estimating gas would print an error to embark’s console log, and would show nothing as their gas estimate in the table. Do not `util.inspect` command output if the result is a string. For API commands being run, allow the command to specify whether or not the output of the command should be HTML escaped. This could pose security risks! For functions that have errors during gas estimation, add a message in the embark console explaining that the error may be due to solidity assertions in the function that prevent the gas from being estimated correctly. For functions that error, show `-ERROR-` in the gas estimation column. Additionally, show a description in the table footer explaining that the error may be due to solidity assertions in the function. For events with no gas estimate, show `-EVENT-` in the gas estimate column of the profile table, and a description in the table footer explaining that there is no gas estimate for events. ### Warnings This PR allows the console command to specify whether or not it should allow for a string result of the command to be HTML-escaped before being sent in the API response. Combining this with Cockpit’s `dangerouslySetInnerHTML`, this could allow a plugin to register a console command that injects XSS in to Cockpit. ![Imgur](https://i.imgur.com/1Rqkjyx.png) ![Imgur](https://i.imgur.com/s6Y1Ecy.png) ![Imgur](https://i.imgur.com/BhsjkBs.png)
2020-02-13 02:14:36 +00:00
self.printError(err.message || err, name, values);
}
getVarianceCb(null, gasAmount);
});
}, (err, variance) => {
if (variance.every(v => v === variance[0])) {
fix(@embark/profiler): Fix profile output and update messaging The profiler was not formatted correctly in the console as `util.inspect` was being applied to the ASCII table before being output to the console REPL. In addition, functions containing solidity assertions (require, revert, assert) that cause the function to fail when estimating gas would print an error to embark’s console log, and would show nothing as their gas estimate in the table. Do not `util.inspect` command output if the result is a string. For API commands being run, allow the command to specify whether or not the output of the command should be HTML escaped. This could pose security risks! For functions that have errors during gas estimation, add a message in the embark console explaining that the error may be due to solidity assertions in the function that prevent the gas from being estimated correctly. For functions that error, show `-ERROR-` in the gas estimation column. Additionally, show a description in the table footer explaining that the error may be due to solidity assertions in the function. For events with no gas estimate, show `-EVENT-` in the gas estimate column of the profile table, and a description in the table footer explaining that there is no gas estimate for events. ### Warnings This PR allows the console command to specify whether or not it should allow for a string result of the command to be HTML-escaped before being sent in the API response. Combining this with Cockpit’s `dangerouslySetInnerHTML`, this could allow a plugin to register a console command that injects XSS in to Cockpit. ![Imgur](https://i.imgur.com/1Rqkjyx.png) ![Imgur](https://i.imgur.com/s6Y1Ecy.png) ![Imgur](https://i.imgur.com/BhsjkBs.png)
2020-02-13 02:14:36 +00:00
gasMap[name] = variance[0] ?? GAS_ERROR;
} else {
// get average
let sum = variance.reduce(function(memo, num) { return memo + num; });
gasMap[name] = sum / variance.length;
}
return gasCb(null, name, abiMethod.type);
});
}
},
(err, name, type) => {
if (err) {
if (type === "constructor" || type === "fallback") name = type;
return cb(err, null, name);
}
cb(null, gasMap, null);
}
);
});
});
}
}