Skip to content

Commit

Permalink
NodeSDK - updates for latest proto files
Browse files Browse the repository at this point in the history
Pulled in latest fabric proto files and clean
up the new chain testing and error handling.

Change-Id: I6323b66ae710ceff8c5b6db2e73aae2b2a2955d8
Signed-off-by: Bret Harrison <[email protected]>
  • Loading branch information
harrisob committed Jan 17, 2017
1 parent 2f3d29e commit 0df2e6b
Show file tree
Hide file tree
Showing 11 changed files with 734 additions and 251 deletions.
506 changes: 312 additions & 194 deletions hfc/lib/Chain.js

Large diffs are not rendered by default.

131 changes: 110 additions & 21 deletions hfc/lib/Orderer.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2016 IBM All Rights Reserved.
Copyright 2016, 2017 IBM All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the 'License');
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -55,82 +55,171 @@ var Orderer = class extends Remote {
}

/**
* Send a BroadcastMessage to the orderer service.
* Send a Broadcast message to the orderer service.
*
* @param {byte} envelope - Byte data to be included in the BroadcastMessage
* @see the ./proto/atomicbroadcast/ab.proto
* @param {byte} envelope - Byte data to be included in the Broadcast
* @see the ./proto/orderer/ab.proto
* @returns {Promise} A Promise for a BroadcastResponse
* @see the ./proto/atomicbroadcast/ab.proto
* @see the ./proto/orderer/ab.proto
*/
sendBroadcast(envelope) {
logger.debug('Orderer.sendBroadcast - start');
logger.debug('sendBroadcast - start');

if(!envelope || envelope == '') {
logger.debug('Orderer.sendBroadcast ERROR - missing envelope');
logger.debug('sendBroadcast ERROR - missing envelope');
var err = new Error('Missing data - Nothing to broadcast');
return Promise.reject(err);
}

var self = this;

// Send the endorsed proposals to the peer node (orderer) via grpc
// The rpc specification on the peer side is:
// rpc Broadcast(stream BroadcastMessage) returns (stream BroadcastResponse) {}
// Send the envelope to the orderer via grpc
return new Promise(function(resolve, reject) {
var broadcast = self._ordererClient.broadcast();
var all_done = false;

var broadcast_timeout = setTimeout(function(){
logger.debug('Orderer.sendBroadcast - timed out after:%s', self._request_timeout);
logger.debug('sendBroadcast - timed out after:%s', self._request_timeout);
return reject(new Error('REQUEST_TIMEOUT'));
}, self._request_timeout);

broadcast.on('data', function (response) {
logger.debug('Orderer.sendBroadcast - on data response: %j', response);
logger.debug('sendBroadcast - on data response: %j', response);
clearTimeout(broadcast_timeout);
all_done = true;

if(response.status) {
if (response.status === 'SUCCESS') {
logger.debug('Orderer.sendBroadcast - resolve with %s', response.status);
logger.debug('sendBroadcast - resolve with %s', response.status);
return resolve(response);
} else {
logger.error('Orderer.sendBroadcast - reject with %s', response.status);
return reject(response);
logger.error('sendBroadcast - reject with %s', response.status);
return reject(new Error(response));
}
}
else {
logger.error('Orderer.sendBroadcast ERROR - reject with invalid response from the orderer');
logger.error('sendBroadcast ERROR - reject with invalid response from the orderer');
return reject(new Error('SYSTEM_ERROR'));
}

});

broadcast.on('end', function (response) {
logger.debug('Orderer.sendBroadcast - on end:');
logger.debug('sendBroadcast - on end:');
// Removing the promise reject here as on an 'error', this case
// will hit before the 'error' event, and we loose the error
// information coming back to the caller
// return reject(response);
});

broadcast.on('error', function (err) {
clearTimeout(broadcast_timeout);
if(all_done) {
return;
}
if(err && err.code) {
if(err.code == 14) {
logger.error('Orderer.sendBroadcast - on error: %j',err.stack ? err.stack : err);
logger.error('sendBroadcast - on error: %j',err.stack ? err.stack : err);
return reject(new Error('SERVICE_UNAVAILABLE'));
}
}
logger.debug('Orderer.sendBroadcast - on error: %j',err.stack ? err.stack : err);
logger.debug('sendBroadcast - on error: %j',err.stack ? err.stack : err);
return reject(new Error(err));
});

broadcast.write(envelope);
broadcast.end();
logger.debug('Orderer.sendBroadcast - sent message');
logger.debug('sendBroadcast - sent message');
});
}

