Refactor Hyperledger Fabric Node SDK low level v
Refactor Hyperledger Fabric Node. SDK low level v 2. 0 11/9/2020 Node. SDK v 2. 0 1
v 2 provides an opportunity to make changes • Move admin functions to a new package – fabric-admin • Move client functions to – fabric-common • Remove application type objects and actions • Restructure APIs and parameters to provide consistency • Refactor identity access and transaction ID • Refactor compound Class/API’s to single actions and endpoints • Refactor event service (replay, registration and notification) • Share peers/orderers across channels. 11/9/2020 Node. SDK v 2. 0 2
V 2. 0 NPM package changes 1. fabric-common – enhance - The applications API’s to be used for endorsements, queries, commits, and events will be added to the existing package 2. fabric-admin – create - The admin API’s to be used for chaincode lifecycle, creating and joining channels. 3. fabric-client – remove – This package will not be have a v 2 and will be removed from master. 11/9/2020 Node. SDK v 2. 0 3
Remove application type objects and actions 1. stores – The user state store and crypto store were provided as a convenience to the application mainly for testing. The high level has a wallet which the applications should be using along with the organization's current user store. The stores will be removed from all Node. SDK packages. 2. Common connection profile – This should all be done at the application level and build the low level required objects. This will be moved to the fabric-network, high level API package. 3. File access – remove asking for file paths, applications should read their own data or custom code. Applications will read their connection profiles and pass them as JSON objects to the high level. Applications will create their own instances of handlers and pass a running instance to the Service. Action. fabric-base 11/9/2020 Node. SDK v 2. 0 4
Restructure APIs and parameters to provide consistency 1. API’s – Group API’s into functional classes • connection options, endpoints, actions, identity/tx. Id 2. Returns - Make all API’s return a single object. Allows for errors and fabric responses on multiple target calls 3. Logging – add more and include method and instance name fabric-base 11/9/2020 Node. SDK v 2. 0 5
Service endpoints Have single purpose endpoints based on the service provided v Peer – endorsements and queries v Eventer – ledger events v Discoverer – config and endorsement plans v Orderer – committing endorsements fabric-base 11/9/2020 Node. SDK v 2. 0 6
Service endpoints – connection settings Move out the connection settings to their own class Allows sharing settings with any service endpoint instance that is located at the same address of the service endpoint New class v Endpoint – URL, g. RPC options fabric-base 11/9/2020 Node. SDK v 2. 0 7
Endpoint class Unique set of options based the client’s current settings These are the options used by g. RPC. Sourced from the ‘Client’ instance. Client will combine: 1. Mutual TLS – once set on the client instance, they will be available to all future connections 2. Default options – pull from the Node. SDK’s config setting ‘connectionoptions’. Application may override 3. This endpoint unique – any unique options provided at the time of the endpoint’s creation, must have URL. fabric-base 11/9/2020 Node. SDK v 2. 0 8
Service actions • Break up the compound calls into new class with discrete steps • Allows for reuse of the payload and signatures • Allows for external signing For example Channel. send. Transaction. Proposal( ) Ø build( ) Endorse. js Ø sign( ) Ø send( ) fabric-base 11/9/2020 Node. SDK v 2. 0 9
Service action classes Have focused classes to perform a single action v Endorsement v Query v Commit v Event. Service v Discovery Each class will do the build, sign, send, plus service unique calls fabric-base 11/9/2020 Node. SDK v 2. 0 10
Allow Peer and Orderer instances to be shared across channels • Have connect and disconnect to run independently of service requests • Have the ‘Client’ store the Peers and Orderers. Discovery will use the “get” call to provide existing service endpoints. Single use Peers and Orderers will be available with the ‘new’ call. • Eventer endpoints will not be shared, the backing service is a g. RPC stream and is bound to just one service action instance (Event. Service). fabric-base 11/9/2020 Node. SDK v 2. 0 11
Refactor Transaction. Id object into identity access and transaction. ID/nonce Remove user context from the ‘Client’ instance and replace with an identity context as input to all requests 1. identity – The needed certificate for requests and access to signing 2. transaction. Id – The transaction id will be built on demand 3. nonce – The unique one time value built at the same time as the transaction id Applications are expected to build a identity context at the start of a request flow similar to how they built the transaction ID object. However they may use the context on each call as the transaction id will be rebuilt when needed. fabric-base 11/9/2020 Node. SDK v 2. 0 12
Channel. Event. Hub improvements • Separate into Service. Endpoint and Service. Action • New ‘Eventer. js’ class for service endpoints • New ‘Event. Serivce. js’ class for service actions • Remove callback on connect • Remove the error callback and have a single callback with (error, event) parameters on the listener callback • Return an event object with all known event info • • Block number Transaction number Last block was received //maybe all that is returned when endblock is seen Chaincode events array Block Filtered block Private data • Have all Chaincode events from a block to be consumed at one time • Allow more than one listener when using playback (start and end block) • Allow multiple targets, first one to succeed in the ‘send()’ will be used fabric-base 11/9/2020 Node. SDK v 2. 0 13
How to Use fabric-base 11/9/2020 Node. SDK v 2. 0 14
Starting point Same starting point as fabric-client const Client = require('fabric-base’); const client = new Client('myclient’); fineprint: connection profile is no longer part of the client create Central point that all other objects are sourced const channel = client. new. Channel(… const endpoint = client. new. Endpoint(… const peer = client. new. Peer(… const orderer = client. new. Orderer(… 11/9/2020 Node. SDK v 2. 0 fabric-base 15
Centralized connection options Assign the TLS client side cert and key to be used by all g. RPC connections associated with this client. set. Tls. Client. Cert. And. Key(cert, key); Then create an Endpoint , a specific set of options const peer 1_endpoint = client. new. Endpoint({ url: 'grpcs: //localhost: 7051', pem: ‘PEMABCD’, 'ssl-target-name-override': 'peer 0. org 1. example. com’ }); "connection-options": { "grpc. max_receive_message_length": -1, "grpc. max_send_message_length": -1, "grpc. keepalive_time_ms": 120000, "grpc. http 2. min_time_between_pings_ms": 120000, "grpc. keepalive_timeout_ms": 20000, "grpc. http 2. max_pings_without_data": 0, "grpc. keepalive_permit_without_calls": 1, "grpc-wait-for-ready-timeout": 3000, "request-timeout" : 45000 }, The client will combine options passed in with the TLS and default connection options fabric-base 11/9/2020 Node. SDK v 2. 0 16
Service Endpoints All service endpoint types extend Remote. js and only have one g. RPC service. Peer. js - Endorser Orderer. js - Atomic. Broadcast Eventer. js - Deliver Discoverer. js - Discovery fabric-base 11/9/2020 Node. SDK v 2. 0 17
Connect – Disconnect - Check With each class having only one service then each can have the methods to work with a single service: • connect(endpoint, options) Sets up the g. RPC connection using the endpoint created by the client. Applications may add unique connection options • disconnect() Shuts down the g. RPC. With event hub will also shutdown the listeners. • check. Connection() Checks the g. RPC connection. fabric-base 11/9/2020 Node. SDK v 2. 0 18
Using an endpoint – peer endorsement example // Client is the starting point for new objects const endpoint 1 = client. new. Endpoint( opts ); const peer 1 = client. new. Peer(‘peer 1. org 1. com’); // endpoint may be used again and again await peer 1. connect(endpoint 1); await peer 1_backup. connect(endpoint 1); await eventer 1. connect(endpoint 1); await discovery 1. connect(endpoint 1); // peer may now be used as the target for an endorsement const endorsement_request = { targets: [ peer 1 ] }; 11/9/2020 fabric-base Node. SDK v 2. 0 19
Using an Identity. Context Applications will build a fabric-common/User. js instance as the source of the required identity material (certs, keys) The client instance will build a fabric-base/Identity. Context. js instance from the identity provided const user = application. get. The. User(. . . ); const idx = client. new. Identity. Context(user); Applications may now use the idx when building and signing outbound requests endorsement. build(idx); endorsement. sign(idx); fabric-base 11/9/2020 Node. SDK v 2. 0 20
Identity. Context – transaction ID The Endorsement. js internals will ask the identity context to build a new transaction ID and nonce. A transaction ID must be based on the identity of the proposal and will be burned into a proposal. idx. calculate. Tx. Id(); const tx. Id = endorsement. transaction. Id; const nonce = endorsement. nonce; The Endorsement will keep track of the transaction ID used, making it available for event monitoring. const tx. Id = endorsement. get. Transaction. Id(); events. regisiter. Tx. Event(tx. Id, . . . fabric-base 11/9/2020 Node. SDK v 2. 0 21
Endorsement – build an Endorsement proposals are for a specific channel and a chaincode running on that channel. The Endorsement object will contain everything related to the proposal, from the proposal itself to the results of the endorsement. const endorsement = channel. new. Endorsement(“my_chaincode”); endorsement. build(idx, { args: [“a”, “b”, “ 400”] }); fabric-base 11/9/2020 Node. SDK v 2. 0 22
Endorsement – sign a proposal internally • Use an identity context with access to a private key • After signing, the proposal object is ready to be sent to be endorsed endorsement. sign(idx); fabric-base 11/9/2020 Node. SDK v 2. 0 23
Endorsement – sign a proposal externally • Building a proposal returns the proposal bytes • Sign the bytes • Provide the signature to the proposal const bytes = endorsement. build(idx, { args: [“a”, “b”, “ 400”] }); const signature = …<application signs the bytes>…. endorsement. sign(signature); 11/9/2020 Node. SDK v 2. 0 fabric-base 24
Endorsement – endorse a proposal Send the proposal to the targeted peers All results and errors will be returned as single results object Results are also stored within the instance const results = await endorsement. send({targets: [peer 1]}); if (results. errors) { … check the results. errors } else { … check results. responses } fabric-base 11/9/2020 Node. SDK v 2. 0 25
Endorsement – endorse a proposal with a handler • Application will decide to use a handler for an endorsement • fabric-base ships with one handler that uses discovery const handler = discovery. new. Handler() const results = await endorsement. send({handler: handler}); fabric-base 11/9/2020 Node. SDK v 2. 0 26
Endorsement – commit a proposal Get the commit Service action instance from an endorsement instance The commit instance has access to the endorsements Send the endorsements to the targeted orderers Ø done at a time till success const commit = endorsement. net. Commit(); commit. build(idx); commit. sign(idx); const results = await commit. send({[targets: [orderer 1]}); fabric-base 11/9/2020 Node. SDK v 2. 0 27
Endorsement – commit an endorsed proposal with a handler • Application will decide to use a handler for a commit • fabric-base ships with one handler that uses discovery const handler = discovery. new. Handler() const results = await commit. send({handler: handler}); fabric-base 11/9/2020 Node. SDK v 2. 0 28
Chaincode queries const query = channel. new. Query(“my_chaincode”); query. build(idx, { args: [“a”] }); query. sign(idx); const results = await query. send({targets: [peer 1]}); if (results. errors) { check (results. errors ); } else { check(results. query. Results ); // this is the chaincode response payload check(results. responses ); //included are the endorsements } fabric-base 11/9/2020 Node. SDK v 2. 0 29
Chaincode queries with a handler • Application will decide to use a handler for a query • fabric-base ships with one handler that uses discovery const handler = discovery. new. Handler() const results = await query. send({handler: handler}); fabric-base 11/9/2020 Node. SDK v 2. 0 30
Events – Service endpoint <-> Service action • Channel. Event. Hub will be refactored into two classes Event. Service. js --- Service. Action Ø build Ø sign Ø send Eventer. js --- Service. Endpoint Ø connect Ø check. Connect Ø disconnect • The fabric peer’s event service is based on a g. RPC two way stream that requires a dedicated client instance fabric-base 11/9/2020 Node. SDK v 2. 0 31
Events – connection setup Service endpoints are sourced from the client const eventer = client. new. Eventer(‘peer 1 -events’); Build a new endpoint or use an existing endpoint const endpoint 1 = client. new. Endpoint( opts ); await eventer. connect(endpoint 1); // notice no callback Maybe check the connection const good = await eventer. check. Connection(); If (good) {. . . fabric-base 11/9/2020 Node. SDK v 2. 0 32
Channel events – usual 3 steps Event listening is based on a channel const event. Service = channel. new. Event. Service(‘channel 1 -events’); Build and Sign using the identity context 1. event. Service. build(idx); 2. event. Service. sign(idx); Send the request and start listening (starts the stream) 3. await event. Service. send(); fabric-base 11/9/2020 Node. SDK v 2. 0 33
Channel events – replay and block type The fabric channel event service is the ‘delivery’ service repackage as an event service. Service initialization requires a start and an end block. To implement ‘replay’ for the applications, we need to ask for start/end information when building the request for service setup (event. Service. build). Same goes for the type of block (full, filtered, and soon to be private data). const options = {start. Block: 1234, block. Type: full} event. Service. build(idx, options); **** Users will still be able to have start. Block and end. Block on the listener registration, however they may not work with the given service startup settings. fabric-base 11/9/2020 Node. SDK v 2. 0 34
Channel events – register transaction listener Transaction event const reg_id = event. Service. register. Transaction. Listener ( tx. Id, // got it from the proposal (error, event) => {}, // only one callback now {unregister: true, endblock: 3333} // options ); Notice only one callback, will have two parameters of which only one will be populated error – Node. js error object event – The attributes of this event fabric-base 11/9/2020 Node. SDK v 2. 0 35
Channel events – register block listener Block event const reg_id = events. register. Block. Listener ( (error, event) => {}, // only one callback now {unregister: true, endblock: 3333} // options ); Notice only one callback, will have two parameters of which only one will be populated error – Node. js error object event – The attributes of this event fabric-base 11/9/2020 Node. SDK v 2. 0 36
Channel events – register chaincode listener Chaincode event const reg_id = events. register. Chaincode. Listener ( ‘myevent+’, // regex matching of chaincode name (error, event) => {}, // only one callback now {unregister: true, endblock: 3333} // options ); Notice only one callback, will have two parameters of which only one will be populated error – Node. js error object event – The attributes of this event fabric-base 11/9/2020 Node. SDK v 2. 0 37
Channel events – Event object New ‘event’ parameter is returned to all listener callbacks. Has the following attributes of which some may not be populated: • Block number • Transaction status • Boolean of end block received (might be the only attribute) • Chaincode events array (all matching chaincode events in all transactions of the block) • Block json object • Filtered block json object • Block with Private data (still being designed) fabric-base 11/9/2020 Node. SDK v 2. 0 38
Discoverer - connection The Discoverer is just like a peer and will be source from the client. const discoverer = client. new. Discoverer(‘peer 1 -discoverer’); Build a new endpoint or use an existing endpoint const endpoint 1 = client. new. Endpoint( opts ); await discoverer. connect(endpoint 1); Maybe check the connection const good = await discoverer. check. Connection(); If (good) {. . . fabric-base 11/9/2020 Node. SDK v 2. 0 39
Discovery – again the usual 3 steps Discovery results are based on a channel, so the discovery instance object must be sourced from a channel. const discovery = channel. new. Discovery(‘mydiscovery’); Build and Sign using the identity context and the proposal to be endorsed (can be an endorsement or a query), then send 1. discovery. build(idx, {proposal: propsal); 2. discovery. sign(idx); 3. await discovery. send({targets: [], as_localhost: true}); fabric-base 11/9/2020 Node. SDK v 2. 0 40
Discovery – endorse with discovery • Using an existing discovery instance that has run ‘discover()’ • get the associated endorsement handler const handler = discovery. new. Endorsement. Handler(); • pass the handler instead of ‘targets’ to the endorsement on the ‘send’call const results = await endorsement. send({handler: handler}); fabric-base 11/9/2020 Node. SDK v 2. 0 41
Discovery – getting discovered endpoints The associated channel will have: • Events – channel. new. Events. For. Org(mspid) • Peers – channel. get. Peers() • Orderers – channel. get. Orderers() • Mspids – channel. get. Mspids() fabric-base 11/9/2020 Node. SDK v 2. 0 42
- Slides: 42