跳转至

GreatVoyage-4.8.1(Democritus)

核心协议

1. 扩展对 ARM64 架构与 JDK 17 的兼容性

为进一步丰富 java-tron 的技术生态,Democritus 版本新增了对 arm64 架构的运行支持,在 arm64 环境下,目前仅支持使用 JDK 17 和 RocksDB 数据库。

  • ARM64 架构
    • 强制 JDK 17: 选用 JDK 17 作为 Java 运行环境,以确保节点在 arm64 架构下运行的稳定性(基于JEP 237、388、391)。
    • 强制 RocksDB: 由于 LevelDB JNI 实现缺乏对 arm64 架构的适配及社区维护,arm64 环境下仅支持 RocksDB (v9.7.4)
    • 浮点计算适配: 浮点计算已通过提案改为使用 StrictMath,以确保不同平台上的计算结果一致。但在提案生效前,由于 arm64 与 x86_64 的浮点运算实现上存在差异,计算结果可能不一致。因此,在 arm64 架构下通过硬编码保持结果与 x86_64 主网一致。
      • 注意: 如果其他x86_64平台下的私有网络使用浮点计算(尤其是涉及pow的Bancor交易),可能导致 arm64 节点无法从零高度完成数据同步。在此类场景下,如需部署 arm64 节点,请务必使用已有区块高度的数据库快照启动。
    • Toolkit工具限制: 在arm64环境下,不支持LevelDB相关命令 (即,db archivedb convert)。
  • x86_64架构下的变更
    • 强制 JDK 8: 由于 JDK 8 以上版本移除了 Java EE 模块(基于 JEP 320),这会导致 @PostConstruct 等注解失效,进而引发空指针异常和区块同步失败。为此,Democritus 版本在 x86_64 架构下引入了 JDK 8 强制校验,以确保运行环境的稳定性。
    • RocksDB/LevelDB兼容性限制: 考虑到 x86_64 与 arm64 环境下 RocksDB 版本对 LevelDB 的兼容性存在差异(x86_64:v5.15.10 支持,而arm64: v9.7.4 不支持),为防止在 arm64 环境下因强行打开 LevelDB 时报数据库损坏错误,Democritus 版本统一禁用了 RocksDB 对 LevelDB 的兼容访问,以确保 x86_64 与 arm64 环境在数据迁移和运行时行为完全一致(此前已通过兼容方式成功打开的存量数据库不受影响)。同时,该版本还优化了 LevelDB 尝试打开 RocksDB 时的错误提示,并标准化了两者的接口定义与异常处理逻辑。
    • Toolkit工具优化: 在 Democritus 之前的版本中,db convert命令默认采用兼容模式进行数据转换,仅修改配置文件中的 engine.properties 为 RocksDB,而底层数据仍保留为 LevelDB 格式。为对齐 arm64 架构对 RocksDB 的硬性存储要求,Democritus 版本重构了db convert 命令,使其默认采用非兼容模式进行数据转换(即原–safe 参数逻辑),相应地,新版本不再单独提供 –safe 参数,且不再支持“兼容模式”,从而确保了跨架构环境下的数据无缝迁移。
  • 其他变动

    • JDK17 兼容性
      • 空指针兼容: 优化了空指针提示信息,方便问题定位(基于 JEP 358)。
      • 数字转换异常兼容: 优化了数字转换异常提示,增加了转换进制错误提示(基于 JDK-8176425)。
      • JDK 版本解析兼容: 适配了 JDK 10 以上版本号格式变化(基于 JEP 223)。
      • var 推断关键字: 支持 var 类型推断机制(基于 JEP 286)。
    • RocksDB 资源优化
      • 增加最大句柄设置参数: 新增参数 dbSettings.maxOpenFiles,默认值为 5000(此前强制且不可配置),开发者可根据服务器负载进行调配。
      • 资源释放优化: 对 RocksDB 资源设置了合理的生命周期,及时释放已使用完资源,避免潜在内存泄漏问题。
    • 依赖变更 为支持 JDK 17 和 ARM64 架构,进行了以下依赖变更:

      组名 包名 原版本号 新版本号
      org.projectlombok lombok 1.18.12 1.18.34
      javax.annotation javax.annotation-api - 1.3.2
      javax.jws javax.jws-api - 1.1
      org.aspectj aspectjrt 1.8.13 1.9.8
      org.rocksdb rocksdbjni - 9.7.4(arm)
  • Issue:https://github.com/tronprotocol/java-tron/issues/5954

  • 源代码: https://github.com/tronprotocol/java-tron/pull/6327 https://github.com/tronprotocol/java-tron/pull/6421 https://github.com/tronprotocol/java-tron/pull/6440 https://github.com/tronprotocol/java-tron/pull/6455 https://github.com/tronprotocol/java-tron/pull/6457 https://github.com/tronprotocol/java-tron/pull/6459 https://github.com/tronprotocol/java-tron/pull/6472 https://github.com/tronprotocol/java-tron/pull/6502

