# 提案和链升级

随着公链的运行，会有若干功能升级或 BUG 修复的需求。要在分布式去中心化网络中完成升级，需要通过提案机制。

{% hint style="info" %}
注意

不是所有的升级都需要提案，例如小的 API 修复，不会影响到链上数据，则节点可以自由选择升级或维持现有版本。

需要升级的情况是指：

* 新增内置合约类型
* 原有内置合约类型的部分处理逻辑有更新
* 新增链基础可配置项
  {% endhint %}

### 提案机制

提案由超级代表发起，一般是修改一个或一组链上参数。例如 energy 价格，是否支持 TVM 的某一新功能，是否开启某种交易类型等。

考虑到提案相关的术语被严重混淆，这里作出界定：

> 提案编号
>
> 即发起的提案在链上的编号，每新发起一个提案，编号 +1.

> 提案参数
>
> 提案所修改的参数名。例如 `EnergyFee`, `AllowTvmSolidity059` 等

> 提案值
>
> 提案参数对应的值。大部分提案是 bool 型，且只能开启，即 =1 。另外还有一部分是 long 型，例如费用相关。

提案发起后，有约3天的投票时间，各超级代表可以选择投票、弃票(不投票)、取消投票(取消之前的投票)。3天后的下一个维护周期进行计票，只记 Active Witness 的票，当有效票数 >= 7/10 \* Active Witness 个数时，提案通过，参数被修改。

若某一节点的 java-tron 版本过旧，遇到不支持的提案参数，会直接报错，停止节点同步。此时节点维护者需要尽快更新 java-tron 版本到最新。

当提案功能通过后，网络还需要判断所有 Active Witness 运行的版本是否已经足够新，可以正常支持新功能，否则网络将变得不稳定，block miss 增多。这里使用 Block Version Fork 机制来判断当前的 Active Witness 节点程序版本是否满足。

### Block Version Fork 机制

Active Witness 产的所有块，都会被自己的地址签名，同时还有自己的 Block Version. 在进行不兼容版本升级时候，Block Version 会增加。

节点在同步区块的过程中，会记录每个 Active Witness 最近一次产块的 Block Version. 提案生效时，会对此作出判断，确认 Active Witness 的版本达到要求。

{% hint style="warning" %}
注意

4.0.1 之前，Block Version Fork 机制要求必须所有 Active Witness 都升级为新版本之后，新功能才生效。

4.0.1 引入了 Block Version min\_upgraded 概念，使得即使有 Active Witness 拒绝升级新版本，新功能依然可以生效，此时拒绝升级新版本的节点将在新功能相关交易出现时出错，停止同步。

min\_upgraded 计算时候使用了 min\_upgraded\_rate \* num\_of\_active\_witness + 1 的错误方法（之前算法是计数 >= 22, 在全网节点数不足的时候无法通过，但比率是对的），导致在极端情况会反直觉。例如假设当前全网只有 20 个节点，要求 min\_upgraded = 0.75, 则至少需要 16 个节点升级（而不是 15）。

此 BUG 将在 4.1 版本上线。
{% endhint %}

### 提案参数列表

所有提案参数列表如下：

```
MAINTENANCE_TIME_INTERVAL(0), //ms  ,0
ACCOUNT_UPGRADE_COST(1), //drop ,1
CREATE_ACCOUNT_FEE(2), //drop ,2
TRANSACTION_FEE(3), //drop ,3
ASSET_ISSUE_FEE(4), //drop ,4
WITNESS_PAY_PER_BLOCK(5), //drop ,5
WITNESS_STANDBY_ALLOWANCE(6), //drop ,6
CREATE_NEW_ACCOUNT_FEE_IN_SYSTEM_CONTRACT(7), //drop ,7
CREATE_NEW_ACCOUNT_BANDWIDTH_RATE(8), // 1 ~ ,8
ALLOW_CREATION_OF_CONTRACTS(9), // 0 / >0 ,9
REMOVE_THE_POWER_OF_THE_GR(10),  // 1 ,10
ENERGY_FEE(11), // drop, 11
EXCHANGE_CREATE_FEE(12), // drop, 12
MAX_CPU_TIME_OF_ONE_TX(13), // ms, 13
ALLOW_UPDATE_ACCOUNT_NAME(14), // 1, 14
ALLOW_SAME_TOKEN_NAME(15), // 1, 15
ALLOW_DELEGATE_RESOURCE(16), // 0, 16
TOTAL_ENERGY_LIMIT(17), // 50,000,000,000, 17
ALLOW_TVM_TRANSFER_TRC10(18), // 1, 18
TOTAL_CURRENT_ENERGY_LIMIT(19), // 50,000,000,000, 19
ALLOW_MULTI_SIGN(20), // 1, 20
ALLOW_ADAPTIVE_ENERGY(21), // 1, 21
UPDATE_ACCOUNT_PERMISSION_FEE(22), // 100, 22
MULTI_SIGN_FEE(23), // 1, 23
ALLOW_PROTO_FILTER_NUM(24), // 1, 24
ALLOW_ACCOUNT_STATE_ROOT(25), // 1, 25
ALLOW_TVM_CONSTANTINOPLE(26), // 1, 26
// ALLOW_SHIELDED_TRANSACTION(27), // 27
// SHIELDED_TRANSACTION_FEE(28), // 28
ADAPTIVE_RESOURCE_LIMIT_MULTIPLIER(29), // 1000, 29
ALLOW_CHANGE_DELEGATION(30), //1, 30
WITNESS_127_PAY_PER_BLOCK(31), //drop, 31
ALLOW_TVM_SOLIDITY_059(32), // 1, 32
ADAPTIVE_RESOURCE_LIMIT_TARGET_RATIO(33), // 10, 33
// SHIELDED_TRANSACTION_CREATE_ACCOUNT_FEE(34); // 34
FORBID_TRANSFER_TO_CONTRACT(35), // 1, 35
ALLOW_SHIELDED_TRC20_TRANSACTION(39); // 1, 39
```
