Hyperledger Fabric 2.5.4开发之通道篇[5]
  iwbGD3gmtxyT 2023年11月02日 32 0

Hyperledger Fabric 2.5.4开发之通道篇[5]_Hyperledger

本篇中,我们来分析在一个Fabric网络中添加与删除排序节点的问题。其实,从全局来看,本文中我们主要分析CLI工具osnadmin的channel子命令的如下三项功能:

join:添加新排序节点到通道中

  • list:列出通道中的所有排序节点
  • remove::把指定排序节点从通道中删除

Ordering Service Node (OSN):排序服务节点,对应于CLI命令行工具osnadmin的前三个字母。

此外,本文中还用到peer channel子命令和configtxlator这两个CLI命令行工具。

一、创建初始集群¶

Fabric支持将新的排序节点添加到现有的正常运行的网络中。本篇中,我们将使用官方的测试网络test-network来展示这项功能的一种简单应用场景。

(一)扩展测试网络以支持第五个排序节点¶

我们将扩展docker-compose-bft和crypto-config-order.yaml,以便实现支持5个排序节点。


Q:这两个文件分别位于什么位置?

A:


首先,我们应该在crypto-config-order.yaml配置文件中添加如下内容:

- Hostname: orderer5
  SANS:
    - localhost

在docker-compose-bft中,我们应该在volumes节部分创建一个新卷:

volumes:
  ...
  orderer5.example.com

现在,添加新排序节点的定义:(注意,您可以根据需要更改端口)

orderer5.example.com:
    container_name: orderer5.example.com
    image: hyperledger/fabric-orderer:latest
    labels:
      service: hyperledger-fabric
    environment:
      - FABRIC_LOGGING_SPEC=DEBUG
      - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
      - ORDERER_GENERAL_LISTENPORT=7060
      - ORDERER_GENERAL_LOCALMSPID=OrdererMSP
      - ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp
      # enabled TLS
      - ORDERER_GENERAL_TLS_ENABLED=true
      - ORDERER_GENERAL_TLS_PRIVATEKEY=/var/hyperledger/orderer/tls/server.key
      - ORDERER_GENERAL_TLS_CERTIFICATE=/var/hyperledger/orderer/tls/server.crt
      - ORDERER_GENERAL_TLS_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]
      - ORDERER_GENERAL_CLUSTER_CLIENTCERTIFICATE=/var/hyperledger/orderer/tls/server.crt
      - ORDERER_GENERAL_CLUSTER_CLIENTPRIVATEKEY=/var/hyperledger/orderer/tls/server.key
      - ORDERER_GENERAL_CLUSTER_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]
      - ORDERER_GENERAL_BOOTSTRAPMETHOD=none
      - ORDERER_CHANNELPARTICIPATION_ENABLED=true
      - ORDERER_ADMIN_TLS_ENABLED=true
      - ORDERER_ADMIN_TLS_CERTIFICATE=/var/hyperledger/orderer/tls/server.crt
      - ORDERER_ADMIN_TLS_PRIVATEKEY=/var/hyperledger/orderer/tls/server.key
      - ORDERER_ADMIN_TLS_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]
      - ORDERER_ADMIN_TLS_CLIENTROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]
      - ORDERER_ADMIN_LISTENADDRESS=0.0.0.0:7061
      - ORDERER_OPERATIONS_LISTENADDRESS=orderer5.example.com:9450
      - ORDERER_METRICS_PROVIDER=prometheus
    working_dir: /root
    command: orderer
    volumes:
      - ../organizations/ordererOrganizations/example.com/orderers/orderer5.example.com/msp:/var/hyperledger/orderer/msp
      - ../organizations/ordererOrganizations/example.com/orderers/orderer5.example.com/tls:/var/hyperledger/orderer/tls
      - orderer5.example.com:/var/hyperledger/production/orderer
    ports:
      - 7060:7060
      - 7061:7061
      - 9450:9450
    networks:
      - test

我们还将以下卷添加到CLI容器定义中:

volumes:
  - ../organizations/ordererOrganizations/example.com/users/Admin@example.com/msp:/var/hyperledger/orderer/msp
  - ../organizations/ordererOrganizations/example.com/users/Admin@example.com/tls:/var/hyperledger/orderer/tls

(二)运行集群

使用如下命令:

./network.sh createChannel -bft

