Skip to content

Commit

Permalink
add upgrade description && compatibility design doc (#1620)
Browse files Browse the repository at this point in the history
1.add upgrade.md
2.add compatibility.md design doc
3.add lightnode expand description
  • Loading branch information
wenlinlee committed Feb 2, 2023
1 parent 2534f90 commit 890c909
Show file tree
Hide file tree
Showing 7 changed files with 297 additions and 77 deletions.
9 changes: 9 additions & 0 deletions 3.x/zh_CN/docs/change_log/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@
.. important::
相关软件和环境版本说明!`请查看 <https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/compatibility.html>`_

升级指南
------------

.. toctree::
:hidden:
:maxdepth: 0

upgrade.md


v3.2.x
------------------
Expand Down
25 changes: 25 additions & 0 deletions 3.x/zh_CN/docs/change_log/upgrade.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# 升级指南
FISCO BCOS 版本迭代,为支持版本之间的兼容升级,设计了[兼容性方案](../design/compatibility.md), 支持可灰度升级,且灰度升级过程中,系统可以正常共识、出块。

具体系统版本升级步骤如下:
1. 升级二进制:停止需要升级版本的节点,需将所有节点的二进制逐步替换为当前版本。为不影响业务,替换过程能够以灰度方式进行,逐个替换并重启节点。替换过程中,当前的链仍然会以旧的数据兼容版本号的逻辑继续执行。
2. 升级数据兼容版本号:当所有节点二进制替换完成并重启后,需用控制台修改数据兼容版本号为当前版本,步骤如下:
- 通过控制台连接节点,执行升级兼容版本号命令:```setSystemConfigByKey compatibility_version 3.x.x```

```
[group0]: /apps> setSystemConfigByKey compatibility_version 3.x.x
{
"code":0,
"msg":"success"
}
注:若开启权限治理功能,需要使用 setSysConfigProposal 命令
```
- 设置成功,再次查询,得到当前版本已升级

```
[group0]: /apps> getSystemConfigByKey compatibility_version
3.x.x
```

当前链已经完成升级,至此,**链开始以新的逻辑继续运行**,并支持了新的特性。
248 changes: 248 additions & 0 deletions 3.x/zh_CN/docs/design/compatibility.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
# 兼容性方案
标签:``兼容性`` ``版本升级``

## 1. 设计目标
FISCO BCOS 3.X版本迭代,为实现各版本之间的兼容,FISCO BCOS针对网络层面与数据层面的兼容性设计了相应的兼容性方案。 方案的目标主要包括两点,第一,
可保证各个版本之间的网络、数据、执行模块、公用的编解码协议(scale/abi)均可向后兼容,第二,支持可灰度升级,且灰度升级过程中,系统可正常共识、出块。


## 2. 网络兼容性设计
FISCO BCOS版本更新时,网络模块会在建立/断开网络连接期间交换、协商版本信息,实现网络模块版本之间的兼容性,具体设计如下:
1. 建立连接/断开重连后,节点间(or 节点与SDK之间)交换版本信息,进行版本协商
2. 每个网络相关的功能模块均对应兼容性版本

具体而言,通过设计ProtocolVersion来标识不同的版本,实现各个版本的兼容:
```c++
enum ProtocolVersion: uint16_t
{
V1 = 1,
V2 = 2,
... ...
};
```

### 2.1 RPC服务接口兼容性
对于RPC服务接口,也需要保证其可向后兼容,并调研、测试tars服务的兼容性,参考:[Versioning gRPC services](https://learn.microsoft.com/en-us/aspnet/core/grpc/versioning?view=aspnetcore-6.0)
- gRPC :
- tars : 不支持接口修改,但可以通过传结构体tars做到接口兼容


### 2.2 网络编解码协议兼容性
对于网络编解码协议兼容性,FISCO BCOS通过在P2PMessage/WSMessage中设计添加version 字段实现兼容,当节点接收到消息后,根据消息中 version 调用相应的编解码方法。
P2PMessage/WSMessage 具体数据结构设计如下:
```c++
class P2PMessageFactory
{
public:
P2PMessageFactory()
{
// 设置m_protocol2Codec
}
// 网络消息包版本到其对应编解码协议之间的映射,初始化时设置
std::shared_ptr<std::map<ProtocolVersion, P2PCodec::Ptr>> m_protocol2Codec;
}

class P2PCodec
{
public:
virtual bool encode(bytes& _buffer, std::weak_ptr<P2PMessage>) = 0;
virtual ssize_t decode(bytesConstRef _buffer, std::weak_ptr<P2PMessage>) = 0;
};

class P2PMessage
{
public:
P2PMessage: m_version(ProtocolVersion::V1){}
// 消息编码
bool encode(bytes& _buffer) override
{
auto encoder = m_protocol2Codec.at(m_version);
return encoder->encode(_buffer, std::weak_ptr<P2PMessage>
(shared_from_this()));
}
// 消息解码
ssize_t decode(bytesConstRef _buffer) override
{
// decode version
auto version = ...
auto codec = m_protocol2Codec.at(version);
return codec->decode(_buffer, std::weak_ptr<P2PMessage>
(shared_from_this()));
}
protected:
ProtocolVersion m_version;
uint32_t m_length;
... ...
std::shared_ptr<std::map<ProtocolVersion, P2PCodec::Ptr>> m_protocol2Codec;
};

```
总的来说,FISCOBCOS在网络应用层(同步、共识)消息均使用PB编码,具备向后兼容性;对于AMOP消息包而言,其采用二进制编码,设计在AMOP信息中添加version字段,便于扩展;
FISCO BCOS在块高推送、群组信息、EventLog推送均采用json编解码,具备向后兼容性。
###2.3 网络层协议兼容性
FISCO BCOS通过握手协商Peer的版本信息:主要涉及的模块包括 Gateway , AMOP , EventSub , RPC;而握手协商的版本信息保存在 Session 中,具体相关协议信息设计如下:
ProtocolInfo定义具体的协议信息:
```c++
class ProtocolInfo
{
// 模块ID
ModuleID m_moduleID;
// 当前使用的版本号
ProtocolVersion m_currentVersion;
// 支持的最小版本号
ProtocolVersion m_minVersion;
// 支持的最大版本
ProtocolVersion m_maxVersion;
};
```
定义本地支持的协议版本:
```c++
class Protocol
{
public:
Protocol()
{
// 初始化本地协议信息,如:
m_supportedProtocols.insert({ModuleID::Gateway, {ModuleID::Gateway,
ProtocolVersion::V1, ProtocolVersion::V1, ProtocolVersionV1}});
... ..
}
~Protocol(){}
private:
std::map<ModuleID, ProtocolInfo::Ptr> m_supportedProtocols;
```
```eval_rst
.. mermaid::
sequenceDiagram
participant NodeA
participant NodeB
NodeA->>NodeB: 建立连接
NodeA->>NodeB: NodeA 协议列表
NodeB->>NodeB: 计算NodeA协议列表
NodeB->>NodeA: NodeB 协议列表
NodeA->>NodeA: 计算NodeB 协议列表
```

协议协商方法设计:
```c++
ProtocolVerison handleProtocol(ModuleID _module, ProtocolInfo::Ptr _protocol)
{
// 找到本地module对应的协议信息
auto localProtocol = m_supportedProtocols.at(_module);
// case1: 握手协商失败
// 本地的最大版本号小于源节点的最小版本号,或者本地的最小版本号大于源节点的最小版本号
if(_protocol->minVersion() > localProtocol->maxVersion() || _protocol->maxVersion() < localProtocol->minVersion())
{
// disconnect session
return -1;
}
// case2: 两者版本号有重叠
return std::min(localProtocol->maxVersion(), _protocol->maxVersion());
}
```
扩充当前modeleID
```c++
enum ModuleID
{
// nodeservice
PBFT = 1000,
Raft = 1001,
BlockSync = 2000,
TxsSync = 2001,
// executorservice
Executor = xxx,
// rpcservice
AMOPClient = 3001, // SDK/bcos-rpc中AMOP协议ID
EventSub = 5000, // 事件监听协议
RPC = 6000, // RPC协议,包括块高推送、握手协议、群组信息推送等
// gatewayservice
AMOPServer = 3000, // bcos-gateway之间AMOP协议ID
Gateway = 4000, // bcos-gateway之间的协议(如交换基本信息等)
};
```

session维护协商的版本信息:
```c++
// bcos-gateway
class Session
{
// 提供接口,可以获取每个session协商的版本号
ProtocolInfo::Ptr getProtocolInfoByModule(ModuleID){}
// 模块ID到协商的版本信息
std::map<ModuleID, ProtocolInfo::Ptr> m_negotiatedVersion;
};
```

共识/同步可向bcos-gateway查询协议版本,bcos-gateway可推送协议版本
```c++
class FrontServiceInterface
{
// 提供获取Protocol的接口
virtual void asyncGetProtocols(ModuleID _module,
std::function<void(Error::Ptr, std::map<NodeID, ProtocolInfo>)>) = 0;
// 可以向注册模块推送Protocol信息
}

```
### 3. 数据兼容性设计
相比于网络层面的兼容行设计,数据层面无法做到像网络层那样平滑升级,须通过系统合约触发系统升级
具体而言FISCO BCOS数据兼容性主要涉及到:
- block、blockHeader、transaction、receipt等基本数据结构:
(1) 这些字段中均带有version,可通过version做到编解码层面兼容;
(2) block, blockHeader, transaction 由共识打包模块 sealer 产生
(3) receipt 由执行模块 Executor 产生
- 交易执行:可根据 BlockContext 中的 m_blockVersion 实现执行层面兼容性
###3.1 数据协议版本定义
FISCOBCOS 设计主版本号与次版本号,例如针对FISCOBCOS 3.x,版本号设计如下:
```c++
3.0.0: 0x03000000
3.1.0: 0x03010000
3.1.1: 0x03010100
3.2.0: 0x03020000
...
```

####3.2 数据协议存储与变更
FISCOBCOS 设计 sys_config 系统表存储记录数据版本号的信息,其key与value如下:
- key: compatibility_version
- value: 下一个块使用的协议版本号,如: 3.0.x , 3.1.x 等

如果发生版本更新,需要变更数据协议,修改 sys_config 的 compatibility_version 配置项即可,对于compability_version的维护,主要涉及打包模块与BlockContext:
- 打包模块:Sealer,用于支持区块、交易等数据结构变更
- BlockContext :用于支持执行兼容性(如Precompiled合约等)

## 4. 结论
综上,FISCOBCOS设计兼容性方案,在上层各模块的编解码协议统一采用PB编码;对于网络协议兼容性,则按照服务进程进行划分,根据服务进程实现不同服务的兼容性,对于数据层面的兼容性,通过block、blockHeader、transaction、receipt等基本数据结构中以及sys_config 系统表中的版本信息实现版本兼容。

```c++
enum ModuleID
{
// nodeservice
PBFT = 1000,
Raft = 1001,
BlockSync = 2000,
TxsSync = 2001,
// executorservice
Executor = xxx,
// rpcservice
AMOPClient = 3001, // SDK/bcos-rpc中AMOP协议ID
EventSub = 5000, // 事件监听协议
RPC = 6000, // RPC协议,包括块高推送、握手协议、群组信息推送等
// gatewayservice
AMOPServer = 3000, // bcos-gateway之间AMOP协议ID
Gateway = 4000, // bcos-gateway之间的协议(如交换基本信息等)
// SDK
};
```

76 changes: 0 additions & 76 deletions 3.x/zh_CN/docs/design/consensus/pbft_optimize.md

This file was deleted.

1 change: 1 addition & 0 deletions 3.x/zh_CN/docs/design/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,5 @@ ___
storage/storage_security.md
storage/archive.md
p2p.md
compatibility.md
```
15 changes: 14 additions & 1 deletion 3.x/zh_CN/docs/tutorial/lightnode/build_chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,4 +137,17 @@ lightnode/
- getTransactionByHashWithProof
- getTransactionReceiptByHashWithProof
- call
- sendTransaction
- sendTransaction
- listAbi

## 轻节点扩容
FISCOBCOS 3.3版本开始,支持通过build_chain.sh脚本扩容轻节点,具体操作流程如下:
1. 新建文件夹config;
2. 将nodes下的根证书文件夹ca拷贝至config文件夹中;
3. 从已存在lightnode文件夹中拷贝config.genesis、config.ini以及nodes.json至config文件夹中;
4. 修改config.ini中rpc与p2p的port字段,将端口号+1(例如原config.ini文件中rpc端口为20202,修改为20203);
5. 执行脚本命令,具体有执行轻节点二进制文件路径以及自动拉取最新轻节点二进制两种扩容方式,如下所示:
- ```bash build_chain.sh -C expand_lightnode -c config(config文件夹) -d config/ca(根证书路径) -o nodes/lightnode1(扩容轻节点输出路径) -L + 指定轻节点二进制下载路径```
- ```bash build_chain.sh -C expand_lightnode -c config(config文件夹) -d config/ca(根证书路径) -o nodes/lightnode1(扩容轻节点输出路径)``` (自动拉取轻节点最新二进制)

6. 扩容成功后生成新的轻节点目录nodes/lightnode1,启动扩容生成的轻节点 bash start.sh
Binary file added 3.x/zh_CN/images/design/protocol_design.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 890c909

Please sign in to comment.