Skip to content

Commit

Permalink
rfc234: remove name prefix modifications
Browse files Browse the repository at this point in the history
  • Loading branch information
doitian committed Jul 22, 2021
1 parent 7bbf578 commit c77c53c
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 160 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,150 +6,93 @@ Author: Chao Luo, Ian Yang
Organization: Nervos Foundation
Created: 2021-07-01
---

# p2p protocol upgrade
# P2P protocol upgrade

## Abstract

这个 RFC 用于描述网络协议在 ckb hard fork 前后的变化,以及如何在 hard frok 过程中让网络协议平稳过度。
This RFC describes how the network protocol changes before and after the ckb hard fork, and how the network protocols smoothly upgrade along the hard fork.

## Motivation

网络协议是分布式应用的基础,hard fork 前后,数据格式将会有小范围的变化,但网络不应该因为这个变化而导致断开或者分裂,我们应当尽可能平稳地过度这一特殊时期,同时要保证在 hard fork 之前,所有客户端可以连接,hard fork 之后,只允许连接支持 hard fork 的客户端。
The network protocol is the foundation of distributed applications. Before and after hard fork, there will be small changes in data format, but the network should not be disconnected or split because of this change. After hard fork, only clients that support hard fork are allowed to connect.

这个 RFC 详细描述了 ckb 节点如何实现上述功能。
This RFC describes in detail how the ckb node implements this functionality.

## Specification

我们将整个 hard fork 的过程分为三个阶段:hard fork 之前,hard fork 时点,hard fork 之后。然后分为两大类手段来描述具体的改动细节,以及如何支持平稳过度。

ckb 对网络协议有两种升级和扩展的方式:
We divide the entire hard fork process into three phases: before hard fork, the moment that hard fork activates, and after hard fork. The protocols are divided into two categories which have different upgrade strategies.

- 对特定协议升级版本,并保证同时支持两个版本协议可同时开启
- 挂载两个功能一样但需要运行时切换的协议用于平滑升级
- Upgrade the version of a specific protocol and ensure that both versions of the protocol are supported and can be enabled at the same time
- Mount two protocols that are functionally identical but require runtime switching for smooth upgrades

### 对于功能和实现都不需要修改的协议
### For protocols whose functionality and implementation do not need to be modified

包含协议:
Including protocols:

- Identify
- Ping
- Feeler
- DisconnectMessage
- Time
- Alert

##### hard fork 之前

将版本支持列表从 [1] 修改为 [1, 2],该客户端将同时支持两个版本的协议,新客户端将开启 2 版本,老客户端将开启 1 版本

##### hard fork 时点

将开启 1 版本协议的客户端全部断开连接,同时在之后拒绝此版本协议开启

##### hard fork 之后

在下一个版本客户端代码中移除 1 版本协议的支持,即支持列表从 [1, 2] 修改为 [2],并清理兼容代码

### 对实现需要微调的协议
##### Before hard fork

#### Identify
Change the version support list from `[1]` to `[1, 2]`, the client will support both versions of the protocol, the new client will enable version 2 and the old client will enable version 1

##### hard fork 之前:
##### Hard fork moment

1. 将版本支持列表从 [1] 修改为 [1, 2]
2. 修改 identify 发送中的 name 字段的验证方式,由绝对匹配修改为 prefix 匹配,允许用不确定的后缀来标识客户端目的,比如是一个监控节点,连接的客户端可以不对其进行节点地址的广播处理
Disconnect all clients with the protocol version 1 on, and reject this version afterwards.

代码如下:
##### After hard fork

```rust
// v2 allow adding specific characters after identify name to identify some non-chain nodes connected
if v2 && !name.starts_with(&self.name) {
debug!("Not the same chain, self: {}, remote: {}", self.name, name);
return None;
} else if self.name != name {
debug!("Not the same chain, self: {}, remote: {}", self.name, name);
return None;
}
```
Remove the support for the protocol version 1 from the next version of client code, i.e. change the support list from `[1, 2]` to `[2]`, and clean up the compatibility code

##### hard fork 时点

将开启 1 版本协议的客户端全部断开连接,同时在之后拒绝此版本协议开启

##### hard fork 之后

在下一个版本客户端代码中移除 1 版本协议的支持,即支持列表从 [1, 2] 修改为 [2],并清理兼容代码
### Implement protocols that requires modification

#### Discovery

##### hard fork 之前:

