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 archive和db 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参数,且不再支持“兼容模式”,从而确保了跨架构环境下的数据无缝迁移。
- 强制 JDK 8:
由于 JDK 8 以上版本移除了 Java EE 模块(基于 JEP 320),这会导致
-
其他变动
- 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)
- JDK17 兼容性
- 源代码: 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),需通过提案投票的方式开启,且开启后不可关闭。
- TIP: https://github.com/tronprotocol/tips/blob/master/tip-6780.md
- 源代码: https://github.com/tronprotocol/java-tron/pull/6383 https://github.com/tronprotocol/java-tron/pull/6448
Net¶
1. 修复同步区块时报出的 gt highNoFork 和 gt 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。
4. 引入 P2P 消息处理速率限制¶
在 Democritus 之前的版本中,并未限制 P2P 消息的处理速率,但节点的处理能力受限于带宽、CPU 和内存等物理资源。处理大量 P2P 消息会导致资源过度消耗。因此,Democritus 版本引入了针对单一对等节点(Peer)的 P2P 消息限速机制。当特定消息的发送频率超过设定阈值时,节点将丢弃该消息并主动断开与该 peer 的连接。具体限速策略如下:具体策略如下:
- 链同步报文(
SyncBlockChainMessage): 在节点同步期间(即ChainInventory.remainNum > 0),处理频率限制为 3 QPS; - 区块请求报文(
FetchInvDataMessage): 在区块同步阶段,请求区块数据时,处理频率限制为 3 QPS; -
断连控制报文(
P2P_DISCONNECT): 消息处理频率限制为 1 QPS。
5. 优化对 PeerConnection 中字段的并发访问¶
Democritus 版本优化了 PeerConnection 的并发访问处理逻辑:为并发访问的字段加 volatile 关键字修饰,同时,调整变量赋值先后顺序,以减少网络同步过程中因状态并发修改而导致的异常。
其它变更¶
配置及依赖
1. 优化 zkSNARK 配置开关¶
Democritus 版本新增配置项 node.allowShieldedTransactionApi 以代替 node.fullNodeAllowShieldedTransaction。
- 源代码: https://github.com/tronprotocol/java-tron/pull/6371 https://github.com/tronprotocol/java-tron/pull/6427
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。
- 源代码: https://github.com/tronprotocol/java-tron/pull/6368 https://github.com/tronprotocol/java-tron/pull/6452
4. 优化缺失 Blackhole 账户配置时的日志提示¶
Democritus 版本优化了在缺失 Blackhole 账户配置时的日志提示,通过更具引导性的提示信息,明确告知用户需要在 config.conf 中正确配置 Blackhole 账户地址。
5. 丰富 FullNode 命令行选项¶
Democritus 版本移除独立的 SolidityNode.jar 与 KeystoreFactory.jar 文件,并将其功能整合至 FullNode 中。用户可通过命令行参数 --solidity 启动 SolidityNode 服务,或通过 --keystore-factory 启动 KeystoreFactory 服务。该优化在保持原有功能完整性的同时,显著缩短了项目构建时间并降低了存储占用,进一步简化了运维部署流程。
- 源代码: https://github.com/tronprotocol/java-tron/pull/6397 https://github.com/tronprotocol/java-tron/pull/6450 https://github.com/tronprotocol/java-tron/pull/6446
6. 对齐 config.conf 与 tron-deployment 中的配置项¶
Democritus 版本实现了 config.conf 与 tron-deployment 存储库中配置项的同步,并优化更新了 seed.node.ip.list 种子节点列表。
7. 规范化全量配置标准与注释准则¶
Democritus 版本引入了一份包含全量配置项的标准配置文件,任何未收录于此文件的配置项均被视为无效或已过期,同时定义了配置文件内的注释规范:
- 整行注释以”#”开头
- 配置项后面的注释用”#”或”//”均可
-
没有默认值的配置项以”#”开头作为注释
8. 升级依赖库¶
Democritus 版本对 grpc-java、Spring、Jackson、Jetty 等核心依赖库进行了版本升级。
| 组名 | 包名 | 原版本号 | 新版本号 |
|---|---|---|---|
| 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 的编译支持,还在性能与稳定性方面进行了多项优化与改进:
- 新增对 JDK 17 的编译支持(#113)。
- 升级grpc-netty、protobuf依赖库 (#110)。
- 优化连接池(connPool)与资源管理逻辑 (#116)。
- 实现了带验证机制的并发外部 IP 获取 (#120, #121)。
-
优化网络探测逻辑 (#122)
-
源代码: https://github.com/tronprotocol/java-tron/pull/6400 https://github.com/tronprotocol/java-tron/pull/6429 https://github.com/tronprotocol/java-tron/pull/6431 https://github.com/tronprotocol/java-tron/pull/6481
9. 定义版本号为 4.8.1¶
调整 java-tron 代码内的版本号,定义 Democritus 的版本号为 4.8.1。
事件服务
1. 优化事件服务对 Transaction Info 的获取逻辑¶
Democritus 版本解决了获取 Transaction info 时的兼容性问题。如果事件服务从 transactionRetStore 数据库读取不到数据,则会兼容地回退到从 transactionHistoryStore 数据库读取。
- 源代码: https://github.com/tronprotocol/java-tron/pull/6443 https://github.com/tronprotocol/java-tron/pull/6453
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 版本对单元测试的资源管理进行了系统性优化,在显著提升执行效能的同时,进一步增强了测试环境的纯净度与稳定性:
- 规范清理机制: 引入了更严格的文件清理机制,确保测试产生的临时数据在执行后被彻底移除。
- 提升执行效能: 通过优化高耗时用例,使单测总时长最高缩短了 30%。
- 加固资源释放: 修复了已知的资源泄漏问题,并标准化了资源释放逻辑。
-
增强稳定运行: 解决了相关单测中的空指针异常。
-
源代码: https://github.com/tronprotocol/java-tron/pull/6437 https://github.com/tronprotocol/java-tron/pull/6483 https://github.com/tronprotocol/java-tron/pull/6486
2. 引入 gRPC 超时机制¶
针对在 arm64 架构环境下,在高频压力测试(如重复执行 100 次以上)时,可能出现的单测阻塞的问题,Democritus 版本引入 gRPC 超时机制:为单个 gRPC 测试用例设置 5 秒的超时时间,并为此次单测执行过程设定 30 秒的超时时间。一旦触发超时限制,系统将自动跳过当前阻塞点并继续执行后续逻辑,从而保障了自动化测试任务的连续性与完整性。
- 源代码: https://github.com/tronprotocol/java-tron/pull/6441 https://github.com/tronprotocol/java-tron/pull/6460
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),将提案过期时间从本地配置模式切换为链上治理模式。
- TIP:https://github.com/tronprotocol/tips/blob/master/tip-767.md
- 源代码: https://github.com/tronprotocol/java-tron/pull/6399 https://github.com/tronprotocol/java-tron/pull/6454
2. 修复 Protocol Buffer 文件语法兼容性问题¶
修复了 ReasonCode 结构体中十六进制赋值时的大小写错误,解决了 JavaScript 环境下的编译兼容性问题。
API¶
1. 新增 eth_getBlockReceipts API¶
Democritus 版本新增 eth_getBlockReceipts 接口,用于查询指定区块中的所有交易回执(Transaction Receipts)。对于创世块,轻节点已经裁剪的块和未生产的块返回 null。
- 参数:区块标识符(必填)。支持十六进制字符串表示的区块号、blockHash(有无0x开头均支持)、或标签( "latest"、"earliest"、"finalized")三种类型。
-
返回值:返回一个对象数组。每个对象为该区块内一笔交易的回执,和 eth_getTransactionReceipt 返回结构一致。
-
源代码: https://github.com/tronprotocol/java-tron/pull/6379 https://github.com/tronprotocol/java-tron/pull/6433
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。
- 源代码: https://github.com/tronprotocol/java-tron/pull/6373 https://github.com/tronprotocol/java-tron/pull/6451
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