TVM

1. 修改 SELFDESTRUCT 指令的行为

继 GreatVoyage-4.8.0(Kant) 通过 TIP-652 提出废弃 SELFDESTRUCT 指令的建议后,Democritus 版本正式引入了对 SELFDESTRUCT 指令行为的调整。此项变更是为了深度兼容 Ethereum 的 EIP-6780,确保 TVM 与 EVM 的行为一致性,详细规范请参考 TIP-6780。

在 Democritus 之前的版本中, SELFDESTRUCT 允许合约自我销毁,并将资金转移到指定地址,同时删除该合约账户的所有数据(代码、存储、账户本身)。 Democritus 版本对SELFDESTRUCT指令的修改如下:

  • 限制 SELFDESTRUCT 的使用场景: 仅在合约被创建的同一笔交易中调用 SELFDESTRUCT 时,才允许其真正删除账户数据(如代码、存储、账户本身)。
    • 场景一:非同一交易中调用 SELFDESTRUCT(默认大多数情况)
      • 不允许真正销毁账户。
      • 当前合约的调用会立即停止。
      • 不会删除任何数据,包括:存储键(storage keys)、代码(code)、账户本身。但会将账户中的所有资产(TRX、质押的TRX、TRC10 代币)转移至目标地址。
      • 如果目标地址就是合约自身,资产不会燃烧。
    • 场景二:同一交易中调用 SELFDESTRUCT (即合约创建后立即自毁),保留旧有行为,即:
      • 当前合约的调用会立即停止。
      • 删除账户的所有数据。
      • 将所有资产转移给目标地址。
      • 如果目标是合约自身,则该合约的余额会被设为 0,资产会被燃烧。
  • 能量(Energy)成本调整: 将 SELFDESTRUCT 操作码的固定能量成本,从原来的 0 增加到 5000,提高使用门槛,进一步限制滥用。

注意,该功能由 TRON 网络的第 94 号参数控制。Democritus 部署后默认关闭(值为 0),需通过提案投票的方式开启,且开启后不可关闭。

Net

1. 修复同步区块时报出的 gt highNoForkgt lastNum 错误

同步服务在个别极端场景中会打印整个异常堆栈,该日志输出不符合其错误级别,需要进行调整。调整后日志只输出具体异常信息,不再打印异常堆栈。

2. 优化轻节点对 FORKED 状态的判定逻辑

在 Democritus 之前的版本中,当轻节点与高度比它低的全节点进行同步时,若全节点的最高固化块不在轻节点的本地主链上,握手时的断连原因会被误判为 FORKED

Democritus版本优化了轻节点对 FORKED 状态的判定逻辑,引入了一个额外条件,只有当轻节点的最低块高度低于全节点的最高固化块高度时,才判定为 FORKED;其他情况时是 LIGHT_NODE_SYNC_FAIL

3. 优化 P2P 断连原因

在 Democritus 之前的版本中,部分 Peer 断开场景下 P2P_DISCONNECT 消息携带的原因代码(Reason Code)定义较为模糊,导致节点无法准确感知真正的断连原因,不利于网络排障。Democritus 版本针对以下三类场景的断连原因进行了优化:

  • 场景1: 节点收到 peer 发送的区块后,如果由于区块签名验证失败而断开与 peer 的连接,则断连原因由 UNKNOWN 改成 BAD_BLOCK
  • 场景2: 在 Democritus 之前的版本中,节点在进行 HelloMessage 的有效性检查时,若发生错误,则返回 UNEXPECTED_IDENTITY 错误代码,但实际上不会执行与身份相关的有效性检查。因此,Democritus版本将这种场景的断连原因从 UNEXPECTED_IDENTITY 改为 INCOMPATIBLE_PROTOCOL
  • 场景3: 当接收到的 P2P_HELLO 消息中包含的区块 ID 的长度不等于32时,断连原因由 UNKNOWN 改为 INCOMPATIBLE_PROTOCOL

  • 源代码: https://github.com/tronprotocol/java-tron/pull/6394

4. 引入 P2P 消息处理速率限制

在 Democritus 之前的版本中,并未限制 P2P 消息的处理速率,但节点的处理能力受限于带宽、CPU 和内存等物理资源。处理大量 P2P 消息会导致资源过度消耗。因此,Democritus 版本引入了针对单一对等节点(Peer)的 P2P 消息限速机制。当特定消息的发送频率超过设定阈值时,节点将丢弃该消息并主动断开与该 peer 的连接。具体限速策略如下:具体策略如下:

  • 链同步报文(SyncBlockChainMessage): 在节点同步期间(即 ChainInventory.remainNum > 0),处理频率限制为 3 QPS;
  • 区块请求报文(FetchInvDataMessage): 在区块同步阶段,请求区块数据时,处理频率限制为 3 QPS;
  • 断连控制报文(P2P_DISCONNECT): 消息处理频率限制为 1 QPS。

  • 源代码: https://github.com/tronprotocol/java-tron/pull/6393

5. 优化对 PeerConnection 中字段的并发访问

Democritus 版本优化了 PeerConnection 的并发访问处理逻辑:为并发访问的字段加 volatile 关键字修饰,同时,调整变量赋值先后顺序,以减少网络同步过程中因状态并发修改而导致的异常。

其它变更

配置及依赖

1. 优化 zkSNARK 配置开关

Democritus 版本新增配置项 node.allowShieldedTransactionApi 以代替 node.fullNodeAllowShieldedTransaction

2. 升级 Gradle 以支持 JitPack 发布

Gradle 版本已升级到 7.6.4,使用 maven-publish 插件支持 jitpack 发布。

3. 优化本地 Witness 初始化逻辑

Democritus 版本优化了本地 Witness 初始化逻辑,只有超级代表节点才执行私钥和地址的初始化逻辑,若是配置了无效 witness 地址, 程序会抛异常并且退出。同时,Democritus 版本将密码库从 org.bouncycastle:bcprov-jdk15on:1.69 升级到了 org.bouncycastle:bcprov-jdk18on:1.79

4. 优化缺失 Blackhole 账户配置时的日志提示

Democritus 版本优化了在缺失 Blackhole 账户配置时的日志提示,通过更具引导性的提示信息,明确告知用户需要在 config.conf 中正确配置 Blackhole 账户地址。

5. 丰富 FullNode 命令行选项

Democritus 版本移除独立的 SolidityNode.jarKeystoreFactory.jar 文件,并将其功能整合至 FullNode 中。用户可通过命令行参数 --solidity 启动 SolidityNode 服务,或通过 --keystore-factory 启动 KeystoreFactory 服务。该优化在保持原有功能完整性的同时,显著缩短了项目构建时间并降低了存储占用,进一步简化了运维部署流程。

6. 对齐 config.conf 与 tron-deployment 中的配置项

Democritus 版本实现了 config.conf 与 tron-deployment 存储库中配置项的同步,并优化更新了 seed.node.ip.list 种子节点列表。

7. 规范化全量配置标准与注释准则

Democritus 版本引入了一份包含全量配置项的标准配置文件,任何未收录于此文件的配置项均被视为无效或已过期,同时定义了配置文件内的注释规范:

8. 升级依赖库

Democritus 版本对 grpc-javaSpringJacksonJetty 等核心依赖库进行了版本升级。

组名 包名 原版本号 新版本号
org.eclipse.jetty jetty-server 9.4.53.v20231009 9.4.57.v20241219
com.cedarsoftware java-util 1.8.0 3.2.0
com.fasterxml.jackson.core jackson-databind 2.13.4.2 2.18.3
org.springframework spring-context 5.3.18 5.3.39
org.springframework spring-test 5.2.0.RELEASE 5.3.39
io.grpc grpc-netty, grpc-protobuf, grpc-stub, grpc-core, grpc-services 1.60.0 1.75.0
com.google.protobuf protobuf-java, protobuf-java-util, protoc 3.25.5 3.25.8

删除依赖库:

组名 包名
com.carrotsearch java-sizeof
org.springframework spring-tx
org.springframework spring-web
org.hamcrest hamcrest-junit
com.google.inject guice
io.vavr vavr

此外,Democritus 版本将底层网络库 libp2p 从 2.2.6 升级至 2.2.7。此版本不仅新增了对 JDK 17 的编译支持,还在性能与稳定性方面进行了多项优化与改进:

9. 定义版本号为 4.8.1

调整 java-tron 代码内的版本号,定义 Democritus 的版本号为 4.8.1。

事件服务

1. 优化事件服务对 Transaction Info 的获取逻辑

Democritus 版本解决了获取 Transaction info 时的兼容性问题。如果事件服务从 transactionRetStore 数据库读取不到数据,则会兼容地回退到从 transactionHistoryStore 数据库读取。

2. 移除 Bloom 过滤器写入开关

section-bloom 数据库用于存储合约日志的 Bloom 过滤器及其对应的区块索引。在处理 eth_getLogs 接口请求时,节点会查询该数据库,快速定位命中区块。这是事件检索的关键步骤。

在 Democritus 之前的版本中: 该数据库的写入受到 node.jsonrpc.httpFullNodeEnable 配置项的控制。若该配置项未开启,节点将不会记录区块的 Bloom 值数据到 section-bloom 数据库。由于此类索引数据在后期无法自动追溯补全,导致用户即使后续开启配置,也无法查询到关闭期间的历史交易事件。

因此,Democritus 版本正式移除了对该配置项的依赖,改为始终向 section-bloom 数据库写入数据,确保了 Bloom 过滤器索引的持续性与完整性,彻底解决了因配置开关状态导致 eth_getLogs 接口查询不到历史数据的问题。

3. 优化事件服务关闭逻辑

Democritus 版本优化了 HistoryEventService 线程关闭逻辑,通过引入全局变量 isClosed,确保即使 close 函数被重复调用,相关资源也只会释放一次。该优化有效避免了资源的重复释放及由此引发的异常,提升了系统退出时的稳定性。

单元测试

1. 优化测试用例的资源管理

Democritus 版本对单元测试的资源管理进行了系统性优化,在显著提升执行效能的同时,进一步增强了测试环境的纯净度与稳定性:

2. 引入 gRPC 超时机制

针对在 arm64 架构环境下,在高频压力测试(如重复执行 100 次以上)时,可能出现的单测阻塞的问题,Democritus 版本引入 gRPC 超时机制:为单个 gRPC 测试用例设置 5 秒的超时时间,并为此次单测执行过程设定 30 秒的超时时间。一旦触发超时限制,系统将自动跳过当前阻塞点并继续执行后续逻辑,从而保障了自动化测试任务的连续性与完整性。

3. 确保单测正确自动停止

Democritus 版本优化了 ConditionalStopTest 单元测试的停止判定逻辑。在 SR 产块场景下,即使遇到出块顺序发生变化的情况,也能准确识别停止条件,从而使单测能够按照预期正确、自动地停止执行。

4. 增强日志上下文隔离机制

Democritus 版本修复了 TronErrorTest 单元测试引发的全局 logger 配置污染问题。通过在 LogService 加载配置阶段,增强错误与警告信息的输出,并在单元测试里显式恢复 logger 上下文,确保了不同测试用例间日志环境的完全隔离。这一改进不仅杜绝了用例间的日志行为干扰,也为快速定位 Logback 配置加载异常提供了更清晰的诊断依据。

5. 修复测试用例中的 CheckStyle 问题

测试用例文件中一个注释的语句增加换行,修复测试用例中的 checkStyle 问题。

Document

1. 更新 Readme 中的 FullNode JVM 启动参数

调整 java-tron 在 x86_64 和 arm64 平台下的 JVM 启动参数,旨在确保 FullNode 节点能够在最低硬件配置下满足基本的容灾需求;同时,修改硬件要求,推荐采用更为稳定的机器配置。

2. 修复 README 徽章显示问题

Democritus 版本修复了 README 文档顶部 GitHub 徽章(Badge)显示为 "unknown" 的问题。通过更新徽章的图片链接,确保了项目信息的正常展示。

3. 更新 README 中的社区群组与文档链接

Democritus 版本更新了 README 中的TRON官方开发讨论群组和文档链接。

其它变更

1. 将提案过期时间切换为链上治理模式

为确保全网治理参数的高度统一并提升协议的一致性,Democritus 版本引入了TRON网络的第 92 号链上参数(PROPOSAL_EXPIRE_TIME),将提案过期时间从本地配置模式切换为链上治理模式。

2. 修复 Protocol Buffer 文件语法兼容性问题

修复了 ReasonCode 结构体中十六进制赋值时的大小写错误,解决了 JavaScript 环境下的编译兼容性问题。

API

1. 新增 eth_getBlockReceipts API

Democritus 版本新增 eth_getBlockReceipts 接口,用于查询指定区块中的所有交易回执(Transaction Receipts)。对于创世块,轻节点已经裁剪的块和未生产的块返回 null

2. 新增查询超级代表实时票数的 API

Democritus 版本新增getpaginatednowwitnesslist接口,用于查询当前 epoch 的实时票数并且返回按降序排序后的witness分页列表,其中票数=上轮维护期结束时的最终票数+当前 epoch 中的投票增量(可能为负)。

  • 参数
    • offset : long ,起始下标,要求 >=0
    • limit : long ,返回条数,要求 >0 ,最大值为 1000
    • visible : boolean ,可选;控制返回 JSON 的address可读编码
  • 返回值
    • 成功时:返回按“实时票数”降序排序的超级代表数组,每项包含地址、票数、URL 等。
    • 失败时:当参数不正确(如: limit<=0 、offset<0、或offset>=总Witness数)时,返回空对象 {}, http code = 200。

该API特有的错误与边界:当处于维护期、并且请求的是非固化数据时,抛出维护期不可用异常, http code = 200。

3. 优化 eth_call 接口的返回信息

在 Democritus 之前的版本中,当合约执行失败时,eth_call 接口仅返回简单的错误消息(如 "REVERT opcode executed"),而其 data 字段始终为空,缺乏具体错误信息,导致开发者难以追查问题。Democritus 版本定义了 JsonRpcException 作为所有 JSON-RPC 异常的基类,同时,实现了 JsonRpcErrorResolver 类,负责 data 字段的生成逻辑。

demo合约 为例,请求 testInsufficientBalance 方法时,修改前返回如下信息,

{
    "jsonrpc": "2.0",
    "id": 1,
    "error": {
        "code": -32000,
        "message": "REVERT opcode executed",
        "data": "{}"
    }
}

修改后data字段返回了错误信息,开发者可以通过abi解析获取具体错误原因(同以太坊节点策略保持一致,除默认的 Error(string)之外均返回未解析数据)。

{
    "jsonrpc": "2.0",
    "id": 1,
    "error": {
        "code": -32000,
        "message": "REVERT opcode executed",
       "data": "0xcf47918100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000064"
    }
}

4. 优化 eth_getLogs 和 eth_getFilterLogs 性能

eth_getLogs 等事件查询接口依赖于一个用于查询 Bloom 数据库的 partialMatch 函数。查询条件是为每个 topic 或 address 生成的 3 个 bitIndex。由于 Bloom 过滤器存在位数限制(2048 位),当 topic 数量达到 683 时,683 * 3 > 2048,必然会发生位冲突,导致重复的 bitIndex,从而产生重复查询。优化方案是在查询前对 bitIndex 进行去重,以减少数据库查询次数。

下表对比了不同 topic 和 address 数量下,bitIndex 的重复率和 partialMatch 的执行时间。从中可见,随着 topic 数量的增加,bitIndex 的重复度越高,优化后的性能提升越显著。

指标 (Metric) 10 Topics 100 Topics 500 Topics 1000 Topics 2000 Addresses
原始耗时 (ms) 2.28 2.51 9.35 21.41 40.15
优化后耗时 (ms) 2.13 2.13 6.95 12.80 15.24
提升率 6.58% 15.14% 25.67% 40.21% 62.04%
重复率 0% 7.60% 29.41% 47.31% 67.62%

To a wise and good man the whole earth is his fatherland.

---Democritus