1. 将版本支持列表从 [1] 修改为 [1, 2]
2. 移除之前实现时多余的编码解码操作
3. 在通信消息上加上字段标识客户端,用于决定是否对改节点信息进行广播,代码类似 identify 的 name 字段

schema:

```mol
union DiscoveryPayloadV2 {
GetNodesV2,
NodesV2,
}
table DiscoveryMessageV2 {
payload: DiscoveryPayloadV2,
}
table GetNodesV2 {
net: Bytes, // new field
version: Uint32,
count: Uint32,
listen_port: PortOpt,
}
##### Before hard fork

table NodesV2 {
net: Bytes, // new field
announce: Bool,
items: NodeVec,
}
```
1. Change the version support list from `[1]` to `[1, 2]`.
2. Remove redundant codec operations from the previous implementation

##### hard fork 时点
##### Hard fork moment

将开启 1 版本协议的客户端全部断开连接,同时在之后拒绝此版本协议开启
Disconnect all clients with the protocol version 1 on, and reject this version afterwards.

##### hard fork 之后
##### After hard fork

在下一个版本客户端代码中移除 1 版本协议的支持,即支持列表从 [1, 2] 修改为 [2],并清理兼容代码
Remove the support for the protocol version 1 from the next version of client code, i.e. change the support list from `[1, 2]` to `[2]`, and clean up the compatibility code

#### Sync

##### hard fork 之前:
##### Before hard fork Before

1. 将版本支持列表从 [1] 修改为 [1, 2]
2. 移除同步时请求列表的 16 一组限制,保留最大同步数的限制,新版本将 block 同步请求上限从 16 改为 32
1. Change the version support list from `[1]` to `[1, 2]`
2. Remove the 16 group limit from the sync request list and keep the maximum number of syncs, new version changes the block sync request limit from 16 to 32

##### hard fork 时点
##### Hard fork moment

将开启 1 版本协议的客户端全部断开连接,同时在之后拒绝此版本协议开启
Disconnect all clients with the protocol version 1 on, and reject this version afterwards.

##### hard fork 之后
##### After hard fork

在下一个版本客户端代码中移除 1 版本协议的支持,即支持列表从 [1, 2] 修改为 [2],并清理兼容代码
Remove the support for the protocol version 1 from the next version of client code, i.e. change the support list from `[1, 2]` to `[2]`, and clean up the compatibility code

### 对行为在 fork 前后会发生冲突的协议
### For protocols whose behavior will conflict before and after fork

#### Relay

##### hard fork 之前:
##### Before hard fork.

由于 relay 协议在 fork 前后可能会因为 vm 不一致而导致交易验证的 cycle 不一致,这样的行为无法通过简单的升级来标识,对于这样的协议,将采取另一种方案进行平滑过度,即打开两个 relay 协议,禁用新协议 relay tx 相关消息,让老协议正常工作
Since relay protocols before and after fork may have inconsistent cycle of transaction validation due to inconsistent vm, such behavior cannot be identified by a simple upgrade, for such protocols, another solution will be adopted to smooth the transition, i.e., open both relay protocols, disable the new protocol relay tx related messages, and let the old protocol work normally

##### hard fork 时点
##### Hard fork moment

1. 禁用 1 版本协议中的 relay tx 相关消息,切换为新 relay 工作
2. 允许打开 1 版本协议
1. Disable relay tx related messages in version 1 protocol and switch to the new relay
2. Allow opening the version 1 protocols

##### hard fork 之后
##### After hard fork

在下一个版本客户端代码中移除老版本 relay 协议的支持,即删除老版本 relay 协议的支持,并清理兼容代码
Remove the support for the old relay protocol in the next version of the client code, i.e. remove the support for the old relay protocol and clean up the compatibility code
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ Organization: Nervos Foundation
Created: 2021-07-01
---

# p2p protocol upgrade
# P2P 协议升级

## Abstract

这个 RFC 用于描述网络协议在 ckb hard fork 前后的变化,以及如何在 hard frok 过程中让网络协议平稳过度。
这个 RFC 用于描述网络协议在 ckb hard fork 前后的变化,以及如何在 hard fork 过程中让网络协议平稳过度。

## Motivation

Expand All @@ -32,6 +32,7 @@ ckb 对网络协议有两种升级和扩展的方式:

包含协议:

- Identify
- Ping
- Feeler
- DisconnectMessage
Expand All @@ -40,93 +41,38 @@ ckb 对网络协议有两种升级和扩展的方式:

##### hard fork 之前

