Skip to content

Commit

Permalink
[FAB-10740] remove executeTransaction
Browse files Browse the repository at this point in the history
The new API method submitTransaction() will supercede
the proposed executeTransaction() method added in
the 1.2 development stream. This CR removes
executeTransaction in preparation for this.

Change-Id: I487bdbd3581bfdfc7f2833e50469ccf734631690
Signed-off-by: andrew-coleman <andrew_coleman@uk.ibm.com>
  • Loading branch information
andrew-coleman committed Jun 20, 2018
1 parent 8935a0b commit e146ad5
Show file tree
Hide file tree
Showing 4 changed files with 0 additions and 304 deletions.
117 changes: 0 additions & 117 deletions fabric-client/lib/Channel.js
Original file line number Diff line number Diff line change
Expand Up @@ -2523,78 +2523,6 @@ const Channel = class {
}
}

/**
* Execute whole transaction lifecycle in a single call, i.e. sending
* transaction proposals, receiving/verifying proposalResponses, and
* send endorsed transaction to the orderer.
*
* @param {ChaincodeInvokeRequest} request
* @returns An array of Promise instances, the last one of which comes
* from "BroadcastResponse" message returned by the orderer that contains
* a single "status" field for a starndard [HTTP response code]{@link https://github.com/hyperledger/fabric/blob/v1.0.0/protos/common/common.proto#L27}.
* It will be an acknowledgement from the orderer of successfully submitted transaction.
*/
async executeTransaction(request) {
let errorMsg =client_utils.checkProposalRequest(request, true);
if (errorMsg) {
throw Error(errorMsg);
}
if (!request.args) {
// args is not optional because we need for transaction to execute
throw Error('Missing "args" in Transaction proposal request');
}

const eventHubs = request.eventHubs;
const txId = request.txId;
const timeout = request.timeout;

const results = await this.sendTransactionProposal(request);
const proposalResponses = results[0];
const proposal = results[1];
let allGood = true;

for (let i in proposalResponses) {
if (!proposalResponses || !proposalResponses[i].response) {
throw Error('failed to get proposalResponse');
}

if (proposalResponses[i].response.status !== 200) {
throw Error('got bad proposalResponse');
}

if (!this.verifyProposalResponse(proposalResponses[i])) {
throw Error('failed to verify proposalResponse');
}
}

if (allGood) {
if (this.compareProposalResponseResults(proposalResponses)) {
logger.debug('All proposals have a matching read/writes sets');
} else {
throw Error('All proposals do not have matching read/write sets');
}
}

if (allGood) {
logger.debug(util.format(
'Successfully sent Proposal and received ProposalResponse: ' +
'Status - %s, message - "%s", metadata - "%s", endorsement signature: %s',
proposalResponses[0].response.status, proposalResponses[0].response.message,
proposalResponses[0].response.payload, proposalResponses[0].endorsement.signature));

const promises = eventHubPromises(eventHubs, txId, timeout);

const ordererRequest = {
proposalResponses: proposalResponses,
proposal: proposal
};
const sendPromise = this.sendTransaction(ordererRequest);

promises.push(sendPromise);
return Promise.all(promises);
}
}

