我已经成功建立了一个组织中的 3 个订购者和一个具有 5 个组织的联盟的结构网络。每个组织只有一个对等节点并加入同一频道。我已经在这个频道中安装并实例化了两个链码。但是,当我通过 *channel.Client 调用链代码时,有时它可以正常工作,有时会出现这样的错误:
Failed to get endorsing peers: Discovery status Code: (11) UNKNOWN. Description: error getting endorsers: no endorsement combination can be satisfied
这是我的开发环境:
# os
Darwin PANZVORHONG-MB0 20.3.0 Darwin Kernel Version 20.3.0: Thu Jan 21 00:07:06 PST 2021; root:xnu-7195.81.3~1/RELEASE_X86_64 x86_64
# golang
go version go1.15.6 darwin/amd64
# docker
Engine Version: 20.10.5
以下是我认为可能有用的 Fabric 配置:configtx.yaml
Organizations:
- &OrdererOrg
Name: OrdererMSP
ID: OrdererMSP
MSPDir: ../fabric/organizations/ordererOrganizations/food.com/msp
Policies:
Readers:
Type: Signature
Rule: "OR('OrdererMSP.member')"
Writers:
Type: Signature
Rule: "OR('OrdererMSP.member')"
Admins:
Type: Signature
Rule: "OR('OrdererMSP.admin')"
OrdererEndpoints:
- orderer1.food.com:7050
- orderer2.food.com:7049
- orderer3.food.com:7048
- &Producer
Name: ProducerMSP
ID: ProducerMSP
MSPDir: ../fabric/organizations/peerOrganizations/producer.food.com/msp
Policies:
Readers:
Type: Signature
Rule: "OR('ProducerMSP.admin', 'ProducerMSP.peer', 'ProducerMSP.client')"
Writers:
Type: Signature
Rule: "OR('ProducerMSP.admin', 'ProducerMSP.client')"
Admins:
Type: Signature
Rule: "OR('ProducerMSP.admin')"
Endorsement:
Type: Signature
Rule: "OR('ProducerMSP.peer')"
AnchorPeers:
- Host: peer0.producer.food.com
Port: 7051
- &Processor
Name: ProcessorMSP
ID: ProcessorMSP
MSPDir: ../fabric/organizations/peerOrganizations/processor.food.com/msp
Policies:
Readers:
Type: Signature
Rule: "OR('ProcessorMSP.admin', 'ProcessorMSP.peer', 'ProcessorMSP.client')"
Writers:
Type: Signature
Rule: "OR('ProcessorMSP.admin', 'ProcessorMSP.client')"
Admins:
Type: Signature
Rule: "OR('ProcessorMSP.admin')"
Endorsement:
Type: Signature
Rule: "OR('ProcessorMSP.peer')"
AnchorPeers:
- Host: peer0.processor.food.com
Port: 7051
...Similar configuration of other nodes
docker-compose.yaml
peer0.producer.food.com:
container_name: peer0.producer.food.com
image: hyperledger/fabric-peer:latest
environment:
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=food
- FABRIC_LOGGING_SPEC=DEBUG
- CORE_PEER_NETWORKID=food
- CORE_PEER_TLS_ENABLED=true
- CORE_PEER_PROFILE_ENABLED=true
- CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt
# Peer specific variabes
- CORE_PEER_ID=peer0.producer.food.com
- CORE_PEER_ADDRESS=peer0.producer.food.com:7051
- CORE_PEER_LISTENADDRESS=0.0.0.0:7051
- CORE_PEER_CHAINCODEADDRESS=peer0.producer.food.com:7052
- CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052
- CORE_PEER_ADDRESSAUTODETECT=true
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0.producer.food.com:7051
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.producer.food.com:7051
- CORE_PEER_LOCALMSPID=ProducerMSP
- GODEBUG=netdns=go
volumes:
- /var/run/docker.sock:/host/var/run/docker.sock
- ../fabric/organizations/peerOrganizations/producer.food.com/peers/peer0.producer.food.com/msp:/etc/hyperledger/fabric/msp
- ../fabric/organizations/peerOrganizations/producer.food.com/peers/peer0.producer.food.com/tls:/etc/hyperledger/fabric/tls
- peer0.producer.food.com:/var/hyperledger/production
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: peer node start
ports:
- 7051:7051
networks:
- food
peer0.processor.food.com:
container_name: peer0.processor.food.com
image: hyperledger/fabric-peer:latest
environment:
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=food
- FABRIC_LOGGING_SPEC=DEBUG
- CORE_PEER_NETWORKID=food
- CORE_PEER_TLS_ENABLED=true
- CORE_PEER_PROFILE_ENABLED=true
- CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt
# Peer specific variabes
- CORE_PEER_ID=peer0.processor.food.com
- CORE_PEER_ADDRESS=peer0.processor.food.com:7051
- CORE_PEER_LISTENADDRESS=0.0.0.0:7051
- CORE_PEER_CHAINCODEADDRESS=peer0.processor.food.com:7052
- CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052
- CORE_PEER_ADDRESSAUTODETECT=true
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.processor.food.com:7051
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0.processor.food.com:7051
- CORE_PEER_LOCALMSPID=ProcessorMSP
- GODEBUG=netdns=go
volumes:
- /var/run/docker.sock:/host/var/run/docker.sock
- ../fabric/organizations/peerOrganizations/processor.food.com/peers/peer0.processor.food.com/msp:/etc/hyperledger/fabric/msp
- ../fabric/organizations/peerOrganizations/processor.food.com/peers/peer0.processor.food.com/tls:/etc/hyperledger/fabric/tls
- peer0.processor.food.com:/var/hyperledger/production
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: peer node start
ports:
- 9051:7051
networks:
- food
...Similar configuration of other nodes
config.yaml 用于fabric-sdk-go
:
channels:
food-channel:
peers:
peer0.producer.food.com:
endorsingPeer: true
chaincodeQuery: true
ledgerQuery: true
eventSource: true
peer0.processor.food.com:
endorsingPeer: true
chaincodeQuery: true
ledgerQuery: true
eventSource: true
......
policies:
queryChannelConfig:
minResponses: 1
maxTargets: 1
retryOpts:
attempts: 5
initialBackoff: 500ms
maxBackoff: 5s
backoffFactor: 2.0
discovery:
maxTargets: 1
retryOpts:
attempts: 4
initialBackoff: 500ms
maxBackoff: 5s
backoffFactor: 2.0
eventService:
resolverStrategy: PreferOrg
balancer: Random
blockHeightLagThreshold: 5
reconnectBlockHeightLagThreshold: 10
peerMonitorPeriod: 5s
......
organizations:
producer:
mspid: ProducerMSP
# This org's MSP store (absolute path or relative to client.cryptoconfig)
cryptoPath: peerOrganizations/producer.food.com/users/{username}@producer.food.com/msp
peers:
- peer0.producer.food.com
processor:
mspid: ProcessorMSP
cryptoPath: peerOrganizations/processor.food.com/users/{username}@processor.food.com/msp
peers:
- peer0.processor.food.com
transporter:
mspid: TransporterMSP
......
peers:
peer0.producer.food.com:
url: localhost:7051
grpcOptions:
ssl-target-name-override: peer0.producer.food.com
keep-alive-time: 5s
keep-alive-timeout: 20s
keep-alive-permit: false
fail-fast: false
allow-insecure: false
tlsCACerts:
path: ./fixtures/fabric/organizations/peerOrganizations/producer.food.com/tlsca/tlsca.producer.food.com-cert.pem
......
entityMatchers:
peer:
# the below matcher will allow dynamic discovery to use the anchor peer (peer0.org1.example.com)
# as a template for all org1 discovered peers config
- pattern: (\w+).producer.food.com:(\d+)
urlSubstitutionExp: localhost:7051
sslTargetOverrideUrlSubstitutionExp: ${1}.producer.food.com
mappedHost: peer0.producer.food.com
- pattern: (\w+).processor.food.com:(\d+)
urlSubstitutionExp: localhost:9051
sslTargetOverrideUrlSubstitutionExp: ${1}.processor.food.com
mappedHost: peer0.processor.food.com
- pattern: (\w+).transporter.food.com:(\d+)
urlSubstitutionExp: localhost:7061
sslTargetOverrideUrlSubstitutionExp: ${1}.transporter.food.com
mappedHost: peer0.transporter.food.com
- pattern: (\w+).seller.food.com:(\d+)
urlSubstitutionExp: localhost:7071
sslTargetOverrideUrlSubstitutionExp: ${1}.seller.food.com
mappedHost: peer0.seller.food.com
- pattern: (\w+).consumer.food.com:(\d+)
urlSubstitutionExp: localhost:7081
sslTargetOverrideUrlSubstitutionExp: ${1}.consumer.food.com
mappedHost: peer0.consumer.food.com
orderer:
- pattern: (\w+).food.com:(\d+)
urlSubstitutionExp: localhost:7050
sslTargetOverrideUrlSubstitutionExp: orderer1.food.com
mappedHost: orderer1.food.com
- pattern: (\w+).food.com:(\d+)
urlSubstitutionExp: localhost:7049
sslTargetOverrideUrlSubstitutionExp: orderer2.food.com
mappedHost: orderer2.food.com
- pattern: (\w+).food.com:(\d+)
urlSubstitutionExp: localhost:7048
sslTargetOverrideUrlSubstitutionExp: orderer3.food.com
mappedHost: orderer3.food.com
这个问题困扰我很久了。有人能帮我吗?
我已经找到了这个问题的原因。这是因为从 channel 得到的 endorsers 应该包含在通过 得到的 peers 列表中discovery
,否则会被过滤掉。并且始终只有一个背书节点从通道或discovery
. 所以,除非两者相等,否则背书是不满足的。channel.policies.discovery.retryOpts.attempts
因此,可能需要多次重试才能成功,否则在到达or时将返回错误channel.policies.discovery.retryOpts.maxBackoff
。
现在的问题是,为什么只能从渠道获得或找到一个背书discovery
?我试图通过修改 yaml 中的一些可能的配置来修复它,但都失败了。