将版本支持列表从 [1] 修改为 [1, 2],该客户端将同时支持两个版本的协议,新客户端将开启 2 版本,老客户端将开启 1 版本
将版本支持列表从 `[1]` 修改为 `[1, 2]`,该客户端将同时支持两个版本的协议,新客户端将开启 2 版本,老客户端将开启 1 版本

##### hard fork 时点

将开启 1 版本协议的客户端全部断开连接,同时在之后拒绝此版本协议开启

##### hard fork 之后

在下一个版本客户端代码中移除 1 版本协议的支持,即支持列表从 [1, 2] 修改为 [2],并清理兼容代码
在下一个版本客户端代码中移除 1 版本协议的支持,即支持列表从 `[1, 2]` 修改为 `[2]`,并清理兼容代码

### 对实现需要微调的协议

#### Identify

##### hard fork 之前:

1. 将版本支持列表从 [1] 修改为 [1, 2]
2. 修改 identify 发送中的 name 字段的验证方式,由绝对匹配修改为 prefix 匹配,允许用不确定的后缀来标识客户端目的,比如是一个监控节点,连接的客户端可以不对其进行节点地址的广播处理

代码如下:

```rust
// v2 allow adding specific characters after identify name to identify some non-chain nodes connected
if v2 && !name.starts_with(&self.name) {
debug!("Not the same chain, self: {}, remote: {}", self.name, name);
return None;
} else if self.name != name {
debug!("Not the same chain, self: {}, remote: {}", self.name, name);
return None;
}
```

##### hard fork 时点

将开启 1 版本协议的客户端全部断开连接,同时在之后拒绝此版本协议开启

##### hard fork 之后

在下一个版本客户端代码中移除 1 版本协议的支持,即支持列表从 [1, 2] 修改为 [2],并清理兼容代码

#### Discovery

##### hard fork 之前:

1. 将版本支持列表从 [1] 修改为 [1, 2]
1. 将版本支持列表从 `[1]` 修改为 `[1, 2]`
2. 移除之前实现时多余的编码解码操作
3. 在通信消息上加上字段标识客户端,用于决定是否对改节点信息进行广播,代码类似 identify 的 name 字段

schema:

```mol
union DiscoveryPayloadV2 {
GetNodesV2,
NodesV2,
}
table DiscoveryMessageV2 {
payload: DiscoveryPayloadV2,
}
table GetNodesV2 {
net: Bytes, // new field
version: Uint32,
count: Uint32,
listen_port: PortOpt,
}
table NodesV2 {
net: Bytes, // new field
announce: Bool,
items: NodeVec,
}
```

##### hard fork 时点

将开启 1 版本协议的客户端全部断开连接,同时在之后拒绝此版本协议开启

##### hard fork 之后

在下一个版本客户端代码中移除 1 版本协议的支持,即支持列表从 [1, 2] 修改为 [2],并清理兼容代码
在下一个版本客户端代码中移除 1 版本协议的支持,即支持列表从 `[1, 2]` 修改为 `[2]`,并清理兼容代码

#### Sync

##### hard fork 之前:

1. 将版本支持列表从 [1] 修改为 [1, 2]
1. 将版本支持列表从 `[1]` 修改为 `[1, 2]`
2. 移除同步时请求列表的 16 一组限制,保留最大同步数的限制,新版本将 block 同步请求上限从 16 改为 32

##### hard fork 时点
Expand All @@ -135,15 +81,15 @@ table NodesV2 {

##### hard fork 之后

在下一个版本客户端代码中移除 1 版本协议的支持,即支持列表从 [1, 2] 修改为 [2],并清理兼容代码
在下一个版本客户端代码中移除 1 版本协议的支持,即支持列表从 `[1, 2]` 修改为 `[2]`,并清理兼容代码

### 对行为在 fork 前后会发生冲突的协议

#### Relay

##### hard fork 之前:

由于 relay 协议在 fork 前后可能会因为 vm 不一致而导致交易验证的 cycle 不一致,这样的行为无法通过简单的升级来标识,对于这样的协议,将采取另一种方案进行平滑过度,即打开两个 relay 协议,禁用新协议 relay tx 相关消息,让老协议正常工作
由于 relay 协议在 fork 前后可能会因为 vm 不一致而导致交易验证的 cycle 不一致,这样的行为无法通过简单的升级来标识,对于这样的协议,将采取另一种方案进行平滑过度,即打开两个 relay 协议,禁用新协议 relay tx 相关消息,让老协议正常工作

##### hard fork 时点

Expand Down

0 comments on commit c77c53c

Please sign in to comment.