/**
* @typedef {Object} ChaincodeQueryRequest
* @property {Peer[]} targets - Optional. The peers that will receive this request,
Expand Down Expand Up @@ -3383,49 +3311,4 @@ function decodeSignaturePolicy(identities) {
return results;
}

function eventHubPromises(eventHubs, txId, timeout) {
let message = '';
const promises = [];

if (!eventHubs) {
return promises;
}
if (!timeout) {
timeout = sdk_utils.getConfigSetting('request-timeout', 30000);
}

eventHubs.forEach((eh) => {
let eventPromise = new Promise((resolve, reject) => {
let event_timeout = setTimeout(() => {
message = 'REQUEST_TIMEOUT:' + eh.getPeerAddr();
logger.error(message);
eh.disconnect();
reject(new Error(message));
}, timeout);

let txIdString = txId.getTransactionID();
eh.registerTxEvent(txIdString, (tx, code, block_num) => {
clearTimeout(event_timeout);

if (code !== 'VALID') {
message = util.format('The invoke chaincode transaction was invalid, code:%s',code);
logger.error(message);
reject(new Error(message));
} else {
message = 'The invoke chaincode transaction was valid.';
logger.debug(message);
resolve({message, block_num});
}
}, (err) => {
clearTimeout(event_timeout);
logger.error(err);
reject(new Error(err));
});
eh.connect();
});
promises.push(eventPromise);
});
return promises;
}

module.exports = Channel;
3 changes: 0 additions & 3 deletions fabric-client/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,6 @@ declare namespace Client {
sendInstantiateProposal(request: ChaincodeInstantiateUpgradeRequest, timeout?: number): Promise<ProposalResponseObject>;
sendTransactionProposal(request: ChaincodeInvokeRequest, timeout?: number): Promise<ProposalResponseObject>;
sendTransaction(request: TransactionRequest): Promise<BroadcastResponse>;
executeTransaction(request: ChaincodeInvokeRequest): Promise<BroadcastResponse[]>;
sendUpgradeProposal(request: ChaincodeInstantiateUpgradeRequest, timeout?: number): Promise<ProposalResponseObject>;
queryByChaincode(request: ChaincodeQueryRequest): Promise<Buffer[]>;
queryBlock(blockNumber: number, target?: Peer | string, useAdmin?: boolean, skipDecode?: false): Promise<Block>;
Expand Down Expand Up @@ -365,8 +364,6 @@ declare namespace Client {
transientMap?: any;
fcn?: string;
args: string[];
eventHubs?: string[];
timeout?: string;
}

export interface ChaincodeQueryRequest {
Expand Down
129 changes: 0 additions & 129 deletions test/integration/invoke.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,17 +77,6 @@ test('\n\n***** invoke transaction with inverted order of endorsements *****\n\n
});
});

test('\n\n***** invoke transaction with a single call *****\n\n', (t) => {
invokeChaincodeSingleCall('org2', 'v0', t, false, [peers[1], peers[0]])
.then((result) => {
t.pass('Successfully invoke transaction chaincode on channel');
t.end();
}, (err) => {
t.fail('Failed to invoke transaction chaincode on channel. ' + err.stack ? err.stack : err);
t.end();
});
});

function init() {
if (!ORGS) {
Client.addConfigFile(path.join(__dirname, 'e2e', './config.json'));
Expand Down Expand Up @@ -312,121 +301,3 @@ function invokeChaincode(userOrg, version, t, shouldFail, peers){
throw new Error('Failed to send proposal due to error: ' + err.stack ? err.stack : err);
});
}

function invokeChaincodeSingleCall(userOrg, version, t, shouldFail, peers){
logger.debug('invokeChaincodeSingleCall begin');
Client.setConfigSetting('request-timeout', 60000);
let channel_name = Client.getConfigSetting('E2E_CONFIGTX_CHANNEL_NAME', testUtil.END2END.channel);
let targets = [], eventHubs = [];

// override t.end function so it'll always disconnect the event hub
t.end = ((context, ehs, f) => {
return function() {
for(let key in ehs) {
let eventhub = ehs[key];
if (eventhub && eventhub.isconnected()) {
logger.debug('Disconnecting the event hub');
eventhub.disconnect();
}
}

f.apply(context, arguments);
};
})(t, eventHubs, t.end);

let client = new Client();
let channel = client.newChannel(channel_name);

let orgName = ORGS[userOrg].name;
let cryptoSuite = Client.newCryptoSuite();

let caRootsPath = ORGS.orderer.tls_cacerts;
let data = fs.readFileSync(path.join(__dirname, 'e2e', caRootsPath));
let caroots = Buffer.from(data).toString();
let tlsInfo = null;

return e2eUtils.tlsEnroll(userOrg)
.then((enrollment) => {
t.pass('Successfully retrieved TLS certificate');
tlsInfo = enrollment;
client.setTlsClientCertAndKey(tlsInfo.certificate, tlsInfo.key);
return testUtil.getSubmitter(client, t, userOrg);
}).then((admin) => {
t.pass('Successfully enrolled user \'admin\'');
the_user = admin;

channel.addOrderer(
client.newOrderer(
ORGS.orderer.url,
{
'pem': caroots,
'ssl-target-name-override': ORGS.orderer['server-hostname']
}
)
);

for (let key in peers) {
let peer = client.newPeer(
peers[key].requests,
{
'pem': peers[key].pem,
'ssl-target-name-override': peers[key]['server-hostname'],
});
channel.addPeer(peer);
}

let data = fs.readFileSync(path.join(__dirname, 'e2e', ORGS[userOrg].peer1['tls_cacerts']));
let eh = client.newEventHub();
eh.setPeerAddr(
ORGS[userOrg].peer1.events,
{
'pem': Buffer.from(data).toString(),
'clientCert': tlsInfo.certificate,
'clientKey': tlsInfo.key,
'ssl-target-name-override': ORGS[userOrg].peer1['server-hostname'],
'grpc.http2.keepalive_time' : 15
}
);
eh.connect();
eventHubs.push(eh);

return channel.initialize();
}).then((nothing) => {
tx_id = client.newTransactionID();

let request = {
eventHubs: eventHubs,
chaincodeId : e2e.chaincodeId,
fcn: 'move',
args: ['a', 'b','100'],
txId: tx_id,
};
return channel.executeTransaction(request);
}).then(results => {
// The previous promise block returns Promise.all() so results is
// an array, and orderer's result comes last in the results.
let response = results.pop();
if (response.status === 'SUCCESS') {
t.pass('Successfully executed transaction.');
} else {
const errorMsg = util.format('error code: %s', response.status);
t.fail(errorMsg);
return Promise.reject(errorMsg);
}

// now see what each of the event hubs reported
for (let i in results) {
let eventHubResult = results[i];
if ('message' in eventHubResult) {
t.pass(eventHubResult.message);
} else {
t.fail(eventHubResult.toString());
return Promise.reject(eventHubResult.toString());
}
return Promise.resolve(response);
}
}).catch(err => {
t.fail('Failed to execute transaction: ' + err.stack ? err.stack : err);
throw new Error('Failed to execute transaction: ' + err.stack ? err.stack : err);
});
}
55 changes: 0 additions & 55 deletions test/unit/channel.js
Original file line number Diff line number Diff line change
Expand Up @@ -1047,61 +1047,6 @@ test('\n\n*** Test per-call timeout support ***\n', function (t) {
});
});

test('\n\n ** Channel executeTransaction() tests **\n\n', async (t) => {
const client = new Client();
const channel = new Channel('does-not-matter', client);

try {
await channel.executeTransaction();
} catch (err) {
const regx = /Missing input request object on the proposal request/;
t.ok(err.toString().match(regx), 'Channel tests, executeTransaction(): empty parameter');
}

try {
await channel.executeTransaction({
eventHubs: 'blah',
// no chaincodeId
fcn: 'blah',
args: ['blah'],
txId: 'blah'
});
} catch (err) {
const regx = /Error: Missing "chaincodeId" parameter in the proposal request/;
t.ok(err.toString().match(regx), 'Channel tests, executeTransaction(): Missing "chaincodeId" parameter');
}


try {
await channel.executeTransaction({
eventHubs: 'blah',
chaincodeId: 'blah',
fcn: 'blah',
args: ['blah']
// no txId
});
} catch (err) {
const regx = /Error: Missing "txId" parameter in the proposal request/;
t.ok(err.toString().match(regx), 'Channel tests, executeTransaction(): Missing "txId" parameter');
}


try {
await channel.executeTransaction({
eventHubs: 'blah',
chaincodeId: 'blah',
fcn: 'blah',
// no args
txId: 'blah'
});
} catch (err) {
const regx = /Error: Missing "args" in Transaction proposal request/;
t.ok(err.toString().match(regx), 'Channel tests, executeTransaction(): Missing "args" parameter');
}

t.end();
});

test('\n\n ** Channel Discover) tests **\n\n', async function (t) {
const client = new Client();
const channel = new Channel('does-not-matter', client);
Expand Down

0 comments on commit e146ad5

Please sign in to comment.