Skip to content

Commit

Permalink
Additional documentation for implicit private data collections
Browse files Browse the repository at this point in the history
Add additional documentation for implicit private data collections.

Signed-off-by: David Enyeart <enyeart@us.ibm.com>
(cherry picked from commit fe71474)
  • Loading branch information
denyeart committed Jul 22, 2021
1 parent 8fd2ad8 commit 9a6b351
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 9 deletions.
60 changes: 51 additions & 9 deletions docs/source/private-data-arch.rst
Expand Up @@ -137,6 +137,44 @@ though the chaincode level endorsement policy may require endorsement from
In this way you can control which organizations are entrusted to write to certain
private data collections.

Implicit private data collections
---------------------------------

In addition to explicitly defined private data collections,
every chaincode has an implicit private data namespace reserved for organization-specific
private data. These implicit organization-specific private data collections can
be used to store an individual organization's private data, and do not need to
be defined explicitly.

The private data dissemination policy and endorsement policy for implicit
organization-specific collections is the respective organization itself.
The implication is that if data exists in an implicit private data collection,
it was endorsed by the respective organization. Implicit private data collections
can therefore be used by an organization to record their agreement or vote
for some fact, which is a useful pattern to leverage in multi-party business
processes implemented in chaincode since other organizations can check
the on-chain hash to verify the organization's record. Private data
can also be shared or transferred to an implicit collection of another organization,
making implicit collections a useful pattern to leverage in chaincode
applications, without the need to explicitly manage collection definitions.

Since implicit private data collections are not explicitly defined,
it is not possible to set the additional collection properties. Specifically,
``memberOnlyRead`` and ``memberOnlyWrite`` are not available,
meaning that access control for clients reading data from or writing data to
an implicit private data collection must be encoded in the chaincode on the organization's peer.
Furthermore, ``blockToLive`` is not available, meaning that private data is never automatically purged.

The properties ``requiredPeerCount`` and ``maxPeerCount`` can however be set in the peer's core.yaml
(``peer.gossip.pvtData.implicitCollectionDisseminationPolicy.requiredPeerCount`` and
``peer.gossip.pvtData.implicitCollectionDisseminationPolicy.maxPeerCount``). An organization
can set these properties based on the number of peers that they deploy, as described
in the next section.

.. note:: Since implicit private data collections are not explicitly defined,
it is not possible to associate CouchDB indexes with them. Utilize
key-based queries and key-range queries rather than JSON queries.

Private data dissemination
--------------------------

Expand All @@ -146,7 +184,7 @@ to all peers in a channel, the endorsing peer plays an important role in
disseminating private data to other peers of authorized organizations. This ensures
the availability of private data in the channel's collection, even if endorsing
peers become unavailable after their endorsement. To assist with this dissemination,
the ``maxPeerCount`` and ``requiredPeerCount`` properties in the collection definition
the ``maxPeerCount`` and ``requiredPeerCount`` properties
control the degree of dissemination at endorsement time.

If the endorsing peer cannot successfully disseminate the private data to at least
Expand Down Expand Up @@ -270,7 +308,8 @@ configuration definitions and how to set them, refer back to the
`Private data collection definition`_ section of this topic.

.. note:: If you would like more granular access control, you can set
``memberOnlyRead`` and ``memberOnlyWrite`` to false. You can then apply your
``memberOnlyRead`` and ``memberOnlyWrite`` to false (implicit collections always
behave as if ``memberOnlyRead`` and ``memberOnlyWrite`` are false). You can then apply your
own access control logic in chaincode, for example by calling the GetCreator()
chaincode API or using the client identity
`chaincode library <https://godoc.org/github.com/hyperledger/fabric-chaincode-go/shim#ChaincodeStub.GetCreator>`__ .
Expand All @@ -284,19 +323,19 @@ shim APIs:
* ``GetPrivateDataByRange(collection, startKey, endKey string)``
* ``GetPrivateDataByPartialCompositeKey(collection, objectType string, keys []string)``

And for the CouchDB state database, JSON content queries can be passed using the
shim API:
And if using explicit private data collections and CouchDB state database,
JSON content queries can be passed using the shim API:

* ``GetPrivateDataQueryResult(collection, query string)``

Limitations:

* Clients that call chaincode that executes range or rich JSON queries should be aware
* Clients that call chaincode that executes key range queries or JSON queries should be aware
that they may receive a subset of the result set, if the peer they query has missing
private data, based on the explanation in Private Data Dissemination section
above. Clients can query multiple peers and compare the results to
determine if a peer may be missing some of the result set.
* Chaincode that executes range or rich JSON queries and updates data in a single
* Chaincode that executes key range queries or JSON queries and updates data in a single
transaction is not supported, as the query results cannot be validated on the peers
that don’t have access to the private data, or on peers that are missing the
private data that they have access to. If a chaincode invocation both queries
Expand All @@ -306,6 +345,9 @@ Limitations:
chaincode function to make the updates. Note that calls to GetPrivateData() to retrieve
individual keys can be made in the same transaction as PutPrivateData() calls, since
all peers can validate key reads based on the hashed key version.
* Since implicit private data collections are not explicitly defined,
it is not possible to associate CouchDB indexes with them.
It is therefore not recommended to utilize JSON queries with implicit private data collections.

Using Indexes with collections
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand All @@ -314,7 +356,7 @@ The topic :doc:`couchdb_as_state_database` describes indexes that can be
applied to the channel’s state database to enable JSON content queries, by
packaging indexes in a ``META-INF/statedb/couchdb/indexes`` directory at chaincode
installation time. Similarly, indexes can also be applied to private data
collections, by packaging indexes in a ``META-INF/statedb/couchdb/collections/<collection_name>/indexes``
collections that are explicitly defined, by packaging indexes in a ``META-INF/statedb/couchdb/collections/<collection_name>/indexes``
directory. An example index is available `here <https://github.com/hyperledger/fabric-samples/blob/{BRANCH}/chaincode/marbles02_private/go/META-INF/statedb/couchdb/collections/collectionMarbles/indexes/indexOwner.json>`_.

Considerations when using private data
Expand All @@ -323,8 +365,8 @@ Considerations when using private data
Private data purging
~~~~~~~~~~~~~~~~~~~~

Private data can be periodically purged from peers. For more details,
see the ``blockToLive`` collection definition property above.
Private data in explicitly defined private data collections can be periodically purged from peers.
For more details, see the ``blockToLive`` collection definition property above.

Additionally, recall that prior to commit, peers store private data in a local
transient data store. This data automatically gets purged when the transaction
Expand Down
8 changes: 8 additions & 0 deletions docs/source/private-data/private-data.md
Expand Up @@ -15,6 +15,14 @@ That's why Fabric offers the ability to create
channel the ability to endorse, commit, or query private data without having to
create a separate channel.

Private data collections can be defined explicitly within a chaincode definition.
Additionally, every chaincode has an implicit private data namespace reserved for organization-specific
private data. These implicit organization-specific private data collections can
be used to store an individual organization's private data, which is useful
if you would like to store private data related to a single organization,
such as details about an asset owned by an organization or an organization's
approval for a step in a multi-party business process implemented in chaincode.

## What is a private data collection?

A collection is the combination of two elements:
Expand Down

0 comments on commit 9a6b351

Please sign in to comment.