此命令将启动一个由4个排序节点、2个Peer节点和1个CLI组成的网络,第五个排序节点的容器也将启动,但在此阶段不属于网络的一部分。该命令还将创建一个名为“mychannel”的通道,4名排序节点和2名Peer节点将参与其中。

二、使用osnadmin CLI将新排序节点添加到测试通道¶

(一)获取最后一个配置块¶

peer命令使用环境变量来定义它将在其中运行的组织的上下文,我们将上下文更改为:

export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG1_CA
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=localhost:7051

export ORDERER_CA=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

为了获得最后一个配置块,我们将进行如下命令:

peer channel fetch config config_block.pb -o orderer.example.com:7050 --ordererTLSHostnameOverride orderer.example.com -c mychannel --tls --cafile "$ORDERER_CA"

(二)将新排序节点添加到通道¶

现在需要将环境变量更新到新的排序节点,并使用新获取的块运行以下命令:

export OSN_TLS_CA_ROOT_CERT=${PWD}/organizations/ordererOrganizations/example.com/tlsca/tlsca.example.com-cert.pem
export ADMIN_TLS_SIGN_CERT=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer5.example.com/tls/server.crt
export ADMIN_TLS_PRIVATE_KEY=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer5.example.com/tls/server.key

osnadmin channel join --channelID [CHANNEL_NAME]  --config-block [CHANNEL_CONFIG_BLOCK] -o [ORDERER_ADMIN_LISTENADDRESS] --ca-file $OSN_TLS_CA_ROOT_CERT --client-cert $ADMIN_TLS_SIGN_CERT --client-key $ADMIN_TLS_PRIVATE_KEY

进行如下替换:

  • CHANNEL_NAME:修改成您要调用此通道的名称。
  • CHANNEL_CONFIG_BLOCK:带有创世区块或最新配置块的路径和文件名。
  • ORDEER_ADMIN_LISTENADDRESS:对应于在ORDERER.yaml中为此排序节点定义的ORDERER.ADMIN.LISTENADDRESS。
  • OSN_TLS_CA_ROOT_CERT:其中包含排序组织TLS CA根证书和中间证书(如果使用中间TLS CA)的路径和文件名。
  • ADMIN_TLS_SIGN_CERT:其中包含来自TLS CA的管理员客户端签名证书的路径和文件名。
  • ADMIN_TLS_PRIVATE_KEY:其中包含TLS CA的管理客户端私钥的路径和文件名。

例如:

osnadmin channel join --channelID mychannel --config-block config_block.pb -o localhost:7061 --ca-file "$OSN_TLS_CA_ROOT_CERT" --client-cert "$ADMIN_TLS_SIGN_CERT" --client-key "$ADMIN_TLS_PRIVATE_KEY"

注意:由于osnadmin CLI和排序节点之间的连接需要双向TLS,因此需要在每个osadmin命令上传递--client cert和--client密钥参数。--client cert参数指向管理客户端证书,--client密钥指的是管理客户端私钥,两者都由管理客户端TLS CA颁发。

此命令的输出类似如下:

Status: 201
{
    "name": "mychannel",
    "url": "/participation/v1/channels/mychannel",
    "consensusRelation": "follower",
    "status": "onboarding",
    "height": 0
}

三、更改配置¶

以下命令应在CLI容器中执行。

(一)将块转换为JSON¶

使用上一节中提取的块,为了更改它,首先将块转换为JSON:

configtxlator proto_decode --input config_block.pb --type common.Block --output config_block.json

然后,从JSON块中提取配置:

jq .data.data[0].payload.data.config config_block.json > original_config.json

(二)将第五个排序节点添加到配置¶

此阶段的输出是更新交易,您可以从CLI容器计算交易,或者复制original_config.json并在本地计算机上进行所有更改。

创建一个名为modified_config.json的original_config.json副本。在新的json文件中,我们需要做4个更改:

1.将排序节点添加到已知端点¶

找到channel_group → groups → Orderer → groups → OrdererOrg → values → Endpoints → value → addresses位置处,添加如下所示的排序端点:

[
    "orderer.example.com:7050",
    "orderer2.example.com:7052",
    "orderer3.example.com:7056",
    "orderer4.example.com:7058",
    "orderer5.example.com:7060"
]

2.将排序节点添加到已知身份¶

