catsdev
catsdev

Reputation: 83

Caliper Error: Transaction returned with failure. The key already exists

I'm still on my journey to set up the Caliper for the first time. Hope you can save me :)

Right know I got the error: Transaction returned with failure: User 1 already exists. when I try to launch the caliper benchmark.

Because I do not allow to register users with an existing userID (verified on my chaincode).

This is my test file:

'use strict';

module.exports.info = 'opening accounts';
const { v1: uuidv4 } = require('uuid')

let account_array = [];

let bc, contx;
var txnPerBatch = 1
let j;
module.exports.init = function (blockchain, context, args) {
    if (!args.hasOwnProperty('txnPerBatch')) {
        args.txnPerBatch = 1;
    }
    txnPerBatch = args.txnPerBatch;
    bc = blockchain;
    contx = context;
    j = 0;

    let workload = [];
    workload.push({
        chaincodeFunction: 'instantiate',
        chaincodeArguments: [],
    });
    bc.invokeSmartContract(contx, 'loyalty', '1', workload);

    return Promise.resolve();
};


function generateWorkload() {
    let workload = [];
    for (let i = 0; i < txnPerBatch; i++) {

        var random = (j+1).toString();

        var gam_admin = {
            userID: random
        };

        workload.push({
            chaincodeFunction: 'createGamificationAdmin',
            chaincodeArguments: [JSON.stringify(gam_admin)],
        });
    }
    return workload;
}

module.exports.run = function () {
    let workload = [];
    
    let args = generateWorkload();
    return bc.invokeSmartContract(contx, 'loyalty', '1', args);
};

module.exports.end = function () {
    return Promise.resolve();
};

module.exports.account_array = account_array;

Do you know how can I solve this? Thanks so much.

Upvotes: 0

Views: 171

Answers (1)

nkl199
nkl199

Reputation: 21

Looking at the callback file you have defined, the User name will always be the same for all transactions that are sent by the caliper workers.

Each time a caliper worker issues a transaction, it will invoke the run function that you have defined ... in this case it forms the same content each time and so you get the conflict that you have seen.

There are ways around this:

  • caliper workers know their index (0 based out of all workers)
  • caliper workers know the transaction that they are working on (0 based out of all transactions sent over the round duration)

It looks like you will have to refactor the work load generation to take into account both the caliper worker index, and the transaction number being send, so that each invocation of run gives you a unique userID

Upvotes: 1

Related Questions