Skip to content

Commit

Permalink
FABN-1491: Updated realtime block event listening (#144)
Browse files Browse the repository at this point in the history
Signed-off-by: Mark S. Lewis <mark_lewis@uk.ibm.com>
  • Loading branch information
bestbeforetoday authored Feb 27, 2020
1 parent c31fa5e commit ddf1d71
Show file tree
Hide file tree
Showing 54 changed files with 1,733 additions and 1,109 deletions.
35 changes: 26 additions & 9 deletions fabric-common/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,20 +52,31 @@ export interface UserConfig {
roles?: string[];
}

export interface ConnectionInfo {
type: string;
name: string;
url: string;
options: object;
}
export interface ServiceError extends Error {
connection: ConnectionInfo;
}

export interface ProposalResponse {
errors: Error[];
errors: ServiceError[];
responses: EndorsementResponse[];
queryResults: Buffer[];
}

export interface EndorsementResponse {
connection: ConnectionInfo;
response: {
status: number;
message: string;
payload: Buffer;
};
payload: Buffer;
endorsment: {
endorsement: {
endorser: Buffer;
signature: Buffer;
};
Expand Down Expand Up @@ -113,8 +124,10 @@ export class DiscoveryHandler extends ServiceHandler {

export class ServiceEndpoint {
public readonly name: string;
public readonly mspid: string;
public readonly endpoint: Endpoint;
constructor(name: string, client: Client, mspid?: string);
public connect(endpoint: Endpoint, options: ConnectOptions): Promise<void>;
public connect(endpoint: Endpoint, options?: ConnectOptions): Promise<void>;
public disconnect(): void;
public checkConnection(): Promise<boolean>;
public isTLS(): boolean;
Expand Down Expand Up @@ -152,8 +165,8 @@ export class ServiceAction {

export class Commit extends Proposal {
constructor(chaincodeName: string, channel: Channel, endorsement: Endorsement);
public build(idContext: IdentityContext, request: any): Buffer;
public send(request: any, options: any): Promise<any>;
public build(idContext: IdentityContext, request?: any): Buffer;
public send(request?: any): Promise<any>;
}

export class Endorsement extends Proposal {
Expand All @@ -171,8 +184,8 @@ export class Proposal extends ServiceAction {
public buildProposalInterest(): any;
public addCollectionInterest(collectionName: string): Proposal;
public addChaincodeCollectionsInterest(collectionName: string, collectionNames: string[]): Proposal;
public build(idContext: IdentityContext, request: any): Buffer;
public send(request: any, options: any): Promise<ProposalResponse>;
public build(idContext: IdentityContext, request?: any): Buffer;
public send(request?: any): Promise<ProposalResponse>;
public verifyProposalResponse(proposalResponse?: any): boolean;
public compareProposalResponseResults(proposalResponses: any[]): boolean;
}
Expand All @@ -181,8 +194,8 @@ export class DiscoveryService extends ServiceAction {
constructor(chaincodeName: string, channel: Channel);
public setDiscoverer(discoverer: Discoverer): DiscoveryService;
public newHandler(): DiscoveryHandler;
public build(idContext: IdentityContext, request: any): Buffer;
public send(request: any): Promise<any>;
public build(idContext: IdentityContext, request?: any): Buffer;
public send(request?: any): Promise<any>;
public getDiscoveryResults(refresh?: boolean): Promise<any>;
public close(): void;
}
Expand Down Expand Up @@ -247,6 +260,7 @@ export class Client {
public newEndpoint(options: ConnectOptions): Endpoint;
public newEndorser(name: string, mspid?: string): Endorser;
public getEndorser(name: string, mspid?: string): Endorser;
public getEndorsers(mspid?: string): Endorser[];
public newCommitter(name: string, mspid?: string): Committer;
public getCommitter(name: string, mspid?: string): Committer;
public newEventer(name: string, mspid?: string): Eventer;
Expand All @@ -270,6 +284,9 @@ export interface ConnectOptions {
}

export class Channel {
readonly name: string;
readonly client: Client;

constructor(name: string, client: Client);
public close(): void;

Expand Down
199 changes: 198 additions & 1 deletion fabric-network/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,208 @@
* @returns {Promise<void>}
*/

/**
* Factory function to obtain transaction event handler instances. Called on every transaction submit.
* @typedef {Function} TxEventHandlerFactory
* @memberof module:fabric-network
* @param {string} transactionId The ID of the transaction being submitted.
* @param {module:fabric-network.Network} network The network on which this transaction is being submitted.
* @returns {module:fabric-network.TxEventHandler} A transaction event handler.
*/

/**
* Handler used to wait for commit events when a transaction is submitted.
* @interface TxEventHandler
* @memberof module:fabric-network
*/
/**
* Resolves when the handler has started listening for transaction commit events. Called after the transaction proposal
* has been accepted and prior to submission of the transaction to the orderer.
* @function module:fabric-network.TxEventHandler#startListening
* @async
* @returns {Promise<void>}
*/
/**
* Resolves (or rejects) when suitable transaction commit events have been received. Called after submission of the
* transaction to the orderer.
* @function module:fabric-network.TxEventHandler#waitForEvents
* @async
* @returns {Promise<void>}
*/
/**
* Called if submission of the transaction to the orderer fails.
* @function module:fabric-network.TxEventHandler#cancelListening
* @returns {void}
*/

/**
* Factory function to obtain query handler instances. Called on every network creation.
* @typedef {Function} QueryHandlerFactory
* @memberof module:fabric-network
* @param {module:fabric-network.Network} network The network on which queries are being evaluated.
* @returns {module:fabric-network.QueryHandler} A query handler.
*/

/**
* Handler used to obtain query results from peers when a transaction is evaluated.
* @interface QueryHandler
* @memberof module:fabric-network
*/
/**
* Called when a transaction is evaluated to obtain query results from suitable network peers.
* @function module:fabric-network.QueryHandler#evaluate
* @async
* @param {module:fabric-network.Query} query Query object that can be used by the handler to send the query to
* specific peers.
* @returns {Promise<Buffer>}
*/

/**
* Used by query handler implementations to evaluate transactions on peers of their choosing.
* @interface Query
* @memberof module:fabric-network
*/
/**
* Get query results from specified peers.
* @function module:fabric-network.Query#evaluate
* @async
* @param {Endorser[]} peers
* @returns {Promise<Array<module:fabric-network.Query~QueryResponse | Error>>}
*/

/**
* @typedef {Object} Query~QueryResponse
* @memberof module:fabric-network
* @property {boolean} isEndorsed True if the proposal was endorsed by the peer.
* @property {number} status The status value from the endorsement. This attriibute will be set by the chaincode.
* @property {Buffer} payload The payload value from the endorsement. This attribute may be considered the query value
* if the proposal was endorsed by the peer.
* @property {string} message The message value from the endorsement. This property contains the error message from
* the peer if it did not endorse the proposal.
*/

/**
* A callback function that will be invoked when either a peer communication error occurs or a transaction commit event
* is received. Only one of the two arguments will have a value for any given invocation.
* @callback Network~CommitListener
* @memberof module:fabric-network
* @param {module:fabric-network.Network~CommitError} [error] Peer communication error.
* @param {module:fabric-network.Network~CommitEvent} [event] Transaction commit event from a specific peer.
*/

/**
* @typedef {Error} Network~CommitError
* @memberof module:fabric-network
* @property {Endorser} peer The peer that raised this error.
*/

/**
* @typedef {EventInfo} Network~CommitEvent
* @memberof module:fabric-network
* @property {Endorser} peer The peer that raised this error.
*/

/**
* A callback function that will be invoked when a block event is received. Block events will be received in order and
* without duplication.
* @callback Network~CommitListener
* @memberof module:fabric-network
* @async
* @param {module:fabric-network.Network~BlockEvent} event Block event.
* @returns {Promise<void>}
*/

/**
* @typedef {EventInfo} Network~BlockEvent
* @memberof module:fabric-network
*/

/**
* A Network represents the set of peers in a Fabric network.
* Applications should get a Network instance using the
* gateway's [getNetwork]{@link module:fabric-network.Gateway#getNetwork} method.
* @interface Network
* @memberof module:fabric-network
*/

/**
* Get the owning Gateway connection.
* @method Network#getGateway
* @memberof module:fabric-network
* @returns {module:fabric-network.Gateway} A Gateway.
*/

/**
* Get an instance of a contract (chaincode) on the current network.
* @method Network#getContract
* @memberof module:fabric-network
* @param {string} chaincodeId - the chaincode identifier.
* @param {string} [name] - the name of the contract.
* @param {string[]} [collections] - the names of collections defined for this chaincode.
* @returns {module:fabric-network.Contract} the contract.
*/

/**
* Get the underlying channel object representation of this network.
* @method Network#getChannel
* @memberof module:fabric-network
* @returns {Channel} A channel.
*/

/**
* Add a listener to receive transaction commit and peer disconnect events for a set of peers.
* @method Network#addCommitListener
* @memberof module:fabric-network
* @param {module:fabric-network.Network~CommitListener} listener A transaction commit listener callback function.
* @param {Endorser[]} peers The peers from which to receive events.
* @param {string} transactionId A transaction ID.
* @returns {module:fabric-network.Network~CommitListener} The added listener.
* @example
* const listener: CommitListener = (error, event) => {
* if (error) {
* // Handle peer communication error
* } else {
* // Handle transaction commit event
* }
* }
* const peers = network.channel.getEndorsers();
* await network.addCommitListener(listener, peers, transactionId);
*/

/**
* Remove a previously added transaction commit listener.
* @method Network#removeCommitListener
* @memberof module:fabric-network
* @param {module:fabric-network.Network~CommitListener} listener A transaction commit listener callback function.
*/

/**
* Add a listener to receive block events for this network. Blocks will be received in order and without duplication.
* @method Network#addBlockListener
* @memberof module:fabric-network
* @param {module:fabric-network.Network~BlockListener} listener A block listener callback function.
* @returns {module:fabric-network.Network~BlockListener} The added listener.
* @example
* const listener: BlockListener = async (event) => {
* // Handle block event, then (optionally) remove myself as a listener
* network.removeBlockListener(listener);
* }
* await network.addBlockListener(listener);
*/

/**
* Remove a previously added block listener.
* @method Network#removeBlockListener
* @memberof module:fabric-network
* @param listener {module:fabric-network.Network~BlockListener} A block listener callback function.
*/


module.exports.Gateway = require('./lib/gateway');
module.exports.Wallet = require('./lib/impl/wallet/wallet').Wallet;
module.exports.Wallets = require('./lib/impl/wallet/wallets').Wallets;
module.exports.IdentityProviderRegistry = require('./lib/impl/wallet/identityproviderregistry').IdentityProviderRegistry;
module.exports.HsmX509Provider = require('./lib/impl/wallet/hsmx509identity').HsmX509Provider;
module.exports.DefaultEventHandlerStrategies = require('./lib/impl/event/defaulteventhandlerstrategies');
module.exports.QueryHandlerStrategies = require('./lib/impl/query/queryhandlerstrategies');
module.exports.DefaultQueryHandlerStrategies = require('./lib/impl/query/defaultqueryhandlerstrategies');
module.exports.TimeoutError = require('./lib/errors/timeouterror').TimeoutError;
2 changes: 1 addition & 1 deletion fabric-network/src/contract.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ class Contract {
if (eventService) {
listener.eventService = eventService;
}
this.network.saveListener(listener, listener);
this.network.saveListener(listener);
await listener.register();

return listener;
Expand Down
43 changes: 4 additions & 39 deletions fabric-network/src/gateway.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@

'use strict';

const Network = require('./network');
const {NetworkImpl: Network} = require('./network');
const NetworkConfig = require('./impl/ccp/networkconfig');
const {Client} = require('fabric-common');
const EventStrategies = require('./impl/event/defaulteventhandlerstrategies');
const QueryStrategies = require('./impl/query/queryhandlerstrategies');
const QueryStrategies = require('./impl/query/defaultqueryhandlerstrategies');

const logger = require('./logger').getLogger('Gateway');

Expand All @@ -35,57 +35,22 @@ const logger = require('./logger').getLogger('Gateway');
* for commit notification to complete.
* @property {number} [endorseTimeout = 30] The timeout period in seconds to wait
* for the endorsement to complete.
* @property {?module:fabric-network.Gateway~TxEventHandlerFactory} [strategy=MSPID_SCOPE_ALLFORTX]
* @property {?module:fabric-network.TxEventHandlerFactory} [strategy=MSPID_SCOPE_ALLFORTX]
* Event handling strategy to identify successful transaction commits. A null value indicates
* that no event handling is desired. The default is
* [MSPID_SCOPE_ALLFORTX]{@link module:fabric-network.EventHandlerStrategies}.
*/

/**
* @typedef {Function} Gateway~TxEventHandlerFactory
* @memberof module:fabric-network
* @param {Transaction} transaction The transaction for which the handler should listen for commit events.
* @param {module:fabric-network.Network} network The network on which this transaction is being submitted.
* @returns {module:fabric-network.Gateway~TxEventHandler} A transaction event handler.
*/

/**
* @typedef {Object} Gateway~TxEventHandler
* @memberof module:fabric-network
* @property {Function} startListening Async function that resolves when the handler has started listening for
* transaction commit events. Called after the transaction proposal has been accepted and prior to submission of
* the transaction to the orderer.
* @property {Function} waitForEvents Async function that resolves (or rejects) when suitable transaction
* commit events have been received. Called after submission of the transaction to the orderer.
* @property {Function} cancelListening Cancel listening. Called if submission of the transaction to the orderer
* fails.
*/

/**
* @typedef {Object} Gateway~QueryOptions
* @memberof module:fabric-network
* @property {number} [timeout = 30] The timeout period in seconds to wait for the query to
* complete.
* @property {module:fabric-network.Gateway~QueryHandlerFactory} [strategy=MSPID_SCOPE_SINGLE]
* @property {module:fabric-network.QueryHandlerFactory} [strategy=MSPID_SCOPE_SINGLE]
* Query handling strategy used to evaluate queries. The default is
* [MSPID_SCOPE_SINGLE]{@link module:fabric-network.QueryHandlerStrategies}.
*/

/**
* @typedef {Function} Gateway~QueryHandlerFactory
* @memberof module:fabric-network
* @param {module:fabric-network.Network} network The network on which queries are being evaluated.
* @param {Object} options The request options to use when queries are being evaluated.
* @returns {module:fabric-network.Gateway~QueryHandler} A query handler.
*/

/**
* @typedef {Object} Gateway~QueryHandler
* @memberof module:fabric-network
* @property {Function} evaluate Async function that takes a [Query]{@link module:fabric-common.Query}
* and resolves with the result of the query evaluation.
*/

/**
* @typedef {Object} Gateway~DiscoveryOptions
* @memberof module:fabric-network
Expand Down
Loading

0 comments on commit ddf1d71

Please sign in to comment.