Skip to content

Commit

Permalink
[FABN-1183] Update quantity to be decimal string
Browse files Browse the repository at this point in the history
Change-Id: I2c17b1eb0439d3f27318f954a7d090ca902e9db1
Signed-off-by: Wenjian Qiao <[email protected]>
  • Loading branch information
wenjianqiao committed Mar 21, 2019
1 parent c448406 commit 8dc6bc0
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 31 deletions.
4 changes: 3 additions & 1 deletion fabric-client/lib/token-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,9 @@ module.exports.buildTokenCommandHeader = (creator, channelId, nonce, tlsCertHash
header.setCreator(creator.serialize());
header.setNonce(nonce);
header.setTimestamp(timestamp);
header.setTlsCertHash(tlsCertHash);
if (tlsCertHash !== undefined && tlsCertHash !== null) {
header.setTlsCertHash(tlsCertHash);
}

return header;
};
Expand Down
12 changes: 6 additions & 6 deletions fabric-client/test/BlockDecoder.js
Original file line number Diff line number Diff line change
Expand Up @@ -496,8 +496,8 @@ describe('BlockDecoder', () => {
});

it('should add action to data when transaction with issue action is given', () => {
const output1 = {owner: {type: 0, raw: Buffer.from('owner1')}, type: 'type1', quantity: '0x3c'};
const output2 = {owner: {type: 0, raw: Buffer.from('owner2')}, type: 'type2', quantity: '0x5d'};
const output1 = {owner: {type: 0, raw: Buffer.from('owner1')}, type: 'type1', quantity: '100'};
const output2 = {owner: {type: 0, raw: Buffer.from('owner2')}, type: 'type2', quantity: '200'};

// build a token transaction protobuf message
const issue = new fabprotos.token.Issue();
Expand All @@ -515,8 +515,8 @@ describe('BlockDecoder', () => {
});

it('should add action to data when transaction with transfer action is given', () => {
const output1 = {owner: {type: 0, raw: Buffer.from('owner1')}, type: 'type1', quantity: '0x3c'};
const output2 = {owner: {type: 0, raw: Buffer.from('owner2')}, type: 'type2', quantity: '0x5d'};
const output1 = {owner: {type: 0, raw: Buffer.from('owner1')}, type: 'type1', quantity: '100'};
const output2 = {owner: {type: 0, raw: Buffer.from('owner2')}, type: 'type2', quantity: '200'};
const tokenId = {index: 0, tx_id: 'input_txid'};

// build a token transaction protobuf message
Expand All @@ -536,8 +536,8 @@ describe('BlockDecoder', () => {
});

it('should add action to data when transaction with redeem action is given', () => {
const output1 = {type: 'type1', quantity: '0x3c'};
const output2 = {owner: {type: 0, raw: Buffer.from('owner2')}, type: 'type2', quantity: '0x5d'};
const output1 = {type: 'type1', quantity: '100'};
const output2 = {owner: {type: 0, raw: Buffer.from('owner2')}, type: 'type2', quantity: '200'};
const tokenId = {index: 0, tx_id: 'input_txid'};

// build a token transaction protobuf message
Expand Down
5 changes: 2 additions & 3 deletions fabric-client/test/TokenClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ const Client = require('../lib/Client');
const {Identity} = require('fabric-common');
const TokenClient = rewire('../lib/TokenClient');
const TransactionID = require('../lib/TransactionID.js');
const token_utils = require('../lib/token-utils.js');
const fabprotos = require('fabric-protos');

const sinon = require('sinon');
Expand Down Expand Up @@ -443,8 +442,8 @@ describe('TokenClient', () => {
// prepare mockResponse for sendTokenComandStub
const tokenId1 = {tx_id: 'mock_tx_id1', index: 0};
const tokenId2 = {tx_id: 'mock_tx_id2', index: 0};
const token1 = {id: tokenId1, type: 'abc123', quantity: token_utils.toHex(100)};
const token2 = {id: tokenId2, type: 'xyz', quantity: token_utils.toHex(200)};
const token1 = {id: tokenId1, type: 'abc123', quantity: '100'};
const token2 = {id: tokenId2, type: 'xyz', quantity: '200'};
mockTokens = [token1, token2];
mockResponse = new fabprotos.token.CommandResponse();
mockResponse.setUnspentTokens({tokens: mockTokens});
Expand Down
30 changes: 23 additions & 7 deletions fabric-client/test/token-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ describe('token-utils', () => {
beforeEach(() => {
// prepare token request
const owner = {type: fabprotos.token.TokenOwner_MSP_IDENTIFIER, raw: Buffer.from('test-owner')};
param = {owner: owner, type: 'abc123', quantity: TokenUtils.toHex(210)};
param = {owner: owner, type: 'abc123', quantity: '210'};
request = {params: [param], txId: txId, tokenIds: tokenIds};
});

Expand Down Expand Up @@ -241,8 +241,8 @@ describe('token-utils', () => {
// prepare token request for issue
const owner1 = {type: fabprotos.token.TokenOwner_MSP_IDENTIFIER, raw: Buffer.from('owner1')};
const owner2 = {type: fabprotos.token.TokenOwner_MSP_IDENTIFIER, raw: Buffer.from('owner2')};
param1 = {owner: owner1, type: 'abc123', quantity: TokenUtils.toHex(210)};
param2 = {owner: owner2, type: 'horizon', quantity: TokenUtils.toHex(300)};
param1 = {owner: owner1, type: 'abc123', quantity: '210'};
param2 = {owner: owner2, type: 'horizon', quantity: '300'};
request = {
params: [param1, param2],
txId: txId,
Expand All @@ -267,8 +267,8 @@ describe('token-utils', () => {
const tokenId = {tx_id: 'mock_tx_id', index: 0};
const owner1 = {type: fabprotos.token.TokenOwner_MSP_IDENTIFIER, raw: Buffer.from('owner1')};
const owner2 = {type: fabprotos.token.TokenOwner_MSP_IDENTIFIER, raw: Buffer.from('owner2')};
param1 = {owner: owner1, quantity: TokenUtils.toHex(100)};
param2 = {owner: owner2, quantity: TokenUtils.toHex(200)};
param1 = {owner: owner1, quantity: '100'};
param2 = {owner: owner2, quantity: '200'};

request = {
tokenIds: [tokenId],
Expand Down Expand Up @@ -296,7 +296,7 @@ describe('token-utils', () => {
beforeEach(() => {
// prepare token request for redeem
const tokenId = {tx_id: 'mock_tx_id', index: 0};
param1 = {quantity: TokenUtils.toHex(100)};
param1 = {quantity: '100'};
request = {
tokenIds: [tokenId],
params: param1,
Expand Down Expand Up @@ -541,7 +541,7 @@ describe('token-utils', () => {
mockCreator = {serialize: serializeStub};
});

it('should return a token command header', () => {
it('should return a token command header with tls cert', () => {
const expectedHeader = new fabprotos.token.Header();
expectedHeader.setChannelId(channelId);
expectedHeader.setCreator(Buffer.from('serialized-creator'));
Expand All @@ -558,6 +558,22 @@ describe('token-utils', () => {
header.toBuffer().should.deep.equal(expectedHeader.toBuffer());
});

it('should return a token command header without tls cert', () => {
const expectedHeader = new fabprotos.token.Header();
expectedHeader.setChannelId(channelId);
expectedHeader.setCreator(Buffer.from('serialized-creator'));
expectedHeader.setNonce(nonce);

const header = TokenUtils.buildTokenCommandHeader(mockCreator, channelId, nonce);

// verify header has timestamp
header.hasOwnProperty('timestamp').should.equal(true);
expectedHeader.timestamp = header.timestamp;

// compare toBuffer since they are protobuf messages
header.toBuffer().should.deep.equal(expectedHeader.toBuffer());
});

it('should get error when creator serialize throws error', () => {
(() => {
const fakeError = new Error('forced build header error');
Expand Down
32 changes: 18 additions & 14 deletions test/integration/token.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,12 @@ test('\n\n***** Token end-to-end flow (green path): issue, transfer, redeem and
let param = {
owner: {type: 0, raw: user1Identity.serialize()},
type: 'abc123',
quantity: tokenUtils.toHex(200),
quantity: '200'
};
const param2 = {
owner: {type: 0, raw: user1Identity.serialize()},
type: 'horizon',
quantity: tokenUtils.toHex(200),
quantity: '200'
};
let request = {
params: [param, param2],
Expand Down Expand Up @@ -162,7 +162,7 @@ test('\n\n***** Token end-to-end flow (green path): issue, transfer, redeem and
// build requst for user1 to redeem token
txId = user1TokenClient.getClient().newTransactionID();
param = {
quantity: tokenUtils.toHex(50),
quantity: '50'
};
request = {
tokenIds: [redeemToken.id],
Expand All @@ -179,7 +179,7 @@ test('\n\n***** Token end-to-end flow (green path): issue, transfer, redeem and
// verify owner's (user1) unspent tokens after redeem - pass optional request
request = {txId: user1TokenClient.getClient().newTransactionID()};
result = await user1TokenClient.list(request);
const remainingQuantity = tokenUtils.toHex(200 - 50);
const remainingQuantity = '150'; // 200 - 50
logger.debug('(org1)list tokens after transfer token %s', util.inspect(result, false, null));
t.equals(result.length, 1, 'Checking number of tokens for user1 after redeem');
t.equals(result[0].type, redeemToken.type, 'Checking token type for user1 after redeem');
Expand Down Expand Up @@ -216,7 +216,7 @@ test('\n\n***** Token end-to-end flow: double spending fails *****\n\n', async (
let param = {
owner: {type: fabprotos.token.TokenOwner_MSP_IDENTIFIER, raw: user1Identity.serialize()},
type: 'abc123',
quantity: tokenUtils.toHex(210)
quantity: '210'
};
let request = {
params: [param],
Expand Down Expand Up @@ -306,7 +306,7 @@ test('\n\n***** Token end-to-end flow: non owner transfer fails *****\n\n', asyn
let param = {
owner: {type: fabprotos.token.TokenOwner_MSP_IDENTIFIER, raw: user1Identity.serialize()},
type: 'abc123',
quantity: tokenUtils.toHex(210)
quantity: '210'
};
let request = {
params: [param],
Expand All @@ -330,7 +330,7 @@ test('\n\n***** Token end-to-end flow: non owner transfer fails *****\n\n', asyn
txId = user2TokenClient.getClient().newTransactionID();
param = {
owner: {type: fabprotos.token.TokenOwner_MSP_IDENTIFIER, raw: user2Identity.serialize()},
quantity: tokenUtils.toHex(10)
quantity: '10'
};
request = {
tokenIds: [transferToken.id],
Expand Down Expand Up @@ -375,7 +375,7 @@ test('\n\n***** Token end-to-end flow: invalid transfer amount fails *****\n\n',
let param = {
owner: {type: fabprotos.token.TokenOwner_MSP_IDENTIFIER, raw: user1Identity.serialize()},
type: 'abc123',
quantity: tokenUtils.toHex(210)
quantity: '210'
};
let request = {
params: [param],
Expand All @@ -399,7 +399,7 @@ test('\n\n***** Token end-to-end flow: invalid transfer amount fails *****\n\n',
txId = user1TokenClient.getClient().newTransactionID();
param = {
owner: {type: fabprotos.token.TokenOwner_MSP_IDENTIFIER, raw: user2Identity.serialize()},
quantity: tokenUtils.toHex(10)
quantity: '10'
};
request = {
tokenIds: [transferToken.id],
Expand Down Expand Up @@ -442,7 +442,7 @@ test('\n\n***** Token end-to-end flow: invalid redeem amount fails *****\n\n', a
let param = {
owner: {type: fabprotos.token.TokenOwner_MSP_IDENTIFIER, raw: user1Identity.serialize()},
type: 'abc123',
quantity: tokenUtils.toHex(100)
quantity: '100'
};
let request = {
params: [param],
Expand All @@ -465,7 +465,7 @@ test('\n\n***** Token end-to-end flow: invalid redeem amount fails *****\n\n', a
// build request for user1 to transfer transfer token to user2
txId = user1TokenClient.getClient().newTransactionID();
param = {
quantity: tokenUtils.toHex(110)
quantity: '110'
};
request = {
tokenIds: [redeemToken.id],
Expand All @@ -481,7 +481,7 @@ test('\n\n***** Token end-to-end flow: invalid redeem amount fails *****\n\n', a
} catch (err) {
t.equals(
err.message,
'command response has error: total quantity [100] from TokenIds is less than quantity [0x6e] to be redeemed',
'command response has error: total quantity [100] from TokenIds is less than quantity [110] to be redeemed',
'Redeem failed as expected because redeemed quantity exceeded token quantity'
);
t.end();
Expand Down Expand Up @@ -546,10 +546,14 @@ function validateTransactionEnvelope(txEnvelope, commandName, expectedInputs, ex
logger.debug('queried transaction is: \n%s', util.inspect(txEnvelope, false, null));
const token_action = txEnvelope.transactionEnvelope.payload.data.token_action;
const action_data = token_action[token_action.data];
t.equals(token_action.data, commandName, 'Validating token transaction matches the command name');
t.equals(token_action.data, commandName, 'Validating token transaction matches command name ' + commandName);
t.equals(action_data.outputs.length, expectedOutputs.length, 'Validationing number of outputs in token transaction');
for (let i = 0; i < expectedOutputs.length; i++) {
t.deepEqual(action_data.outputs[i], expectedOutputs[i], 'Validationing output in token transaction');
// fabtoken uses hex string in token transaction, so convert expectedQuantity to hex string
const expectedQuantityToHex = tokenUtils.toHex(parseInt(expectedOutputs[i].quantity));
t.deepEqual(action_data.outputs[i].quantity, expectedQuantityToHex, 'Validationing quantity in token transaction');
t.deepEqual(action_data.outputs[i].owner, expectedOutputs[i].owner, 'Validationing owner in token transaction');
t.deepEqual(action_data.outputs[i].type, expectedOutputs[i].type, 'Validationing type in token transaction');
}
if (expectedInputs) {
t.deepEqual(action_data.inputs, expectedInputs, 'Validationing inputs in token transaction');
Expand Down

0 comments on commit 8dc6bc0

Please sign in to comment.