Skip to content

Commit a901f85

Browse files
docs: add AGENTS.md and reorganize project documentation (#6871)
1 parent cfcd63e commit a901f85

19 files changed

Lines changed: 497 additions & 109 deletions

‎.codeclimate.yml‎

Lines changed: 0 additions & 6 deletions
This file was deleted.

‎.dockerignore‎

Lines changed: 0 additions & 3 deletions
This file was deleted.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#!/usr/bin/env bash
2+
# Prints every Java file that uses java.lang.Math: bare `Math.` calls, fully
3+
# qualified `java.lang.Math.` calls (including static imports) and
4+
# `import java.lang.Math`. No output means no forbidden usage.
5+
# StrictMathWrapper.java and MathWrapper.java are exempt. String literals, char
6+
# literals and comments are stripped before matching, so `StrictMath.` and
7+
# mentions in text are not reported.
8+
# Used by .github/workflows/math-check.yml; run it locally from any directory.
9+
set -euo pipefail
10+
11+
cd "$(dirname "$0")/../.."
12+
13+
find . -type f -name '*.java' -not -path '*/build/*' | while IFS= read -r file; do
14+
case "$(basename "$file")" in
15+
StrictMathWrapper.java|MathWrapper.java) continue ;;
16+
esac
17+
18+
perl -0777 -ne '
19+
s/"([^"\\]|\\.)*"//g;
20+
s/'\''([^'\''\\]|\\.)*'\''//g;
21+
s!/\*([^*]|\*[^/])*\*/!!g;
22+
s!//[^\n]*!!g;
23+
$hasMath = 0;
24+
$hasMath = 1 if /^[\s]*import[\s]+java\.lang\.Math\b/m;
25+
$hasMath = 1 if /\bjava\s*\.\s*lang\s*\.\s*Math\s*\./;
26+
$hasMath = 1 if /(?<![\w\.])(?<!Strict)Math\s*\./;
27+
print "$ARGV\n" if $hasMath;
28+
' "$file"
29+
done | sort -u

‎.github/workflows/math-check.yml‎

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,30 +19,9 @@ jobs:
1919
shell: bash
2020
run: |
2121
echo "Checking for java.lang.Math usage..."
22-
23-
touch math_usage.txt
24-
25-
while IFS= read -r file; do
26-
filename=$(basename "$file")
27-
if [[ "$filename" == "StrictMathWrapper.java" || "$filename" == "MathWrapper.java" ]]; then
28-
continue
29-
fi
30-
31-
perl -0777 -ne '
32-
s/"([^"\\]|\\.)*"//g;
33-
s/'\''([^'\''\\]|\\.)*'\''//g;
34-
s!/\*([^*]|\*[^/])*\*/!!g;
35-
s!//[^\n]*!!g;
36-
$hasMath = 0;
37-
$hasMath = 1 if /^[\s]*import[\s]+java\.lang\.Math\b/m;
38-
$hasMath = 1 if /\bjava\s*\.\s*lang\s*\.\s*Math\s*\./;
39-
$hasMath = 1 if /(?<![\w\.])(?<!Strict)Math\s*\./;
40-
print "$ARGV\n" if $hasMath;
41-
' "$file" >> math_usage.txt
42-
done < <(find . -type f -name "*.java")
43-
44-
sort -u math_usage.txt -o math_usage.txt
45-
22+
23+
bash .github/scripts/check_math_usage.sh > math_usage.txt
24+
4625
if [ -s math_usage.txt ]; then
4726
echo "❌ Error: Forbidden Math usage found in the following files:"
4827
cat math_usage.txt

