Skip to content

Commit

Permalink
Merge pull request #782 from aklenik/adapter-fixes
Browse files Browse the repository at this point in the history
Fix CI workloads and enhance error handling
  • Loading branch information
nklincoln authored Apr 3, 2020
2 parents ec6f582 + 2b3091e commit d559eaa
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 61 deletions.
29 changes: 20 additions & 9 deletions packages/caliper-core/lib/worker/client/message-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ class MessageHandler {
if (error) {
// send(to, type, data)
context.messenger.send(['orchestrator'], type, {error: error.toString()});
logger.error(`Handled unsuccessful "init" message for worker ${context.workerId}, with error: ${error.toString()}`);
logger.error(`Handled unsuccessful "init" message for worker ${context.workerId}, with error: ${error.stack}`);
} else {
context.workerClient = new CaliperLocalClient(context.adapter, context.workerId, context.messenger);
context.messenger.send(['orchestrator'], type, {});
Expand Down Expand Up @@ -117,7 +117,7 @@ class MessageHandler {
if (error) {
// send(to, type, data)
context.messenger.send(['orchestrator'], type, {error: error.toString()});
logger.error(`Handled unsuccessful "prepare" message for worker ${context.workerId} and test round ${message.testRound} with error ${error.toString()}`);
logger.error(`Handled unsuccessful "prepare" message for worker ${context.workerId} and test round ${message.testRound} with error ${error.stack}`);
} else {
context.messenger.send(['orchestrator'], type, {});
logger.info(`Handled successful "prepare" message for worker ${context.workerId} and test round ${message.testRound}`);
Expand All @@ -139,12 +139,19 @@ class MessageHandler {
* Called after processing the "test" message.
* @param {object} context The context/state of the message handler.
* @param {object} message The message object.
* @param {object} error An error conditioning message
*/
static async afterTest(context, message) {
await CaliperUtils.sleep(200);
static async afterTest(context, message, error) {
const type = 'testResult';
context.messenger.send(['orchestrator'], type, context.testResult);
logger.info(`Handled "test" message for worker ${context.workerId}`);

if (error) {
// send(to, type, data)
context.messenger.send(['orchestrator'], type, {error: error.toString()});
logger.error(`Handled unsuccessful "test" message for worker ${context.workerId} and test round ${message.testRound} with error ${error.stack}`);
} else {
context.messenger.send(['orchestrator'], type, context.testResult);
logger.info(`Handled successful "test" message for worker ${context.workerId} and test round ${message.testRound}`);
}
}

/**
Expand Down Expand Up @@ -216,9 +223,13 @@ class MessageHandler {
break;
}
case 'test': {
await context.beforeTestHandler(context, message);
context.testResult = await context.testHandler(context, message);
await context.afterTestHandler(context, message);
try {
await context.beforeTestHandler(context, message);
context.testResult = await context.testHandler(context, message);
await context.afterTestHandler(context, message, undefined);
} catch (err) {
await context.afterTestHandler(context, message, err);
}

break;
}
Expand Down
90 changes: 54 additions & 36 deletions packages/caliper-ethereum/lib/ethereum.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,48 +211,66 @@ class Ethereum extends BlockchainInterface {
let status = new TxStatus();
let params = {from: context.fromAddress};
let contractInfo = context.contracts[contractID];
try {
context.engine.submitCallback(1);
let receipt = null;
let methodType = 'send';
if (methodCall.isView) {
methodType = 'call';
} else if (context.nonces && (typeof context.nonces[context.fromAddress] !== 'undefined')) {
let nonce = context.nonces[context.fromAddress];
context.nonces[context.fromAddress] = nonce + 1;
params.nonce = nonce;
// leaving these values unset causes web3 to fetch gasPrice and
// chainId on the fly. This can cause transactions to be
// reordered, which in turn causes nonce failures
params.gasPrice = context.gasPrice;
params.chainId = context.chainId;

context.engine.submitCallback(1);
let receipt = null;
let methodType = 'send';
if (methodCall.isView) {
methodType = 'call';
} else if (context.nonces && (typeof context.nonces[context.fromAddress] !== 'undefined')) {
let nonce = context.nonces[context.fromAddress];
context.nonces[context.fromAddress] = nonce + 1;
params.nonce = nonce;

// leaving these values unset causes web3 to fetch gasPrice and
// chainId on the fly. This can cause transactions to be
// reordered, which in turn causes nonce failures
params.gasPrice = context.gasPrice;
params.chainId = context.chainId;
}

const onFailure = (err) => {
status.SetStatusFail();
logger.error('Failed tx on ' + contractID + ' calling method ' + methodCall.verb + ' nonce ' + params.nonce);
logger.error(err);
};

const onSuccess = (rec) => {
status.SetID(rec.transactionHash);
status.SetResult(rec);
status.SetVerification(true);
status.SetStatusSuccess();
};

if (methodCall.args) {
if (contractInfo.gas && contractInfo.gas[methodCall.verb]) {
params.gas = contractInfo.gas[methodCall.verb];
} else if (contractInfo.estimateGas) {
params.gas = 1000 + await contractInfo.contract.methods[methodCall.verb](...methodCall.args).estimateGas();
}

if (methodCall.args) {
if (contractInfo.gas && contractInfo.gas[methodCall.verb]) {
params.gas = contractInfo.gas[methodCall.verb];
} else if (contractInfo.estimateGas) {
params.gas = 1000 + await contractInfo.contract.methods[methodCall.verb](...methodCall.args).estimateGas();
}
try {
receipt = await contractInfo.contract.methods[methodCall.verb](...methodCall.args)[methodType](params);
} else {
if (contractInfo.gas && contractInfo.gas[methodCall.verb]) {
params.gas = contractInfo.gas[methodCall.verb];
} else if (contractInfo.estimateGas) {
params.gas = 1000 + await contractInfo.contract.methods[methodCall.verb].estimateGas(params);
}
onSuccess(receipt);
} catch (err) {
onFailure(err);
}
} else {
if (contractInfo.gas && contractInfo.gas[methodCall.verb]) {
params.gas = contractInfo.gas[methodCall.verb];
} else if (contractInfo.estimateGas) {
params.gas = 1000 + await contractInfo.contract.methods[methodCall.verb].estimateGas(params);
}

try {
receipt = await contractInfo.contract.methods[methodCall.verb]()[methodType](params);
onSuccess(receipt);
} catch (err) {
onFailure(err);
}
status.SetID(receipt.transactionHash);
status.SetResult(receipt);
status.SetVerification(true);
status.SetStatusSuccess();
} catch (err) {
status.SetStatusFail();
logger.error('Failed tx on ' + contractID + ' calling method ' + methodCall.verb + ' nonce ' + params.nonce);
logger.error(err);
}
return Promise.resolve(status);

return status;
}

/**
Expand Down
9 changes: 3 additions & 6 deletions packages/caliper-sawtooth/lib/sawtooth.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const {
const request = require('request-promise');
const _ = require('lodash');

let configPath;
let config;
let lastKnownBlockId=null;
//let blockCommitSatus = new Map();
let batchCommitStatus = new Map();
Expand All @@ -48,7 +48,6 @@ let currentEndpoint= 0;
* @return {String} rest endpoint url
*/
function getRESTUrl() {
let config = require(configPath);
let restApiUrls = config.sawtooth.network.restapi.urls;
currentEndpoint++;
if(currentEndpoint >= restApiUrls.length) {
Expand Down Expand Up @@ -270,7 +269,6 @@ function getState(address) {
* @return {Promise<object>} The promise for the result of the execution.
*/
function querybycontext(context, contractID, contractVer, address, workspaceRoot) {
let config = require(configPath);
const builder = BatchBuilderFactory.getBatchBuilder(contractID, contractVer, config, workspaceRoot);
const addr = builder.calculateAddress(address);
if(context.engine) {
Expand Down Expand Up @@ -323,7 +321,8 @@ class Sawtooth extends BlockchainInterface {
*/
constructor(workerIndex) {
super();
configPath = CaliperUtils.resolvePath(ConfigUtil.get(ConfigUtil.keys.NetworkConfig));
let configPath = CaliperUtils.resolvePath(ConfigUtil.get(ConfigUtil.keys.NetworkConfig));
config = require(configPath);
this.bcType = 'sawtooth';
this.workspaceRoot = path.resolve(ConfigUtil.get(ConfigUtil.keys.Workspace));
this.clientIndex = workerIndex;
Expand Down Expand Up @@ -365,7 +364,6 @@ class Sawtooth extends BlockchainInterface {
* @return {Promise} The return promise.
*/
getContext(name, args) {
let config = require(this.configPath);
let context = config.sawtooth.context;
if(typeof context === 'undefined') {
let validatorUrl = config.sawtooth.network.validator.url;
Expand Down Expand Up @@ -403,7 +401,6 @@ class Sawtooth extends BlockchainInterface {
*/
async invokeSmartContract(context, contractID, contractVer, args, timeout) {
try {
let config = require(configPath);
let builder = BatchBuilderFactory.getBatchBuilder(contractID, contractVer, config, this.workspaceRoot);
const batchBytes = builder.buildBatch(args);
if(context.engine) {
Expand Down
4 changes: 2 additions & 2 deletions packages/caliper-tests-integration/besu_tests/open.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,12 @@ function generateWorkload() {
let acc_id = generateAccount();
account_array.push(acc_id);

if (bc.bcType === 'fabric') {
if (bc.getType() === 'fabric') {
workload.push({
chaincodeFunction: 'open',
chaincodeArguments: [acc_id, initMoney.toString()],
});
} else if (bc.bcType === 'ethereum') {
} else if (bc.getType() === 'ethereum') {
workload.push({
verb: 'open',
args: [acc_id, initMoney]
Expand Down
2 changes: 1 addition & 1 deletion packages/caliper-tests-integration/besu_tests/query.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ module.exports.init = function(blockchain, context, args) {
module.exports.run = function() {
const acc = account_array[Math.floor(Math.random()*(account_array.length))];

if (bc.bcType === 'fabric') {
if (bc.getType() === 'fabric') {
let args = {
chaincodeFunction: 'query',
chaincodeArguments: [acc],
Expand Down
4 changes: 2 additions & 2 deletions packages/caliper-tests-integration/besu_tests/transfer.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@ module.exports.run = function () {
const account2 = account_array[Math.floor(Math.random() * (account_array.length))];
let args;

if (bc.bcType === 'fabric') {
if (bc.getType() === 'fabric') {
args = {
chaincodeFunction: 'transfer',
chaincodeArguments: [account1, account2, initmoney.toString()],
};
} else if (bc.bcType === 'ethereum') {
} else if (bc.getType() === 'ethereum') {
args = {
verb: 'transfer',
args: [account1, account2, initmoney]
Expand Down
4 changes: 2 additions & 2 deletions packages/caliper-tests-integration/ethereum_tests/open.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,12 @@ function generateWorkload() {
let acc_id = generateAccount();
account_array.push(acc_id);

if (bc.bcType === 'fabric') {
if (bc.getType() === 'fabric') {
workload.push({
chaincodeFunction: 'open',
chaincodeArguments: [acc_id, initMoney.toString()],
});
} else if (bc.bcType === 'ethereum') {
} else if (bc.getType() === 'ethereum') {
workload.push({
verb: 'open',
args: [acc_id, initMoney]
Expand Down
2 changes: 1 addition & 1 deletion packages/caliper-tests-integration/ethereum_tests/query.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ module.exports.init = function(blockchain, context, args) {
module.exports.run = function() {
const acc = account_array[Math.floor(Math.random()*(account_array.length))];

if (bc.bcType === 'fabric') {
if (bc.getType() === 'fabric') {
let args = {
chaincodeFunction: 'query',
chaincodeArguments: [acc],
Expand Down
4 changes: 2 additions & 2 deletions packages/caliper-tests-integration/ethereum_tests/transfer.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@ module.exports.run = function () {
const account2 = account_array[Math.floor(Math.random() * (account_array.length))];
let args;

if (bc.bcType === 'fabric') {
if (bc.getType() === 'fabric') {
args = {
chaincodeFunction: 'transfer',
chaincodeArguments: [account1, account2, initmoney.toString()],
};
} else if (bc.bcType === 'ethereum') {
} else if (bc.getType() === 'ethereum') {
args = {
verb: 'transfer',
args: [account1, account2, initmoney]
Expand Down

0 comments on commit d559eaa

Please sign in to comment.