2. 版本升级说明

2.1. 概述

本文档主要描述将旧版本chainmaker升级为新版本的步骤,正常情况下,伴随着新版发布,都会有相应的升级描述。本文档根据版本号倒序排版,即最新版本升级描述会在最前面,请读者注意。

1.2.x升级到2.x版本需要先迁移到2.2.1版本。

2.3.0以前的版本想要升级到2.3.0以后,需要先升级到2.3.0过度。

说明:升级时尽量采用逐个版本升级的方式,尽量不要一次性跳跃升级。

2.2. v2.3.7 -> v2.3.8版本升级指南

⚠️ 升级前必读:本版本升级涉及两项关键操作,请务必仔细阅读并按顺序执行:

1. 处理历史数据库数据格式变更

本版本对HistoryDB的数据格式进行了修改,新版本无法读取旧版本存储的历史数据。需要根据您的业务需求选择合适的升级方案(详见下方HistoryDB数据格式变更说明)。

2. 清理布隆过滤器文件

如果您的配置中启用了布隆过滤器,需要在升级前手动删除布隆过滤器文件(详见下方布隆过滤器文件清理)。

2.2.1. HistoryDB数据格式变更说明

重要提示:本版本对HistoryDB(历史数据库)的数据格式进行了修改,新版本无法读取旧版本存储的历史数据

2.2.1.1. 变更说明

本版本修复了历史数据库在数据存储方面存在的问题,主要包括:

  1. 修复数据存储顺序问题:旧版本中,历史数据的存储格式存在设计缺陷,导致按状态变更、账户或合约查询历史记录时可能出现顺序错乱。本版本修正了键格式,确保历史记录按区块高度正确排序。

  2. 统一账户地址表示:旧版本中,使用不同方式(证书、哈希、别名等)的账户,其历史记录存储方式不一致,导致同一账户的历史数据可能分散存储。本版本统一了账户格式,确保同一账户的所有历史记录集中存储。

2.2.1.2. 数据不兼容的影响

由于上述变更,升级后会出现以下情况:

  1. 旧历史数据无法查询:升级前存储的历史数据(账户交易历史、合约调用历史、状态变更历史)将无法被新版本正确解析和查询

  2. 新历史数据正常写入:升级后新产生的交易历史数据将使用新格式正常存储

  3. 不影响其他功能:区块数据、状态数据、结果数据等其他账本数据不受影响

2.2.1.3. 升级方案

前提条件:以下升级方案仅适用于启用了历史数据库(disable_historydb: false)的场景。如果您已禁用历史数据库(disable_historydb: true),则无需处理历史数据,直接按照常规升级流程操作即可。

根据您的业务需求,选择以下方案之一:

2.2.1.4. 方案一:使用运维工具离线重建数据(推荐)

适用于需要不停机升级或保留历史数据的场景。具体步骤如下:

  1. 使用运维工具对历史数据进行离线重建(工具使用方法请参考运维工具文档)

  2. 重建完成后,根据您使用的数据库类型修改节点配置文件(chainmaker.yml)中的历史数据库配置:

    ⚠️ 重要:配置的数据路径或数据库须与运维工具重建的数据路径/库保持一致,否则会导致数据逻辑错误。

    KV数据库(LevelDB/BadgerDB)

    修改 store_path 指向重建后的数据目录:

    historydb_config:
      provider: leveldb
      leveldb_config:
        store_path: ../data/{org_id}/history_new  # 修改为重建后的数据目录
    

    SQL数据库(MySQL等)

    如果重建后的数据,可通过配置 db_prefix 来切换到新数据库:

    historydb_config:
      provider: sqlkv  # 或 sql
      sqldb_config:
        sqldb_type: mysql
        dsn: root:password@tcp(127.0.0.1:3306)/ 
        db_prefix: "new_"  # 添加前缀,新数据库将在原数据库名前加上此前缀
    

    说明db_prefix 会在原数据库名前添加前缀生成新的数据库名。例如,原数据库为 chainmaker_history,设置 db_prefix: "new_" 后,将使用 new_chainmaker_history 数据库。请确保 db_prefix 与运维工具重建时使用的前缀保持一致。

  3. 停止节点

  4. 替换二进制文件为新版本

  5. 启动节点

2.2.1.5. 方案二:清空历史数据库(需要等待历史数据恢复完成,影响节点提供服务时间)

可以直接清空历史数据库,节点启动后会自动恢复数据。具体步骤如下:

  1. 停止节点

  2. 清空历史数据库:

    • LevelDB/BadgerDB:删除配置文件中 store_path 指向的 history 目录

    • MySQL/SQL数据库:清空或删除历史数据相关库/表

  3. 替换二进制文件为新版本

  4. 启动节点,节点将自动恢复历史数据

重要说明

  • 节点启动后,会根据区块数据自动重建历史数据索引

  • 恢复过程中节点不可提供正常服务,需等待历史数据恢复完成后才能正常对外提供服务

  • 恢复时间取决于历史数据量的大小,数据量越大恢复时间越长,请提前评估数据量和恢复时间,合理安排升级窗口期

