117 lines
3.2 KiB
JavaScript
Raw Normal View History

const asciiTable = require('ascii-table');
const GasEstimator = require('./gasEstimator.js');
class Profiler {
2018-08-01 13:27:50 -04:00
constructor(embark, options) {
this.embark = embark;
this.logger = embark.logger;
this.events = embark.events;
2018-08-01 13:27:50 -04:00
this.plugins = options.plugins;
this.gasEstimator = new GasEstimator(embark);
this.registerConsoleCommand();
2018-08-01 13:27:50 -04:00
this.registerApi();
}
2018-08-01 15:09:16 -04:00
profileJSON(contractName, returnCb) {
2018-08-01 14:02:37 -04:00
const self = this;
let profileObj = {};
profileObj.name = contractName;
profileObj.methods = [];
2018-08-01 15:09:16 -04:00
self.events.request('contracts:contract', contractName, (contract) => {
if (!contract || !contract.deployedAddress) {
return returnCb("-- couldn't profile " + contractName + " - it's not deployed or could be an interface");
2018-08-01 14:02:37 -04:00
}
2018-08-03 13:08:55 -04:00
self.gasEstimator.estimateGas(contractName, function(err, gastimates, _name) {
2018-08-01 15:09:16 -04:00
if (err) {
return returnCb(err);
2018-08-01 14:02:37 -04:00
}
2018-08-01 15:09:16 -04:00
contract.abiDefinition.forEach((abiMethod) => {
let methodName = abiMethod.name;
if (['constructor', 'fallback'].indexOf(abiMethod.type) >= 0) {
methodName = abiMethod.type;
}
profileObj.methods.push({
name: methodName,
payable: abiMethod.payable,
mutability: abiMethod.stateMutability,
2018-08-01 15:16:41 -04:00
inputs: abiMethod.inputs || [],
outputs: abiMethod.outputs || [],
2018-08-01 15:09:16 -04:00
gasEstimates: gastimates[methodName]
});
2018-08-01 14:02:37 -04:00
});
2018-08-01 15:09:16 -04:00
returnCb(null, profileObj);
});
2018-08-01 14:02:37 -04:00
});
}
2018-08-01 15:09:16 -04:00
profile(contractName, returnCb) {
const self = this;
2018-08-01 14:10:02 -04:00
2018-08-01 15:09:16 -04:00
this.profileJSON(contractName, (err, profileObj) => {
if (err) {
self.logger.error(JSON.stringify(err));
2018-08-01 13:27:50 -04:00
return returnCb(err);
}
2018-08-01 14:10:02 -04:00
let table = new asciiTable(contractName);
table.setHeading('Function', 'Payable', 'Mutability', 'Inputs', 'Outputs', 'Gas Estimates');
profileObj.methods.forEach((method) => {
2018-08-01 15:16:41 -04:00
table.addRow(method.name, method.payable, method.mutability, self.formatParams(method.inputs), self.formatParams(method.outputs), method.gasEstimates);
});
2018-08-01 13:27:50 -04:00
return returnCb(null, table.toString());
});
}
formatParams(params) {
2018-08-01 15:16:41 -04:00
return "(" + (params || []).map(param => param.type).join(',') + ")";
}
registerConsoleCommand() {
const self = this;
self.embark.registerConsoleCommand((cmd, _options) => {
let cmdName = cmd.split(' ')[0];
let contractName = cmd.split(' ')[1];
if (cmdName === 'profile') {
2018-08-01 15:09:16 -04:00
self.logger.info("-- profile for " + contractName);
self.profile(contractName, (err, table) => {
if (err) {
return self.logger.error(err);
}
2018-08-01 15:09:16 -04:00
self.logger.info(table);
});
2018-08-01 15:09:16 -04:00
return "";
}
return false;
});
}
2018-08-01 13:27:50 -04:00
registerApi() {
const self = this;
let plugin = this.plugins.createPlugin('profiler', {});
plugin.registerAPICall(
'get',
'/embark-api/profiler/:contractName',
(req, res) => {
let contractName = req.params.contractName;
2018-08-01 15:09:16 -04:00
self.profileJSON(contractName, (err, table) => {
if (err) {
return res.send({error: err});
2018-08-01 13:27:50 -04:00
}
2018-08-01 15:09:16 -04:00
res.send(table);
2018-08-01 13:27:50 -04:00
});
}
);
}
}
module.exports = Profiler;