Version
Overview
Connector Configuration
Tutorials
Reference
General
Fabric
Table of contents
- Introducing the new Fabric Connector
- Overview
- Installing dependencies
- Runtime settings
- The connector API
- Gathered TX data
- Network configuration file reference
- Network Configuration Example
- License
Introducing the new Fabric Connector
This page describes the new fabric connector implementation that replaces the deprecated legacy fabric connector
The differences between the 2 implementations are as follows
- A more logical network configuration utilising provided connection profiles from a network provider
- More robust implementation
- Fixes and improvements will only be done on the new connector implementation
- The new connector implementation has dropped some of the capability of the old connector
- Cannot specify targetPeers during install/instantiate of a contract
- storing or reading identities from node-sdk credential/cypto stores is not implemented
- Support for automatically registering and enroling identities through a Certificate Authority is not implemented
- Cannot specify to use an admin identity in a workload request using the
#ORG2
type notation
How you select which implementation you use is via the provided network configuration file and specifically the version you declare in that file
- a version of 1.0 selects the legacy connector
- a version of 2.0.0 selects the new connector
For example
name: Fabric
version: "1.0"
would select the legacy connector and the file must conform to the old deprecated network configuration file format
name: Fabric
version: "2.0.0"
would select the new connector and the file must conform to the new network configuration file format
Overview
This page introduces the Fabric adapter that utilizes the Common Connection Profile (CCP) feature of the Fabric SDK to provide compatibility and a unified programming model across different Fabric versions.
The latest supported version of Hyperledger Fabric is v2.x The ability to discover can only be used if you use the
gateway
option
The adapter exposes many SDK features directly to the user callback modules, making it possible to implement complex scenarios.
Some highlights of the provided features:
- supporting multiple orderers
- supporting multiple channels and contracts
- metadata and private collection support for contracts
- support for TLS and mutual TLS communication
- option to select the identity for submitting a TX/query
- detailed execution data for every TX
Installing dependencies
You must bind Caliper to a specific Fabric SDK to target the corresponding (or compatible) SUT version. Refer to the binding documentation for details. It is confirmed that a 1.4 Fabric SDK is compatible with a Fabric 2.1 and 2.2 SUT however any installation or instantiation of contracts (chaincode) will only work if you are still using the old lifecycle implementation.
Binding with Fabric SDK 2.x
Note that when using the binding target for the Fabric SDK 2.x there are capability restrictions:
- The 2.x SDK does not facilitate administration actions. It it not possible to create/join channels, nor install/instantiate contract. Consequently the 2.x binding only facilitates operation with a
--caliper-flow-only-test
flag- The 2.x SDK only supports operation using a
gateway
. Consequently the 2.x binding requires a--caliper-fabric-gateway-enabled
flag
Using the Operational capabilities of the Adapters
The ability to create channels and perform install/instantiate of contracts (chaincode) remains in the new 1.x sdk based adapters, and nothing equivalent exists for the 2.x sdk based adapters. This capability remains mainly to support the Caliper integration tests and the use of these mechanisms to setup your channels and contracts is highly discouraged. This capability is considered legacy and will not be maintained. You should look into alternative methods for setting up your network prior to running Caliper to benchmark it.
Runtime settings
Common settings
Some runtime properties of the adapter can be set through Caliper’s runtime configuration mechanism. For the available settings, see the caliper.fabric
section of the default configuration file and its embedded documentation.
The above settings are processed when starting Caliper. Modifying them during testing will have no effect. However, you can override the default values before Caliper starts from the usual configuration sources.
Note: An object hierarchy in a configuration file generates a setting entry for every leaf property. Consider the following configuration file:
caliper: fabric: gateway: localhost: false enabled: true
After naming the project settings file
caliper.yaml
and placing it in the root of your workspace directory, it will override the following two setting keys with the following values:
- Setting
caliper-fabric-gateway-enabled
is set totrue
- Setting
caliper-fabric-gateway-localhost
is set tofalse
The other settings remain unchanged.
The setting caliper-fabric-gateway-discovery
is not supported in these new connectors and should be defined within the configuration file but remains available only to support the legacy fabric connectors.
Skip channel creation
Additionally, the adapter provides a dynamic setting (family) for skipping the creation of a channel. The setting key format is caliper-fabric-skipcreatechannel-<channel_name>
. Substitute the name of the channel you want to skip creating into <channel_name>
, for example:
user@ubuntu:~/caliper-benchmarks$ export CALIPER_FABRIC_SKIPCREATECHANNEL_MYCHANNEL=true
Note: This settings is intended for easily skipping the creation of a channel that is specified in the network configuration file as “not created”. However, if you know that the channel always will be created during benchmarking, then it is recommended to denote this explicitly in the network configuration file.
Naturally, you can specify the above setting multiple ways (e.g., command line argument, configuration file entry).
The connector API
The workload modules interact with the adapter at three phases of the tests: during the initialization of the user module (in the initializeWorkloadModule
callback), when submitting invoke or query transactions (in the submitTransaction
callback), and at the optional cleanup of the user module (in the cleanupWorkloadModule
callback).
The initializeWorkloadModule
function
See the corresponding documentation of the function for the description of its parameters.
The last argument of the function is a sutContext
object, which is a platform-specific object provided by the backend blockchain’s connector. The context object provided by this connector is a FabricConnectorContext
instance but this doesn’t provide anything of use at this time.
For the current details/documentation of the API, refer to the source code.
The submitTransaction
function
The sutAdapter
object received (and saved) in the initializeWorkloadModule
function is of type ConnectorInterface
. Its getType()
function returns the fabric
string value.
The sendRequests
method of the connector API allows the workload module to submit requests to the SUT. It takes a single parameter: an object or array of objects containing the settings of the requests.
The settings object has the following structure:
contractId
: string. Required. The ID of the contract to call.contractFunction
: string. Required. The name of the function to call in the contract.contractArguments
: string[]. Optional. The list of string arguments to pass to the contract.readOnly
: boolean. Optional. Indicates whether the request is a TX or a query. Defaults tofalse
.timeout
: number. Optional. The timeout in seconds to use for this request. This setting is not applicable when gateway use is enabled.transientMap
: Map<string, byte[]>. Optional. The transient map to pass to the contract.invokerIdentity
: string. Optional. The name of the user who should invoke the contract. If not provided a user will be selected from the organization defined byinvokerMspId
or the first organization in the network configuration file if that property is not providedinvokerMspId
: string. Optional. The mspid of the user organization who should invoke the contract. Defaults to the first organization in the network configuration file.targetPeers
: string[]. Optional. An array of endorsing peer names as the targets of the transaction proposal. If omitted, the target list will be chosen for you. If discovery is used then the node sdk uses discovery to determine the correct peers.targetOrganizations
: string[]. Optional. An array of endorsing organizations as the targets of the invoke. If both targetPeers and are specified then targetPeers will take precedenceorderer
: string. Optional. The name of the target orderer for the transaction broadcast. If omitted, then an orderer node of the channel will be automatically selected.channel
: string. Optional. The name of the channel on which the contract to call resides.
So invoking a contract looks like the following:
let requestSettings = {
contractId: 'marbles',
contractFunction: 'initMarble',
contractArguments: ['MARBLE#1', 'Red', '100', 'Attila'],
invokerIdentity: 'client0.org2.example.com',
timeout: 10
};
await this.sutAdapter.sendRequests(requestSettings);
Note:
sendRequests
also accepts an array of request settings. However, Fabric does not support submitting an atomic batch of transactions like Sawtooth, so there is no guarantee that the order of these transactions will remain the same, or whether they will reside in the same block.
Gathered TX data
The previously discussed sendRequests
function returns the result (or an array of results) for the submitted request(s) with the type of TxStatus. The class provides some standard and platform-specific information about its corresponding transaction.
The standard data provided are the following:
GetID():string
returns the transaction ID.GetStatus():string
returns the final status of the transaction, eithersuccess
orfailed
.GetTimeCreate():number
returns the epoch when the transaction was submitted.GetTimeFinal():number
return the epoch when the transaction was finished.IsVerified():boolean
indicates whether we are sure about the final status of the transaction. Unverified (considered failed) transactions could occur, for example, if the adapter loses the connection with every Fabric event hub, missing the final status of the transaction.GetResult():Buffer
returns one of the endorsement results returned by the contract as aBuffer
. It is the responsibility of the user callback to decode it accordingly to the contract-side encoding.
The adapter also gathers the following platform-specific data (if observed) about each transaction, each exposed through a specific key name. The placeholders <P>
and <O>
in the key names are node names taking their values from the top-level peers and orderers sections from the network configuration file (e.g., endorsement_result_peer0.org1.example.com
). The Get(key:string):any
function returns the value of the observation corresponding to the given key. Alternatively, the GetCustomData():Map<string,any>
returns the entire collection of gathered data as a Map
.
The adapter-specific data keys are that are common across both the gateway and non gateway adapters are :
Key name | Data type | Description |
---|---|---|
request_type |
string | Either the transaction or query string value for traditional transactions or queries, respectively. |
The adapter-specific data keys that only the v1.x non gateway adapter makes available are :
Key name | Data type | Description |
---|---|---|
time_endorse |
number | The Unix epoch when the adapter received the proposal responses from the endorsers. Saved even in the case of endorsement errors. |
proposal_error |
string | The error message in case an error occurred during sending/waiting for the proposal responses from the endorsers. |
proposal_response_error_<P> |
string | The error message in case the endorser peer <P> returned an error as endorsement result. |
endorsement_result_<P> |
Buffer | The encoded contract invocation result returned by the endorser peer <P> . It is the user callback’s responsibility to decode the result. |
endorsement_verify_error_<P> |
string | Has the value of 'INVALID' if the signature and identity of the endorser peer <P> couldn’t be verified. This verification step can be switched on/off through the runtime configuration options. |
endorsement_result_error<P> |
string | If the transaction proposal or query execution at the endorser peer <P> results in an error, this field contains the error message. |
read_write_set_error |
string | Has the value of 'MISMATCH' if the sent transaction proposals resulted in different read/write sets. |
time_orderer_ack |
number | The Unix epoch when the adapter received the confirmation from the orderer that it successfully received the transaction. Note, that this isn’t the actual ordering time of the transaction. |
broadcast_error_<O> |
string | The warning message in case the adapter did not receive a successful confirmation from the orderer node <O> . Note, that this does not mean, that the transaction failed (e.g., a timeout occurred while waiting for the answer due to some transient network delay/error). |
broadcast_response_error_<O> |
string | The error message in case the adapter received an explicit unsuccessful response from the orderer node <O> . |
unexpected_error |
string | The error message in case some unexpected error occurred during the life-cycle of a transaction. |
commit_timeout_<P> |
string | Has the value of 'TIMEOUT' in case the event notification about the transaction did not arrive in time from the peer node <P> . |
commit_error_<P> |
string | Contains the error code in case the transaction validation fails at the end of its life-cycle on peer node <P> . |
commit_success_<P> |
number | The Unix epoch when the adapter received a successful commit event from the peer node <P> . Note, that transactions committed in the same block have nearly identical commit times, since the SDK receives them block-wise, i.e., at the same time. |
event_hub_error_<P> |
string | The error message in case some event hub connection-related error occurs with peer node <P> . |
You can access these data in your workload module after calling sendRequests
:
let requestSettings = {
contractId: 'marbles',
contractVersion: '0.1.0',
contractFunction: 'initMarble',
contractArguments: ['MARBLE#1', 'Red', '100', 'Attila'],
invokerIdentity: 'client0.org2.example.com',
timeout: 10
};
// single argument, single return value
const result = await this.sutAdapter.sendRequests(requestSettings);
let shortID = result.GetID().substring(8);
let executionTime = result.GetTimeFinal() - result.GetTimeCreate();
console.log(`TX [${shortID}] took ${executionTime}ms to execute. Result: ${result.GetStatus()}`);
The cleanupWorkloadModule function
The cleanupWorkloadModule
function is called at the end of the round, and can be used to perform any resource cleanup required by your workload implementation.
Network configuration file reference
The YAML network configuration file of the adapter mainly describes the organizations and the identities associated with those organizations, It also provides explicit information about the channels in your fabric network and the contracts (chaincode) deployed to those channels. It will reference Common Connection Profiles for each organization (as common connection profiles are specific to a single organization). These are the same connection profiles that would be consumed by the node-sdk. Whoever creates the fabric network and channels would be able to provide appropriate profiles for each organization.
The following sections detail each part separately. For a complete example, please refer to the example section or one of the files in the Caliper repository, such as the caliper-fabric test folder
Note: Unknown keys are not allowed anywhere in the configuration. The only exception is the
info
property and when network artifact names serve as keys (peer names, channel names, etc.).
name
Required. Non-empty string.
The name of the configuration file.
name: Fabric
version
Required. Non-empty string.
Specifies the YAML schema version that the Fabric SDK will use. Only the '2.0.0'
string should be specified.
version: '2.0.0'
caliper
Required. Non-empty object.
Contains runtime information for Caliper. Can contain the following keys.
-
blockchain
Required. Non-empty string.
Only the"fabric"
string is allowed for this adapter.caliper: blockchain: fabric
-
sutOptions
Optional. Non-empty object.
These are sut specific options block, the following are specific to the fabric implementation-
mutualTls
Optional. Boolean.
Indicates whether to use client-side TLS in addition to server-side TLS. Cannot be set totrue
without using server-side TLS. Defaults tofalse
.caliper: blockchain: fabric sutOptions: mutualTls: true
-
-
command
Optional. Non-empty object.
Specifies the start and end scripts.Must contain at least one of the following keys.
-
start
Optional. Non-empty string.
Contains the command to execute at startup time. The current working directory for the commands is set to the workspace.caliper: command: start: my-startup-script.sh
-
end
Optional. Non-empty string.
Contains the command to execute at exit time. The current working directory for the commands is set to the workspace.caliper: command: end: my-cleanup-script.sh
-
info
Optional. Object.
Specifies custom key-value pairs that will be included as-is in the generated report. The key-value pairs have no influence on the runtime behavior.
info:
Version: 1.1.0
Size: 2 Orgs with 2 Peers
Orderer: Solo
Distribution: Single Host
StateDB: CouchDB
organizations
Required. Non-empty object.
Contains information about 1 or more organizations that will be used when running a workload. Even in a multi-organization fabric network, workloads would usually only be run from a single organization so it would be common to only see 1 organization defined. However it does support defining multiple organizations for which a workload can explicitly declare which organization to use. The first Organization in the network configuration will be the default organization if no explicit organization is requested.
organizations:
- mspid: Org1MSP
identities:
wallet:
path: './org1wallet'
adminNames:
- admin
certificates:
- name: 'User1'
clientPrivateKey:
pem: |-
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
clientSignedCert:
pem: |-
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
connectionProfile:
path: './Org1ConnectionProfile.yaml'
discover: true
- mspid: Org2MSP
connectionProfile:
path: './Org2ConnectionProfile.yaml'
discover: false
identities:
wallet:
path: './org2wallet'
adminNames:
- admin
Each organization must have mspid
, connectionProfle
and identities
provided and at least 1 cerficate or wallet definition in the identities section so that at least 1 identity is defined
-
mspid
Required. Non-empty string.
The unique MSP ID of the organization.organizations: - mspid: Org1MSP
-
connectionProfile
Required. Non-empty object.
Reference to a fabric network Common Connection Profile. These profiles are the same profiles that the fabric SDKs would consume in order to interact with a fabric network. A Common Connection Profile is organization specific so you need to ensure you point to a Common Connection Profile that is representive of the organization it is being included under. Connection Profiles also can be in 2 forms. A static connection profile will contain a complete description of the fabric network, ie all the peers and orderers as well as all the channels that the organization is part of. A dynamic connection profile will contain a minimal amount of information usually just a list of 1 or more peers belonging to the organization (or is allowed to access) in order to discover the fabric network nodes and channels.organizations: - mspid: Org1MSP connectionProfile: path: './test/sample-configs/Org1ConnectionProfile.yaml' discover: true
-
path
Required. Non-empty string.
The path to the connection profile fileorganizations: - mspid: Org1MSP connectionProfile: path: './test/sample-configs/Org1ConnectionProfile.yaml'
-
discover
Optional. Boolean.
A value oftrue
indicates that the connection profile is a dynamic connection profile and discovery should be used. If not specified then it defaults to false. You can only set this value to true if you plan to use thegateway
optionorganizations: - mspid: Org1MSP connectionProfile: path: './test/sample-configs/Org1ConnectionProfile.yaml' discover: true
-
-
identities
Required. Non-empty object.
Defines the location of 1 or more identities available for use. Currently only supports explicit identities by providing a certificate and private key as PEM or an SDK wallet that contains 1 or more identities on the file system. At least 1 identity must be provided via one of the child properties of identity.identities: wallet: path: './wallets/org1wallet' adminNames: - admin certificates: - name: 'User1' clientPrivateKey: pem: |- -----BEGIN PRIVATE KEY----- ... -----END PRIVATE KEY----- clientSignedCert: pem: |- -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE-----
-
certificates
Optional. A List of non-empty objects.
Defines 1 or more identities by providing the PEM information for the client certificate and client private key as either an embedded PEM, a base64 encoded string of the PEM file contents or a path to individual PEM filescertificates: - name: 'User1' clientPrivateKey: path: path/to/privateKey.pem clientSignedCert: path: path/to/cert.pem - name: 'Admin' admin: true clientPrivateKey: pem: |- -----BEGIN PRIVATE KEY----- MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgIRZo3SAPXAJnGVOe jRALBJ208m+ojeCYCkmJQV2aBqahRANCAARnoGOEw1k+MtjHH4y2rTxRjtOaKWXn FGpsALLXfBkKZvxIhbr+mPOFZVZ8ztihIsZBaCuCIHjw1Tx65szJADcO -----END PRIVATE KEY----- clientSignedCert: pem: |- -----BEGIN CERTIFICATE----- MIICSDCCAe+gAwIBAgIQfpGy5OOXBYpKZxg89x75hDAKBggqhkjOPQQDAjB2MQsw CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy YW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEfMB0GA1UEAxMWdGxz Y2Eub3JnMS5leGFtcGxlLmNvbTAeFw0xODA5MjExNzU3NTVaFw0yODA5MTgxNzU3 NTVaMHYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQH Ew1TYW4gRnJhbmNpc2NvMRkwFwYDVQQKExBvcmcxLmV4YW1wbGUuY29tMR8wHQYD VQQDExZ0bHNjYS5vcmcxLmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0D AQcDQgAED4FM1+iq04cjveIDyn4uj90lJlO6rASeOIzm/Oc2KQOjpRRlB3H+mVnp rXN6FacjOp0/6OKeEiW392dcdCMvRqNfMF0wDgYDVR0PAQH/BAQDAgGmMA8GA1Ud JQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zApBgNVHQ4EIgQgPQRWjQR5EUJ7 xkV+zbfY618IzOYGIpfLaV8hdlZfWVIwCgYIKoZIzj0EAwIDRwAwRAIgYzk8553v fWAOZLxiDuMN9RiHve1o5aAQad+uD+eLpxMCIBmv8CtXf1C60h/0zyG1D6tTTnrB H8Zua3x+ZQn/kqVv -----END CERTIFICATE----- - name: 'User3' clientPrivateKey: pem: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JR0hBZ0VBTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEJHMHdhd0lCQVFRZ0lSWm8zU0FQWEFKbkdWT2UKalJBTEJKMjA4bStvamVDWUNrbUpRVjJhQnFhaFJBTkNBQVJub0dPRXcxaytNdGpISDR5MnJUeFJqdE9hS1dYbgpGR3BzQUxMWGZCa0tadnhJaGJyK21QT0ZaVlo4enRpaElzWkJhQ3VDSUhqdzFUeDY1c3pKQURjTwotLS0tLUVORCBQUklWQVRFIEtFWS0tLS0tCg== clientSignedCert: pem: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNXRENDQWY2Z0F3SUJBZ0lSQU1wU2dXRmpESE9vaFhhMFI2ZTlUSGd3Q2dZSUtvWkl6ajBFQXdJd2RqRUwKTUFrR0ExVUVCaE1DVlZNeEV6QVJCZ05WQkFnVENrTmhiR2xtYjNKdWFXRXhGakFVQmdOVkJBY1REVk5oYmlCRwpjbUZ1WTJselkyOHhHVEFYQmdOVkJBb1RFRzl5WnpFdVpYaGhiWEJzWlM1amIyMHhIekFkQmdOVkJBTVRGblJzCmMyTmhMbTl5WnpFdVpYaGhiWEJzWlM1amIyMHdIaGNOTWpBd09UQTNNVEUwTWpBd1doY05NekF3T1RBMU1URTAKTWpBd1dqQjJNUXN3Q1FZRFZRUUdFd0pWVXpFVE1CRUdBMVVFQ0JNS1EyRnNhV1p2Y201cFlURVdNQlFHQTFVRQpCeE1OVTJGdUlFWnlZVzVqYVhOamJ6RVpNQmNHQTFVRUNoTVFiM0puTVM1bGVHRnRjR3hsTG1OdmJURWZNQjBHCkExVUVBeE1XZEd4elkyRXViM0puTVM1bGVHRnRjR3hsTG1OdmJUQlpNQk1HQnlxR1NNNDlBZ0VHQ0NxR1NNNDkKQXdFSEEwSUFCTWRMdlNVRElqV1l1Qnc0WVZ2SkVXNmlmRkx5bU9BWDdHS1k2YnRWUERsa2RlSjh2WkVyWExNegpKV2ppdnIvTDVWMlluWnF2ME9XUE1NZlB2K3pIK1JHamJUQnJNQTRHQTFVZER3RUIvd1FFQXdJQnBqQWRCZ05WCiBIU1VFRmpBVUJnZ3JCZ0VGQlFjREFnWUlLd1lCQlFVSEF3RXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QXBCZ05WCkhRNEVJZ1FnNWZPaHl6d2FMS20zdDU0L0g0YjBhVGU3L25HUHlKWk5oOUlGUks2ZkRhQXdDZ1lJS29aSXpqMEUKQXdJRFNBQXdSUUloQUtFbnkvL0pZN0dYWi9USHNRSXZVVFltWHNqUC9iTFRJL1Z1TFg3VHpjZWZBaUJZb1N5WQp5OTByZHBySTZNcDZSUGlxalZmMDJQNVpDODZVa1AwVnc0cGZpUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
-
name
Required. Non-empty string.
Specifies a name to associate with this identity. This name doesn’t have to match anything within the certificate itself but must be uniquecertificates: - name: 'User1'
-
admin
Optional. Boolean.
Indicates if this identity can be considered an admin identity for the organization. Defaults to false if not provided This only needs to be provided if you plan to create channels and/or install and instantiate contracts (chaincode)certificates: - name: 'User2' admin: true
-
clientPrivateKey
Required. Non-empty object.
Specifies the identity’s private key for the organization.Must contain at most one of the following keys.
-
path
Optional. Non-empty string.
The path of the file containing the private key.clientPrivateKey: path: path/to/cert.pem
-
pem
Optional. Non-empty string.
The content of the private key file either in exact PEM format (which must split into multiple lines for yaml, or contain newline characters for JSON), or it could be a base 64 encoded version of the PEM (which will also encode the required newlines) as a single string. This single string format makes it much easier to embed into the network configuration file especially for a JSON based fileclientPrivateKey: pem: | -----BEGIN PRIVATE KEY----- MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgIRZo3SAPXAJnGVOe jRALBJ208m+ojeCYCkmJQV2aBqahRANCAARnoGOEw1k+MtjHH4y2rTxRjtOaKWXn FGpsALLXfBkKZvxIhbr+mPOFZVZ8ztihIsZBaCuCIHjw1Tx65szJADcO -----END PRIVATE KEY-----
-
-
clientSignedCert
Required. Non-empty object.
Specifies the identity’s certificate for the organization.Must contain at most one of the following keys.
-
path
Optional. Non-empty string.
The path of the file containing the certificate.clientSignedCert: path: path/to/cert.pem
-
pem
Optional. Non-empty string.
The content of the certificate file either in exact PEM format (which must split into multiple lines for yaml, or contain newline characters for JSON), or it could be a base 64 encoded version of the PEM (which will also encode the required newlines) as a single string. This single string format makes it much easier to embed into the network configuration file especially for a JSON based fileclientSignedCert: pem: | -----BEGIN CERTIFICATE----- MIICSDCCAe+gAwIBAgIQfpGy5OOXBYpKZxg89x75hDAKBggqhkjOPQQDAjB2MQsw CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy YW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEfMB0GA1UEAxMWdGxz Y2Eub3JnMS5leGFtcGxlLmNvbTAeFw0xODA5MjExNzU3NTVaFw0yODA5MTgxNzU3 NTVaMHYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQH Ew1TYW4gRnJhbmNpc2NvMRkwFwYDVQQKExBvcmcxLmV4YW1wbGUuY29tMR8wHQYD VQQDExZ0bHNjYS5vcmcxLmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0D AQcDQgAED4FM1+iq04cjveIDyn4uj90lJlO6rASeOIzm/Oc2KQOjpRRlB3H+mVnp rXN6FacjOp0/6OKeEiW392dcdCMvRqNfMF0wDgYDVR0PAQH/BAQDAgGmMA8GA1Ud JQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zApBgNVHQ4EIgQgPQRWjQR5EUJ7 xkV+zbfY618IzOYGIpfLaV8hdlZfWVIwCgYIKoZIzj0EAwIDRwAwRAIgYzk8553v fWAOZLxiDuMN9RiHve1o5aAQad+uD+eLpxMCIBmv8CtXf1C60h/0zyG1D6tTTnrB H8Zua3x+ZQn/kqVv -----END CERTIFICATE-----
-
-
-
wallet
Optional. Non-empty object
Provide the path to a file system wallet. Be aware that the persistence format used between v1.x and v2.x of the node sdks changed so make sure you provide a wallet created in the appropriate format for the version of SUT you bind to.-
path
Required. Non-empty string.
The path to the file system walletidentities: wallet: path: './wallets/org1wallet'
-
adminNames
Oprional. List of strings.
1 or more names in the wallet that are identitied as organization administrators. This only needs to be provided if you plan to create channels and/or install and instantiate contracts (chaincode)identities: wallet: path: './wallets/org1wallet' adminNames: - admin - another_admin
-
-
channels
Required. A list of objects.
Contains one or more unique channels with associated information about the contracts (chaincode) that will be available on the channel
channels:
- channelName: mychannel
create:
buildTransaction:
capabilities: []
consortium: 'SampleConsortium2'
msps: ['Org1MSP', 'Org2MSP']
version: 0
contracts:
- id: marbles
contractID: myMarbles
install:
version: v0
language: golang
path: marbles/go
metadataPath: src/marbles/go/metadata
instantiate:
initFunction: init
initArguments: []
initTransientMap:
key1: value1
key2: value2
endorsementPolicy: ''
collectionsConfig: ''
- channelName: somechannel
create:
prebuiltTransaction: 'channel.tx'
-
channelName
Required. Non-empty String.
The name of the channel.channels: - channelName: mychannel
-
create
Optional. Non-empty object.
Indicates That a channel should be created and the child properties will define how the channel will be created either by building a channel transaction or by using a prebuilt onechannels: - channelName: mychannel create: buildTransaction: capabilities: [] consortium: 'SampleConsortium2' msps: ['Org1MSP', 'Org2MSP'] version: 0 ... - channelName: somechannel create: prebuiltTransaction: 'channel.tx' ...
Must contain at most one of the following keys.
-
prebuiltTransaction
Optional. Non-empty string.
If a channel doesn’t exist yet, the adapter will create it based on the provided path of a channel configuration binary (which is typically the output of the configtxgen tool).channels: - channelName: somechannel create: prebuiltTransaction: 'channel.tx'
-
buildTransaction
Optional. Object.
If a channel doesn’t exist yet, the adapter will create it based on the provided information on how to build a transaction that will create a channel, consisting of multiple properties.channels: - channelName: somechannel create: buildTransaction: capabilities: [] consortium: SampleConsortium msps: ['Org1MSP', 'Org2MSP'] version: 0
-
capabilities
Required. Non-sparse array of strings.
List of channel capabilities to include in the configuration transaction. -
consortium
Required. Non-empty string.
The name of the consortium. -
msps
Required. Non-sparse array of unique strings.
The MSP IDs of the organizations in the channel. -
version
Required. Non-negative integer.
The version number of the configuration.
-
-
-
contracts
Required. Non-sparse array of objects.
Each array element contains information about a contract in the channel.Note: the
contractID
value of every contract in every channel must be unique on the configuration file level! IfcontractID
is not specified for a contract then its default value is theid
of the contract.channels: mychannel: contracts: - id: simple # other properties of simple CC - id: smallbank # other properties of smallbank CC
Some prorperties are required depending on whether a contract needs to be deployed. The following constraints apply:
Note:
Constraints for installing contracts:
- if
metadataPath
is provided,path
is also required - if
path
is provided,language
is also required
Constraints for instantiating contracts:
- if any of the following properties are provided,
language
is also needed:initArguments
,initFunction
,initTransientMap
,collectionsConfig
,endorsementPolicy
Each element can contain the following properties.
-
id
Required. Non-empty string.
The ID of the contract.channels: mychannel: contracts: - id: simple # other properties
-
contractID
Optional. Non-empty string.
The Caliper-level unique ID of the contract. This ID will be referenced from the user callback modules. Can be an arbitrary name, it won’t effect the contract properties on the Fabric side.If omitted, it defaults to the
id
property value.channels: mychannel: contracts: - contractID: simpleContract # other properties
-
install
Optional. Non-empty object
Defines the requirement that the contract (chaincode) will be installed and instantiated. The sub properties provided will define the information about the contract (chaincode) to be installed. This can only be used with a 1.4 SUT and can only be used against a Fabric 2.x network if the new lifecycle has not been enabled.contracts: - id: marbles contractID: myMarbles install: version: v0 language: golang path: marbles/go metadataPath: src/marbles/go/metadata
-
version
Required. Non-empty string.
The version string of the contract.channels: mychannel: contracts: install: version: v1.0 # other properties
-
language
Optional. Non-empty string.
Denotes the language of the contract. Currently supported values:golang
,node
andjava
.channels: mychannel: contracts: install: language: node # other properties
-
path
Optional. Non-empty string.
The path to the contract directory. For golang contracts, it is the fully qualified package name (relative to theGOPATH/src
directory). Note, thatGOPATH
is temporarily set to the workspace directory by default. To disable this behavior, set thecaliper-fabric-overwritegopath
setting key tofalse
.channels: mychannel: contracts: install: path: contracts/mycontract # other properties
-
metadataPath
Optional. Non-empty string.
The directory path for additional metadata for the contract (like CouchDB indexes). Only supported since Fabric v1.1.channels: mychannel: contracts: install: metadataPath: contracts/mycontract/metadata # other properties
-
-
instantiate
Optional. Non-empty object.
Defines the optional parameters to provided during the instantiate phase. This section does not control whether the contact (chaincode) is instantiated or not it just provides the capability to provide optional instantiation parameters. This can only be used with a 1.4 SUT and can only be used against a Fabric 2.x network if the new lifecycle has not been enabled.contracts: - id: marbles contractID: myMarbles # define the install requirements to install chaincode if chaincode is to be installed install: version: v0 language: golang path: marbles/go metadataPath: src/marbles/go/metadata # define the instantiate requirements to instantiate chaincode all of this section is optional depending on chaincode requirements instantiate: initFunction: init initArguments: [] initTransientMap: key1: value1 key2: value2 endorsementPolicy: '' collectionsConfig: ''
-
initArguments
Optional. Non-sparse array of strings.
The list of string arguments to pass to the contract’sInit
function during instantiation. Defaults to an empty array if not specifiedinstantiate: initArguments: ['arg1', 'arg2'] # other properties
-
initFunction
Optional. String.
The function name to pass to the contract’sInit
function during instantiation. Defaults toinit
if not specifiedinstantiate: initFunction: 'bootstrap' # other properties
-
initTransientMap
Optional. Object containing string keys associated with string values.
The transient key-value map to pass to theInit
function when instantiating a contract. The adapter encodes the values as byte arrays before sending them.instantiate: initTransientMap: pemContent: | -----BEGIN PRIVATE KEY----- MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgQDk37WuVcnQUjE3U NTW7PpPfcp54q/KBKNrtFXjAtUChRANCAAQ0xnSUxoocDsb2YIrmtFIKZ4XAiwqu V0BCfsl+ByVKUUdXypNrluQfm28AxX7sEDQLKtHVmuMi/BGaKahZ6Snk -----END PRIVATE KEY----- stringArg: this is also passed as a byte array # other properties
-
collectionsConfig
Optional. Non-empty, non-sparse array of objects.
List of private collection definitions for the contract or a path to the JSON file containing the definitions. For details about the content of such definitions, refer to the SDK page.instantiate: collectionsConfig: - name: twoOrgCollection policy: identities: - role: name: member mspId: Org1MSP - role: name: member mspId: Org2MSP policy: 2-of: - signed-by: 0 - signed-by: 1 requiredPeerCount: 1 maxPeerCount: 1 blockToLive: 0 # other properties
-
endorsementPolicy
Optional. Object.
The endorsement policy of the contract as required by the Fabric Node.js SDK. If omitted, then a default N-of-N policy is used based on the target peers (thus organizations) of the contract.instantiate: endorsementPolicy: identities: - role: name: member mspId: Org1MSP - role: name: member mspId: Org2MSP policy: 2-of: - signed-by: 0 - signed-by: 1 # other properties
-
- if
Network Configuration Example
The following example is a Fabric network configuration for the following network topology and artifacts:
- two organizations
Org1MSP
andOrg2MSP
- one channel named
mychannel
marbles@v0
contract installed and instantiated inmychannel
on every peer;- the nodes of the network use TLS communication, but not mutual TLS;
- the local network is deployed and cleaned up automatically by Caliper.
name: Fabric
version: "2.0.0"
caliper:
blockchain: fabric
sutOptions:
mutualTls: false
command:
start: docker-compose -f network/fabric-v1.1/2org2peergoleveldb/docker-compose-tls.yaml up -d;sleep 3s
end: docker-compose -f network/fabric-v1.1/2org2peergoleveldb/docker-compose-tls.yaml down;docker rm $(docker ps -aq);docker rmi $(docker images dev* -q)
info:
Version: 1.1.0
Size: 2 Orgs
Orderer: Raft
Distribution: Single Host
StateDB: GoLevelDB
channels:
- channelName: mychannel
create:
buildTransaction:
capabilities: []
consortium: 'SampleConsortium'
msps: ['Org1MSP', 'Org2MSP']
version: 0
# Array of contracts to be installed/instantiated on the named channel and available for use by the workload module
contracts:
- id: marbles
contractID: myMarbles
install:
version: v0
language: golang
path: marbles/go
metadataPath: src/marbles/go/metadata
instantiate:
initFunction: init
initArguments: []
endorsementPolicy:
identities:
- role:
name: member
mspId: Org1MSP
- role:
name: member
mspId: Org2MSP
policy:
2-of:
- signed-by: 0
- signed-by: 1
organizations:
- mspid: Org1MSP
identities:
certificates:
- name: 'admin.org1.example.com'
admin: true
clientPrivateKey:
pem: |-
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
clientSignedCert:
pem: |-
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
connectionProfile:
path: './Org1ConnectionProfile.yaml'
discover: true
- mspid: Org2MSP
connectionProfile:
identities:
certificates:
- name: 'admin.org2.example.com'
admin: true
clientPrivateKey:
pem: |-
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
clientSignedCert:
pem: |-
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
path: './Org2ConnectionProfile.json'
discover: true
License
The Caliper codebase is released under the Apache 2.0 license. Any documentation developed by the Caliper Project is licensed under the Creative Commons Attribution 4.0 International License. You may obtain a copy of the license, titled CC-BY-4.0, at http://creativecommons.org/licenses/by/4.0/.