2.2.1.6. 注意事项

  1. 升级前请务必备份数据

  2. 建议在测试环境验证升级流程后再在生产环境执行

  3. 如果您禁用了部分历史数据类型(如 disable_key_history: truedisable_contract_history: truedisable_account_history: true),则对应类型的历史数据不受影响

2.2.2. 布隆过滤器文件清理

需要注意,如果您的配置中已启用布隆过滤器(storage.statedb_config.bloom_config.enable: true),由于 2.3.7 之前版本的布隆过滤器存在假阴性概率,为确保数据正确性,在版本升级前,您务必手动删除布隆过滤器文件,文件路径由配置项 bloom_config.dump_path指定。

配置参考如下

storage:
  # State db config
  statedb_config:
    provider: leveldb
    leveldb_config:
      store_path: ../data/{org_id}/state
      write_buffer_size: 64

    # bloom config for state db, it only takes effect when using kvdb
    bloom_config:
      enable: true # enable bloom filter or not
      dump_path: "../data/{org_id}/state/bloom" # bloom filter data dump to file in the path
      # bloom filter calculates the number of enabled hash functions and the number of bits used
      # based on the key capacity and false positive rate.
      keys_capacity: 1000000000
      false_positive_rate: 0.01
      dump_per_blocks_committed: 1000 # do dump every n blocks added to bloom filter

2.2.3. 平滑升级

请参考 v2.3.4 -> v2.3.5版本升级指南。

如果您使用vm-engine镜像,请更新chainmakerofficial/chainmaker-vm-engine,命令如下:

docker pull chainmakerofficial/chainmaker-vm-engine:v2.3.7

2.3. v2.3.6 -> v2.3.7版本升级指南

请参考 v2.3.4 -> v2.3.5版本升级指南。需要注意,对于cgroup v1的环境,chainmaker-vm-engine版本与v2.3.5一致即可,也无需更新start.sh启动脚本,其他步骤不变。对于cgroup v2的环境,则需使用最新的start.sh启动脚本,并使用chainmaker-vm-engine的v2.3.6版本镜像,该版本在v2.3.5的基础上,增加了对cgroup v2环境的支持。

如果您需要更新vm-engine镜像,请更新chainmakerofficial/chainmaker-vm-engine,命令如下:

docker pull chainmakerofficial/chainmaker-vm-engine:v2.3.6

2.4. v2.3.5 -> v2.3.6版本升级指南

直接参考 v2.3.4 -> v2.3.5版本升级指南即可,chainmaker-vm-engine版本与v2.3.5一致。

2.5. v2.3.4 -> v2.3.5版本升级指南

2.5.1. 平滑升级

从v2.3.1版开始,支持了区块链网络的平滑升级,逐个将区块链网络中的节点升级为新版本,而在升级过程中区块链网络始终保持正常的接收交易和打包区块。 从v2.3.4平滑升级v2.3.5具体操作步骤如下:

1.查看链配置,确保链版本为v2.3.4