转到channel_group → groups → Orderer → policies → BlockValidation → policy → value → identities处,添加身份证书的base64编码,请根据您的需要更正路径。

{
    "principal": {
          "id_bytes": ".../test-network/organizations/ordererOrganizations/example.com/orderers/orderer5.example.com/msp/signcerts/orderer5.example.com-cert.pem",
          "mspid": "OrdererMSP"
    },
    "principal_classification": "IDENTITY"
}

3.将排序节点添加到策略规则¶

转到channel_group → groups → Orderer → policies → BlockValidation → policy → value → rule,把n修改成:

# Given that the new number of nodes in cluster is num_of_nodes:
f = int((num_of_nodes - 1) / 3)
n = ceil((num_of_nodes + f + 1) / 2)

并为新排序节点添加一个signed_by对象:

{
  "n_out_of": {
    "n": 4,
    "rules": [
      {
        "signed_by": 0
      },
      {
        "signed_by": 1
      },
      {
        "signed_by": 2
      },
      {
        "signed_by": 3
      },
      {
        "signed_by": 4
      }
    ]
  }
}

4.将排序节点添加到共识映射¶

转到channel_group → groups → Orderer → values → Orderers → value → consenter_mapping位置,并添加身份、客户端TLS和服务器TLS证书的base64编码,请根据您的需要更正路径。

{
    "client_tls_cert": ".../test-network/organizations/ordererOrganizations/example.com/orderers/orderer5.example.com/msp/tlscacerts/tlsca.example.com-cert.pem",
    "host": "orderer5.example.com",
    "id": 5,
    "identity": ".../test-network/organizations/ordererOrganizations/example.com/orderers/orderer5.example.com/msp/signcerts/orderer5.example.com-cert.pem",
    "msp_id": "OrdererMSP",
    "port": 7060,
    "server_tls_cert": ".../test-network/organizations/ordererOrganizations/example.com/orderers/orderer5.example.com/msp/tlscacerts/tlsca.example.com-cert.pem"
}

我们简化了这个过程,并创建了一个Python脚本,该脚本可以在脚本子文件夹中找到(步骤1-4)!脚本用法示例:

python3 scripts/add_new_orderer_to_config.py original_config.json modified_config.json \
-a orderer5.example.com:7060 \
-i ./organizations/ordererOrganizations/example.com/orderers/orderer5.example.com/msp/signcerts/orderer5.example.com-cert.pem \
-s ./organizations/ordererOrganizations/example.com/orderers/orderer5.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
-c ./organizations/ordererOrganizations/example.com/orderers/orderer5.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

使用以下方法计算更新:

configtxlator proto_encode --input original_config.json --type common.Config --output original_config.pb
configtxlator proto_encode --input modified_config.json --type common.Config --output modified_config.pb
configtxlator compute_update --channel_id mychannel --original original_config.pb --updated modified_config.pb --output config_update.pb
configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate --output config_update.json
echo '{"payload":{"header":{"channel_header":{"channel_id":"mychannel", "type":2}},"data":{"config_update":'$(cat config_update.json)'}}}' | jq . >config_update_in_envelope.json
configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope --output envelope.pb

envelope.pb是配置更新交易,请注意,它不包含任何路径,如果它是在本地计算机上创建的,请将其复制到CLI容器中。

Hyperledger Fabric 2.5.4开发之通道篇[5]_通道_02

进行更新¶

通过CLI方式,我们需要使用组织的Peer节点之一和排序组织来签署交易。由于我们处于Peer组织Org1的背景下,我们可以简单地:

peer channel signconfigtx -f envelope.pb

现在,我们切换到排序组织Orderer

export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="OrdererMSP"
export CORE_PEER_TLS_ROOTCERT_FILE=/var/hyperledger/orderer/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/var/hyperledger/orderer/msp
export CORE_PEER_ADDRESS=localhost:7050

现在,我们开始更新排序节点:

peer channel update -o orderer.example.com:7050 --ordererTLSHostnameOverride orderer.example.com -c mychannel -f envelope.pb --tls --cafile "$ORDERER_CA"

此命令的输出类似于:

INFO [channelCmd] InitCmdFactory -> Endorser and orderer connections initialized
INFO [channelCmd] update -> Successfully submitted channel update

您还可以使用以下命令来确认添加的排序节点的状态:

osnadmin channel list --channelID mychannel -o localhost:7061 --ca-file "$OSN_TLS_CA_ROOT_CERT" --client-cert "$ADMIN_TLS_SIGN_CERT" --client-key "$ADMIN_TLS_PRIVATE_KEY"

此时,应该看到类似于以下输出的内容,即添加的排序节点的consensusRelation状态自动更改为conseter:

{
        "name": "mychannel",
        "url": "/participation/v1/channels/mychannel",
        "consensusRelation": "consenter",
        "status": "active",
        "height": 4
}

您应该在新的排序节点日志中看到类似于以下的内容:

DEBU [orderer.consensus.smartbft.consensus] ProcessMessages -> 5 got message from 1: <HeartBeat with view: 0, seq: 7 channel=mychannel
DEBU [orderer.consensus.smartbft.consensus] handleHeartBeat -> Received heartbeat from 1, last heartbeat was 5.995614586s ago channel=mychannel
DEBU [orderer.consensus.smartbft.consensus] followerTick -> Last heartbeat from 1 was 1.000437542s ago channel=mychannel
DEBU [orderer.consensus.smartbft.consensus] followerTick -> Last heartbeat from 1 was 2.003549876s ago channel=mychannel
DEBU [orderer.consensus.smartbft.consensus] followerTick -> Last heartbeat from 1 was 3.00110746s ago channel=mychannel
DEBU [orderer.consensus.smartbft.consensus] followerTick -> Last heartbeat from 1 was 3.99966021s ago channel=mychannel
DEBU [orderer.consensus.smartbft.consensus] followerTick -> Last heartbeat from 1 was 5.000054669s ago channel=mychannel
DEBU [orderer.consensus.smartbft.consensus] followerTick -> Last heartbeat from 1 was 5.999811586s ago channel=mychannel

注:您可以在官方网站的此处进一步了解osnadmin这个CLI命令行工具。

从现有网络中删除排序节点¶

切换到Peer组织:

export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID=Org1MSP
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/organizations/peerOrganizations/org1.example.com/tlsca/tlsca.org1.example.com-cert.pem
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=localhost:7051

使用以下方法获取最后一个块:

peer channel fetch config config_block.pb -o orderer.example.com:7050 --ordererTLSHostnameOverride orderer.example.com -c mychannel --tls --cafile "$ORDERER_CA"

将其转换为JSON:

configtxlator proto_decode --input config_block.pb --type common.Block --output config_block.json
jq .data.data[0].payload.data.config config_block.json > original_config.json

现在,从JSON中删除新的orderer(按照与上一节相反的顺序),并将其保存为modified_config.JSON。

现在计算更新:

echo '{"payload":{"header":{"channel_header":{"channel_id":"mychannel", "type":2}},"data":{"config_update":'$(cat config_update.json)'}}}' | jq . >config_update_in_envelope.json
configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope --output envelope.pb

然后,使用Peer组织进行签名:

peer channel signconfigtx -f envelope.pb

现在切换到排序组织并发布:

export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="OrdererMSP"
export CORE_PEER_TLS_ROOTCERT_FILE=/var/hyperledger/orderer/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/var/hyperledger/orderer/msp
export CORE_PEER_ADDRESS=localhost:7050
peer channel update -o orderer.example.com:7050 --ordererTLSHostnameOverride orderer.example.com -c mychannel -f envelope.pb --tls --cafile "$ORDERER_CA"

结果应该成为:

INFO [channelCmd] InitCmdFactory -> Endorser and orderer connections initialized
INFO [channelCmd] update -> Successfully submitted channel update

现在,让我们使用以下命令从通道中删除排序节点即可:

osnadmin channel remove -o localhost:7061 --ca-file "$ORDERER_CA" --client-cert "$ORDERER_ADMIN_TLS_SIGN_CERT" --client-key "$ORDERER_ADMIN_TLS_PRIVATE_KEY" --channelID mychannel

结果应该成为:

Status: 204

您应该在排序节点日志中看到类似于以下的内容:

INFO [orderer.consensus.smartbft.chain] Halt -> Shutting down chain channel=mychannel
INFO [orderer.consensus.smartbft.consensus] func1 -> Exiting channel=mychannel
INFO [orderer.consensus.smartbft.consensus] func1 -> Exiting channel=mychannel
INFO [orderer.common.multichannel] removeMember -> Removed channel: mychannel


重要引用



【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
iwbGD3gmtxyT