/**
* Send a Deliver message to the orderer service.
*
* @param {byte} envelope - Byte data to be included in the Deliver
* @see the ./proto/orderer/ab.proto
* @returns {Promise} A Promise for a DeliverResponse
* @see the ./proto/orderer/ab.proto
*/
sendDeliver(envelope) {
logger.debug('sendDeliver - start');

if(!envelope || envelope == '') {
logger.debug('sendDeliver ERROR - missing envelope');
var err = new Error('Missing data - Nothing to deliver');
return Promise.reject(err);
}

var self = this;

// Send the seek info to the orderer via grpc
return new Promise(function(resolve, reject) {
try {
var deliver = self._ordererClient.deliver();
var all_done = false;
var deliver_timeout = setTimeout(function(){
logger.debug('sendDeliver - timed out after:%s', self._request_timeout);
deliver.cancel();
all_done = true;
return reject(new Error('REQUEST_TIMEOUT'));
}, self._request_timeout);

deliver.on('data', function (response) {
logger.debug('sendDeliver - on data response: %j', response);
clearTimeout(deliver_timeout);
deliver.cancel();
all_done = true;

if(response.status) {
// first check if the block is there, right now the 'status' will be 'UNKNOWN' when the block comes back
if (response.block) {
logger.debug('sendDeliver - resolve with block found - return status:%s', response.status);
return resolve(response);
} else {
logger.error('sendDeliver - reject with %s', response.status);
return reject(new Error(response));
}
}
else {
logger.error('sendDeliver ERROR - reject with invalid response from the orderer');
return reject(new Error('SYSTEM_ERROR'));
}
});

deliver.on('end', function (response) {
logger.debug('sendDeliver - on end');
// this will hit before the 'error'
// so do not send reject yet
// return reject(response);
});

deliver.on('error', function (err) {
logger.debug('sendDeliver - on error');
if(all_done) {
return;
}
else {
clearTimeout(deliver_timeout);
deliver.cancel();
all_done = true;
}
if(err && err.code) {
if(err.code == 14) {
logger.error('sendDeliver - on error code 14: %j',err.stack ? err.stack : err);
return reject(new Error('SERVICE_UNAVAILABLE'));
}
}
logger.debug('sendDeliver - on error: %j',err.stack ? err.stack : err);
return reject(new Error(err));
});

deliver.write(envelope);
deliver.end();
logger.debug('sendDeliver - sent message');
}
catch(error) {
logger.error('sendDeliver - system error ::' + error.stack ? error.stack : error);
return reject(new Error(error));
}
});
}

Expand Down
17 changes: 17 additions & 0 deletions hfc/lib/protos/common/common.proto
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ enum HeaderType {
CONFIGURATION_ITEM = 2; // Used inside of the the reconfiguration message for signing over ConfigurationItems
ENDORSER_TRANSACTION = 3; // Used by the SDK to submit endorser based transactions
ORDERER_TRANSACTION = 4; // Used internally by the orderer for management
DELIVER_SEEK_INFO = 5; // Used as the type for Envelope messages submitted to instruct the Deliver API to seek
}

// This enum enlist indexes of the block metadata array
Expand All @@ -49,6 +50,22 @@ enum BlockMetadataIndex {
TRANSACTIONS_FILTER = 2; // Block metadata array poistion to store serialized bit array filter of invalid transactions
}

// LastConfiguration is the encoded value for the Metadata message which is encoded in the LAST_CONFIGURATION block metadata index
message LastConfiguration {
uint64 index = 1;
}

// Metadata is a common structure to be used to encode block metadata
message Metadata {
bytes value = 1;
repeated MetadataSignature signatures = 2;
}

message MetadataSignature {
bytes signatureHeader = 1; // An encoded SignatureHeader
bytes signature = 2; // The signature over the concatenation of the Metadata value bytes, signatureHeader, and block header
}

message Header {
ChainHeader chainHeader = 1;
SignatureHeader signatureHeader = 2;
Expand Down
20 changes: 13 additions & 7 deletions hfc/lib/protos/common/configuration.proto
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
syntax = "proto3";

import "common.proto";
import "msp_principal.proto";

option go_package = "github.com/hyperledger/fabric/protos/common";

Expand Down Expand Up @@ -47,18 +48,25 @@ message ConfigurationEnvelope {
repeated SignedConfigurationItem Items = 1;
}

// ConfigurationTemplate is used as a serialization format to share configuration templates
// The orderer supplies a configuration template to the user to use when constructing a new
// chain creation transaction, so this is used to facilitate that.
message ConfigurationTemplate {
repeated ConfigurationItem Items = 1;
}

// This message may change slightly depending on the finalization of signature schemes for transactions
message SignedConfigurationItem {
bytes ConfigurationItem = 1;
repeated ConfigurationSignature Signatures = 2; // Signatures over the hash of ConfigurationItem
repeated ConfigurationSignature Signatures = 2;
}

message ConfigurationItem {
enum ConfigurationType {
Policy = 0; // Implies that the Value is a marshaled Policy message, and may be referred to by Key as a ModificationPolicy
Chain = 1; // Marshaled format for this type is yet to be determined
Orderer = 2; // Marshaled format for this type is yet to be determined
Fabric = 3; // Marshaled format for this type is yet to be determined
Peer = 3; // Marshaled format for this type is yet to be determined
}
ChainHeader Header = 1; // The header which ties this configuration to a particular chain
ConfigurationType Type = 2; // The type of configuration this is.
Expand All @@ -69,12 +77,10 @@ message ConfigurationItem {
}

message ConfigurationSignature {
bytes signatureHeader = 1;
bytes signature = 2; // Signature over the concatenation of configurationItem bytes and signatureHeader bytes
bytes signatureHeader = 1; // A marshaled SignatureHeader
bytes signature = 2; // Signature over the concatenation of configurationItem bytes and signatureHeader bytes
}

//

// Policy expresses a policy which the orderer can evaluate, because there has been some desire expressed to support
// multiple policy engines, this is typed as a oneof for now
message Policy {
Expand All @@ -91,7 +97,7 @@ message Policy {
message SignaturePolicyEnvelope {
int32 Version = 1;
SignaturePolicy Policy = 2;
repeated bytes Identities = 3;
repeated MSPPrincipal Identities = 3;
}

// SignaturePolicy is a recursive message structure which defines a featherweight DSL for describing
Expand Down
Loading

0 comments on commit 0df2e6b

Please sign in to comment.