fix callbacks in gas estimator, add more fallback support and clean up console logs to better display potential errors

Signed-off-by: VoR0220 <catalanor0220@gmail.com>
This commit is contained in:
VoR0220 2018-06-12 12:10:35 -05:00
parent e0470b8ef4
commit 43c8525d48
3 changed files with 23 additions and 16 deletions

View File

@ -17,7 +17,7 @@ class ContractFuzzer {
generateFuzz(iterations, contract) { generateFuzz(iterations, contract) {
const self = this; const self = this;
let fuzzMap = {}; let fuzzMap = {};
contract.abiDefinition.filter((x) => x.inputs && x.inputs.length != 0).forEach((abiMethod) => { contract.abiDefinition.filter((x) => x.inputs && x.inputs.length != 0 && x.type != "event").forEach((abiMethod) => {
let name = abiMethod.type === "constructor" ? "constructor" : abiMethod.name; let name = abiMethod.type === "constructor" ? "constructor" : abiMethod.name;
let inputTypes = abiMethod.inputs.map(input => input.type); let inputTypes = abiMethod.inputs.map(input => input.type);
fuzzMap[name] = {}; fuzzMap[name] = {};

View File

@ -20,41 +20,42 @@ class GasEstimator {
let fuzzMap = self.fuzzer.generateFuzz(3, contract); let fuzzMap = self.fuzzer.generateFuzz(3, contract);
self.logger.info("-- Beginning gastimation for contract -- " + contractName); self.logger.info("-- Beginning gastimation for contract -- " + contractName);
let contractObj = new web3.eth.Contract(contract.abiDefinition, contract.deployedAddress); let contractObj = new web3.eth.Contract(contract.abiDefinition, contract.deployedAddress);
async.each(contract.abiDefinition, async.each(contract.abiDefinition.filter((x) => x.type !== "event"),
(abiMethod, gasCb) => { (abiMethod, gasCb) => {
let name = abiMethod.name; let name = abiMethod.name;
console.log("NAME: ", name);
console.log("ABI INPUTS: ", abiMethod.inputs);
if (abiMethod.type === "constructor") { if (abiMethod.type === "constructor") {
// already provided for us // already provided for us
gasCb(null, 'constructor', contract.gasEstimates.creation.totalCost.toString()); gasMap['constructor'] = contract.gasEstimates.creation.totalCost.toString();
gasCb(null);
} else if (abiMethod.type === "fallback") { } else if (abiMethod.type === "fallback") {
gasCb(null, 'fallback', contract.gasEstimates.external[""].toString()); gasMap['fallback'] = contract.gasEstimates.external[""].toString();
gasCb(null);
} else if (abiMethod.inputs === null || abiMethod.inputs === undefined || abiMethod.inputs.length === 0) { } else if (abiMethod.inputs === null || abiMethod.inputs === undefined || abiMethod.inputs.length === 0) {
console.log("Are we hitting here");
// just run it and register it // just run it and register it
contractObj.methods[name] contractObj.methods[name]
.apply(contractObj.methods[name], []) .apply(contractObj.methods[name], [])
.estimateGas((err, gasAmount) => { .estimateGas((err, gasAmount) => {
if (err) gasCb(err); if (err) {
gasMap[name] = gasAmount; return gasCb(err);
gasCb(err, gasAmount, name); } else {
gasMap[name] = gasAmount;
gasCb(null, gasAmount, name);
}
}); });
} else { } else {
// async concatenate all the fuzz values and their gas cost outputs and check for equality // async concatenate all the fuzz values and their gas cost outputs and check for equality
async.concat(fuzzMap[name], (values, getVarianceCb) => { async.concat(fuzzMap[name], (values, getVarianceCb) => {
contractObj.methods[name] contractObj.methods[name].apply(contractObj.methods[name], values)
.apply(contractObj.methods[name], values)
.estimateGas((err, gasAmount) => { .estimateGas((err, gasAmount) => {
getVarianceCb(err, [gasAmount]); getVarianceCb(err, [gasAmount]);
}); });
}, (err, variance) => { }, (err, variance) => {
if (err) { if (err) {
gasCb(err); return gasCb(err);
} else if (_.isEqual(variance[0], variance[1]) && _.isEqual(variance[1], variance[2])) { } else if (_.isEqual(variance[0], variance[1]) && _.isEqual(variance[1], variance[2])) {
gasMap[name] = variance[0]; gasMap[name] = variance[0];
} else { } else {
gasMap[name] = 'variable'; gasMap[name] = 'infinite';
} }
gasCb(); gasCb();
}); });

View File

@ -11,18 +11,24 @@ class Profiler {
this.registerConsoleCommand(); this.registerConsoleCommand();
} }
profile(contractName, contract) { profile(contractName, contract, cb) {
const self = this; const self = this;
let table = new asciiTable(contractName); let table = new asciiTable(contractName);
table.setHeading('Function', 'Payable', 'Mutability', 'Inputs', 'Outputs', 'Gas Estimates'); table.setHeading('Function', 'Payable', 'Mutability', 'Inputs', 'Outputs', 'Gas Estimates');
self.gasEstimator.estimateGas(contractName, function(err, gastimates) { self.gasEstimator.estimateGas(contractName, function(err, gastimates) {
if (err) throw new Error(err); if (err) {
self.logger.error(err);
return;
}
contract.abiDefinition.forEach((abiMethod) => { contract.abiDefinition.forEach((abiMethod) => {
console.log("Abi Method Gastimate: ", gastimates[abiMethod.name]); console.log("Abi Method Gastimate: ", gastimates[abiMethod.name]);
switch(abiMethod.type) { switch(abiMethod.type) {
case "constructor": case "constructor":
table.addRow("constructor", abiMethod.payable, abiMethod.stateMutability, self.formatParams(abiMethod.inputs), self.formatParams(abiMethod.outputs), gastimates['constructor']); table.addRow("constructor", abiMethod.payable, abiMethod.stateMutability, self.formatParams(abiMethod.inputs), self.formatParams(abiMethod.outputs), gastimates['constructor']);
break; break;
case "fallback":
table.addRow("fallback", abiMethod.payable, abiMethod.stateMutability, self.formatParams(abiMethod.inputs), self.formatParams(abiMethod.outputs), gastimates['fallback']);
break;
default: default:
table.addRow(abiMethod.name, abiMethod.payable, abiMethod.stateMutability, self.formatParams(abiMethod.inputs), self.formatParams(abiMethod.outputs), gastimates[abiMethod.name]); table.addRow(abiMethod.name, abiMethod.payable, abiMethod.stateMutability, self.formatParams(abiMethod.inputs), self.formatParams(abiMethod.outputs), gastimates[abiMethod.name]);
} }