【问题标题】:How to select endorsing peers when submitting transaction which uses private data提交使用私有数据的交易时如何选择背书节点
【发布时间】:2020-03-17 14:02:23
【问题描述】:

我有一个包含两个组织的 Hyperledger Fabric 网络:Org1 和 Org2。发现已启用。私有数据集合用于保护敏感数据。特别是,只有 Org2 的成员可以访问一个私有数据集合。当我尝试提交需要访问仅 Org2 私有数据的交易时,我观察到它也被发送到 Org1 的对等方以进行背书:

const gateway = new Gateway();
await gateway.connect(ccp, { wallet, identity: userName, discovery: { enabled: true, asLocalhost: false } });
const network = await gateway.getNetwork(channelName);
const contract = await network.getContract(contractName);
await contract.createTransaction(command).setTransient(transient).submit();

使用的连接配置文件没有列出来自 Org2 的对等点,但我的猜测是 Node SDK 通过发现找到来自 Org1 的对等点并将交易提案发送给它们。 Org1 中的对等日志显示它无法访问私有数据,这是意料之中的:

2019-11-21T12:03:03.684Z ERROR [contracts-spi/chaincodefromcontract.js]  
    {"message":"GET_STATE failed: transaction ID: 25f22c0abd0318b2ec1da06ae28b90a8e6af55e6d0ea825461938cce8b2d0801: private data matching public hash version is not available. Public hash version = {BlockNum: 951, TxNum: 4}, Private data version = <nil>","stack":"Error: GET_STATE failed: transaction ID: 25f22c0abd0318b2ec1da06ae28b90a8e6af55e6d0ea825461938cce8b2d0801: private data matching public hash version is not available. Public hash version = {BlockNum: 951, TxNum: 4}, Private data version = <nil>\n    at parseResponse (/usr/local/src/node_modules/fabric-shim/lib/handler.js:751:15)\n    at MsgQueueHandler.handleMsgResponse (/usr/local/src/node_modules/fabric-shim/lib/handler.js:136:40)\n    at ClientDuplexStream.<anonymous> (/usr/local/src/node_modules/fabric-shim/lib/handler.js:290:46)\n    at emitOne (events.js:116:13)\n    at ClientDuplexStream.emit (events.js:211:7)\n    at addChunk (_stream_readable.js:263:12)\n    at readableAddChunk (_stream_readable.js:250:11)\n    at ClientDuplexStream.Readable.push (_stream_readable.js:208:10)\n    at Object.onReceiveMessage (/usr/local/src/node_modules/grpc/src/client_interceptors.js:1292:19)\n    at InterceptingListener.recvMessageWithContext (/usr/local/src/node_modules/grpc/src/client_interceptors.js:607:19)"}
2019-11-21T12:03:03.684Z ERROR [lib/handler.js] [channel123-25f22c0a]Calling chaincode Invoke() returned error response [Error: GET_STATE failed: transaction ID: 25f22c0abd0318b2ec1da06ae28b90a8e6af55e6d0ea825461938cce8b2d0801: private data matching public hash version is not available. Public hash version = {BlockNum: 951, TxNum: 4}, Private data version = <nil>]. Sending ERROR message back to peer

客户端也会显示类似的输出。仅在客户端应用程序中,它是警告而不是错误。

2019-11-21T15:15:53.165Z - warn: [DiscoveryEndorsementHandler]: _build_endorse_group_member >> G2:0 - endorsement failed - Error: transaction returned with failure: Error: GET_STATE failed: transaction ID: 0b3e90c745535af7520ffab7b82b041394d409850cb5efff96071c24f5f75817: private data matching public hash version is not available. Public hash version = {BlockNum: 957, TxNum: 0}, Private data version = <nil>

尽管出现上述错误/警告,但交易成功。对分类帐和私有数据集合执行预期更新。

问题是:考虑到私有数据,是否可以从客户端控制哪些对等方用于特定交易的背书?

我发现Channel.getEndorsementPlan(endorsement_hint) 可以正确识别哪些节点可以访问特定的链码和私有数据集合。是否可以使用此函数的输出来控制Transaction.submit() 的行为?