‎AGENTS.md‎

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
# AGENTS.md
2+
3+
Guidance for AI coding assistants and new contributors working on java-tron: how to build, test, and navigate the codebase, plus the constraints that CI enforces and the invariants that must not be broken. For running a node, see the [README](./README.md) and [`docs/`](./docs).
4+
5+
## Guidelines
6+
7+
- **Keep changes minimal and focused.** Only modify code directly related to the task at hand. Do not refactor unrelated code, rename existing variables or functions for style, or bundle unrelated fixes into the same commit or PR.
8+
- **Do not add, remove, or update dependencies** unless the task explicitly requires it. Dependency changes in a consensus node are high-risk, need separate review, and require regenerating dependency verification metadata (see checklist step 6).
9+
- **Never hand-edit generated sources.** Protobuf / gRPC Java stubs are generated at build time from `protocol/src/main/protos/` (`core/`, `api/`) and are git-ignored. Rebuild after changing a `.proto`.
10+
11+
## Build & Test
12+
13+
Supported platforms: **Linux** and **macOS** only. The JDK requirement is determined by CPU architecture: **JDK 8** on x86_64, **JDK 17** on ARM64/aarch64 (Apple Silicon, AWS Graviton). The build fails fast if the JDK major version does not match the architecture.
14+
15+
```bash
16+
./gradlew clean build -x test # build without tests
17+
./gradlew build # build with tests
18+
./gradlew test # run all tests
19+
./gradlew :framework:test # test one module
20+
./gradlew :framework:test --tests "org.tron.core.db.TronDatabaseTest" # one class
21+
./gradlew :framework:test --tests "org.tron.core.db.TronDatabaseTest.TestGetUnchecked" # one method
22+
./gradlew :framework:testWithRocksDb # RocksDB tests (x86 only)
23+
./gradlew jacocoTestReport # coverage report
24+
```
25+
26+
- Main entry point: `org.tron.program.FullNode`.
27+
- Tests also run in parallel in CI: `framework/build.gradle` sets `maxParallelForks` without checking the `CI` env var. Each module configures its own test parallelism in its `build.gradle`.
28+
- On ARM64/aarch64, only the RocksDB storage engine is supported; the build forces RocksDB and skips the LevelDB tests.
29+
- CI builds the full matrix: **JDK 8 / x86_64** (rockylinux, debian11) and **JDK 17 / aarch64** (macOS, ubuntu24). A change must compile on both.
30+
31+
## Pre-Commit Checklist
32+
33+
Run **all** applicable checks before committing. Each maps to a CI job that will otherwise fail the PR.
34+
35+
### 1. Build
36+
37+
```bash
38+
./gradlew clean build -x test
39+
```
40+
41+
### 2. Tests
42+
43+
```bash
44+
./gradlew test
45+
```
46+
47+
### 3. Checkstyle
48+
49+
Run exactly what CI runs (`.github/workflows/pr-check.yml`):
50+
51+
```bash
52+
./gradlew :framework:checkstyleMain :framework:checkstyleTest :plugins:checkstyleMain
53+
```
54+
55+
The `pr-check.yml` Checkstyle gate covers only `framework` and `plugins`; `protocol` is checked by `protoLint` instead (see Protobuf below). `p2p` also applies Checkstyle, but with a separate config at the repo root (`config/checkstyle/checkStyleAll.xml`, distinct from the `framework/config/checkstyle/` one that `framework` and `plugins` use) — it is still enforced, by `./gradlew clean build` in `pr-build.yml`, just not part of the `pr-check.yml` command. A bare `./gradlew checkstyleMain` does not reproduce the gate.
56+
57+
### 4. Forbidden `Math` usage
58+
59+
CI (`.github/workflows/math-check.yml`) **fails the build on any use of `java.lang.Math`** anywhere in the repository: bare `Math.` calls, fully qualified `java.lang.Math.` calls (including static imports), and `import java.lang.Math`. Only `StrictMathWrapper.java` and `MathWrapper.java` are exempt.
60+
61+
Use `org.tron.common.math.StrictMathWrapper` instead. Self-check before pushing with the script CI runs (`StrictMath.` and occurrences in strings or comments are ignored):
62+
63+
```bash
64+
bash .github/scripts/check_math_usage.sh
65+
```
66+
67+
No output means the gate passes.
68+
69+
This exists because `java.lang.Math` gives platform-dependent results for floating-point operations, which breaks cross-JVM determinism between the x86/JDK 8 and ARM64/JDK 17 builds.
70+
71+
### 5. Config validation — only if you touched `reference.conf`
72+
73+
```bash
74+
pip install -r .github/scripts/requirements.txt # pyhocon, required by the first script
75+
python3 .github/scripts/check_reference_conf.py common/src/main/resources/reference.conf
76+
python3 .github/scripts/check_reference_comments.py common/src/main/resources/reference.conf
77+
```
78+
79+
Both gates run in CI. The rules:
80+
81+
- Every key path segment must match `^[a-z][a-zA-Z0-9]*$` (only the first character is constrained; acronyms such as `httpPBFTEnable` are fine). This is what `ConfigBeanFactory` bean-binding requires.
82+
- Total path depth ≤ **5**; each list/array step counts as one level.
83+
- Service-binding port values (leaf named `port` or ending in `Port`, outside arrays) must be unique; `0` and `-1` are reserved sentinels.
84+
- **Every key needs a comment** — inline on the same line, or on the immediately preceding line. Blank lines do not count.
85+
86+
See [`docs/configuration-conventions.md`](./docs/configuration-conventions.md).
87+
88+
### 6. Dependency verification — only if you touched dependencies
89+
90+
`gradle/verification-metadata.xml` pins checksums for every resolved artifact (`verify-metadata=true`). Adding, removing, or upgrading any dependency requires regenerating it, or the build fails for everyone:
91+
92+
```bash
93+
./gradlew --write-verification-metadata sha256 help
94+
```
95+
96+
Review the resulting diff — it must contain only the artifacts your change actually introduces.
97+
98+
### 7. Do not commit binaries
99+
100+
No `*.jar`, `build/`, logs, or database files — whether produced by the main build or as byproducts of investigation.
101+
102+
## Module Layout
103+
104+
| Module | Responsibility |
105+
|--------|----------------|
106+
| `framework` | Main entry (`org.tron.program.FullNode`); wires all modules; largest test suite |
107+
| `protocol` | Protobuf / gRPC definitions |
108+
| `chainbase` | Blockchain storage abstraction (LevelDB / RocksDB); snapshot & rollback |
109+
| `consensus` | Pluggable DPoS consensus engine |
110+
| `actuator` | Transaction execution; one Actuator class per transaction type |
111+
| `crypto` | Cryptographic primitives (depends only on `common`) |
112+
| `common` | Shared utilities |
113+
| `p2p` | Peer discovery, connection management and DNS-based node lists; vendored from [tronprotocol/libp2p](https://github.com/tronprotocol/libp2p) (see [`p2p/README.md`](./p2p/README.md)) |
114+
| `platform` | Architecture-specific implementations selected at build time (separate `x86` / `arm` / `common` source sets): math wrappers, LevelDB/RocksDB order-price comparators — relevant to cross-JVM determinism |
115+
| `plugins` | Standalone tools (`Toolkit.jar`, `ArchiveManifest.jar`) |
116+
117+
`errorprone` and `example:actuator-example` are build-support and sample modules, not part of the node.
118+
119+
**Module dependency direction is one-way — do not introduce reverse dependencies:**
120+
121+
```text
122+
framework → chainbase, protocol, actuator, consensus, p2p
123+
chainbase → protocol, common, crypto
124+
common → protocol, p2p, platform
125+
actuator → chainbase, protocol, crypto
126+
consensus → chainbase, protocol (only via ConsensusDelegate; never call Manager directly)
127+
crypto → common
128+
```
129+
130+
`platform` and `p2p` are leaf modules with no dependencies of their own. `platform` holds the architecture-specific code; `common` and `plugins` depend on it directly, while `framework` picks it up only transitively through `common`. `plugins` depends on `crypto`, `platform`, and `protocol`.
131+
132+
## Hard Constraints
133+
134+
**Cross-JVM determinism** (consensus, state transition, block ordering) — the same block must produce the same state on every supported platform:
135+
- Never use `java.lang.Math` — use `org.tron.common.math.StrictMathWrapper` instead (CI-enforced, see checklist step 4).
136+
- Never use `float` / `double` in consensus-relevant arithmetic.
137+
- Never depend on `HashMap` iteration order for a business decision.
138+
- Use the DPoS slot time for produced-block timestamps, not `System.currentTimeMillis()`.
139+
- Never call `String.toLowerCase()` / `toUpperCase()` without an explicit `Locale` — ErrorProne enforces this as a compile error (`StringCaseLocaleUsage`).
140+
141+
**DB / Store:**
142+
- State changes run inside the revoking session that `Manager` opens per transaction and per block; it is `merge()`d / `commit()`ted on success and revoked otherwise.
143+
- Actuators, the VM and stores call `put()` / `delete()` directly and must never open their own session: an `ISession` closed without `merge()` / `commit()` discards its writes, and `buildSession()` moves the snapshot head of every store.
144+
- A new consensus-state store extends `TronStoreWithRevoking<T>`, which registers itself in `@PostConstruct init()`; never call `revokingDatabase.add()` yourself. Auxiliary, non-revocable stores extend `TronDatabase<T>`.
145+
146+
**Actuator:**
147+
- New actuators are registered automatically: place the class in the `org.tron.core.actuator` package, extend `AbstractActuator`, and pass the `ContractType` to `super(...)` from a no-arg constructor. `TransactionRegister.registerActuator()` discovers it by reflection at startup — there is no manual registration step.
148+
- `validate()` must check that the owner can afford `calcFee()` plus any amount being moved; the fee itself is charged inside `execute()` together with the state change, so a failed `execute()` rolls back both. Bandwidth, multi-signature and memo fees are charged by `Manager.processTransaction()` before the actuator runs — an actuator never touches them.
149+
- `validate()` must not mutate state.
150+
151+
**Protobuf:**
152+
- Fields may only be added — never removed or renumbered.
153+
- Message field numbers start at `1`; the first enum value must be `0`.
154+
- In a new enum, the zero value's name must start with `UNKNOWN_` (e.g. `UNKNOWN_STATUS = 0;`, not `SUCCESS = 0;`). `protocol/protoLint.gradle` enforces this during `./gradlew build`; only the existing enums in its `legacyEnums` whitelist are exempt.
155+
156+
**API / Threads:**
157+
- New HTTP servlets must go through `HttpApiAccessFilter` and use `Wallet` (never inject `Manager` directly).
158+
- A new gRPC or HTTP query that depends on historical data (unavailable on a lite fullnode) must be added to the deny-list in `LiteFnQueryGrpcInterceptor` / `LiteFnQueryHttpFilter`; other methods need no action — the interceptor and filter are installed server-wide.
159+
- No bare `new Thread()` — use a named Executor, shut down via `shutdown()` → `awaitTermination()` → `shutdownNow()`.
160+
161+
## Common Pitfalls
162+
163+
1. **ErrorProne is skipped below JDK 17.** An x86/JDK 8 build therefore does not report `StringCaseLocaleUsage` violations, while the same code fails to compile in the aarch64/JDK 17 CI jobs.
164+
2. **`./gradlew checkstyleMain` is not the CI gate.** Use the exact module-scoped command in checklist step 3.
165+
3. **Adding a config key without a comment fails CI**, even if the key itself is valid.
166+
4. **Changing a dependency without regenerating `verification-metadata.xml` breaks the build for everyone**, not just you.
167+
5. **Generated protobuf sources are git-ignored.** If a build error references a missing generated class, rebuild instead of creating the file.
168+
6. **Consensus-affecting behaviour changes need a proposal / fork gate**, not just a code change. Changing how an existing transaction validates or executes will fork the network unless gated. When in doubt, ask before implementing.
169+
170+
## Authoritative Documentation
171+
172+
- **Build / run / node operation:** [README](./README.md)
173+
- **Configuration:** [`docs/configuration.md`](./docs/configuration.md), [`docs/configuration-conventions.md`](./docs/configuration-conventions.md)
174+
- **Protobuf protocol:** the `.proto` files under `protocol/src/main/protos/` are the source of truth; [`docs/protobuf-protocol-document.md`](./docs/protobuf-protocol-document.md) explains the main messages (the Markdown copies under `protocol/src/main/protos/` are outdated).
175+
- **Extending / deployment:** the [`docs/`](./docs) directory (customized actuator, modular deployment).
176+
- **P2P module:** [`p2p/README.md`](./p2p/README.md) (standalone use, DNS node-list publishing, API).
177+
- **Contributing:** [CONTRIBUTING.md](./CONTRIBUTING.md) (workflow, coding style, commit/PR conventions).
178+
- **Security policy:** [SECURITY.md](./SECURITY.md) (supported versions, vulnerability disclosure).
179+
180+
## Commit & PR Convention
181+
182+
Commit messages and PR titles follow `type(scope): description`. The allowed types, the full scope list and the subject rules are defined in [CONTRIBUTING.md](./CONTRIBUTING.md#commit-messages) — follow it there.
183+
184+
PR titles and descriptions are validated in CI by `.github/workflows/pr-check.yml`. Fill in `.github/PULL_REQUEST_TEMPLATE.md`.

‎CONTRIBUTING.md‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ We would like all developers to follow a standard development flow and coding st
147147
2. Review the code before submission.
148148
3. Run standardized tests.
149149
150-
`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.
150+
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.
151151
152152
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.
153153
@@ -158,7 +158,6 @@ Please do not be discouraged if your pull request is not accepted, as it may be
158158
Please make sure your submission meets the following code style:
159159
160160
- The code must conform to [Google Code Style](https://google.github.io/styleguide/javaguide.html).
161-
- The code must have passed the Sonar scanner test.
162161
- The code has to be pulled from the `develop` branch.
163162
- The commit message should start with a verb, whose initial should not be capitalized.
164163
- The commit message title should be between 10 and 72 characters in length.

‎README.md‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
- [Building the Source Code](#building-the-source-code)
2121
- [Executables](#executables)
2222
- [Running java-tron](#running-java-tron)
23+
- [Documentation](#documentation)
2324
- [Community](#community)
2425
- [Contribution](#contribution)
2526
- [Resources](#resources)
@@ -80,6 +81,7 @@ The java-tron project comes with several runnable artifacts and helper scripts f
8081
| :---------------------- | :---------- |
8182
| **`FullNode.jar`** | Main TRON node executable (generated in `build/libs/` after a successful build following the above guidance). Runs as a full node by default. `java -jar FullNode.jar --help` for command line options|
8283
| **`Toolkit.jar`** | Node management utility (generated in `build/libs/`): partition, prune, copy, convert DBs; shadow-fork tool. [Usage](https://tronprotocol.github.io/documentation-en/using_javatron/toolkit/#toolkit-a-java-tron-node-maintenance-suite) |
84+
| **`p2p-standalone.jar`** | Peer discovery, connection management and DNS-based node lists (generated in `build/libs/`). See the [p2p guide](./p2p/README.md). |
8385
| **`start.sh`** | Quick start script (x86_64, JDK 8) to download/build/run `FullNode.jar`. See the tool [guide](./shell.md). |
8486
| **`start.sh.simple`** | Quick start script template (ARM64, JDK 17). See usage notes inside the script. |
8587

@@ -195,6 +197,24 @@ When exposing any of these APIs to a public interface, ensure the node is protec
195197

196198
Public hosted HTTP endpoints for both mainnet and testnet are provided by TronGrid. Please refer to the [TRON Network HTTP Endpoints](https://developers.tron.network/docs/connect-to-the-tron-network#tron-network-http-endpoints) for the latest list. For supported methods and request formats, see the HTTP API reference above.
197199

200+
# Documentation
201+
202+
More detailed guides live in the [`docs/`](./docs) directory:
203+
204+
- **Configuration**
205+
- [Configuration Reference](./docs/configuration.md) — full `config.conf` option reference
206+
- [Configuration Conventions](./docs/configuration-conventions.md)
207+
- **Modular architecture & deployment**
208+
- [Modular Introduction](./docs/modular-introduction-en.md) · [中文版](./docs/modular-introduction-zh.md)
209+
- [Modular Deployment](./docs/modular-deployment-en.md) · [中文版](./docs/modular-deployment-zh.md)
210+
- [P2P Module](./p2p/README.md) — peer discovery, connection management and DNS-based node lists
211+
- **Extending java-tron**
212+
- [Implement a Customized Actuator](./docs/implement-a-customized-actuator-en.md) · [中文版](./docs/implement-a-customized-actuator-zh.md)
213+
- **Protocol**
214+
- [TRON Protobuf Protocol Document](./docs/protobuf-protocol-document.md) — guide to the main Protobuf messages; the `.proto` files under [`protocol/src/main/protos`](./protocol/src/main/protos) are the source of truth
215+
- **Observability**
216+
- [Metrics Changelog](./docs/metrics-changelog.md) — Prometheus metric additions, changes, and removals across java-tron releases
217+
198218
# Community
199219

200220
[TRON Developers & SRs](https://discord.gg/hqKvyAM) is TRON's official Discord channel. Feel free to join this channel if you have any questions.

0 commit comments

Comments
 (0)