使用cmc的链配置查看命令,查看当前链配置的版本(此时二进制文件还没有替换

./cmc client chainconfig query \
--sdk-conf-path=./testdata/sdk_config.yml

其中返回的”version”字段如果是”2030400”则直接进入下一步,如果不是,则需要通过之前的版本升级方式先升级至v2.3.4版本。

2.停止并替换二进制

如果您需要保持区块链网络的持续运行,可以修改客户端连接,将交易发送到另一个节点,然后使用stop.sh停止一个节点(需要停止虚拟机),然后替换二进制。如果是基于Docker或者K8s则停用容器或Pod,然后更新Docker镜像为v2.3.5版本。

3.升级 Docker Go 虚拟机

如果您使用vm-engine镜像,请更新chainmakerofficial/chainmaker-vm-engine,命令如下:

docker pull chainmakerofficial/chainmaker-vm-engine:v2.3.5

如果您使用vm-docker-go镜像,请更新chainmakerofficial/chainmaker-vm-docker-go,命令如下:

docker pull chainmakerofficial/chainmaker-vm-docker-go:v2.3.1

4.启动节点和Docker Go虚拟机

如果您使用了Docker Go虚拟机:

  • 如果Docker Go是本机部署,需要同时替换下bin目录下的start.sh脚本,脚本会处理新合约虚拟机的拉起和停止。脚本由build_release.sh生成,可以参考《编译和安装包制作》

  • 如果Docker Go是独立部署(比如部署在其他host),可以参考《独立部署DockerVM》

重新执行start.sh脚本启动节点(需要启动虚拟机)。

5.逐个替换所有节点的二进制和DockerGo虚拟机

针对链中的每一个共识节点和同步节点,逐个执行步骤2、3、4的操作,也就是行:停止->替换->启动 操作,确保所有节点都已经升级为最新版本。

6.更新链配置,设置链版本为2030500

当所有共识节点都升级完二进制后,使用cmc更新链配置version到最新的2030500

./cmc client contract user invoke \
--contract-name=CHAIN_CONFIG \
--method=UPDATE_VERSION \
--params="{\"block_version\":\"2030500\"}" \
--sdk-conf-path=./testdata/sdk_config.yml \
--sync-result=true \
--admin-key-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.sign.key,./testdata/crypto-config/wx-org2.chainmaker.org/user/admin1/admin1.sign.key,./testdata/crypto-config/wx-org3.chainmaker.org/user/admin1/admin1.sign.key \
--admin-crt-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.sign.crt,./testdata/crypto-config/wx-org2.chainmaker.org/user/admin1/admin1.sign.crt,./testdata/crypto-config/wx-org3.chainmaker.org/user/admin1/admin1.sign.crt

7.检查升级是否成功

更新链配置后,正常发起业务交易,系统会打包新区块,通过cmc查询最新区块,关注header中的block_version字段,如果该值为2030500,则说明平滑升级成功。

./cmc query block-by-height  --sdk-conf-path=./testdata/sdk_config.yml

2.6. v2.3.3 -> v2.3.4版本升级指南

2.6.1. 平滑升级

从v2.3.1版开始,支持了区块链网络的平滑升级,逐个将区块链网络中的节点升级为新版本,而在升级过程中区块链网络始终保持正常的接收交易和打包区块。 从v2.3.3平滑升级v2.3.4具体操作步骤如下:

1.查看链配置,确保链版本为v2.3.3

使用cmc的链配置查看命令,查看当前链配置的版本(此时二进制文件还没有替换

./cmc client chainconfig query \
--sdk-conf-path=./testdata/sdk_config.yml

其中返回的”version”字段如果是”2030300”则直接进入下一步,如果不是,则需要通过之前的版本升级方式先升级至v2.3.3版本。

2.停止并替换二进制

如果您需要保持区块链网络的持续运行,可以修改客户端连接,将交易发送到另一个节点,然后使用stop.sh停止一个节点(需要停止虚拟机),然后替换二进制。如果是基于Docker或者K8s则停用容器或Pod,然后更新Docker镜像为v2.3.4版本。

3.升级 Docker Go 虚拟机

如果您使用vm-engine镜像,请更新chainmakerofficial/chainmaker-vm-engine,命令如下:

docker pull chainmakerofficial/chainmaker-vm-engine:v2.3.4

如果您使用vm-docker-go镜像,请更新chainmakerofficial/chainmaker-vm-docker-go,命令如下:

docker pull chainmakerofficial/chainmaker-vm-docker-go:v2.3.1

4.启动节点和Docker Go虚拟机

如果您使用了Docker Go虚拟机:

  • 如果Docker Go是本机部署,需要同时替换下bin目录下的start.sh脚本,脚本会处理新合约虚拟机的拉起和停止。脚本由build_release.sh生成,可以参考《编译和安装包制作》

  • 如果Docker Go是独立部署(比如部署在其他host),可以参考《独立部署DockerVM》

重新执行start.sh脚本启动节点(需要启动虚拟机)。

5.逐个替换所有节点的二进制和DockerGo虚拟机

针对链中的每一个共识节点和同步节点,逐个执行步骤2、3、4的操作,也就是行:停止->替换->启动 操作,确保所有节点都已经升级为最新版本。

6.更新链配置,设置链版本为2030400

当所有共识节点都升级完二进制后,使用cmc更新链配置version到最新的2030400

./cmc client contract user invoke \
--contract-name=CHAIN_CONFIG \
--method=UPDATE_VERSION \
--params="{\"block_version\":\"2030400\"}" \
--sdk-conf-path=./testdata/sdk_config.yml \
--sync-result=true \
--admin-key-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.sign.key,./testdata/crypto-config/wx-org2.chainmaker.org/user/admin1/admin1.sign.key,./testdata/crypto-config/wx-org3.chainmaker.org/user/admin1/admin1.sign.key \
--admin-crt-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.sign.crt,./testdata/crypto-config/wx-org2.chainmaker.org/user/admin1/admin1.sign.crt,./testdata/crypto-config/wx-org3.chainmaker.org/user/admin1/admin1.sign.crt

7.检查升级是否成功

更新链配置后,正常发起业务交易,系统会打包新区块,通过cmc查询最新区块,关注header中的block_version字段,如果该值为2030400,则说明平滑升级成功。

./cmc query block-by-height  --sdk-conf-path=./testdata/sdk_config.yml

2.7. v2.3.2 -> v2.3.3版本升级指南

2.7.1. 平滑升级

从v2.3.1版开始,支持了区块链网络的平滑升级,逐个将区块链网络中的节点升级为新版本,而在升级过程中区块链网络始终保持正常的接收交易和打包区块。 理论上可以由v2.3.1版本直接升级为v2.3.3版本,但稳妥起见,建议先从v2.3.1升级到v2.3.2,再由v2.3.2升级至v2.3.3。

从v2.3.2平滑升级v2.3.3具体操作步骤如下:

1.更新链配置,确保链版本为v2.3.2

使用cmc的链配置查看命令,查看当前链配置的版本(此时二进制文件还没有替换

./cmc client chainconfig query \
--sdk-conf-path=./testdata/sdk_config.yml

其中返回的”version”字段如果是”2030200”则直接进入下一步,如果不是,则需要执行以下命令修改链配置中的版本:

./cmc client contract user invoke \
--contract-name=CHAIN_CONFIG \
--method=UPDATE_VERSION \
--params="{\"block_version\":\"2030200\"}" \
--sdk-conf-path=./testdata/sdk_config.yml \
--sync-result=true \
--admin-key-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.sign.key,./testdata/crypto-config/wx-org2.chainmaker.org/user/admin1/admin1.sign.key,./testdata/crypto-config/wx-org3.chainmaker.org/user/admin1/admin1.sign.key \
--admin-crt-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.sign.crt,./testdata/crypto-config/wx-org2.chainmaker.org/user/admin1/admin1.sign.crt,./testdata/crypto-config/wx-org3.chainmaker.org/user/admin1/admin1.sign.crt

执行成功后可以再次查询链配置中的version字段,确保version值为 “2030200”。

3.停止并替换二进制

如果您需要保持区块链网络的持续运行,可以修改客户端连接,将交易发送到另一个节点,然后使用stop.sh停止一个节点(需要停止虚拟机),然后替换二进制。如果是基于Docker或者K8s则停用容器或Pod,然后更新Docker镜像为v2.3.3版本。

4.升级 Docker Go 虚拟机

如果您使用vm-engine镜像,请更新chainmakerofficial/chainmaker-vm-engine,命令如下:

docker pull chainmakerofficial/chainmaker-vm-engine:v2.3.3

如果您使用vm-docker-go镜像,请更新chainmakerofficial/chainmaker-vm-docker-go(理论上是没有变化的,但建议更新),命令如下:

docker pull chainmakerofficial/chainmaker-vm-docker-go:v2.3.1

5.启动节点和Docker Go虚拟机

如果您使用了Docker Go虚拟机:

  • 如果Docker Go是本机部署,需要同时替换下bin目录下的start.sh脚本,脚本会处理新合约虚拟机的拉起和停止。脚本由build_release.sh生成,可以参考《编译和安装包制作》

  • 如果Docker Go是独立部署(比如部署在其他host),可以参考《独立部署DockerVM》

storage:
  statedb_config: #StateDB 数据库配置
    provider: sqlkv  #数据库类型,支持LevelDB,BadgerDB,TikvDB,Mysql,这里示例为Mysql, 优先推荐使用'sqlkv'代替 'sql'
    # 或者 provider: sql
    sqldb_config: #SQL数据库的详细配置
      sqldb_type:  mysql #具体的RDBMS为mysql,也可以是sqlite、mssql等
      dsn:  root:password@tcp(127.0.0.1:3306)/ #MySQL的数据库连接字符串
      max_idle_conns: 10  #连接池中维持的最大的空闲连接数,默认为10
      max_open_conns: 10  #最大的可用连接数,默认为10
      conn_max_lifetime: 60  #连接维持的最长时间,单位秒,默认为60
  

配置完成后, 重新执行start.sh脚本启动节点(需要启动虚拟机)。

6.逐个替换所有节点的二进制和DockerGo虚拟机

针对链中的每一个共识节点和同步节点,逐个执行步骤2、3、4的操作,也就是行:停止->替换->启动 操作,确保所有节点都已经升级为最新版本。

7.更新链配置,设置链版本为2030300

当所有共识节点都升级完二进制后,使用cmc更新链配置version到最新的2030300

./cmc client contract user invoke \
--contract-name=CHAIN_CONFIG \
--method=UPDATE_VERSION \
--params="{\"block_version\":\"2030300\"}" \
--sdk-conf-path=./testdata/sdk_config.yml \
--sync-result=true \
--admin-key-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.sign.key,./testdata/crypto-config/wx-org2.chainmaker.org/user/admin1/admin1.sign.key,./testdata/crypto-config/wx-org3.chainmaker.org/user/admin1/admin1.sign.key \
--admin-crt-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.sign.crt,./testdata/crypto-config/wx-org2.chainmaker.org/user/admin1/admin1.sign.crt,./testdata/crypto-config/wx-org3.chainmaker.org/user/admin1/admin1.sign.crt

8.检查升级是否成功

更新链配置后,正常发起业务交易,系统会打包新区块,通过cmc查询最新区块,关注header中的block_version字段,如果该值为2030300,则说明平滑升级成功。

./cmc query block-by-height  --sdk-conf-path=./testdata/sdk_config.yml

2.8. v2.3.1 -> v2.3.2版本升级指南

2.8.1. 平滑升级

从v2.3.1版开始,支持了区块链网络的平滑升级,逐个将区块链网络中的节点升级为新版本,而在升级过程中区块链网络始终保持正常的接收交易和打包区块。从v2.3.1平滑升级v2.3.2具体操作步骤如下:

1.更新链配置,确保链版本为v2.3.1

使用cmc的链配置查看命令,查看当前链配置的版本(此时二进制文件还没有替换

./cmc client chainconfig query \
--sdk-conf-path=./testdata/sdk_config.yml

其中返回的”version”字段如果是”2030100”则直接进入下一步,如果不是,则需要执行以下命令修改链配置中的版本:

./cmc client contract user invoke \
--contract-name=CHAIN_CONFIG \
--method=UPDATE_VERSION \
--params="{\"block_version\":\"2030100\"}" \
--sdk-conf-path=./testdata/sdk_config.yml \
--sync-result=true \
--admin-key-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.sign.key,./testdata/crypto-config/wx-org2.chainmaker.org/user/admin1/admin1.sign.key,./testdata/crypto-config/wx-org3.chainmaker.org/user/admin1/admin1.sign.key \
--admin-crt-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.sign.crt,./testdata/crypto-config/wx-org2.chainmaker.org/user/admin1/admin1.sign.crt,./testdata/crypto-config/wx-org3.chainmaker.org/user/admin1/admin1.sign.crt

执行成功后可以再次查询链配置中的version字段,确保version值为 “2030100”。

2.停止并替换二进制

如果您需要保持区块链网络的持续运行,可以修改客户端连接,将交易发送到另一个节点,然后使用stop.sh停止一个节点(需要停止虚拟机),然后替换二进制。如果是基于Docker或者K8s则停用容器或Pod,然后更新Docker镜像为v2.3.2版本。

3.升级 Docker Go 虚拟机

如果您使用vm-engine镜像,请更新chainmakerofficial/chainmaker-vm-engine,命令如下:

docker pull chainmakerofficial/chainmaker-vm-engine:v2.3.2

如果您使用vm-docker-go镜像,请更新chainmakerofficial/chainmaker-vm-docker-go,命令如下:

docker pull chainmakerofficial/chainmaker-vm-docker-go:v2.3.1

4.启动节点和Docker Go虚拟机

如果您使用了Docker Go虚拟机:

  • 如果Docker Go是本机部署,需要同时替换下bin目录下的start.sh脚本,脚本会处理新合约虚拟机的拉起和停止。脚本由build_release.sh生成,可以参考《编译和安装包制作》

  • 如果Docker Go是独立部署(比如部署在其他host),可以参考《独立部署DockerVM》

重新执行start.sh脚本启动节点(需要启动虚拟机)。

5.逐个替换所有节点的二进制和DockerGo虚拟机

针对链中的每一个共识节点和同步节点,逐个执行步骤2、3、4的操作,也就是行:停止->替换->启动 操作,确保所有节点都已经升级为最新版本。

6.更新链配置,设置链版本为2030200

当所有共识节点都升级完二进制后,使用cmc更新链配置version到最新的2030200

./cmc client contract user invoke \
--contract-name=CHAIN_CONFIG \
--method=UPDATE_VERSION \
--params="{\"block_version\":\"2030200\"}" \
--sdk-conf-path=./testdata/sdk_config.yml \
--sync-result=true \
--admin-key-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.sign.key,./testdata/crypto-config/wx-org2.chainmaker.org/user/admin1/admin1.sign.key,./testdata/crypto-config/wx-org3.chainmaker.org/user/admin1/admin1.sign.key \
--admin-crt-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.sign.crt,./testdata/crypto-config/wx-org2.chainmaker.org/user/admin1/admin1.sign.crt,./testdata/crypto-config/wx-org3.chainmaker.org/user/admin1/admin1.sign.crt

7.检查升级是否成功

更新链配置后,正常发起业务交易,系统会打包新区块,通过cmc查询最新区块,关注header中的block_version字段,如果该值为2030200,则说明平滑升级成功。

./cmc query block-by-height  --sdk-conf-path=./testdata/sdk_config.yml

2.8.2. 新系统合约的启用

在本次v2.3.2的版本升级中,增加交易黑名单新特性,如果您考虑使用该功能,在完成了上述的平滑升级后,可以通过以下命令初始化之前版本中没有初始化的系统合约:

./cmc client contract user invoke \
--contract-name=CONTRACT_MANAGE \
--method=INIT_NEW_NATIVE_CONTRACT \
--sdk-conf-path=./testdata/sdk_config.yml \
--sync-result=true \
--result-to-string=true

本命令返回的message是OK,则说明新系统合约初始化成功。

2.9. v2.3.0 -> v2.3.1版本升级指南

2.9.1. 平滑升级

在之前的版本中,要进行版本升级需要将所有节点停止,然后进行二进制替换和配置修改,会造成业务服务的中断,从v2.3.1版开始,将支持了区块链网络的平滑升级,逐个将区块链网络中的节点升级为新版本,而在升级过程中区块链网络始终保持正常的接收交易和打包区块。平滑升级具体操作步骤如下:

1.更新链配置,确保链版本为v2.3.0

使用cmc的链配置查看命令,查看当前链配置的版本(此时二进制文件还没有替换

./cmc client chainconfig query \
--sdk-conf-path=./testdata/sdk_config.yml

其中返回的”version”字段如果是”v2.3.0”则直接进入下一步,如果不是,则需要执行以下命令修改链配置中的版本:

./cmc client contract user invoke \
--contract-name=CHAIN_CONFIG \
--method=UPDATE_VERSION \
--params="{\"block_version\":\"2301\"}" \
--sdk-conf-path=./testdata/sdk_config.yml \
--sync-result=true \
--admin-key-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.sign.key,./testdata/crypto-config/wx-org2.chainmaker.org/user/admin1/admin1.sign.key,./testdata/crypto-config/wx-org3.chainmaker.org/user/admin1/admin1.sign.key \
--admin-crt-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.sign.crt,./testdata/crypto-config/wx-org2.chainmaker.org/user/admin1/admin1.sign.crt,./testdata/crypto-config/wx-org3.chainmaker.org/user/admin1/admin1.sign.crt

执行成功后可以再次查询链配置中的version字段,确保version值为 “v2.3.0“或者是”2301”都可。

2.停止并替换二进制

如果您需要保持区块链网络的持续运行,可以修改客户端连接,将交易发送到另一个节点,然后使用stop.sh停止一个节点(需要停止虚拟机),然后替换二进制。如果是基于Docker或者K8s则停用容器或Pod,然后更新Docker镜像为v2.3.1版本。

3.升级 Docker Go 虚拟机

如果您使用vm-engine镜像,请更新chainmakerofficial/chainmaker-vm-engine,命令如下:

docker pull chainmakerofficial/chainmaker-vm-engine:v2.3.1

如果您使用vm-docker-go镜像,请更新chainmakerofficial/chainmaker-vm-docker-go,命令如下:

docker pull chainmakerofficial/chainmaker-vm-docker-go:v2.3.1

4.启动节点和Docker Go虚拟机

如果您使用了Docker Go虚拟机:

  • 如果Docker Go是本机部署,需要同时替换下bin目录下的start.sh脚本,脚本会处理新合约虚拟机的拉起和停止。脚本由build_release.sh生成,可以参考《编译和安装包制作》

  • 如果Docker Go是独立部署(比如部署在其他host),可以参考《独立部署DockerVM》

重新执行start.sh脚本启动节点(需要启动虚拟机)。

5.逐个替换所有节点的二进制和DockerGo虚拟机

针对链中的每一个共识节点和同步节点,逐个执行步骤2、3、4的操作,也就是行:停止->替换->启动 操作,确保所有节点都已经升级为最新版本。

6.更新链配置,设置链版本为2030100

当所有共识节点都升级完二进制后,使用cmc更新链配置version到最新的2030100

./cmc client contract user invoke \
--contract-name=CHAIN_CONFIG \
--method=UPDATE_VERSION \
--params="{\"block_version\":\"2030100\"}" \
--sdk-conf-path=./testdata/sdk_config.yml \
--sync-result=true \
--admin-key-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.sign.key,./testdata/crypto-config/wx-org2.chainmaker.org/user/admin1/admin1.sign.key,./testdata/crypto-config/wx-org3.chainmaker.org/user/admin1/admin1.sign.key \
--admin-crt-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.sign.crt,./testdata/crypto-config/wx-org2.chainmaker.org/user/admin1/admin1.sign.crt,./testdata/crypto-config/wx-org3.chainmaker.org/user/admin1/admin1.sign.crt

7.检查升级是否成功

更新链配置后,正常发起业务交易,系统会打包新区块,通过cmc查询最新区块,关注header中的block_version字段,如果该值为2030100,则说明平滑升级成功。

./cmc query block-by-height  --sdk-conf-path=./testdata/sdk_config.yml

2.9.2. 新系统合约的启用

在本次v2.3.1的版本升级中,启用了中继跨链使用的系统合约,如果您考虑使用中继跨链功能,在完成了上述的平滑升级后,可以通过以下命令初始化之前版本中没有初始化的系统合约:

./cmc client contract user invoke \
--contract-name=CONTRACT_MANAGE \
--method=INIT_NEW_NATIVE_CONTRACT \
--sdk-conf-path=./testdata/sdk_config.yml \
--sync-result=true \
--result-to-string=true

本命令返回的message是OK,则说明新系统合约初始化成功。

2.9.3. 账本文件临时存储的启用

长安链默认使用文件来存储区块和交易的账本数据,使用数据库存储区块和交易的索引信息,由于账本文件占存储空间的大部分,出于成本和扩展性的考虑,一般会将账本文件存储在NFS之类的网络文件系统中。但是NFS的临时卡顿会影响整个链的出块,为此可以启用账本文件的临时存储功能。具体操作步骤如下:

1.修改配置文件

修改节点的chainmaekr.yml配置,storage选项下,增加block_store_tmp_path选项,值为本地高速磁盘

storage:
  store_path: /nfs/ledgerData  #账本的持久化文件存储路径
  block_store_tmp_path: /ssd/ledgerData_tmp #启用临时的账本文件存储,建议本地高速磁盘
  ......

2.停止节点,移动.END文件,启动节点

停止节点,将store_path下的.END文件移动到block_store_tmp_path下,这里的移动为了安全起见,建议先拷贝再删除原有的.END文件。移动完成后启动节点即可。

3.若节点为多链结构

若节点为多链结构,则chainID有多个,如: chain1,chain2,chain3…, 此时:

originfile1: /data/wx-org1.chainmaker.org/ledgerData1/chain1/bfdb —-移动.END文件到—> tmpfile1: /ssd/ledgerData_TMP/chain1/bfdb

originfile2: /data/wx-org1.chainmaker.org/ledgerData1/chain2/bfdb —-移动.END文件到—> tmpfile1: /ssd/ledgerData_TMP/chain2/bfdb

originfile3: /data/wx-org1.chainmaker.org/ledgerData1/chain3/bfdb —-移动.END文件到—> tmpfile1: /ssd/ledgerData_TMP/chain3/bfdb

2.10. v2.2.1 -> v2.3.1版本升级指南

由于v2.3.1中启用了全新的平滑升级特性,该特性通过读取链配置中的version来决定所产区块的版本,所以必须通过先升级v2.3.0的方式,然后再按前面提到的v2.3.0升级v2.3.1的操作流程升级到v2.3.1。

长安链不支持v2.2.1及之前版本直接升v2.3.1

长安链不支持v2.2.1及之前版本直接升v2.3.1

长安链不支持v2.2.1及之前版本直接升v2.3.1

2.11. v2.2.1 -> v2.3.0版本升级指南

若未选用docker-vm虚拟机引擎,则直接参考:通用升级步骤参考

版本v2.3.0进行了Docker Go合约引擎重构升级,相比之前的版本具有一定的性能和稳定性提升,支持多语言跨合约调用,推荐升级到v2.3.0版本。v2.3.0之前的Docker Go合约文件需要参考v2.3.0合约升级指南进行修改并升级。

2.11.1. 升级 Docker Go 虚拟机

1. 更新镜像

更新镜像chainmakerofficial/chainmaker-vm-engine,命令如下:

docker pull chainmakerofficial/chainmaker-vm-engine:v2.3.0.1

2. 替换启停脚本

如果Docker VM是本机部署,在编译替换chainmaker的时候,需要同时替换下bin目录下的start.sh, stop.sh, restart.sh三个脚本,脚本会处理合约虚拟机的拉起和停止。脚本由build_release.sh生成,可以参考《编译和安装包制作》

如果Docker VM是独立部署(比如部署在其他host),可以参考《独立部署DockerVM》

3. 更新配置文件

v2.3.0版本中chainmaker.yml中vm相关的配置项如下:

  1. 只运行旧版本合约,请参考《支持旧版本Docker VM》

  2. 只运行新版本合约,请参考《支持新版本Docker VM》

  3. 同时运行新旧版本合约,或存在旧版本合约升级到新版本合约的操作,需要同时进行上述两种配置。

4. 合约升级(推荐)

通用升级步骤参考第7步启动链成功之后,推荐更新合约SDK并重新编译合约。

合约SDK主要变更如下:

  1. package import 路径变更

  2. 添加key、field校验,仅支持数字、字母以及._-

  3. 新增Contract合约接口方法UpgradeContract,合约升级时由调用InitContract改为调用UpgradeContract

  4. 更新Contract合约接口方法InvokeContract,由之前的传递CMStubInterface来获取method,改为入参传递method,无需再传递stub手动获取method

  5. SDK使用方式变更,由之前每个函数入参传递一个CMStubInterface实例来使用SDK接口方法改为通过sdk.Instance全局变量来使用SDK提供的接口方法。

v2.3.0版本合约编写请参考:《使用Golang进行智能合约开发》

2.12. v2.1.0, v2.2.0 -> v2.2.1版本升级指南

由于版本v2.2.0使用了新版本的wasm引擎,请注意在执行 通用升级步骤参考 的第4步时,需要同时将 ./main/libwasmer_runtime_c_api.so 文件复制为生产环境的 /usr/lib64/libwasmer.so 文件。

2.12.1. 升级 Docker Go VM虚拟机

如果启用了Docker VM虚拟机,除通用升级步骤参考中的操作外,需要额外做以下操作:

  1. 替换启停脚本

    在v2.2.1 版本中Docker VM虚拟机不再由Chainmaker节点程序拉起,

    如果Docker VM是本机部署,在第4步编译替换chainmaker的时候,需要同时替换下bin目录下的start.sh, stop.sh, restart.sh三个脚本,脚本会处理合约虚拟机的拉起和停止。脚本由build_release.sh生成,可以参考《通过命令行体验链》

    如果Docker VM是独立部署(比如部署在其他host),可以参考《启动支持Docker_VM的链》

  2. 更新vm-docker-go虚拟机镜像

    在第4步替换二进制之后,也需要更新vm-docker-go虚拟机镜像(chainmakerofficial/chainmaker-vm-docker-go)至v2.2.1版本,命令如下:

    docker pull chainmakerofficial/chainmaker-vm-docker-go:v2.2.1
    
  3. contract-sdk-docker-go 合约升级(强烈建议)

    在第7步启动链成功之后,强烈建议更新合约SDK。

    更新合约SDK镜像(chainmakerofficial/chainmaker-docker-go-contract)至v2.2.1版本,命令如下:

    docker pull chainmakerofficial/chainmaker-docker-go-contract:v2.2.1
    

    如果是v2.2.0之前的合约文件还需要对合约源码进行一些修改,参考v2.1.0 -> v2.2.0版本升级指南升级合约文件。

2.13. v2.1.0 -> v2.2.0版本升级指南

由于版本v2.2.0使用了新版本的wasm引擎,请注意在执行 通用升级步骤参考 的第4步时,需要同时将 ./main/libwasmer_runtime_c_api.so 文件复制为生产环境的 /usr/lib64/libwasmer.so 文件。

2.13.1. vm-docker-go 虚拟机引擎升级

如果启用了vm-docker-go虚拟机(必须), 通用升级步骤参考中需要额外做以下操作:

其中,在第3步停止节点之后,需要更新vm-docker-go虚拟机镜像(chainmakerofficial/chainmaker-vm-docker-go)至v2.2.0.1版本,命令如下:

docker pull chainmakerofficial/chainmaker-vm-docker-go:v2.2.0.1

2.13.2. contract-sdk-docker-go 合约升级(强烈建议)

在第7步启动链成功之后,强烈建议更新合约SDK。

更新合约SDK镜像(chainmakerofficial/chainmaker-docker-go-contract)至v2.2.0.1版本,命令如下:

docker pull chainmakerofficial/chainmaker-docker-go-contract:v2.2.0.1

在第8步编译合约文件之前,还需要对合约源码进行一些修改,修改内容如下,【合约编译步骤参考】

v2.1.0版本合约源码示例如下:

package main

import (
  "encoding/json"
  "log"
  "strconv"

  "chainmaker.org/chainmaker-contract-sdk-docker-go/pb/protogo"
  "chainmaker.org/chainmaker-contract-sdk-docker-go/shim"
)
   // ---snip---

v2.2.0.1版本合约源码需要修改至如下格式(合约SDK import路径需要更新):

package main

import (
    "encoding/json"
    "log"
    "strconv"

    "chainmaker.org/chainmaker/chainmaker-contract-sdk-docker-go/pb/protogo"
    "chainmaker.org/chainmaker/chainmaker-contract-sdk-docker-go/shim"
)
// ---snip---

2.14. v2.0.0 -> v2.1.0版本升级指南

v2.1.0兼容v2.0.0,升级时只需要替换相应二进制文件(无需修改配置文件),并重启所有节点。升级所有生态工具即可。

通用升级步骤参考

从历史版本升级为 v2.1.0版本,新功能只支持自研网络(需将所有节点停止,并修改chainmaker.yml文件的net.provider为liquid后,再启动)。若想体验其他新功能如java国密、公钥身份、透明加密等,请重新安装新版本ChainMaker。

2.15. 通用升级操作步骤

写在最前面:建议所有操作都备份

  • 1.停止交易: 停止所有向节点发交易请求,即不要再让链出新块。

  • 2.确认同步: 确认现有全部节点状态已同步到一致,即块高度一致。

  • 3.停止节点: 停止所有节点服务。

  • 4.编译chainmaker: 编译新版本的可执行文件,并替换原版本的可执行文件(一般在目录bin中)。

  • 5.修改配置: 若不使用新版本特性,则可跳过;若需使用,可修改所有节点的chainmaker.yml对应部分。

  • 6.启动: 启动所有节点,观察日志有无错误信息。若使用cluster_quick_start.sh 命令启动则需要移除release下的*tar.gz文件。

  • 7.链升级成功: 正常情况下,至此版本升级成功。

  • 8.(强烈建议)编译合约文件: 使用和chainmaker-go最近版本的合约SDK编译新的合约文件。

  • 9.(强烈建议)升级合约: 使用新的合约升级以前版本的合约。

  • 10.(强烈建议)升级配套工具: 如果有使用sdk或者cmc工具,请将sdkcmc版本升级为和链一致的版本,否则可能会导致交易失败。

2.15.1. 新添加节点注意事项

1.新节点的bc*.yml文件必须与旧版本时期保持一致(路径参数则需要路径对应的内容保持一致),无需修改为新的版本。新的版本程序已对其做了兼容,如果修改bc*.yml会导致创世块不一致,无法完成同步。

2.新节点的chainmaker.yml文件需要与新的版本格式保持一致。