From 4d458c5f865ba40740a2cdd27963b53abe5182aa Mon Sep 17 00:00:00 2001
From: dev25519 <57280008+dev25519@users.noreply.github.com>
Date: Sat, 2 Nov 2019 12:46:45 +0800
Subject: [PATCH 1/2] Create README-CN.md

---
 gxip-004/README-CN.md | 108 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 108 insertions(+)
 create mode 100644 gxip-004/README-CN.md

diff --git a/gxip-004/README-CN.md b/gxip-004/README-CN.md
new file mode 100644
index 0000000..17a01cd
--- /dev/null
+++ b/gxip-004/README-CN.md
@@ -0,0 +1,108 @@
+## 摘要
+一种提升验证人网络稳定性的实施方案
+
+## 动机
+1. 验证人节点故障时,系统能够自动保证网络稳定性
+2. 增加节点维护工具,支持离线/上线操作
+3. 在一定程度上增加备选节点出块的机会
+
+## 技术细节
+总体的解决方案是:
+1. 在验证人节点运维方面,增加验证人节点离线、上线操作。验证人节点升级/维护时,分3个阶段:
+ * 1) 通过cli_wallet发起节点离线操作, 节点下线,不再参与出块
+ * 2) 准备升级/维护,完成后,通过观察日志或者RPC命令,确保在正常工作
+ * 3) 通过cli_wallet发起节点上线操作,重新上线,参与出块
+2. 网络稳定性方面,若验证人节点长时间离线,系统强制将其离线,设置为禁闭状态,并踢出当前活跃验证人集合,由排名靠后的备选节点补上,参与网络出块,保证了网络稳定性。
+3. 被系统强制关禁闭的验证人节点,需要一定时间后才可以重新上线。作为惩罚,重新上线时,需要燃烧一定数量的GXC。
+
+本方案涉及协议升级,需要设置合理的hardfork time。
+
+### 1. 系统强制验证人节点离线
+若验证人节点长时间不出块,系统强制将其离线,由备选节点补上。触发系统强制离线条件为:
+
+1. 在单个维护周期内,验证人节点累计缺失块数大于 **max_missed_blocks**
+2. max_missed_blocks 为全局参数,默认为25
+
+按照当前维护周期1小时,21个验证人节点平均出块数约为57, 将max_missed_blocks默认设置为25,可保证节点缺数率不能超43%。这样可以额外解决一个问题:验证人节点服务器时间不准确的情况下(3秒左右的延迟),抢先出块或者延迟出块造成网络分叉。此种情况下,引入验证人节点强制离后结,网络将在1小时内通过把该节点被强制关禁闭,恢复稳定。
+
+系统强制离线处理逻辑,建议在内存数据库中维护一个数组跟踪活跃验证人缺失块数,每个维护周期在统计投票前检查是否需要强制离线,执行一次; 投票统计结束后,将数组清空。
+
+### 2. 验证人节点离线/上线操作
+
+#### 离线/offline_operation
+结构体定义:
+```
+struct offline_operation : public base_operation
+{
+    struct fee_parameters_type {
+        uint64_t fee  = GRAPHENE_BLOCKCHAIN_PRECISION / 1000;
+    };  
+
+    account_id_type                             from;
+    extensions_type                             extensions;
+
+    account_id_type fee_payer() const { return from; }
+    void validate() const { } 
+
+    share_type calculate_fee( const fee_parameters_type& k ) const {
+        return k.fee;
+    }   
+};
+~      
+```
+
+#### 验证条件
+1. 交易发起者是验证人节点
+2. 验证人节点状态是online
+3. 账户余额可以支付交易手续费
+
+#### 节点状态
+验证人节点的状态有3种:
+```
+enum validtor_status {
+    online = 0, // 在线
+    offline = 1, // 离线
+    jailed = 2  // 禁闭
+};
+```
+* 如果验证人节点主动发起offline_operation,则节点状态将被置为offline
+* 如果是系统强制离线,则节点状态将被置为jailed
+
+
+#### 上线/online_operation
+离线/禁闭的验证人节点, 可发起上线操作。 禁闭节点重新上线,将从帐户扣除惩罚金,惩罚金全部注入系统资金储备池,用于验证人节点出块奖励。
+
+结构体定义:
+```
+struct online_operation : public base_operation
+{
+    struct fee_parameters_type {
+        uint64_t fee  = GRAPHENE_BLOCKCHAIN_PRECISION / 1000;
+    };  
+
+    account_id_type                             from;
+    extensions_type                             extensions;
+
+    account_id_type fee_payer() const { return from; }
+    void validate() const { } 
+
+    share_type calculate_fee( const fee_parameters_type& k ) const {
+        return k.fee;
+    }   
+};
+```
+
+#### 验证条件
+* 验证人节点状态是offline,或者状态为jailed,并且当前时间已超过禁闭期(jailed_seconds)。
+* 帐户余额可以支付交易手续费(禁闭节点,需要支付额外费用)
+
+#### 节点状态
+* 如果节处于offline状态,上线时需要基本的交易手续费
+* 如果节点处于jailed状态,上线时需要基本交易手续费 + 惩罚
+
+
+#### 增加的全局参数
+
+1. 验证人节点最大缺块数 ```max_missed_blocks```,建议默认25
+2. 禁闭期 ```jailed_seconds```,为了增加备选节点的出块机会,同时惩罚禁闭的节点,建议禁闭期7天-14天
+3. 禁闭后重新上线的惩罚 ```punished_fee```,建议1000 GXC

From 1bea0c768895b85c81dbc1815d72d5cf3d090e41 Mon Sep 17 00:00:00 2001
From: dev25519 <57280008+dev25519@users.noreply.github.com>
Date: Sat, 2 Nov 2019 21:08:33 +0800
Subject: [PATCH 2/2] updated

---
 gxip-004/README-CN.md | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/gxip-004/README-CN.md b/gxip-004/README-CN.md
index 17a01cd..98c6e55 100644
--- a/gxip-004/README-CN.md
+++ b/gxip-004/README-CN.md
@@ -39,6 +39,7 @@ struct offline_operation : public base_operation
     };  
 
     account_id_type                             from;
+    validtor_status                             new_status;
     extensions_type                             extensions;
 
     account_id_type fee_payer() const { return from; }
@@ -56,6 +57,10 @@ struct offline_operation : public base_operation
 2. 验证人节点状态是online
 3. 账户余额可以支付交易手续费
 
+cli_wallet构造交易时new_status默认值为offline,表示主动下线。
+
+为了记录验证人节点禁闭的交易历史,系统强制验证人节点禁闭时,执行一个virutal op,其中new_status为jailed。
+
 #### 节点状态
 验证人节点的状态有3种:
 ```