Skip to content

Commit

Permalink
[green path] contracts.js
Browse files Browse the repository at this point in the history
  • Loading branch information
davidkhala committed Jan 26, 2024
1 parent 9a4bb8d commit b02221c
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 135 deletions.
14 changes: 11 additions & 3 deletions app/chaincodeHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import {discoveryChaincodeInterestBuilder} from '../common/nodejs/serviceDiscove
import {couchDBIndex} from '../common/nodejs/couchdb.js';
import {ChaincodeType} from '../common/nodejs/formatter/chaincode.js';
import {lifecycle as Lifecycle} from '../common/nodejs/binManager/peer.js';
import assert from 'assert';
import {isEven} from '@davidkhala/light/array.js';


filedirname(import.meta);
Expand Down Expand Up @@ -49,13 +51,19 @@ export const prepareInstall = (chaincodeId, binManager, outputDir) => {

return [ccPack, packageid, cleanup];
};
export const install = async (peers, {chaincodeId}, user) => {
export const install = async (peers, chaincodeId, user) => {
const binPath = path.resolve(__dirname, '../common/bin');
const binManager = new Lifecycle(binPath);
const [ccPack, packageId, cleanup] = prepareInstall(chaincodeId, binManager);
const chaincodeAction = new ChaincodeAction(peers, user);
const result = await chaincodeAction.install(ccPack);
return [result, cleanup];
const result = await chaincodeAction.install(ccPack, packageId);
if (!result) {
return packageId;
}
const ids = result.queryResults.map(({package_id}) => package_id);
assert.ok(isEven(ids));
cleanup();
return ids[0];
};

const simplePolicyBuilder = (identities, n) => {
Expand Down
85 changes: 27 additions & 58 deletions app/installHelper.js → app/chaincodeOperator.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import assert from 'assert';
import {importFrom} from '@davidkhala/light/es6.mjs';
import {consoleLogger} from '@davidkhala/logger/log4.js';
import {install, getEndorsePolicy, getCollectionConfig} from './chaincodeHelper.js';
import ChaincodeAction from '../common/nodejs/chaincodeOperation.js';
Expand All @@ -10,50 +9,7 @@ import Transaction from '../common/nodejs/transaction.js';
import {isEven} from '@davidkhala/light/array.js';
import * as util from 'util';

const globalConfig = importFrom(import.meta, '../config/orgs.json');
const logger = consoleLogger('install helper');

// only one time, one org could deploy
export const installs = async (chaincodeId, orgName, peerIndexes = Object.keys(globalConfig.organizations[orgName].peers)) => {
const peers = helper.newPeers(peerIndexes, orgName);
for (const peer of peers) {
await peer.connect();
}
const user = helper.getOrgAdmin(orgName);
const [result, t1] = await install(peers, {chaincodeId}, user);
const ids = result.responses.map(({response}) => response.package_id);
assert.ok(isEven(ids));
const packageID = ids[0];
t1();
for (const peer of peers) {
peer.disconnect();
}
return packageID;
};
export const installAll = async (chaincodeId, channelName) => {
let package_id_already;
const installOnOrg = async (peerOrg, peerIndexes) => {
const package_id = await installs(chaincodeId, peerOrg, peerIndexes);
if (package_id_already) {
assert.strictEqual(package_id, package_id_already);
} else {
package_id_already = package_id;
}

};
if (channelName) {
for (const [peerOrg, {peerIndexes}] of Object.entries(globalConfig.channels[channelName].organizations)) {
await installOnOrg(peerOrg, peerIndexes);
logger.info('[DONE] installOnOrg', peerOrg);
}
} else {
for (const [peerOrg, {peers}] of Object.entries(globalConfig.organizations)) {
await installOnOrg(peerOrg, Object.keys(peers));
logger.info('[DONE] installOnOrg', peerOrg);
}
}
return package_id_already;
};
const logger = consoleLogger('chaincode operator');

export class ChaincodeDefinitionOperator {
/**
Expand All @@ -67,7 +23,6 @@ export class ChaincodeDefinitionOperator {
const channel = helper.prepareChannel(channelName);
this.waitForConsensus = 1000;
const chaincodeAction = new ChaincodeAction(peers, admin, channel, logger);
chaincodeAction.init_required = !!init_required;
this.forceUpgrade = true;
Object.assign(this, {chaincodeAction, peers, admin, channel, channelName});

Expand All @@ -82,6 +37,12 @@ export class ChaincodeDefinitionOperator {
await tx.submit({init: true}, orderer);
}

async install(chaincodeId) {
const package_id = await install(this.peers, chaincodeId, this.admin);
logger.info(`${package_id} installed to peers ${this.peers.map(peer => peer.toString())}`);
return package_id;
}

async approves({sequence, package_id}, orderer, gate) {
const {waitForConsensus, chaincodeAction} = this;

Expand Down Expand Up @@ -134,14 +95,15 @@ export class ChaincodeDefinitionOperator {
chaincodeAction.setCollectionsConfig(getCollectionConfig(name));
const readyStates = await chaincodeAction.checkCommitReadiness({name, sequence});
assert.ok(isEven(readyStates), `CommitReadiness should be even, but got ${util.inspect(readyStates)}`);

return readyStates[0];
}

async queryDefinition(chaincodeID) {
const {chaincodeAction} = this;
const results = await chaincodeAction.queryChaincodeDefinition(chaincodeID);
if (results) {
results.every(e => assert.deepEqual(e, results[0]));
assert.ok(isEven(results));
return results[0];
}

Expand All @@ -166,7 +128,8 @@ export class ChaincodeDefinitionOperator {

const queryHub = new QueryHub(peers, admin);
const queryResults = await queryHub.chaincodesInstalled(label);
assert.ok(isEven(queryResults), 'chaincodesInstalled results should be even');
assert.ok(isEven(queryResults), `ChaincodesInstalled should be even, but got ${util.inspect(queryResults)}`);

const queryResult = queryResults[0];

const uncommitted = [], committed = [];
Expand All @@ -186,8 +149,8 @@ export class ChaincodeDefinitionOperator {
}
}
}

return [queryResult, uncommitted, committed];
assert.ok(committed.length < 2, 'committed contract should not be more than 1');
return [queryResult, uncommitted, committed[0]];
}

async queryAndCommit(chaincodeID, orderer) {
Expand All @@ -205,9 +168,10 @@ export class ChaincodeDefinitionOperator {
*
* @param {string} chaincodeId
* @param {Orderer} _orderer
* @param {string} uncommitted_packageId
* @param {string} [_gate]
*/
async queryInstalledAndApprove(chaincodeId, _orderer, _gate) {
async queryInstalledAndApprove(chaincodeId, _orderer, uncommitted_packageId, _gate) {

const [_, uncommitted, committed] = await this.queryInstalled(chaincodeId);

Expand All @@ -217,15 +181,20 @@ export class ChaincodeDefinitionOperator {
if (isCommitted) {
sequence = isCommitted.sequence + 1;
}
for (const package_id of uncommitted) {
await this.approves({package_id, sequence}, _orderer, _gate);
}
if (uncommitted.length === 0 && this.forceUpgrade) {
// force update
for (const package_id of committed.map(({package_id}) => package_id)) {
await this.approves({package_id, sequence}, _orderer, _gate);
let package_id;
if (uncommitted.includes(uncommitted_packageId)) {
package_id = uncommitted_packageId;
} else if (committed && committed.package_id === uncommitted_packageId) {
if (this.forceUpgrade) {
package_id = uncommitted_packageId;
} else {
return;
}
} else {
throw Error(`package ${uncommitted_packageId} not found within chaincode=${chaincodeId} namespace`);
}

await this.approves({package_id, sequence}, _orderer, _gate);

}
}
51 changes: 34 additions & 17 deletions cc/golang/contracts.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import assert from 'assert';
import * as helper from '../../app/helper.js';
import {installAll} from '../../app/installHelper.js';
import FabricGateway from '../../common/nodejs/fabric-gateway/index.js';
import {consoleLogger} from '@davidkhala/logger/log4.js';
import UserBuilder from '../../common/nodejs/admin/user.js';
import {dev, smartApprove, commit} from '../testutil.js';
import {dev, installAndApprove, commit} from '../testutil.js';

const chaincodeID = 'contracts';
const logger = consoleLogger(`chaincode:${chaincodeID}`);
Expand All @@ -15,26 +14,20 @@ const channel = 'allchannel';
describe('deploy', function () {
this.timeout(0);

it('install', async () => {
await installAll(chaincodeID);
});
it('dev', async () => {
const orgs = ['icdd', 'astri.org'];
for (const org of orgs) {
await dev(org, chaincodeID);
}
});
it('query installed & approve', async () => {


it('install & approve', async () => {
const orgs = ['icdd', 'astri.org'];
for (const org of orgs) {
await smartApprove(org, chaincodeID, orderer);
await installAndApprove(org, chaincodeID, orderer);
}

});
it('commit', async () => {
// TODO migrate to testutil.js
const org = 'icdd';
await commit(org, chaincodeID, orderer);
});
Expand All @@ -51,23 +44,46 @@ describe('invoke', function () {
it('touch', async () => {
contract.subContract = 'StupidContract';
await contract.evaluateTransaction('ping');
// touch submit
await contract.submitTransaction('ping');
delete contract.subContract;
});
it('who', async () => {
contract.subContract = 'SmartContract';
const result = await contract.evaluateTransaction('who');
logger.info(result);
delete contract.subContract;
});
it('touch submit', async () => {
contract.subContract = 'StupidContract';
await contract.submitTransaction('ping');

});
it('p1e', async () => {
it('error', async () => {
await assert.rejects(async () => {
await contract.evaluateTransaction('StupidContract:p1E');
await contract.evaluateTransaction('StupidContract:error');
});
});
it('UnUsedContext', async () => {
const r = await contract.evaluateTransaction('StupidContract:UnUsedContext');
assert.ok(!r);
});
it('OnlyParams', async () => {
await assert.rejects(contract.evaluateTransaction('StupidContract:OnlyParams'));
await assert.rejects(contract.evaluateTransaction('StupidContract:OnlyParams', 'git', 'hub'));
});
it('StringParam', async () => {
const p1 = 'git';
assert.deepEqual(await contract.evaluateTransaction('StupidContract:StringParam', p1), p1);
});
it('StringParams', async () => {

await assert.rejects(contract.evaluateTransaction('StupidContract:StringParams', ['a', 'b']));
await assert.rejects(contract.evaluateTransaction('StupidContract:StringParams', 'a', 'b'));
});
it('standard', async () => {
await assert.rejects(contract.evaluateTransaction('standard'));
assert.equal(await contract.evaluateTransaction('standard', 'a'), 'a');


});
it('stress 10', async () => {
contract.subContract = 'StupidContract';
for (let i = 0; i < 10; i++) {
await contract.submitTransaction('ping');
}
Expand All @@ -77,6 +93,7 @@ describe('invoke', function () {
for (let i = 0; i < 10; i++) {
await contract.evaluateTransaction('ping');
}
delete contract.subContract;
});
});

Expand Down
33 changes: 33 additions & 0 deletions cc/golang/ecosystem.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import * as helper from '../../app/helper.js';
import {installAll} from '../../app/chaincodeOperator.js';
import {installAndApprove, commit} from '../testutil.js';

const chaincodeID = 'ecosystem';
const orderers = helper.newOrderers();
const orderer = orderers[0];


describe('deploy', function () {
this.timeout(0);
it('install', async () => {
await installAll(chaincodeID);
});
it('query installed & approve', async () => {

const orgs = ['icdd', 'astri.org'];
for (const org of orgs) {
await installAndApprove(org, chaincodeID, orderer);
}

});
it('commit', async () => {
const org = 'icdd';
await commit(org, chaincodeID, orderer);
});
});
describe('invoke', function () {
this.timeout(0);
it('CreateToken', async () => {

});
});
43 changes: 0 additions & 43 deletions cc/golang/ecosystem/index.js

This file was deleted.

8 changes: 5 additions & 3 deletions cc/testutil.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as helper from '../app/helper.js';
import {ChaincodeDefinitionOperator} from '../app/installHelper.js';
import {ChaincodeDefinitionOperator} from '../app/chaincodeOperator.js';
import {consoleLogger} from '@davidkhala/logger/log4.js';

const channel = 'allchannel';
Expand All @@ -16,12 +16,14 @@ export async function dev(org, chaincodeID, init_required = false) {
await operator.disconnect();
}

export async function smartApprove(org, chaincodeID, orderer, init_required = false) {
export async function installAndApprove(org, chaincodeId, orderer, init_required = false) {
const admin = helper.getOrgAdmin(org);

const peers = helper.newPeers([0, 1], org);
const operator = new ChaincodeDefinitionOperator(channel, admin, peers, init_required);
await operator.connect();
await operator.queryInstalledAndApprove(chaincodeID, orderer);
const package_id = await operator.install(chaincodeId);
await operator.queryInstalledAndApprove(chaincodeId, orderer, package_id);
await operator.disconnect();
}

Expand Down
Loading

0 comments on commit b02221c

Please sign in to comment.