Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FABN-1491: Updated realtime block event listening #144

Merged
merged 1 commit into from
Feb 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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