Fabric1.4.1 网络在已有组织下新增peer节点
本文关于新的peer节点加入网络的相关操作是基于java版本的sdk进行的。
假设你原本是基于Template创建的节点
修改crypto-config.yaml配置
OrdererOrgs:
# orderer的配置在这里就省略了
- ...
PeerOrgs:
- Name: Org1
Domain: org1.example.com
CA:
Hostname: ca
# 这里原本是2,现在我们新增一个节点,将这里修改为3
Template:
Count: 3
Users:
Count: 1
生成peer节点证书
# 执行命令生成的时候没有打印,要确认是否生成ok,可以使用tree命令查看一下目录结构
# 使用cryptogen工具的extend指令
./bin/cryptogen extend --config=./crypto-config.yaml
环境变量文件
#default env. vars settings
#TLS: etcdraft 模式下必须开启tls(因为有指定各orderer节点的TLS证书)
TLS=true
CLIENT_AUTH_REQUIRED=false
#docker-compose config for setting project name
COMPOSE_PROJECT_NAME=tld
#Image tags - Fabric versions.
#V 1.4.1
IMAGE_TAG_FABRIC=1.4.1
IMAGE_TAG_FABRIC_CA=1.4.1
#log
LOG_LEVEL=INFO
#DNS server address,如果在/etc/hosts中添加了节点映射,这里可以忽略(私有域名服务器地址)
DNS_ADDR_01=192.168.1.111
#other
V11_IDENTITIES_ALLOWREMOVE=--cfg.identities.allowremove
V11_AFFILIATIONS_ALLOWREMOVE=--cfg.affiliations.allowremove
编写peer节点的启动配置
docker-compose-tld-peer3org1.yaml
# 版本
version: '3'
# 网络
networks:
basic:
driver: bridge
# 服务
services:
peer3.org1.example.com:
container_name: peer3.org1.example.com
hostname: peer3.org1.example.com
image: hyperledger/fabric-peer:${IMAGE_TAG_FABRIC}
restart: always
environment:
- CORE_PEER_ID=peer3.org1.example.com
# 云服务器环境下需要加这个配置
- GODEBUG=netdns=go
- CORE_PEER_ADDRESS=peer3.org1.example.com:7051
- CORE_PEER_EVENTS_ADDRESS=0.0.0.0:7053
- CORE_PEER_CHAINCODELISTENADDRESS=peer3.org1.example.com:7052
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer3.org1.example.com:7051
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org1.example.com:7051
- CORE_PEER_LOCALMSPID=Org1MSP
- CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/peer/msp/cacerts/ca.org1.example.com-cert.pem
- CORE_PEER_TLS_CLIENTROOTCAS_FILES=/etc/hyperledger/fabric/peer/msp/tlscacerts/tlsca.org1.example.com-cert.pem
# ---
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=${COMPOSE_PROJECT_NAME}_basic
- FABRIC_LOGGING_SPEC=${LOG_LEVEL}
- CORE_PEER_ENDORSER_ENABLED=true
- CORE_PEER_CHANNELSERVICE_ENABLED=true
- CORE_CHAINCODE_STARTUPTIMEOUT=10m
- CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/peer/msp
- CORE_PEER_GOSSIP_USELEADERELECTION=true
- CORE_PEER_GOSSIP_ORGLEADER=false
- CORE_PEER_PROFILE_ENABLED=false
- CORE_PEER_TLS_ENABLED=${TLS}
- CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/peer/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/peer/tls/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/peer/tls/ca.crt
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: peer node start
volumes:
# 注意同步时间,这里只是同步了时间,还需要注意同步时区
- /etc/localtime:/etc/localtime
- /var/run/:/host/var/run/
- ./crypto-config/peerOrganizations/org1.example.com/peers/peer3.org1.example.com:/etc/hyperledger/fabric/peer:ro
- ./fabric-data/peer3.org1.example.com:/var/hyperledger/production
ports:
- 7051:7051
- 7052:7052
- 7053:7053
networks:
- basic
启动节点
docker-compose -f ./docker-compose-tld-peer3org1.yaml up -d
新节点加入通道
这里需要注意下,hfClient客户端程序中指定的用户是PeerAdmin以及其相关的证书。
这里牵扯的代码比较多,在这里只放一些关键的代码。
@Test
public void newPeerJoinChannel() throws Exception {
Map<String, String> peerLocations = new HashMap<>();
peerLocations.put("peer3.org1.example.com", FabricManager.grpcUrl(true, "x.x.x.x", "7051"));
org1.setPeerLocations(peerLocations);
channelManager.newOrgPeerJoinChannel(org1, admin);
}
public void newOrgPeerJoinChannel(IntermediateOrg org, IntermediateUser user) throws Exception {
// 这里的参数为true的话是特别指定了使用的用户证书是peeradmin的
HFClient client = this.getClient(org, user, true);
// 从store中获取通道,类似cli操作中的channel.block
Channel channel = FabricStore.getChannel(client, channelName);
for (String peerName : org.getPeerNames()) {
String peerLocation = org.getPeerLocation(peerName);
Properties peerProperties = FABRIC_CONFIGURATION.getPeerProperties(peerName);
if (peerProperties == null) {
peerProperties = new Properties();
}
// set specific options on grpc's NettyChannelBuilder
peerProperties.put("grpc.NettyChannelBuilderOption.maxInboundMessageSize", FabricConstant.PEER_PROPERTIES_MAX_INBOUND_MESSAGE_SIZE);
Peer peer = client.newPeer(peerName, peerLocation, peerProperties);
channel.joinPeer(peer, createPeerOptions().setPeerRoles(EnumSet.of(Peer.PeerRole.ENDORSING_PEER,
Peer.PeerRole.LEDGER_QUERY, Peer.PeerRole.CHAINCODE_QUERY, Peer.PeerRole.EVENT_SOURCE)));
logger.debug(format(" Peer %s joined channel %s", peerName, channelName));
}
FabricStore.saveChannel(channel);
}
节点安装链码并升级链码
我们不用人为的选择节点,因为前面的操作依据将新节点包含在channel中了。
如果不想每个节点都去升级,那么也可以单独的对这个节点做安装和实例化操作。
// 安装链码
@Test
public void install() throws Exception {
Map res = chainCodeManager.install();
System.out.println("安装结果:" + res);
}
// 升级链码
@Test
public void upgrade() throws Exception {
String[] args = {"test_007", "100"};
String endorsementFilePath = "src/main/java/fabric/edu/fixture/chaincode/javacc/chaincodeendorsementpolicy.yaml";
Map res = chainCodeManager.upgrade(args, endorsementFilePath);
System.out.println("升级结果:" + res);
}
// 转账
@Test
public void invoke() throws Exception {
String[] args = {"a", "b","100","sign"};
Map res = chainCodeManager.invoke(admin, "move", args);
System.out.println("调用结果:" + res);
}
// 查询链码
@Test
public void query() throws Exception {
String[] args = {"test_007"};
Map res = chainCodeManager.query(admin, "queryAccount", args);
System.out.println("查询结果:" + res);
}