Repository navigation
docs: add AGENTS.md and reorganize project documentation #6871
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
SeriousCoding789
wants to merge
33
commits into
tronprotocol:release_v4.8.3
Choose a base branch
from
Little-Peony:fix_readme
base: release_v4.8.3
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
33 commits
Select commit
Hold shift + click to select a range
0098981
docs(readme): add Documentation section linking guides and protocol doc
Little-Peony 90dea2c
docs(config): add super-representative private-key security notes
Little-Peony 6dea9d6
docs: move protocol document into docs/ with a shorter name
Little-Peony b661d06
docs: move metrics changelog into docs/ and link from README
Little-Peony 5d565d6
docs: mark outdated protobuf protocol copies as superseded
Little-Peony 6f1f3e9
chore(ci): remove unused CodeClimate and Sonar configs
Little-Peony 21f7d6c
delete .dockerignore
Little-Peony f6ec27a
modify chinese
Little-Peony 8334a03
docs: drop stale Sonar references and fix metrics changelog link
Little-Peony 0369ec4
chore: remove unused Sonar entries from verification-metadata
Little-Peony c7011ba
docs: add AGENTS.md for AI assistants and contributors
Little-Peony 741c49f
docs: correct AGENTS.md platform and build details
Little-Peony 3e90afb
merge
Little-Peony 6266117
chore: remove obsolete start scripts
Little-Peony a6dcbc6
update agents.md
Little-Peony 6d79908
docs: qualify --tests examples with the framework module
Little-Peony 1b0690f
docs: correct the actuator registration rule in AGENTS.md
Little-Peony 016e727
docs: use the fully qualified StrictMathWrapper name
Little-Peony d785afb
docs: reference the real ISession type in the DB rule
Little-Peony ff4ca6c
docs: correct the lite-fullnode query rule in AGENTS.md
Little-Peony 92ff475
docs: point commit convention to CONTRIBUTING.md
Little-Peony d6dfa94
docs: drop Script from the README executables header
Little-Peony f457100
docs: correct test parallelism and actuator fee rules in AGENTS.md
Little-Peony 642e539
chore: restore start.sh and start.sh.simple
Little-Peony 800f084
fix: disable download in start.sh
Little-Peony 6d40041
revert: disable download in start.sh
Little-Peony 3c07622
docs: restore shell.md and start script entries in README
Little-Peony 960d65b
docs: align AGENTS.md checks with CI
Little-Peony 61485b6
docs: sync protobuf protocol document with the proto files
Little-Peony 6b28b14
Merge branch 'release_v4.8.3' into fix_readme
Little-Peony 0db602d
add libp2p related in doc
Little-Peony 57c356c
docs: add p2p-standalone.jar to README and trim p2p details
Little-Peony 3303a35
docs: reword the p2p-standalone.jar entry in README
Little-Peony File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| #!/usr/bin/env bash | ||
| # Prints every Java file that uses java.lang.Math: bare `Math.` calls, fully | ||
| # qualified `java.lang.Math.` calls (including static imports) and | ||
| # `import java.lang.Math`. No output means no forbidden usage. | ||
| # StrictMathWrapper.java and MathWrapper.java are exempt. String literals, char | ||
| # literals and comments are stripped before matching, so `StrictMath.` and | ||
| # mentions in text are not reported. | ||
| # Used by .github/workflows/math-check.yml; run it locally from any directory. | ||
| set -euo pipefail | ||
|
|
||
| cd "$(dirname "$0")/../.." | ||
|
|
||
| find . -type f -name '*.java' -not -path '*/build/*' | while IFS= read -r file; do | ||
| case "$(basename "$file")" in | ||
| StrictMathWrapper.java|MathWrapper.java) continue ;; | ||
| esac | ||
|
|
||
| perl -0777 -ne ' | ||
| s/"([^"\\]|\\.)*"//g; | ||
| s/'\''([^'\''\\]|\\.)*'\''//g; | ||
| s!/\*([^*]|\*[^/])*\*/!!g; | ||
| s!//[^\n]*!!g; | ||
| $hasMath = 0; | ||
| $hasMath = 1 if /^[\s]*import[\s]+java\.lang\.Math\b/m; | ||
| $hasMath = 1 if /\bjava\s*\.\s*lang\s*\.\s*Math\s*\./; | ||
| $hasMath = 1 if /(?<![\w\.])(?<!Strict)Math\s*\./; | ||
| print "$ARGV\n" if $hasMath; | ||
| ' "$file" | ||
| done | sort -u |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,184 @@ | ||
| # AGENTS.md | ||
|
|
||
| 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). | ||
|
|
||
| ## Guidelines | ||
|
|
||
| - **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. | ||
| - **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). | ||
| - **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`. | ||
|
|
||
| ## Build & Test | ||
|
|
||
| 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. | ||
|
|
||
| ```bash | ||
| ./gradlew clean build -x test # build without tests | ||
| ./gradlew build # build with tests | ||
| ./gradlew test # run all tests | ||
| ./gradlew :framework:test # test one module | ||
| ./gradlew :framework:test --tests "org.tron.core.db.TronDatabaseTest" # one class | ||
| ./gradlew :framework:test --tests "org.tron.core.db.TronDatabaseTest.TestGetUnchecked" # one method | ||
| ./gradlew :framework:testWithRocksDb # RocksDB tests (x86 only) | ||
| ./gradlew jacocoTestReport # coverage report | ||
| ``` | ||
|
|
||
| - Main entry point: `org.tron.program.FullNode`. | ||
| - 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`. | ||
| - On ARM64/aarch64, only the RocksDB storage engine is supported; the build forces RocksDB and skips the LevelDB tests. | ||
| - CI builds the full matrix: **JDK 8 / x86_64** (rockylinux, debian11) and **JDK 17 / aarch64** (macOS, ubuntu24). A change must compile on both. | ||
|
|
||
| ## Pre-Commit Checklist | ||
|
|
||
| Run **all** applicable checks before committing. Each maps to a CI job that will otherwise fail the PR. | ||
|
|
||
| ### 1. Build | ||
|
|
||
| ```bash | ||
| ./gradlew clean build -x test | ||
| ``` | ||
|
|
||
| ### 2. Tests | ||
|
|
||
| ```bash | ||
| ./gradlew test | ||
| ``` | ||
|
|
||
| ### 3. Checkstyle | ||
|
|
||
| Run exactly what CI runs (`.github/workflows/pr-check.yml`): | ||
|
|
||
| ```bash | ||
| ./gradlew :framework:checkstyleMain :framework:checkstyleTest :plugins:checkstyleMain | ||
| ``` | ||
|
|
||
| CI runs Checkstyle only for `framework` and `plugins`; `protocol` is checked by `protoLint` instead (see Protobuf below). `p2p` has its own Checkstyle configuration (`./gradlew :p2p:checkstyleMain :p2p:checkstyleTest`) that is not part of the CI gate. A bare `./gradlew checkstyleMain` does not reproduce the CI gate. | ||
|
|
||
| ### 4. Forbidden `Math` usage | ||
|
|
||
| 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. | ||
|
|
||
| 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): | ||
|
|
||
| ```bash | ||
| bash .github/scripts/check_math_usage.sh | ||
| ``` | ||
|
|
||
| No output means the gate passes. | ||
|
|
||
| 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. | ||
|
|
||
| ### 5. Config validation — only if you touched `reference.conf` | ||
|
|
||
| ```bash | ||
| pip install -r .github/scripts/requirements.txt # pyhocon, required by the first script | ||
| python3 .github/scripts/check_reference_conf.py common/src/main/resources/reference.conf | ||
| python3 .github/scripts/check_reference_comments.py common/src/main/resources/reference.conf | ||
| ``` | ||
|
|
||
| Both gates run in CI. The rules: | ||
|
|
||
| - 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. | ||
| - Total path depth ≤ **5**; each list/array step counts as one level. | ||
| - Service-binding port values (leaf named `port` or ending in `Port`, outside arrays) must be unique; `0` and `-1` are reserved sentinels. | ||
| - **Every key needs a comment** — inline on the same line, or on the immediately preceding line. Blank lines do not count. | ||
|
|
||
| See [`docs/configuration-conventions.md`](./docs/configuration-conventions.md). | ||
|
|
||
| ### 6. Dependency verification — only if you touched dependencies | ||
|
|
||
| `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: | ||
|
|
||
| ```bash | ||
| ./gradlew --write-verification-metadata sha256 help | ||
| ``` | ||
|
|
||
| Review the resulting diff — it must contain only the artifacts your change actually introduces. | ||
|
|
||
| ### 7. Do not commit binaries | ||
|
|
||
| No `*.jar`, `build/`, logs, or database files — whether produced by the main build or as byproducts of investigation. | ||
|
|
||
| ## Module Layout | ||
|
|
||
| | Module | Responsibility | | ||
| |--------|----------------| | ||
| | `framework` | Main entry (`org.tron.program.FullNode`); wires all modules; largest test suite | | ||
| | `protocol` | Protobuf / gRPC definitions | | ||
| | `chainbase` | Blockchain storage abstraction (LevelDB / RocksDB); snapshot & rollback | | ||
| | `consensus` | Pluggable DPoS consensus engine | | ||
| | `actuator` | Transaction execution; one Actuator class per transaction type | | ||
| | `crypto` | Cryptographic primitives (depends only on `common`) | | ||
| | `common` | Shared utilities | | ||
| | `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)) | | ||
| | `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 | | ||
| | `plugins` | Standalone tools (`Toolkit.jar`, `ArchiveManifest.jar`) | | ||
|
|
||
| `errorprone` and `example:actuator-example` are build-support and sample modules, not part of the node. | ||
|
|
||
| **Module dependency direction is one-way — do not introduce reverse dependencies:** | ||
|
|
||
| ```text | ||
| framework → chainbase → common → protocol | ||
| actuator → chainbase | ||
| consensus → chainbase / common (only via ConsensusDelegate; never call Manager directly) | ||
| crypto → common | ||
| ``` | ||
|
|
||
| `platform` is a leaf module (no project dependencies of its own) that `common`, `framework`, and `plugins` depend on for architecture-specific code. | ||
|
|
||
| `p2p` is also a leaf module. | ||
|
|
||
| ## Hard Constraints | ||
|
|
||
| **Cross-JVM determinism** (consensus, state transition, block ordering) — the same block must produce the same state on every supported platform: | ||
| - Never use `java.lang.Math` — use `org.tron.common.math.StrictMathWrapper` instead (CI-enforced, see checklist step 4). | ||
| - Never use `float` / `double` in consensus-relevant arithmetic. | ||
| - Never depend on `HashMap` iteration order for a business decision. | ||
| - Use the DPoS slot time for produced-block timestamps, not `System.currentTimeMillis()`. | ||
| - Never call `String.toLowerCase()` / `toUpperCase()` without an explicit `Locale` — ErrorProne enforces this as a compile error (`StringCaseLocaleUsage`). | ||
|
|
||
| **DB / Store:** | ||
| - All writes must happen inside a revocable session — `try (ISession session = revokingStore.buildSession())` — never a bare `put()`. | ||
| - A new store must extend `TronStoreWithRevoking<T>` and register with the `RevokingDatabase`. | ||
| - Multi-store updates must roll back fully on exception. | ||
|
|
||
| **Actuator:** | ||
| - 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. | ||
| - `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. | ||
| - `validate()` must not mutate state. | ||
|
|
||
| **Protobuf:** | ||
| - Fields may only be added — never removed or renumbered. | ||
| - Message field numbers start at `1`; the first enum value must be `0`. | ||
| - 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. | ||
|
|
||
| **API / Threads:** | ||
| - New HTTP servlets must go through `HttpApiAccessFilter` and use `Wallet` (never inject `Manager` directly). | ||
| - 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. | ||
| - No bare `new Thread()` — use a named Executor, shut down via `shutdown()` → `awaitTermination()` → `shutdownNow()`. | ||
|
|
||
| ## Common Pitfalls | ||
|
|
||
| 1. **ErrorProne only runs on JDK 11+.** Building on x86/JDK 8 will *not* surface `StringCaseLocaleUsage` violations, but the aarch64/JDK 17 CI jobs will fail. If you only build on x86, you will not see these locally. | ||
| 2. **`./gradlew checkstyleMain` is not the CI gate.** Use the exact module-scoped command in checklist step 3. | ||
| 3. **Adding a config key without a comment fails CI**, even if the key itself is valid. | ||
| 4. **Changing a dependency without regenerating `verification-metadata.xml` breaks the build for everyone**, not just you. | ||
| 5. **Generated protobuf sources are git-ignored.** If a build error references a missing generated class, rebuild instead of creating the file. | ||
| 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. | ||
|
|
||
| ## Authoritative Documentation | ||
|
|
||
| - **Build / run / node operation:** [README](./README.md) | ||
| - **Configuration:** [`docs/configuration.md`](./docs/configuration.md), [`docs/configuration-conventions.md`](./docs/configuration-conventions.md) | ||
| - **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). | ||
| - **Extending / deployment:** the [`docs/`](./docs) directory (customized actuator, modular deployment). | ||
| - **P2P module:** [`p2p/README.md`](./p2p/README.md) (standalone use, DNS node-list publishing, API). | ||
| - **Contributing:** [CONTRIBUTING.md](./CONTRIBUTING.md) (workflow, coding style, commit/PR conventions). | ||
| - **Security policy:** [SECURITY.md](./SECURITY.md) (supported versions, vulnerability disclosure). | ||
|
|
||
| ## Commit & PR Convention | ||
|
|
||
| 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. | ||
|
|
||
| PR titles and descriptions are validated in CI by `.github/workflows/pr-check.yml`. Fill in `.github/PULL_REQUEST_TEMPLATE.md`. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[SHOULD] This rule is the reverse of how the codebase works, and an agent following it will write code that silently loses state.
Manageropens sessions: one per transaction (pushTransaction,generateBlock) and one per block (applyBlock, fork switch),merge()d /commit()ted on success. In main sourcesgit grep 'buildSession('only hits Manager.java (besides theRevokingDatabaseinterface andSnapshotManager). Actuators, the VM and stores callput()directly, e.g.TransferActuator.java:55.merge()/commit()is revoked (SnapshotManager.java:621-625), so the writes inside it vanish.buildSession()is alsosynchronizedand advances the snapshot head of every registered store (L119,advance()at L160-162), so opening one from actuator/service/API code moves shared state outside Manager's control.TronStoreWithRevoking's@PostConstruct init()(L82-86). A manualrevokingDatabase.add()appends the sameChainbaseagain (dbsis a plainArrayList) and replaces the store's flush executor without shutting the old one down. Non-revoking auxiliary stores legitimately extendTronDatabase<T>(CommonStore, CheckPointV2Store, ZKProofStore, ...).Suggested L142-144: