From 2eccf3ac485610966a1218c7bd9e92dfa6f6af4a Mon Sep 17 00:00:00 2001 From: GrapeS Date: Thu, 9 Apr 2026 10:29:08 +0800 Subject: [PATCH 01/11] docs: update outdated content across all six doc files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit implement-a-customized-actuator (EN+ZH): - Fix test lifecycle: @Before/@After → @BeforeClass/@AfterClass so the Spring context is created only once per test class, not per test method - Fix Args initialization order: Args.setParam() must be called before Args.getInstance() to avoid passing a stale unconfigured instance to appTest.initServices() - Replace hardcoded dbPath with @ClassRule TemporaryFolder to keep test directories isolated and auto-cleaned - Add @Rule Timeout to guard against hangs - Remove the specific protoc v3.4.0 version note; point readers to the version declared in build.gradle instead modular-deployment (EN+ZH): - Replace CMS GC flags (-XX:+UseConcMarkSweepGC, -XX:+CMSParallelRemarkEnabled, -XX:+CMSScavengeBeforeRemark) that were removed in JDK 14 and would cause startup failures on JDK 17 (required for ARM64) - Add -Xms/-Xmx to the example and note JDK 8/17 compatibility modular-introduction (EN+ZH): - Update module count from six to eight - Add descriptions for the crypto and plugins modules Co-Authored-By: Claude Sonnet 4.6 --- docs/implement-a-customized-actuator-en.md | 52 +++++++++++----------- docs/implement-a-customized-actuator-zh.md | 52 +++++++++++----------- docs/modular-deployment-en.md | 7 ++- docs/modular-deployment-zh.md | 7 ++- docs/modular-introduction-en.md | 11 ++++- docs/modular-introduction-zh.md | 11 ++++- 6 files changed, 78 insertions(+), 62 deletions(-) diff --git a/docs/implement-a-customized-actuator-en.md b/docs/implement-a-customized-actuator-en.md index 551a6d63d3b..19eae423778 100644 --- a/docs/implement-a-customized-actuator-en.md +++ b/docs/implement-a-customized-actuator-en.md @@ -60,13 +60,11 @@ service Wallet { ``` At last, recompile the modified proto files. Compiling the java-tron project directly will compile the proto files as well, `protoc` command is also supported. -*Currently, java-tron uses protoc v3.4.0. Please keep the same version when compiling by `protoc` command.* - ```shell -# recommended +# recommended — also recompiles proto files automatically ./gradlew build -x test -# or build via protoc +# or build via protoc (ensure the protoc version matches the one declared in build.gradle) protoc -I=src/main/protos -I=src/main/protos/core --java_out=src/main/java Tron.proto protoc -I=src/main/protos/core/contract --java_out=src/main/java math_contract.proto protoc -I=src/main/protos/api -I=src/main/protos/core -I=src/main/protos --java_out=src/main/java api.proto @@ -210,48 +208,52 @@ At last, run a test class to validate whether the above steps are correct: ```java public class SumActuatorTest { private static final Logger logger = LoggerFactory.getLogger("Test"); - private String serviceNode = "127.0.0.1:50051"; - private String confFile = "config-localtest.conf"; - private String dbPath = "output-directory"; - private TronApplicationContext context; - private Application appTest; - private ManagedChannel channelFull = null; - private WalletGrpc.WalletBlockingStub blockingStubFull = null; + private static final String SERVICE_NODE = "127.0.0.1:50051"; + + @ClassRule + public static TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @Rule + public Timeout timeout = new Timeout(30, TimeUnit.SECONDS); + + private static TronApplicationContext context; + private static Application appTest; + private static ManagedChannel channelFull; + private static WalletGrpc.WalletBlockingStub blockingStubFull; /** - * init the application. + * init the application once for all tests in this class. */ - @Before - public void init() { - CommonParameter argsTest = Args.getInstance(); - Args.setParam(new String[]{"--output-directory", dbPath}, - confFile); + @BeforeClass + public static void init() throws IOException { + Args.setParam(new String[]{"--output-directory", + temporaryFolder.newFolder().toString()}, "config-localtest.conf"); context = new TronApplicationContext(DefaultConfig.class); RpcApiService rpcApiService = context.getBean(RpcApiService.class); appTest = ApplicationFactory.create(context); appTest.addService(rpcApiService); - appTest.initServices(argsTest); + appTest.initServices(Args.getInstance()); appTest.startServices(); appTest.startup(); - channelFull = ManagedChannelBuilder.forTarget(serviceNode) + channelFull = ManagedChannelBuilder.forTarget(SERVICE_NODE) .usePlaintext() .build(); blockingStubFull = WalletGrpc.newBlockingStub(channelFull); } /** - * destroy the context. + * destroy the context after all tests finish. */ - @After - public void destroy() throws InterruptedException { + @AfterClass + public static void destroy() throws InterruptedException { if (channelFull != null) { - channelFull.shutdown().awaitTermination(5, TimeUnit.SECONDS); + channelFull.shutdown(); + channelFull.awaitTermination(5, TimeUnit.SECONDS); } - Args.clearParam(); appTest.shutdownServices(); appTest.shutdown(); context.destroy(); - FileUtil.deleteDir(new File(dbPath)); + Args.clearParam(); } @Test diff --git a/docs/implement-a-customized-actuator-zh.md b/docs/implement-a-customized-actuator-zh.md index a03f6aeb228..2d1671929b8 100644 --- a/docs/implement-a-customized-actuator-zh.md +++ b/docs/implement-a-customized-actuator-zh.md @@ -62,13 +62,11 @@ service Wallet { ``` 最后重新编译修改过 proto 文件,可自行编译也可直接通过编译 java-tron 项目来编译 proto 文件: -*目前 java-tron 采用的是 protoc v3.4.0,自行编译时确保 protoc 版本一致。* - ```shell -# recommended +# 推荐方式 —— 直接编译项目,proto 文件会自动重新编译 ./gradlew build -x test -# or build via protoc +# 或者手动使用 protoc(版本需与 build.gradle 中声明的一致) protoc -I=src/main/protos -I=src/main/protos/core --java_out=src/main/java Tron.proto protoc -I=src/main/protos/core/contract --java_out=src/main/java math_contract.proto protoc -I=src/main/protos/api -I=src/main/protos/core -I=src/main/protos --java_out=src/main/java api.proto @@ -212,48 +210,52 @@ public class WalletApi extends WalletImplBase { ```java public class SumActuatorTest { private static final Logger logger = LoggerFactory.getLogger("Test"); - private String serviceNode = "127.0.0.1:50051"; - private String confFile = "config-localtest.conf"; - private String dbPath = "output-directory"; - private TronApplicationContext context; - private Application appTest; - private ManagedChannel channelFull = null; - private WalletGrpc.WalletBlockingStub blockingStubFull = null; + private static final String SERVICE_NODE = "127.0.0.1:50051"; + + @ClassRule + public static TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @Rule + public Timeout timeout = new Timeout(30, TimeUnit.SECONDS); + + private static TronApplicationContext context; + private static Application appTest; + private static ManagedChannel channelFull; + private static WalletGrpc.WalletBlockingStub blockingStubFull; /** - * init the application. + * 整个测试类只初始化一次应用上下文。 */ - @Before - public void init() { - CommonParameter argsTest = Args.getInstance(); - Args.setParam(new String[]{"--output-directory", dbPath}, - confFile); + @BeforeClass + public static void init() throws IOException { + Args.setParam(new String[]{"--output-directory", + temporaryFolder.newFolder().toString()}, "config-localtest.conf"); context = new TronApplicationContext(DefaultConfig.class); RpcApiService rpcApiService = context.getBean(RpcApiService.class); appTest = ApplicationFactory.create(context); appTest.addService(rpcApiService); - appTest.initServices(argsTest); + appTest.initServices(Args.getInstance()); appTest.startServices(); appTest.startup(); - channelFull = ManagedChannelBuilder.forTarget(serviceNode) + channelFull = ManagedChannelBuilder.forTarget(SERVICE_NODE) .usePlaintext() .build(); blockingStubFull = WalletGrpc.newBlockingStub(channelFull); } /** - * destroy the context. + * 所有测试结束后统一销毁上下文。 */ - @After - public void destroy() throws InterruptedException { + @AfterClass + public static void destroy() throws InterruptedException { if (channelFull != null) { - channelFull.shutdown().awaitTermination(5, TimeUnit.SECONDS); + channelFull.shutdown(); + channelFull.awaitTermination(5, TimeUnit.SECONDS); } - Args.clearParam(); appTest.shutdownServices(); appTest.shutdown(); context.destroy(); - FileUtil.deleteDir(new File(dbPath)); + Args.clearParam(); } @Test diff --git a/docs/modular-deployment-en.md b/docs/modular-deployment-en.md index ef48f54b269..ef713e50f89 100644 --- a/docs/modular-deployment-en.md +++ b/docs/modular-deployment-en.md @@ -45,12 +45,11 @@ java-tron-1.0.0/bin/FullNode -c config.conf -w JVM options can also be specified, located in `bin/java-tron.vmoptions`: ``` -# demo --XX:+UseConcMarkSweepGC +# demo (compatible with JDK 8 / JDK 17) +-Xms256m +-Xmx4g -XX:+PrintGCDetails -Xloggc:./gc.log -XX:+PrintGCDateStamps --XX:+CMSParallelRemarkEnabled -XX:ReservedCodeCacheSize=256m --XX:+CMSScavengeBeforeRemark ``` \ No newline at end of file diff --git a/docs/modular-deployment-zh.md b/docs/modular-deployment-zh.md index 54a42df7d1f..a23970d869d 100644 --- a/docs/modular-deployment-zh.md +++ b/docs/modular-deployment-zh.md @@ -43,12 +43,11 @@ java-tron-1.0.0/bin/FullNode -c config.conf -w java-tron 支持对 jvm 参数进行配置,配置文件为 bin 目录下的 java-tron.vmoptions 文件。 ``` -# demo --XX:+UseConcMarkSweepGC +# demo(兼容 JDK 8 / JDK 17) +-Xms256m +-Xmx4g -XX:+PrintGCDetails -Xloggc:./gc.log -XX:+PrintGCDateStamps --XX:+CMSParallelRemarkEnabled -XX:ReservedCodeCacheSize=256m --XX:+CMSScavengeBeforeRemark ``` \ No newline at end of file diff --git a/docs/modular-introduction-en.md b/docs/modular-introduction-en.md index eab212e9771..1a4827ded42 100644 --- a/docs/modular-introduction-en.md +++ b/docs/modular-introduction-en.md @@ -16,7 +16,7 @@ The aim of java-tron modularization is to enable developers to easily build a de ![modular-structure](https://github.com/tronprotocol/java-tron/blob/develop/docs/images/module.png) -A modularized java-tron consists of six modules: framework, protocol, common, chainbase, consensus and actuator. The function of each module is elaborated below. +A modularized java-tron consists of eight modules: framework, protocol, common, chainbase, consensus, actuator, crypto and plugins. The function of each module is elaborated below. ### framework @@ -67,4 +67,11 @@ Actuator module defines the `Actuator` interface, which includes 4 different met 4. calcFee: define the logic of calculating transaction fees Depending on their businesses, developers may set up Actuator accordingly and customize the processing of different types of transactions. - \ No newline at end of file + +### crypto + +Crypto module encapsulates cryptographic primitives used across the project, including elliptic curve key operations, hash functions and signature verification. It depends only on `common` and has no dependency on other business modules, keeping cryptographic logic isolated and auditable. + +### plugins + +Plugins module provides standalone operational tools packaged as independent executable JARs, such as `Toolkit.jar` and `ArchiveManifest.jar`. These tools support database maintenance tasks like migration, compaction and lite-node data pruning, and can be run without starting a full node. diff --git a/docs/modular-introduction-zh.md b/docs/modular-introduction-zh.md index ba2c5d4b8f5..58d8d172a7f 100644 --- a/docs/modular-introduction-zh.md +++ b/docs/modular-introduction-zh.md @@ -14,7 +14,7 @@ java-tron 模块化的目的是为了帮助开发者方便地构建出特定应 ![modular-structure](https://github.com/tronprotocol/java-tron/blob/develop/docs/images/module.png) -模块化后的 java-tron 目前分为6个模块:framework、protocol、common、chainbase、consensus、actuator,下面分别简单介绍一下各个模块的作用。 +模块化后的 java-tron 目前分为8个模块:framework、protocol、common、chainbase、consensus、actuator、crypto、plugins,下面分别简单介绍一下各个模块的作用。 ### framework @@ -65,4 +65,11 @@ actuator模块定义了 Actuator 接口,该接口有4个方法: 4. calcFee: 定义交易手续费计算逻辑 开发者可以根据自身业务实现 Actuator 接口,就能实现自定义交易类型的处理。 - \ No newline at end of file + +### crypto + +crypto 模块封装了项目中使用的密码学原语,包括椭圆曲线密钥操作、哈希函数及签名验证等。该模块仅依赖 `common`,不依赖其他业务模块,保持密码学逻辑的独立性与可审计性。 + +### plugins + +plugins 模块提供独立的运维工具,打包为可单独执行的 JAR(如 `Toolkit.jar`、`ArchiveManifest.jar`)。这些工具支持数据库迁移、压缩、轻节点数据裁剪等维护任务,无需启动完整节点即可运行。 From 01a6bdbf70b3ba71106786f87879ac0a68474c92 Mon Sep 17 00:00:00 2001 From: GrapeS Date: Thu, 9 Apr 2026 10:36:57 +0800 Subject: [PATCH 02/11] docs: set recommended JVM heap to -Xms2g -Xmx9g Co-Authored-By: Claude Sonnet 4.6 --- docs/modular-deployment-en.md | 4 ++-- docs/modular-deployment-zh.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/modular-deployment-en.md b/docs/modular-deployment-en.md index ef713e50f89..d3e7de2f5ad 100644 --- a/docs/modular-deployment-en.md +++ b/docs/modular-deployment-en.md @@ -46,8 +46,8 @@ java-tron-1.0.0/bin/FullNode -c config.conf -w JVM options can also be specified, located in `bin/java-tron.vmoptions`: ``` # demo (compatible with JDK 8 / JDK 17) --Xms256m --Xmx4g +-Xms2g +-Xmx9g -XX:+PrintGCDetails -Xloggc:./gc.log -XX:+PrintGCDateStamps diff --git a/docs/modular-deployment-zh.md b/docs/modular-deployment-zh.md index a23970d869d..9a149fa9367 100644 --- a/docs/modular-deployment-zh.md +++ b/docs/modular-deployment-zh.md @@ -44,8 +44,8 @@ java-tron-1.0.0/bin/FullNode -c config.conf -w java-tron 支持对 jvm 参数进行配置,配置文件为 bin 目录下的 java-tron.vmoptions 文件。 ``` # demo(兼容 JDK 8 / JDK 17) --Xms256m --Xmx4g +-Xms2g +-Xmx9g -XX:+PrintGCDetails -Xloggc:./gc.log -XX:+PrintGCDateStamps From 895290218ce013d448e64218cb630e87d02fb6a5 Mon Sep 17 00:00:00 2001 From: GrapeS Date: Thu, 9 Apr 2026 10:43:08 +0800 Subject: [PATCH 03/11] docs: fix code accuracy issues found by codebase verification implement-a-customized-actuator (EN+ZH): - SumContract field number: 52 is already taken by MarketSellAssetContract; change to 60 (next available number after CancelAllUnfreezeV2Contract=59) - SumActuator: add missing static import for TRANSFER_FEE from Parameter.ChainConstant (not inherited from AbstractActuator) - SumActuatorTest: Application does not have addService()/initServices()/ startServices()/shutdownServices(); replace with startup()/shutdown() which are the actual API methods Co-Authored-By: Claude Sonnet 4.6 --- docs/implement-a-customized-actuator-en.md | 9 +++------ docs/implement-a-customized-actuator-zh.md | 9 +++------ 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/docs/implement-a-customized-actuator-en.md b/docs/implement-a-customized-actuator-en.md index 19eae423778..8b6f9e1d2bf 100644 --- a/docs/implement-a-customized-actuator-en.md +++ b/docs/implement-a-customized-actuator-en.md @@ -36,7 +36,7 @@ message Transaction { AccountCreateContract = 0; TransferContract = 1; ........ - SumContract = 52; + SumContract = 60; } ... } @@ -77,6 +77,8 @@ After compilation, the corresponding .class under the java_out directory will be For now, the default Actuator supported by java-tron is located in `org.tron.core.actuator`. Creating `SumActuator` under this directory: ```java +import static org.tron.core.config.Parameter.ChainConstant.TRANSFER_FEE; + public class SumActuator extends AbstractActuator { public SumActuator() { @@ -229,11 +231,7 @@ public class SumActuatorTest { Args.setParam(new String[]{"--output-directory", temporaryFolder.newFolder().toString()}, "config-localtest.conf"); context = new TronApplicationContext(DefaultConfig.class); - RpcApiService rpcApiService = context.getBean(RpcApiService.class); appTest = ApplicationFactory.create(context); - appTest.addService(rpcApiService); - appTest.initServices(Args.getInstance()); - appTest.startServices(); appTest.startup(); channelFull = ManagedChannelBuilder.forTarget(SERVICE_NODE) .usePlaintext() @@ -250,7 +248,6 @@ public class SumActuatorTest { channelFull.shutdown(); channelFull.awaitTermination(5, TimeUnit.SECONDS); } - appTest.shutdownServices(); appTest.shutdown(); context.destroy(); Args.clearParam(); diff --git a/docs/implement-a-customized-actuator-zh.md b/docs/implement-a-customized-actuator-zh.md index 2d1671929b8..3fd494ee5c7 100644 --- a/docs/implement-a-customized-actuator-zh.md +++ b/docs/implement-a-customized-actuator-zh.md @@ -38,7 +38,7 @@ message Transaction { AccountCreateContract = 0; TransferContract = 1; ........ - SumContract = 52; + SumContract = 60; } ... } @@ -79,6 +79,8 @@ protoc -I=src/main/protos/api -I=src/main/protos/core -I=src/main/protos --java 目前 java-tron 默认支持的 Actuator 存放在该模块的 org.tron.core.actuator 目录下,同样在该目录下创建 `SumActuator` : ```java +import static org.tron.core.config.Parameter.ChainConstant.TRANSFER_FEE; + public class SumActuator extends AbstractActuator { public SumActuator() { @@ -231,11 +233,7 @@ public class SumActuatorTest { Args.setParam(new String[]{"--output-directory", temporaryFolder.newFolder().toString()}, "config-localtest.conf"); context = new TronApplicationContext(DefaultConfig.class); - RpcApiService rpcApiService = context.getBean(RpcApiService.class); appTest = ApplicationFactory.create(context); - appTest.addService(rpcApiService); - appTest.initServices(Args.getInstance()); - appTest.startServices(); appTest.startup(); channelFull = ManagedChannelBuilder.forTarget(SERVICE_NODE) .usePlaintext() @@ -252,7 +250,6 @@ public class SumActuatorTest { channelFull.shutdown(); channelFull.awaitTermination(5, TimeUnit.SECONDS); } - appTest.shutdownServices(); appTest.shutdown(); context.destroy(); Args.clearParam(); From 3d5bb28e868fa1c990a250d42a84469f8d3df1bc Mon Sep 17 00:00:00 2001 From: GrapeS Date: Thu, 9 Apr 2026 10:50:26 +0800 Subject: [PATCH 04/11] docs: fix missing api.proto import and clarify auto-registration implement-a-customized-actuator (EN+ZH): - Add the missing 'import "core/contract/math_contract.proto"' step in api.proto; without it the proto compiler cannot resolve SumContract in the InvokeSum RPC definition (compile failure) - Add a note explaining that SumActuator must live in org.tron.core.actuator: TransactionRegister.registerActuator() uses Reflections to scan that package at startup and auto-registers every AbstractActuator subclass via the super() constructor call into TransactionFactory Co-Authored-By: Claude Sonnet 4.6 --- docs/implement-a-customized-actuator-en.md | 10 +++++++++- docs/implement-a-customized-actuator-zh.md | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/docs/implement-a-customized-actuator-en.md b/docs/implement-a-customized-actuator-en.md index 8b6f9e1d2bf..9cd5b4958db 100644 --- a/docs/implement-a-customized-actuator-en.md +++ b/docs/implement-a-customized-actuator-en.md @@ -42,7 +42,13 @@ message Transaction { } ``` -Then register a function to ensure that gRPC can receive and identify the requests of this contract. Currently, gRPC protocols are all defined in `src/main/protos/api/api.proto`. To add an `InvokeSum` interface in Wallet Service: +Then register a function to ensure that gRPC can receive and identify the requests of this contract. Currently, gRPC protocols are all defined in `src/main/protos/api/api.proto`. First add the import for the new proto file at the top of `api.proto`: + +```protobuf +import "core/contract/math_contract.proto"; +``` + +Then add an `InvokeSum` interface in the Wallet service: ```protobuf service Wallet { @@ -76,6 +82,8 @@ After compilation, the corresponding .class under the java_out directory will be For now, the default Actuator supported by java-tron is located in `org.tron.core.actuator`. Creating `SumActuator` under this directory: +> **Note**: The Actuator must be placed in the `org.tron.core.actuator` package. At node startup, `TransactionRegister.registerActuator()` uses reflection to scan that package and auto-discovers every `AbstractActuator` subclass. Each subclass is instantiated once (triggering the `super()` constructor which calls `TransactionFactory.register()`), so no manual registration code is needed. + ```java import static org.tron.core.config.Parameter.ChainConstant.TRANSFER_FEE; diff --git a/docs/implement-a-customized-actuator-zh.md b/docs/implement-a-customized-actuator-zh.md index 3fd494ee5c7..1c2bcd8f082 100644 --- a/docs/implement-a-customized-actuator-zh.md +++ b/docs/implement-a-customized-actuator-zh.md @@ -44,7 +44,13 @@ message Transaction { } ``` -然后还需要注册一个方法来保证 gRPC 能够接收并识别该类型合约的请求,目前 gRPC 协议统一定义在 src/main/protos/api/api.proto,在 api.proto 中的 Wallet Service 新增 `InvokeSum` 接口: +然后还需要注册一个方法来保证 gRPC 能够接收并识别该类型合约的请求,目前 gRPC 协议统一定义在 src/main/protos/api/api.proto。首先在 `api.proto` 顶部添加对新 proto 文件的 import: + +```protobuf +import "core/contract/math_contract.proto"; +``` + +然后在 Wallet service 中新增 `InvokeSum` 接口: ```protobuf service Wallet { @@ -78,6 +84,8 @@ protoc -I=src/main/protos/api -I=src/main/protos/core -I=src/main/protos --java 目前 java-tron 默认支持的 Actuator 存放在该模块的 org.tron.core.actuator 目录下,同样在该目录下创建 `SumActuator` : +> **注意**:Actuator 必须放在 `org.tron.core.actuator` 包下。节点启动时,`TransactionRegister.registerActuator()` 会通过反射扫描该包,自动发现所有 `AbstractActuator` 的子类,并各实例化一次(触发 `super()` 构造器,进而调用 `TransactionFactory.register()`)。因此无需手动编写注册代码。 + ```java import static org.tron.core.config.Parameter.ChainConstant.TRANSFER_FEE; From d96a1f2f15e670614c342896a1700d5e189799bc Mon Sep 17 00:00:00 2001 From: GrapeS Date: Thu, 9 Apr 2026 10:54:54 +0800 Subject: [PATCH 05/11] docs: remove Windows references and fix deprecation note in deployment guide modular-deployment (EN+ZH): - Remove 'will be deprecated' note for java -jar FullNode.jar: README shows it as a fully supported launch method alongside the script - Add explicit platform note: Linux and macOS only, Windows not supported - Remove '*.bat on Windows' startup instruction: Windows is not supported per README line 39 Co-Authored-By: Claude Sonnet 4.6 --- docs/modular-deployment-en.md | 6 +++--- docs/modular-deployment-zh.md | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/modular-deployment-en.md b/docs/modular-deployment-en.md index d3e7de2f5ad..c93ba6c39d8 100644 --- a/docs/modular-deployment-en.md +++ b/docs/modular-deployment-en.md @@ -1,8 +1,8 @@ # How to deploy java-tron after modularization -After modularization, java-tron is launched via shell script instead of typing command: `java -jar FullNode.jar`. +After modularization, the recommended way to launch java-tron is via the shell script generated in `bin/`. The classic `java -jar FullNode.jar` command is still fully supported as an alternative. -*`java -jar FullNode.jar` still works, but will be deprecated in future*. +> **Supported platforms**: Linux and macOS. Windows is not supported. ## Download @@ -29,7 +29,7 @@ After unzip, two directories will be generated in java-tron: `bin` and `lib`, sh ## Startup -Use the corresponding script to start java-tron according to the OS type, use `*.bat` on Windows, Linux demo is as below: +Use the shell script to start java-tron (Linux / macOS): ``` # default java-tron-1.0.0/bin/FullNode diff --git a/docs/modular-deployment-zh.md b/docs/modular-deployment-zh.md index 9a149fa9367..27cc2ab3856 100644 --- a/docs/modular-deployment-zh.md +++ b/docs/modular-deployment-zh.md @@ -1,8 +1,8 @@ # 模块化后的 java-tron 部署方式 -模块化后,命令行下的程序启动方式将不再使用 `java -jar FullNode.jar` 的方式启动,而是使用脚本的方式启动,本文内容基于 develop 分支。 +模块化后,推荐使用 `bin/` 目录下生成的脚本启动 java-tron。原有的 `java -jar FullNode.jar` 方式仍完全支持,作为备选方式使用。 -*原有的启动方式依然保留,但即将废弃*。 +> **支持平台**:Linux 和 macOS。不支持 Windows。 ## 下载 @@ -29,7 +29,7 @@ unzip -o java-tron-1.0.0.zip ## 启动 -不同的 os 对应不同脚本,windows 即为 bat 文件,以 linux 系统为例启动 java-tron: +使用脚本启动 java-tron(Linux / macOS): ``` # 默认配置文件启动 java-tron-1.0.0/bin/FullNode From 38f5f1371e66c5d00db42d41db06447b73295ece Mon Sep 17 00:00:00 2001 From: GrapeS Date: Thu, 9 Apr 2026 11:30:55 +0800 Subject: [PATCH 06/11] chore(scripts): fix shell script bugs and modernize JVM flags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - start.sh: fix always-false `if $darwin` → `if [[ "$(uname)" == "Darwin" ]]` - start.sh: replace `$(\`echo fn\`)` anti-pattern with `$(fn)` in 8 call sites - start.sh: replace removed CMS GC flags with G1GC - start.sh: fix always-true `ALL_OPT_LENGTH -eq 0 || -gt 0` and duplicate restart - ver.sh: remove `set -x` debug mode left in by mistake - ver.sh: fix Version.java path to framework/src/main/java/org/tron/program/Version.java Co-Authored-By: Claude Sonnet 4.6 --- start.sh | 28 ++++++++++++---------------- ver.sh | 5 ++--- 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/start.sh b/start.sh index 89f13cf25a7..7317249fdee 100644 --- a/start.sh +++ b/start.sh @@ -77,7 +77,7 @@ if [ -z "$JAVA_HOME" ]; then # readlink(1) is not available as standard on Solaris 10. readLink=`which readlink` if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then - if $darwin ; then + if [[ "$(uname)" == "Darwin" ]]; then javaHome="`dirname \"$javaExecutable\"`" javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" else @@ -151,7 +151,7 @@ getLatestReleaseVersion() { } checkVersion() { - github_release_version=$(`echo getLatestReleaseVersion`) + github_release_version=$(getLatestReleaseVersion) if [[ -n $github_release_version ]]; then echo "info: github latest version: $github_release_version" echo $github_release_version @@ -162,7 +162,7 @@ checkVersion() { } upgrade() { - latest_version=$(`echo getLatestReleaseVersion`) + latest_version=$(getLatestReleaseVersion) echo "info: latest version: $latest_version" if [[ -n $latest_version ]]; then old_jar="$PWD/$JAR_NAME" @@ -204,7 +204,7 @@ mkdirFullNode() { } quickStart() { - full_node_version=$(`echo getLatestReleaseVersion`) + full_node_version=$(getLatestReleaseVersion) if [[ -n $full_node_version ]]; then mkdirFullNode echo "info: check latest version: $full_node_version" @@ -280,7 +280,7 @@ stopService() { checkAllowMemory() { os=`uname` - totalMemory=$(`echo getTotalMemory`) + totalMemory=$(getTotalMemory) total=`expr $totalMemory / 1024` if [[ $os == 'Darwin' ]]; then return @@ -333,7 +333,7 @@ setJVMMemory() { JVM_MX=$(echo "$SPECIFY_MEMORY/1024*0.6" | bc | awk -F. '{print $1"g"}') JVM_MS=$JVM_MX else - total=$(`echo getTotalMemory`) + total=$(getTotalMemory) MAX_DIRECT_MEMORY=$(echo "$total/1024/1024*0.1" | bc | awk -F. '{print $1"g"}') JVM_MX=$(echo "$total/1024/1024*0.6" | bc | awk -F. '{print $1"g"}') JVM_MS=$JVM_MX @@ -355,8 +355,8 @@ startService() { exit fi - nohup $JAVACMD -Xms$JVM_MS -Xmx$JVM_MX -XX:+UseConcMarkSweepGC -XX:+PrintGCDetails -Xloggc:./gc.log \ - -XX:+PrintGCDateStamps -XX:+CMSParallelRemarkEnabled -XX:ReservedCodeCacheSize=256m -XX:+UseCodeCacheFlushing \ + nohup $JAVACMD -Xms$JVM_MS -Xmx$JVM_MX -XX:+UseG1GC -XX:+PrintGCDetails -Xloggc:./gc.log \ + -XX:+PrintGCDateStamps -XX:ReservedCodeCacheSize=256m -XX:+UseCodeCacheFlushing \ -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m \ -XX:MaxDirectMemorySize=$MAX_DIRECT_MEMORY -XX:+HeapDumpOnOutOfMemoryError \ -XX:NewRatio=2 -jar \ @@ -383,7 +383,7 @@ rebuildManifest() { $JAVACMD -jar $ARCHIVE_JAR -d $REBUILD_DIR -m $REBUILD_MANIFEST_SIZE -b $REBUILD_BATCH_SIZE else echo 'info: download the rebuild manifest plugin from the github' - local latest=$(`echo getLatestReleaseVersion`) + local latest=$(getLatestReleaseVersion) download $RELEASE_URL/download/GreatVoyage-v"$latest"/$ARCHIVE_JAR $ARCHIVE_JAR if [[ $download == 0 ]]; then echo 'info: download success, rebuild manifest' @@ -428,7 +428,7 @@ specifyConfig(){ checkSign() { echo 'info: verify signature' - local latest_version=$(`echo getLatestReleaseVersion`) + local latest_version=$(getLatestReleaseVersion) download $RELEASE_URL/download/$latest_version/sha256sum.txt sha256sum.txt fullNodeSha256=$(cat sha256sum.txt|grep 'FullNode'| awk -F ' ' '{print $1}') @@ -603,7 +603,7 @@ if [[ $UPGRADE == true ]]; then fi if [[ $DOWNLOAD == true ]]; then - latest=$(`echo getLatestReleaseVersion`) + latest=$(getLatestReleaseVersion) if [[ -n $latest ]]; then download $RELEASE_URL/download/$latest/$JAR_NAME $latest exit @@ -612,11 +612,7 @@ if [[ $DOWNLOAD == true ]]; then fi fi -if [[ $ALL_OPT_LENGTH -eq 0 || $ALL_OPT_LENGTH -gt 0 ]]; then - restart -fi - -if [[ $RUN == true ]]; then +if [[ $ALL_OPT_LENGTH -eq 0 || $RUN == true ]]; then restart fi diff --git a/ver.sh b/ver.sh index ad3c7ae79f9..7f79788305d 100755 --- a/ver.sh +++ b/ver.sh @@ -1,6 +1,5 @@ #!/bin/bash -set -x -currentBranch=`git rev-parse --abbrev-ref HEAD` +currentBranch=$(git rev-parse --abbrev-ref HEAD) if [ "$currentBranch"x != "master"x ] then @@ -24,7 +23,7 @@ then fi -versionPath="src/main/java/org/tron/program/Version.java" +versionPath="framework/src/main/java/org/tron/program/Version.java" sed -i -e "s/VERSION_NAME.*$/VERSION_NAME = \"$versionName\";/g;s/VERSION_CODE.*$/VERSION_CODE = \"$versionCode\";/g" $versionPath git add $versionPath git commit -m "update a new version. version name:$versionName,version code:$versionCode" From 7788fff375f4957f3ab0f62421f1f6bb5aaca3b4 Mon Sep 17 00:00:00 2001 From: GrapeS Date: Mon, 13 Apr 2026 10:39:28 +0800 Subject: [PATCH 07/11] docs: audit and update root-level docs and scripts - gen.sh: fix proto paths, add shebang and -I include flags, split core/api - build.md: rewrite with current JDK matrix; deduplicate vs README via links - run.md: rewrite to remove dead links, fix SR private key security issue, remove gradle run -Pwitness and 2018-era log output - quickstart.md: remove deprecated Solidity Node port/references; mark docker-tron-quickstart as community-maintained - CONTRIBUTING.md: replace Travis CI with GitHub Actions; fix commit title length from 50 to 10-72 chars to match PR Title Format section Co-Authored-By: Claude Sonnet 4.6 --- CONTRIBUTING.md | 6 +- build.md | 77 +++++++------------ gen.sh | 33 ++++++++- quickstart.md | 9 ++- run.md | 193 ++++++------------------------------------------ 5 files changed, 88 insertions(+), 230 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 53a9dd75824..ef67a81e3ee 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -147,7 +147,7 @@ We would like all developers to follow a standard development flow and coding st 2. Review the code before submission. 3. Run standardized tests. -`Sonar`-scanner and `Travis CI` continuous integration scanner will be automatically triggered when a pull request has been submitted. When a PR passes all the checks, the **java-tron** maintainers will then review the PR and offer feedback and modifications when necessary. Once adopted, the PR will be closed and merged into the `develop` branch. +`Sonar`-scanner and CI checks (GitHub Actions) will be automatically triggered when a pull request has been submitted. When a PR passes all the checks, the **java-tron** maintainers will then review the PR and offer feedback and modifications when necessary. Once adopted, the PR will be closed and merged into the `develop` branch. We are glad to receive your pull requests and will try our best to review them as soon as we can. Any pull request is welcome, even if it is for a typo. @@ -161,7 +161,7 @@ Please make sure your submission meets the following code style: - The code must have passed the Sonar scanner test. - The code has to be pulled from the `develop` branch. - The commit message should start with a verb, whose initial should not be capitalized. -- The commit message should be less than 50 characters in length. +- The commit message title should be between 10 and 72 characters in length. @@ -196,7 +196,7 @@ The message header is a single line that contains succinct description of the ch The `scope` can be anything specifying place of the commit change. For example: `framework`, `api`, `tvm`, `db`, `net`. For a full list of scopes, see [Type and Scope Reference](#type-and-scope-reference). You can use `*` if there isn't a more fitting scope. The subject contains a succinct description of the change: -1. Limit the subject line, which briefly describes the purpose of the commit, to 50 characters. +1. Limit the subject line, which briefly describes the purpose of the commit, to 72 characters (minimum 10). 2. Start with a verb and use first-person present-tense (e.g., use "change" instead of "changed" or "changes"). 3. Do not capitalize the first letter. 4. Do not end the subject line with a period. diff --git a/build.md b/build.md index 1f3671b2c7d..449717240d5 100644 --- a/build.md +++ b/build.md @@ -1,53 +1,48 @@ # How to Build -## Prepare dependencies +## Hardware Requirements -* JDK 1.8 (JDK 1.9+ are not supported yet) -* On Linux Ubuntu system (e.g. Ubuntu 16.04.4 LTS), ensure that the machine has [__Oracle JDK 8__](https://www.digitalocean.com/community/tutorials/how-to-install-java-with-apt-get-on-ubuntu-16-04), instead of having __Open JDK 8__ in the system. If you are building the source code by using __Open JDK 8__, you will get [__Build Failed__](https://github.com/tronprotocol/java-tron/issues/337) result. -* Open **UDP** ports for connection to the network -* **Minimum** 2 CPU Cores +For mainnet deployment, refer to the [Hardware Requirements for Mainnet](README.md#hardware-requirements-for-mainnet) table in the README. -## Build and Deploy automatically using scripts +For compilation only (not running a node), a minimum of **4 CPU cores, 16 GB RAM, and 10 GB free disk space** is sufficient. -- Please take a look at the [Tron Deployment Scripts](https://github.com/tronprotocol/TronDeployment) repository. +## Prerequisites, Source Code, and Console Build -## Getting the code with git +See [Building the Source Code](README.md#building-the-source-code) in the README for: +- Hardware/OS/JDK prerequisites +- Dependency installation (`install_dependencies.sh`) +- `git clone` and `./gradlew build` instructions -* Use Git from the console, see the [Setting up Git](https://help.github.com/articles/set-up-git/) and [Fork a Repo](https://help.github.com/articles/fork-a-repo/) articles. -* `develop` branch: the newest code -* `master` branch: more stable than develop. -In the shell command, type: - ```bash - git clone https://github.com/tronprotocol/java-tron.git - git checkout -t origin/master - ``` +## Building in IntelliJ IDEA -* For Mac, you can also install **[GitHub for Mac](https://mac.github.com/)** then **[fork and clone our repository](https://guides.github.com/activities/forking/)**. +Run `./gradlew build -x test` once from the terminal before opening the project to generate protobuf sources. -* If you'd rather not use Git, **[Download the ZIP](https://github.com/tronprotocol/java-tron/archive/develop.zip)** +1. Open IntelliJ IDEA and select **File → Open**, locate the `java-tron` directory, and click **Open**. +2. When prompted, select **Trust Project**. +3. Wait for Gradle sync to complete. +4. In **Settings → Build, Execution, Deployment → Compiler → Annotation Processors**, enable **Annotation Processing**. +5. In the **Gradle** panel, navigate to **Tasks → build** and double-click **build**. -## Including java-tron as dependency +## Including java-tron as a Dependency -If you don't want to checkout the code and build the project, you can include it directly as a dependency. +**Gradle:** -**Using gradle:** - -``` +```groovy repositories { - maven { url 'https://jitpack.io' } + maven { url 'https://jitpack.io' } } dependencies { - implementation 'com.github.tronprotocol:java-tron:develop-SNAPSHOT' + implementation 'com.github.tronprotocol:java-tron:develop-SNAPSHOT' } ``` - -**Using maven:** + +**Maven:** ```xml - - jitpack.io - https://jitpack.io + + jitpack.io + https://jitpack.io @@ -55,27 +50,5 @@ dependencies { com.github.tronprotocol java-tron develop-SNAPSHOT - ``` - -## Building from source code - -- **Building using the console:** - - ```bash - cd java-tron - ./gradlew build - ``` - -- **Building using [IntelliJ IDEA](https://www.jetbrains.com/idea/) (community version is enough):** - - **Please run `./gradlew build` once to build the protocol files** - - 1. Start IntelliJ. - Select `File` -> `Open`, then locate to the java-tron folder which you have git cloned to your local drive. Then click `Open` button on the right bottom. - 2. Check on `Use auto-import` on the `Import Project from Gradle` dialog. Select JDK 1.8 in the `Gradle JVM` option. Then click `OK`. - 3. IntelliJ will import the project and start gradle syncing, which will take several minutes, depending on your network connection and your IntelliJ configuration - 4. Enable Annotations, `Preferences` -> Search `annotations` -> check `Enable Annotation Processing`. - 5. When the syncing finishes, select `Gradle` -> `Tasks` -> `build`, and then double click `build` option. - diff --git a/gen.sh b/gen.sh index f08b36865de..1bab2142016 100644 --- a/gen.sh +++ b/gen.sh @@ -1 +1,32 @@ -protoc --java_out=./ ./core/*.proto ./api/*.proto \ No newline at end of file +#!/usr/bin/env bash +# Helper script for manually regenerating Java sources from .proto files. +# The recommended approach is `./gradlew build`, which compiles protos via the +# Gradle protobuf plugin automatically. Use this script only if you need to run +# protoc directly (e.g., for a single proto file during development). +# +# Requirements: protoc v3.x installed and available on PATH. +# Proto sources live under protocol/src/main/protos/. + +set -e + +PROTO_SRC="protocol/src/main/protos" +JAVA_OUT="protocol/src/main/java" + +# Compile core protos (Tron.proto + all contract protos) +protoc \ + -I="$PROTO_SRC" \ + -I="$PROTO_SRC/core" \ + -I="$PROTO_SRC/core/contract" \ + --java_out="$JAVA_OUT" \ + "$PROTO_SRC/core/Tron.proto" \ + "$PROTO_SRC/core/contract/"*.proto + +# Compile API proto +protoc \ + -I="$PROTO_SRC" \ + -I="$PROTO_SRC/core" \ + -I="$PROTO_SRC/api" \ + --java_out="$JAVA_OUT" \ + "$PROTO_SRC/api/api.proto" + +echo "Proto compilation complete. Output: $JAVA_OUT" diff --git a/quickstart.md b/quickstart.md index 6eda855f1e9..b3eeb7b7713 100644 --- a/quickstart.md +++ b/quickstart.md @@ -45,7 +45,7 @@ docker pull tronprotocol/java-tron You can run the command below to start the java-tron: ``` -docker run -it -d -p 8090:8090 -p 8091:8091 -p 18888:18888 -p 50051:50051 --restart always tronprotocol/java-tron +docker run -it -d -p 8090:8090 -p 18888:18888 -p 50051:50051 --restart always tronprotocol/java-tron ``` The `-p` flag defines the ports that the container needs to be mapped on the host machine. By default the container will start and join in the mainnet @@ -65,8 +65,9 @@ Note: The directory `/Users/tron/docker/conf` must contain the file `config-loca ## Quickstart for using docker-tron-quickstart -The image exposes a Full Node, Solidity Node, and Event Server. Through TRON Quickstart, users can deploy DApps, smart contracts, and interact with the TronWeb library. -Check more information at [Quickstart:](https://github.com/TRON-US/docker-tron-quickstart) +The image exposes a Full Node and Event Server. Through TRON Quickstart, users can deploy DApps, smart contracts, and interact with the TronWeb library. + +> Note: `docker-tron-quickstart` is a community-maintained tool. Check its repository for the latest status: [Quickstart](https://github.com/TRON-US/docker-tron-quickstart) ### Node.JS Console Node.JS is used to interact with the Full and Solidity Nodes via Tron-Web. @@ -84,7 +85,7 @@ docker pull trontools/quickstart ## Setup TRON Quickstart ### TRON Quickstart Run -Run the "docker run" command to launch TRON Quickstart. TRON Quickstart exposes port 9090 for Full Node, Solidity Node, and Event Server. +Run the "docker run" command to launch TRON Quickstart. TRON Quickstart exposes port 9090 for Full Node and Event Server. ```shell docker run -it \ -p 9090:9090 \ diff --git a/run.md b/run.md index c0ecbe4d91f..74fc5fc8edd 100644 --- a/run.md +++ b/run.md @@ -1,193 +1,46 @@ -# How to Running +# How to Run -### Running multi-nodes +For a comprehensive guide on running java-tron, including hardware requirements, network types, and API configuration, see the [Running java-tron](README.md#running-java-tron) section of the README. -https://github.com/tronprotocol/Documentation/blob/master/TRX/Solidity_and_Full_Node_Deployment_EN.md +## Quick Reference -## Running a local node and connecting to the public testnet - -Use the [Testnet Config](https://github.com/tronprotocol/TronDeployment/blob/master/test_net_config.conf) or use the [Tron Deployment Scripts](https://github.com/tronprotocol/TronDeployment). - - -### Running a Super Representative Node for mainnet - -**Use the executable JAR(Recommended way):** +### Start a full node (mainnet) ```bash -java -jar FullNode.jar -p --witness -c your config.conf(Example:/data/java-tron/config.conf) -Example: -java -jar FullNode.jar -p --witness -c /data/java-tron/config.conf - +java -jar ./build/libs/FullNode.jar ``` -This is similar to running a private testnet, except that the IPs in the `config.conf` are officially declared by TRON. - -
-Correct output +### Start a full node with a custom config ```bash - -20:43:18.138 INFO [main] [o.t.p.FullNode](FullNode.java:21) Full node running. -20:43:18.486 INFO [main] [o.t.c.c.a.Args](Args.java:429) Bind address wasn't set, Punching to identify it... -20:43:18.493 INFO [main] [o.t.c.c.a.Args](Args.java:433) UDP local bound to: 10.0.8.146 -20:43:18.495 INFO [main] [o.t.c.c.a.Args](Args.java:448) External IP wasn't set, using checkip.amazonaws.com to identify it... -20:43:19.450 INFO [main] [o.t.c.c.a.Args](Args.java:461) External address identified: 47.74.147.87 -20:43:19.599 INFO [main] [o.s.c.a.AnnotationConfigApplicationContext](AbstractApplicationContext.java:573) Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@124c278f: startup date [Fri Apr 27 20:43:19 CST 2018]; root of context hierarchy -20:43:19.972 INFO [main] [o.s.b.f.a.AutowiredAnnotationBeanPostProcessor](AutowiredAnnotationBeanPostProcessor.java:153) JSR-330 'javax.inject.Inject' annotation found and supported for autowiring -20:43:20.380 INFO [main] [o.t.c.d.DynamicPropertiesStore](DynamicPropertiesStore.java:244) update latest block header timestamp = 0 -20:43:20.383 INFO [main] [o.t.c.d.DynamicPropertiesStore](DynamicPropertiesStore.java:252) update latest block header number = 0 -20:43:20.393 INFO [main] [o.t.c.d.DynamicPropertiesStore](DynamicPropertiesStore.java:260) update latest block header id = 00 -20:43:20.394 INFO [main] [o.t.c.d.DynamicPropertiesStore](DynamicPropertiesStore.java:265) update state flag = 0 -20:43:20.559 INFO [main] [o.t.c.c.TransactionCapsule](TransactionCapsule.java:83) Transaction create succeeded! -20:43:20.567 INFO [main] [o.t.c.c.TransactionCapsule](TransactionCapsule.java:83) Transaction create succeeded! -20:43:20.568 INFO [main] [o.t.c.c.TransactionCapsule](TransactionCapsule.java:83) Transaction create succeeded! -20:43:20.568 INFO [main] [o.t.c.c.TransactionCapsule](TransactionCapsule.java:83) Transaction create succeeded! -20:43:20.569 INFO [main] [o.t.c.c.TransactionCapsule](TransactionCapsule.java:83) Transaction create succeeded! -20:43:20.596 INFO [main] [o.t.c.d.Manager](Manager.java:300) create genesis block -20:43:20.607 INFO [main] [o.t.c.d.Manager](Manager.java:306) save block: BlockCapsule - +java -jar ./build/libs/FullNode.jar -c /path/to/config.conf ``` -Then observe whether block synchronization success,If synchronization successfully explains the success of the super node - -
+### Start a Super Representative node +Add the `--witness` flag. The private key must be set in `localwitness` inside the configuration file — **do not pass it on the command line**. -### Running a Super Representative Node for private testnet -* use master branch -* You should modify the config.conf - 1. Replace existing entry in genesis.block.witnesses with your address. - 2. Replace existing entry in seed.node ip.list with your ip list. - 3. The first Super Node start, needSyncCheck should be set false - 4. Set p2pversion to 61 - -* Use the executable JAR(Recommended way) - -```bash -cd build/libs -java -jar FullNode.jar -p --witness -c your config.conf (Example:/data/java-tron/config.conf) -Example: -java -jar FullNode.jar -p --witness -c /data/java-tron/config.conf - +```conf +# config.conf +localwitness = [ + +] ``` - -
-Show Output ```bash -> ./gradlew run -Pwitness - -> Task :generateProto UP-TO-DATE -Using TaskInputs.file() with something that doesn't resolve to a File object has been deprecated and is scheduled to be removed in Gradle 5.0. Use TaskInputs.files() instead. - -> Task :run -20:39:22.749 INFO [o.t.c.c.a.Args] private.key = 63e62a71ed3... -20:39:22.816 WARN [o.t.c.c.a.Args] localwitness size must be one, get the first one -20:39:22.832 INFO [o.t.p.FullNode] Here is the help message.output-directory/ -三月 22, 2018 8:39:23 下午 org.tron.core.services.RpcApiService start -信息: Server started, listening on 50051 -20:39:23.706 INFO [o.t.c.o.n.GossipLocalNode] listener message -20:39:23.712 INFO [o.t.c.o.n.GossipLocalNode] sync group = a41d27f10194c53703be90c6f8735bb66ffc53aa10ea9024d92dbe7324b1aee3 -20:39:23.716 INFO [o.t.c.s.WitnessService] Sleep : 1296 ms,next time:2018-03-22T20:39:25.000+08:00 -20:39:23.734 WARN [i.s.t.BootstrapFactory] Env doesn't support epoll transport -20:39:23.746 INFO [i.s.t.TransportImpl] Bound to: 192.168.10.163:7080 -20:39:23.803 INFO [o.t.c.n.n.NodeImpl] other peer is nil, please wait ... -20:39:25.019 WARN [o.t.c.d.Manager] nextFirstSlotTime:[2018-03-22T17:57:20.001+08:00],now[2018-03-22T20:39:25.067+08:00] -20:39:25.019 INFO [o.t.c.s.WitnessService] ScheduledWitness[448d53b2df0cd78158f6f0aecdf60c1c10b15413],slot[1946] -20:39:25.021 INFO [o.t.c.s.WitnessService] It's not my turn -20:39:25.021 INFO [o.t.c.s.WitnessService] Sleep : 4979 ms,next time:2018-03-22T20:39:30.000+08:00 -20:39:30.003 WARN [o.t.c.d.Manager] nextFirstSlotTime:[2018-03-22T17:57:20.001+08:00],now[2018-03-22T20:39:30.052+08:00] -20:39:30.003 INFO [o.t.c.s.WitnessService] ScheduledWitness[6c22c1af7bfbb2b0e07148ecba27b56f81a54fcf],slot[1947] -20:39:30.003 INFO [o.t.c.s.WitnessService] It's not my turn -20:39:30.003 INFO [o.t.c.s.WitnessService] Sleep : 4997 ms,next time:2018-03-22T20:39:35.000+08:00 -20:39:33.803 INFO [o.t.c.n.n.NodeImpl] other peer is nil, please wait ... -20:39:35.005 WARN [o.t.c.d.Manager] nextFirstSlotTime:[2018-03-22T17:57:20.001+08:00],now[2018-03-22T20:39:35.054+08:00] -20:39:35.005 INFO [o.t.c.s.WitnessService] ScheduledWitness[48e447ec869216de76cfeeadf0db37a3d1c8246d],slot[1948] -20:39:35.005 INFO [o.t.c.s.WitnessService] It's not my turn -20:39:35.005 INFO [o.t.c.s.WitnessService] Sleep : 4995 ms,next time:2018-03-22T20:39:40.000+08:00 -20:39:40.005 WARN [o.t.c.d.Manager] nextFirstSlotTime:[2018-03-22T17:57:20.001+08:00],now[2018-03-22T20:39:40.055+08:00] -20:39:40.010 INFO [o.t.c.d.Manager] postponedTrxCount[0],TrxLeft[0] -20:39:40.022 INFO [o.t.c.d.DynamicPropertiesStore] update latest block header id = fd30a16160715f3ca1a5bcad18e81991cd6f47265a71815bd2c943129b258cd2 -20:39:40.022 INFO [o.t.c.d.TronStoreWithRevoking] Address is [108, 97, 116, 101, 115, 116, 95, 98, 108, 111, 99, 107, 95, 104, 101, 97, 100, 101, 114, 95, 104, 97, 115, 104], BytesCapsule is org.tron.core.capsule.BytesCapsule@2ce0e954 -20:39:40.023 INFO [o.t.c.d.DynamicPropertiesStore] update latest block header number = 140 -20:39:40.024 INFO [o.t.c.d.TronStoreWithRevoking] Address is [108, 97, 116, 101, 115, 116, 95, 98, 108, 111, 99, 107, 95, 104, 101, 97, 100, 101, 114, 95, 110, 117, 109, 98, 101, 114], BytesCapsule is org.tron.core.capsule.BytesCapsule@83924ab -20:39:40.024 INFO [o.t.c.d.DynamicPropertiesStore] update latest block header timestamp = 1521722380001 -20:39:40.024 INFO [o.t.c.d.TronStoreWithRevoking] Address is [108, 97, 116, 101, 115, 116, 95, 98, 108, 111, 99, 107, 95, 104, 101, 97, 100, 101, 114, 95, 116, 105, 109, 101, 115, 116, 97, 109, 112], BytesCapsule is org.tron.core.capsule.BytesCapsule@ca6a6f8 -20:39:40.024 INFO [o.t.c.d.Manager] updateWitnessSchedule number:140,HeadBlockTimeStamp:1521722380001 -20:39:40.025 WARN [o.t.c.u.RandomGenerator] index[-3] is out of range[0,3],skip -20:39:40.070 INFO [o.t.c.d.TronStoreWithRevoking] Address is [73, 72, -62, -24, -89, 86, -39, 67, 112, 55, -36, -40, -57, -32, -57, 61, 86, 12, -93, -115], AccountCapsule is account_name: "Sun" -address: "IH\302\350\247V\331Cp7\334\330\307\340\307=V\f\243\215" -balance: 9223372036854775387 - -20:39:40.081 INFO [o.t.c.d.TronStoreWithRevoking] Address is [41, -97, 61, -72, 10, 36, -78, 10, 37, 75, -119, -50, 99, -99, 89, 19, 47, 21, 127, 19], AccountCapsule is type: AssetIssue -address: ")\237=\270\n$\262\n%K\211\316c\235Y\023/\025\177\023" -balance: 420 - -20:39:40.082 INFO [o.t.c.d.TronStoreWithRevoking] Address is [76, 65, 84, 69, 83, 84, 95, 83, 79, 76, 73, 68, 73, 70, 73, 69, 68, 95, 66, 76, 79, 67, 75, 95, 78, 85, 77], BytesCapsule is org.tron.core.capsule.BytesCapsule@ec1439 -20:39:40.083 INFO [o.t.c.d.Manager] there is account List size is 8 -20:39:40.084 INFO [o.t.c.d.Manager] there is account ,account address is 448d53b2df0cd78158f6f0aecdf60c1c10b15413 -20:39:40.084 INFO [o.t.c.d.Manager] there is account ,account address is 548794500882809695a8a687866e76d4271a146a -20:39:40.084 INFO [o.t.c.d.Manager] there is account ,account address is 48e447ec869216de76cfeeadf0db37a3d1c8246d -20:39:40.084 INFO [o.t.c.d.Manager] there is account ,account address is 55ddae14564f82d5b94c7a131b5fcfd31ad6515a -20:39:40.085 INFO [o.t.c.d.Manager] there is account ,account address is 6c22c1af7bfbb2b0e07148ecba27b56f81a54fcf -20:39:40.085 INFO [o.t.c.d.Manager] there is account ,account address is 299f3db80a24b20a254b89ce639d59132f157f13 -20:39:40.085 INFO [o.t.c.d.Manager] there is account ,account address is abd4b9367799eaa3197fecb144eb71de1e049150 -20:39:40.085 INFO [o.t.c.d.Manager] there is account ,account address is 4948c2e8a756d9437037dcd8c7e0c73d560ca38d -20:39:40.085 INFO [o.t.c.d.TronStoreWithRevoking] Address is [108, 34, -63, -81, 123, -5, -78, -80, -32, 113, 72, -20, -70, 39, -75, 111, -127, -91, 79, -49], WitnessCapsule is org.tron.core.capsule.WitnessCapsule@4cb4f7fb -20:39:40.086 INFO [o.t.c.d.TronStoreWithRevoking] Address is [41, -97, 61, -72, 10, 36, -78, 10, 37, 75, -119, -50, 99, -99, 89, 19, 47, 21, 127, 19], WitnessCapsule is org.tron.core.capsule.WitnessCapsule@7be2474a -20:39:40.086 INFO [o.t.c.d.TronStoreWithRevoking] Address is [72, -28, 71, -20, -122, -110, 22, -34, 118, -49, -18, -83, -16, -37, 55, -93, -47, -56, 36, 109], WitnessCapsule is org.tron.core.capsule.WitnessCapsule@3e375891 -20:39:40.086 INFO [o.t.c.d.TronStoreWithRevoking] Address is [68, -115, 83, -78, -33, 12, -41, -127, 88, -10, -16, -82, -51, -10, 12, 28, 16, -79, 84, 19], WitnessCapsule is org.tron.core.capsule.WitnessCapsule@55d77b83 -20:39:40.090 INFO [o.t.c.d.Manager] countWitnessMap size is 0 -20:39:40.091 INFO [o.t.c.d.TronStoreWithRevoking] Address is [41, -97, 61, -72, 10, 36, -78, 10, 37, 75, -119, -50, 99, -99, 89, 19, 47, 21, 127, 19], WitnessCapsule is org.tron.core.capsule.WitnessCapsule@310dd876 -20:39:40.092 INFO [o.t.c.d.TronStoreWithRevoking] Address is [72, -28, 71, -20, -122, -110, 22, -34, 118, -49, -18, -83, -16, -37, 55, -93, -47, -56, 36, 109], WitnessCapsule is org.tron.core.capsule.WitnessCapsule@151b42bc -20:39:40.092 INFO [o.t.c.d.TronStoreWithRevoking] Address is [108, 34, -63, -81, 123, -5, -78, -80, -32, 113, 72, -20, -70, 39, -75, 111, -127, -91, 79, -49], WitnessCapsule is org.tron.core.capsule.WitnessCapsule@2d0388aa -20:39:40.092 INFO [o.t.c.d.TronStoreWithRevoking] Address is [68, -115, 83, -78, -33, 12, -41, -127, 88, -10, -16, -82, -51, -10, 12, 28, 16, -79, 84, 19], WitnessCapsule is org.tron.core.capsule.WitnessCapsule@478a55e7 -20:39:40.101 INFO [o.t.c.d.TronStoreWithRevoking] Address is [-3, 48, -95, 97, 96, 113, 95, 60, -95, -91, -68, -83, 24, -24, 25, -111, -51, 111, 71, 38, 90, 113, -127, 91, -46, -55, 67, 18, -101, 37, -116, -46], BlockCapsule is BlockCapsule{blockId=fd30a16160715f3ca1a5bcad18e81991cd6f47265a71815bd2c943129b258cd2, num=140, parentId=dadeff07c32d342b941cfa97ba82870958615e7ae73fffeaf3c6a334d81fe3bd, generatedByMyself=true} -20:39:40.102 INFO [o.t.c.d.Manager] save block: BlockCapsule{blockId=fd30a16160715f3ca1a5bcad18e81991cd6f47265a71815bd2c943129b258cd2, num=140, parentId=dadeff07c32d342b941cfa97ba82870958615e7ae73fffeaf3c6a334d81fe3bd, generatedByMyself=true} -20:39:40.102 INFO [o.t.c.s.WitnessService] Block is generated successfully, Its Id is fd30a16160715f3ca1a5bcad18e81991cd6f47265a71815bd2c943129b258cd2,number140 -20:39:40.102 INFO [o.t.c.n.n.NodeImpl] Ready to broadcast a block, Its hash is fd30a16160715f3ca1a5bcad18e81991cd6f47265a71815bd2c943129b258cd2 -20:39:40.107 INFO [o.t.c.s.WitnessService] Produced -20:39:40.107 INFO [o.t.c.s.WitnessService] Sleep : 4893 ms,next time:2018-03-22T20:39:45.000+08:00 -20:39:43.805 INFO [o.t.c.n.n.NodeImpl] other peer is nil, please wait ... -20:39:45.002 WARN [o.t.c.d.Manager] nextFirstSlotTime:[2018-03-22T20:39:45.001+08:00],now[2018-03-22T20:39:45.052+08:00] -20:39:45.003 INFO [o.t.c.s.WitnessService] ScheduledWitness[48e447ec869216de76cfeeadf0db37a3d1c8246d],slot[1] -20:39:45.003 INFO [o.t.c.s.WitnessService] It's not my turn -20:39:45.003 INFO [o.t.c.s.WitnessService] Sleep : 4997 ms,next time:2018-03-22T20:39:50.000+08:00 -20:39:50.002 WARN [o.t.c.d.Manager] nextFirstSlotTime:[2018-03-22T20:39:45.001+08:00],now[2018-03-22T20:39:50.052+08:00] -20:39:50.003 INFO [o.t.c.s.WitnessService] ScheduledWitness[6c22c1af7bfbb2b0e07148ecba27b56f81a54fcf],slot[2] -20:39:50.003 INFO [o.t.c.s.WitnessService] It's not my turn -20:39:50.003 INFO [o.t.c.s.WitnessService] Sleep : 4997 ms,next time:2018-03-22T20:39:55.000+08:00 - +java -jar ./build/libs/FullNode.jar --witness -c /path/to/config.conf ``` -
- -* In IntelliJ IDEA - -
- - -Open the configuration panel: - - - -![](docs/images/program_configure.png) +### Monitor sync progress -
- -
- - -In the `Program arguments` option, fill in `--witness`: - - +```bash +tail -f ./logs/tron.log +``` -![](docs/images/set_witness_param.jpeg) +### Running multiple nodes -
- -Then, run `FullNode::main()` again. +Refer to the [Private Network guidance](https://tronprotocol.github.io/documentation-en/using_javatron/private_network/) for setting up a multi-node private network. -## Advanced Configurations +### Advanced configuration -Read the [Advanced Configurations](common/src/main/java/org/tron/core/config/README.md). +See the [configuration reference](https://tronprotocol.github.io/documentation-en/using_javatron/installing_javatron/) for all supported options including JVM tuning, database settings, and network parameters. From cf78e9c23d9c6bc464eafb1979f2fb63bd798c8d Mon Sep 17 00:00:00 2001 From: GrapeS Date: Mon, 13 Apr 2026 10:48:53 +0800 Subject: [PATCH 08/11] chore(scripts): add comment explaining G1GC replacement for CMS Co-Authored-By: Claude Sonnet 4.6 --- start.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/start.sh b/start.sh index 7317249fdee..0cc226c1ab0 100644 --- a/start.sh +++ b/start.sh @@ -355,6 +355,8 @@ startService() { exit fi + # G1GC is used here for JDK 8/17 compatibility. CMS flags (-XX:+UseConcMarkSweepGC etc.) + # were removed in JDK 14 and cause JVM startup failure on JDK 17 (required for ARM64). nohup $JAVACMD -Xms$JVM_MS -Xmx$JVM_MX -XX:+UseG1GC -XX:+PrintGCDetails -Xloggc:./gc.log \ -XX:+PrintGCDateStamps -XX:ReservedCodeCacheSize=256m -XX:+UseCodeCacheFlushing \ -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m \ From 076d3910ee4e97af16e4905728e9563b365f916e Mon Sep 17 00:00:00 2001 From: GrapeS Date: Wed, 15 Apr 2026 15:06:27 +0800 Subject: [PATCH 09/11] docs: add platform module description and update count to nine Co-Authored-By: Claude Sonnet 4.6 --- docs/modular-introduction-en.md | 6 +++++- docs/modular-introduction-zh.md | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/docs/modular-introduction-en.md b/docs/modular-introduction-en.md index 1a4827ded42..654fbfcf995 100644 --- a/docs/modular-introduction-en.md +++ b/docs/modular-introduction-en.md @@ -16,7 +16,7 @@ The aim of java-tron modularization is to enable developers to easily build a de ![modular-structure](https://github.com/tronprotocol/java-tron/blob/develop/docs/images/module.png) -A modularized java-tron consists of eight modules: framework, protocol, common, chainbase, consensus, actuator, crypto and plugins. The function of each module is elaborated below. +A modularized java-tron consists of nine modules: framework, protocol, common, chainbase, consensus, actuator, crypto, plugins and platform. The function of each module is elaborated below. ### framework @@ -75,3 +75,7 @@ Crypto module encapsulates cryptographic primitives used across the project, inc ### plugins Plugins module provides standalone operational tools packaged as independent executable JARs, such as `Toolkit.jar` and `ArchiveManifest.jar`. These tools support database maintenance tasks like migration, compaction and lite-node data pruning, and can be run without starting a full node. + +### platform + +Platform module provides the JNI bindings for the native database engines — LevelDB and RocksDB. It is architecture-aware: LevelDB is excluded on ARM64 (Apple Silicon and Linux aarch64) where only RocksDB is supported, while both are available on x86_64. diff --git a/docs/modular-introduction-zh.md b/docs/modular-introduction-zh.md index 58d8d172a7f..e1a02f6b778 100644 --- a/docs/modular-introduction-zh.md +++ b/docs/modular-introduction-zh.md @@ -14,7 +14,7 @@ java-tron 模块化的目的是为了帮助开发者方便地构建出特定应 ![modular-structure](https://github.com/tronprotocol/java-tron/blob/develop/docs/images/module.png) -模块化后的 java-tron 目前分为8个模块:framework、protocol、common、chainbase、consensus、actuator、crypto、plugins,下面分别简单介绍一下各个模块的作用。 +模块化后的 java-tron 目前分为9个模块:framework、protocol、common、chainbase、consensus、actuator、crypto、plugins、platform,下面分别简单介绍一下各个模块的作用。 ### framework @@ -73,3 +73,7 @@ crypto 模块封装了项目中使用的密码学原语,包括椭圆曲线密 ### plugins plugins 模块提供独立的运维工具,打包为可单独执行的 JAR(如 `Toolkit.jar`、`ArchiveManifest.jar`)。这些工具支持数据库迁移、压缩、轻节点数据裁剪等维护任务,无需启动完整节点即可运行。 + +### platform + +platform 模块提供原生数据库引擎 LevelDB 和 RocksDB 的 JNI 绑定,与架构强相关:ARM64(Apple Silicon 及 Linux aarch64)平台仅支持 RocksDB,LevelDB 被排除;x86_64 平台两者均可使用。 From e7cd7d7927e2ff6e3345da61e6867183dc3c0513 Mon Sep 17 00:00:00 2001 From: GrapeS Date: Wed, 15 Apr 2026 15:20:06 +0800 Subject: [PATCH 10/11] docs: remove redundant root-level build.md, run.md and gen.sh README already covers build prerequisites and run instructions. IntelliJ IDEA setup and jitpack dependency details belong in the official documentation site, not the project README. Co-Authored-By: Claude Sonnet 4.6 --- build.md | 54 ------------------------------------------------------ gen.sh | 32 -------------------------------- run.md | 46 ---------------------------------------------- 3 files changed, 132 deletions(-) delete mode 100644 build.md delete mode 100644 gen.sh delete mode 100644 run.md diff --git a/build.md b/build.md deleted file mode 100644 index 449717240d5..00000000000 --- a/build.md +++ /dev/null @@ -1,54 +0,0 @@ -# How to Build - -## Hardware Requirements - -For mainnet deployment, refer to the [Hardware Requirements for Mainnet](README.md#hardware-requirements-for-mainnet) table in the README. - -For compilation only (not running a node), a minimum of **4 CPU cores, 16 GB RAM, and 10 GB free disk space** is sufficient. - -## Prerequisites, Source Code, and Console Build - -See [Building the Source Code](README.md#building-the-source-code) in the README for: -- Hardware/OS/JDK prerequisites -- Dependency installation (`install_dependencies.sh`) -- `git clone` and `./gradlew build` instructions - -## Building in IntelliJ IDEA - -Run `./gradlew build -x test` once from the terminal before opening the project to generate protobuf sources. - -1. Open IntelliJ IDEA and select **File → Open**, locate the `java-tron` directory, and click **Open**. -2. When prompted, select **Trust Project**. -3. Wait for Gradle sync to complete. -4. In **Settings → Build, Execution, Deployment → Compiler → Annotation Processors**, enable **Annotation Processing**. -5. In the **Gradle** panel, navigate to **Tasks → build** and double-click **build**. - -## Including java-tron as a Dependency - -**Gradle:** - -```groovy -repositories { - maven { url 'https://jitpack.io' } -} -dependencies { - implementation 'com.github.tronprotocol:java-tron:develop-SNAPSHOT' -} -``` - -**Maven:** - -```xml - - - jitpack.io - https://jitpack.io - - - - - com.github.tronprotocol - java-tron - develop-SNAPSHOT - -``` diff --git a/gen.sh b/gen.sh deleted file mode 100644 index 1bab2142016..00000000000 --- a/gen.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env bash -# Helper script for manually regenerating Java sources from .proto files. -# The recommended approach is `./gradlew build`, which compiles protos via the -# Gradle protobuf plugin automatically. Use this script only if you need to run -# protoc directly (e.g., for a single proto file during development). -# -# Requirements: protoc v3.x installed and available on PATH. -# Proto sources live under protocol/src/main/protos/. - -set -e - -PROTO_SRC="protocol/src/main/protos" -JAVA_OUT="protocol/src/main/java" - -# Compile core protos (Tron.proto + all contract protos) -protoc \ - -I="$PROTO_SRC" \ - -I="$PROTO_SRC/core" \ - -I="$PROTO_SRC/core/contract" \ - --java_out="$JAVA_OUT" \ - "$PROTO_SRC/core/Tron.proto" \ - "$PROTO_SRC/core/contract/"*.proto - -# Compile API proto -protoc \ - -I="$PROTO_SRC" \ - -I="$PROTO_SRC/core" \ - -I="$PROTO_SRC/api" \ - --java_out="$JAVA_OUT" \ - "$PROTO_SRC/api/api.proto" - -echo "Proto compilation complete. Output: $JAVA_OUT" diff --git a/run.md b/run.md deleted file mode 100644 index 74fc5fc8edd..00000000000 --- a/run.md +++ /dev/null @@ -1,46 +0,0 @@ -# How to Run - -For a comprehensive guide on running java-tron, including hardware requirements, network types, and API configuration, see the [Running java-tron](README.md#running-java-tron) section of the README. - -## Quick Reference - -### Start a full node (mainnet) - -```bash -java -jar ./build/libs/FullNode.jar -``` - -### Start a full node with a custom config - -```bash -java -jar ./build/libs/FullNode.jar -c /path/to/config.conf -``` - -### Start a Super Representative node - -Add the `--witness` flag. The private key must be set in `localwitness` inside the configuration file — **do not pass it on the command line**. - -```conf -# config.conf -localwitness = [ - -] -``` - -```bash -java -jar ./build/libs/FullNode.jar --witness -c /path/to/config.conf -``` - -### Monitor sync progress - -```bash -tail -f ./logs/tron.log -``` - -### Running multiple nodes - -Refer to the [Private Network guidance](https://tronprotocol.github.io/documentation-en/using_javatron/private_network/) for setting up a multi-node private network. - -### Advanced configuration - -See the [configuration reference](https://tronprotocol.github.io/documentation-en/using_javatron/installing_javatron/) for all supported options including JVM tuning, database settings, and network parameters. From 550f524369b560ba5663ad399bd6e67dfb548779 Mon Sep 17 00:00:00 2001 From: GrapeS Date: Wed, 15 Apr 2026 15:46:23 +0800 Subject: [PATCH 11/11] fix(scripts): anchor ver.sh working directory to script location Add `cd "$(dirname "$0")"` so both invocation paths work correctly: - Direct: `./ver.sh` from repo root - Via Gradle: `./gradlew version` (runs from framework/ directory) Without this, the Gradle invocation resolves versionPath to framework/framework/src/... which does not exist. Co-Authored-By: Claude Sonnet 4.6 --- ver.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ver.sh b/ver.sh index 7f79788305d..817409f2d26 100755 --- a/ver.sh +++ b/ver.sh @@ -1,4 +1,5 @@ #!/bin/bash +cd "$(dirname "$0")" currentBranch=$(git rev-parse --abbrev-ref HEAD) if [ "$currentBranch"x != "master"x ]