【问题讨论】:

  • 我知道这并没有多大帮助,但是 - 作为记录,Go SDK 支持这一点。对等方允许这样的查询。您可以将发现查询的提示传递给要使用集合的对等方,它将过滤掉不在集合中的对等方。见hyperledger-fabric.readthedocs.io/en/release-1.4/…
  • 这种使用发现来查询集合的能力在节点sdk中可用,但不能通过网关接口(即高级api)。您可以切换到使用低级 api(客户端/通道实例)并从那里开始。网关实现(当发布新版本时)不使用发现工具,而只是允许您自己指定对等点,这不是很有用,但我想确实可以让您实现所需的目标。

标签: hyperledger-fabric hyperledger


【解决方案1】:

允许您针对特定对等点的代码位于网关(高级 api)代码库中,但不幸的是,它不在节点 sdk 的当前版本中,当前版本为 1.4.4。希望在某个时候会发布一个包含此功能的 1.4.5 版本。npm 上可能有更新的 fabric-node-sdk 快照版本,您现在可以尝试一下。作为参考,如果您查看此处的参考文档https://fabric-sdk-node.github.io/release-1.4/module-fabric-network.Transaction.html,您应该会看到一个名为setEndorsingPeers 的方法。这应该允许您为您的交易执行对等目标。可以在此处找到测试中使用的示例https://github.com/hyperledger/fabric-sdk-node/blob/bf8c663fbbb9adeeb872b27eb8ccec60c03af6de/test/typescript/integration/network-e2e/invoke.ts#L954

node-sdk 低级 api(客户端/通道接口)确实具有发现和确定集合的能力,但不能通过网关/网络/合约接口使用(目前不存在它的代码)。这是一个如何使用它的参考https://fabric-sdk-node.github.io/release-1.4/tutorial-discovery.html,但客户端/通道 api 不提供对钱包的支持或为您处理事件,因此您需要自己进行身份处理和事件处理。

【讨论】:

  • 大卫,所以没有人在节点 SDK 客户端实现这种支持?自 2018 年起在服务器端支持此功能...
  • 我已经更新了我的答案,@yacovm 感谢您对支持集合发现的发现的提醒
  • 感谢@david_k 的回答。实际上,Transaction.setEndorsingPeers() 是我的第一枪,但在运行时我被告知“Transaction.setEndorsingPeers() 不是函数”:-) 官方 API 文档和官方 API 实现之间的差异非常烦人......无论如何,我接受您的回答并将等待 1.4.5 版本发布,希望它能赶上文档。
  • 您可以尝试在 package.json 中引用 1.4.5-snapshot.77 版本的 fabric-network。这包含setEndorsingPeers 调用,因此您可以尝试一下。
【解决方案2】:

我认为更好的方法是创建一个特定的查询处理程序(FABRIC 2):

import { QueryHandler, QueryHandlerFactory, Query, QueryResults } from 'fabric-network';
import { Endorser } from 'fabric-common';
import * as util from 'util';

/**
 * Query handler implementation
 */
class SameOrgQueryHandler implements QueryHandler {
  private readonly peers: Endorser[];

  constructor(peers: Endorser[]) {
    this.peers = peers;
  }

  public async evaluate(query: Query): Promise<Buffer> {
    const errorMessages: string[] = [];

    for (const peer of this.peers) {
      const results: QueryResults = await query.evaluate([peer]);
      const result = results[peer.name];
      if (result instanceof Error) {
        errorMessages.push(result.toString());
      } else {
        if (result.isEndorsed) {
          console.log(`QueryHandler: ${result.payload}`);
          return result.payload;
        }
        throw new Error(result.message);
      }
    }

    const message = util.format('Query failed. Errors: %j', errorMessages);
    throw new Error(message);
  }
}

/**
 * Factory function for creating sample query handlers.
 * @param {Network} network The network where transactions are to be evaluated.
 * @returns {QueryHandler} A query handler implementation.
 */
export const createQueryHandler: QueryHandlerFactory = network => {
  const mspId = network.getGateway().getIdentity().mspId;
  //const mspIdOrg2 = 'Org2MSP';
  const channel = network.getChannel();
  const orgPeers = channel.getEndorsers(mspId);
  const otherPeers = channel.getEndorsers().filter(peer => !orgPeers.includes(peer));
  const allPeers = orgPeers.concat(otherPeers);
  return new SameOrgQueryHandler(allPeers);
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-13
    • 1970-01-01
    • 1970-01-01
    • 2018-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多