Skip to content
Open
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand All @@ -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.



Expand Down Expand Up @@ -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.
Expand Down
77 changes: 25 additions & 52 deletions build.md
Original file line number Diff line number Diff line change
@@ -1,81 +1,54 @@
# How to Build
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After the rewrite, both build.md and run.md are mostly thin wrappers that point back to the README. Maintaining multiple files that say "see README" adds indirection for readers and maintenance burden (they can easily drift out of sync again — which is how they got stale in the first place).

Suggestion: consider removing build.md and run.md entirely, and moving the unique content (IntelliJ IDEA setup steps, jitpack dependency snippet) into the README or a CONTRIBUTING.md section. This would be a net reduction in maintenance surface.


## 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
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>

<dependency>
<groupId>com.github.tronprotocol</groupId>
<artifactId>java-tron</artifactId>
<version>develop-SNAPSHOT</version>
<!--You can use any of the tag/branch name available-->
</dependency>
```

## 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.

69 changes: 38 additions & 31 deletions docs/implement-a-customized-actuator-en.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,19 @@ message Transaction {
AccountCreateContract = 0;
TransferContract = 1;
........
SumContract = 52;
SumContract = 60;
}
...
}
```

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 {
Expand All @@ -60,13 +66,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
Expand All @@ -78,7 +82,11 @@ 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;

public class SumActuator extends AbstractActuator {

public SumActuator() {
Expand Down Expand Up @@ -210,48 +218,47 @@ 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.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
Expand Down
69 changes: 38 additions & 31 deletions docs/implement-a-customized-actuator-zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,19 @@ message Transaction {
AccountCreateContract = 0;
TransferContract = 1;
........
SumContract = 52;
SumContract = 60;
}
...
}
```

然后还需要注册一个方法来保证 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 {
Expand All @@ -62,13 +68,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
Expand All @@ -80,7 +84,11 @@ 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;

public class SumActuator extends AbstractActuator {

public SumActuator() {
Expand Down Expand Up @@ -212,48 +220,47 @@ 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.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
Expand Down
Loading
Loading