Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 128 additions & 14 deletions .github/workflows/pr-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,11 @@ jobs:
restore-keys: macos26-${{ matrix.arch }}-gradle-

- name: Build
run: ./gradlew clean build --no-daemon
shell: bash
run: |
set -euo pipefail
mkdir -p ci-logs
./gradlew clean build --no-daemon --console=plain 2>&1 | tee ci-logs/build.log

- name: Toolkit jar smoke test
run: |
Expand All @@ -63,6 +67,17 @@ jobs:
java -jar "$JAR" db archive -h
java -jar "$JAR" keystore --help

- name: Upload test diagnostics
if: failure()
uses: actions/upload-artifact@v6
with:
name: tron-test-logs-${{ github.job }}-jdk${{ matrix.java }}-${{ matrix.arch }}
path: |
**/logs/tron-test.log
ci-logs/*.log
if-no-files-found: warn
retention-days: 7

build-ubuntu:
name: Build ubuntu24 (JDK 17 / aarch64)
if: ${{ github.event_name == 'pull_request' || inputs.job == 'all' || inputs.job == 'ubuntu' }}
Expand Down Expand Up @@ -91,7 +106,11 @@ jobs:
restore-keys: ubuntu24-aarch64-gradle-

- name: Build
run: ./gradlew clean build --no-daemon
shell: bash
run: |
set -euo pipefail
mkdir -p ci-logs
./gradlew clean build --no-daemon --console=plain 2>&1 | tee ci-logs/build.log

- name: Toolkit jar smoke test
run: |
Expand All @@ -102,6 +121,17 @@ jobs:
java -jar "$JAR" db archive -h
java -jar "$JAR" keystore --help

- name: Upload test diagnostics
if: failure()
uses: actions/upload-artifact@v6
with:
name: tron-test-logs-${{ github.job }}
path: |
**/logs/tron-test.log
ci-logs/*.log
if-no-files-found: warn
retention-days: 7

docker-build-rockylinux:
name: Build rockylinux (JDK 8 / x86_64)
if: ${{ github.event_name == 'pull_request' || inputs.job == 'all' || inputs.job == 'rockylinux' }}
Expand All @@ -113,15 +143,31 @@ jobs:

env:
GRADLE_USER_HOME: /github/home/.gradle
LANG: en_US.UTF-8
LC_ALL: en_US.UTF-8
LANG: C.utf8
LC_ALL: C.utf8

steps:
- name: Install dependencies (Rocky 8 + JDK8)
run: |
set -euxo pipefail
dnf -y install java-1.8.0-openjdk-devel git wget unzip which jq bc curl glibc-langpack-en
dnf -y groupinstall "Development Tools"
# Rocky 8 already provides CA certificates, JNI runtime libraries, tar and gzip.
# Its built-in C.utf8 locale provides UTF-8 without an extra language pack.
# git-core provides checkout commands; zstd supports actions/cache compression.
# Abandon connections below 256 KiB/s for 30 seconds so DNF can try another mirror.
dnf -y \
--setopt=install_weak_deps=False \
--setopt=max_parallel_downloads=10 \
--setopt=minrate=256k \
--setopt=timeout=30 \
install java-1.8.0-openjdk-devel git-core zstd
# Set JAVA_HOME so the Gradle wrapper does not need which.
javac_path=$(command -v javac)
javac_real=$(readlink -f "$javac_path")
jdk_bin=$(dirname "$javac_real")
jdk_home=$(dirname "$jdk_bin")
test -x "$jdk_home/bin/java"
test -x "$jdk_home/bin/javac"
printf 'JAVA_HOME=%s\n' "$jdk_home" >> "$GITHUB_ENV"

- name: Checkout code
uses: actions/checkout@v5
Expand All @@ -143,7 +189,11 @@ jobs:
run: ./gradlew --stop || true

- name: Build
run: ./gradlew clean build --no-daemon
shell: bash
run: |
set -euo pipefail
mkdir -p ci-logs
./gradlew clean build --no-daemon --console=plain 2>&1 | tee ci-logs/build.log

- name: Toolkit jar smoke test
run: |
Expand All @@ -155,7 +205,22 @@ jobs:
java -jar "$JAR" keystore --help

- name: Test with RocksDB engine
run: ./gradlew :framework:testWithRocksDb --no-daemon
shell: bash
run: |
set -euo pipefail
mkdir -p ci-logs
./gradlew :framework:testWithRocksDb --no-daemon --console=plain 2>&1 | tee ci-logs/rocksdb-test.log

- name: Upload test diagnostics
if: failure()
uses: actions/upload-artifact@v6
with:
name: tron-test-logs-${{ github.job }}
path: |
**/logs/tron-test.log
ci-logs/*.log
if-no-files-found: warn
retention-days: 7

docker-build-debian11:
name: Build debian11 (JDK 8 / x86_64)
Expand Down Expand Up @@ -197,7 +262,11 @@ jobs:
debian11-x86_64-gradle-

- name: Build
run: ./gradlew clean build --no-daemon --no-build-cache
shell: bash
run: |
set -euo pipefail
mkdir -p ci-logs
./gradlew clean build --no-daemon --no-build-cache --console=plain 2>&1 | tee ci-logs/build.log

- name: Toolkit jar smoke test
run: |
Expand All @@ -209,10 +278,18 @@ jobs:
java -jar "$JAR" keystore --help

- name: Test with RocksDB engine
run: ./gradlew :framework:testWithRocksDb --no-daemon --no-build-cache
shell: bash
run: |
set -euo pipefail
mkdir -p ci-logs
./gradlew :framework:testWithRocksDb --no-daemon --no-build-cache --console=plain 2>&1 | tee ci-logs/rocksdb-test.log

- name: Generate module coverage reports
run: ./gradlew jacocoTestReport --no-daemon
shell: bash
run: |
set -euo pipefail
mkdir -p ci-logs
./gradlew jacocoTestReport --no-daemon --console=plain 2>&1 | tee ci-logs/coverage.log

- name: Upload PR coverage reports
uses: actions/upload-artifact@v6
Expand All @@ -222,6 +299,17 @@ jobs:
**/build/reports/jacoco/test/jacocoTestReport.xml
if-no-files-found: error

- name: Upload test diagnostics
if: failure()
uses: actions/upload-artifact@v6
with:
name: tron-test-logs-${{ github.job }}
path: |
**/logs/tron-test.log
ci-logs/*.log
if-no-files-found: warn
retention-days: 7

coverage-base:
name: Coverage Base (JDK 8 / x86_64)
if: ${{ github.event_name == 'pull_request' }}
Expand Down Expand Up @@ -260,19 +348,33 @@ jobs:
coverage-base-x86_64-gradle-

- name: Build (base)
id: base_build
# Test failures on the base branch are tolerated: merge-order races can
# leave the base with a pre-existing failing test that is unrelated to
# this PR. The only output we need from this job is the jacoco XML for
# coverage diffing, so we must not let a stale test failure block it.
continue-on-error: true
run: ./gradlew clean build --no-daemon --no-build-cache
shell: bash
run: |
set -euo pipefail
mkdir -p ci-logs
./gradlew clean build --no-daemon --no-build-cache --console=plain 2>&1 | tee ci-logs/build.log

- name: Test with RocksDB engine (base)
id: base_rocksdb_test
continue-on-error: true
run: ./gradlew :framework:testWithRocksDb --no-daemon --no-build-cache
shell: bash
run: |
set -euo pipefail
mkdir -p ci-logs
./gradlew :framework:testWithRocksDb --no-daemon --no-build-cache --console=plain 2>&1 | tee ci-logs/rocksdb-test.log

- name: Generate module coverage reports (base)
run: ./gradlew jacocoTestReport --no-daemon
shell: bash
run: |
set -euo pipefail
mkdir -p ci-logs
./gradlew jacocoTestReport --no-daemon --console=plain 2>&1 | tee ci-logs/coverage.log

- name: Upload base coverage reports
uses: actions/upload-artifact@v6
Expand All @@ -282,6 +384,18 @@ jobs:
**/build/reports/jacoco/test/jacocoTestReport.xml
if-no-files-found: warn

- name: Upload test diagnostics
# Preserve logs for test failures tolerated by continue-on-error above.
if: ${{ failure() || steps.base_build.outcome == 'failure' || steps.base_rocksdb_test.outcome == 'failure' }}
uses: actions/upload-artifact@v6
with:
name: tron-test-logs-${{ github.job }}
path: |
**/logs/tron-test.log
ci-logs/*.log
if-no-files-found: warn
retention-days: 7

coverage-gate:
name: Coverage Gate
needs: [docker-build-debian11, coverage-base]
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/pr-cancel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ jobs:
'pr-build.yml',
'codeql.yml',
'integration-test-single-node.yml',
'integration-test-multinode.yml',
];
const headSha = context.payload.pull_request.head.sha;
const prNumber = context.payload.pull_request.number;
Expand Down
15 changes: 11 additions & 4 deletions .github/workflows/pr-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,16 @@ jobs:
errors.push(`PR title is too long (${title.length}/72 characters).`);
}

// 2. Conventional format check
const conventionalRegex = /^(feat|fix|refactor|docs|style|test|chore|ci|perf|build|revert)(\([^)]+\))?:\s\S.*/;
if (title && !conventionalRegex.test(title)) {
// 2. Conventional format check (require a space after the colon)
const titlePrefix = '(?:feat|fix|refactor|docs|style|test|chore|ci|perf|build|revert)(?:[(][^)]+[)])?';
const missingSpaceAfterColonRegex = new RegExp(`^${titlePrefix}:[^ ]`);
const conventionalRegex = new RegExp(`^${titlePrefix}: [^ ].*`);
if (title && missingSpaceAfterColonRegex.test(title)) {
errors.push(
'PR title must include a space after the colon.\n' +
' Example: `feat(tvm): add blob opcodes`'
);
} else if (title && !conventionalRegex.test(title)) {
errors.push(
'PR title must follow conventional format: `type(scope): description`\n' +
' Allowed types: ' + allowedTypes.map(t => `\`${t}\``).join(', ') + '\n' +
Expand All @@ -60,7 +67,7 @@ jobs:

// 4. Description part should not start with a capital letter
if (title) {
const descMatch = title.match(/^\w+(?:\([^)]+\))?:\s*(.+)/);
const descMatch = title.match(/^\w+(?:\([^)]+\))?: (.+)/);
if (descMatch) {
const desc = descMatch[1];
if (/^[A-Z]/.test(desc)) {
Expand Down
14 changes: 12 additions & 2 deletions .github/workflows/pr-reviewer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,23 @@ jobs:
const normalize = s => s.toLowerCase().replace(/[\s\-_]/g, '');

// ── Extract scope from conventional commit title ──────────
// Format: type(scope): description
// Formats documented by CONTRIBUTING.md:
// type(scope): description
// type: description
// Also supports: type(scope1,scope2): description
// Only bare "ci" currently has an equivalent reviewer scope.
const scopeMatch = title.match(/^\w+\(([^)]+)\):/);
const rawScope = scopeMatch ? scopeMatch[1] : null;
const bareTypeMatch = title.match(/^(\w+):/);
const inferredScope = !scopeMatch && bareTypeMatch?.[1].toLowerCase() === 'ci'
? 'ci'
: null;
const rawScope = scopeMatch ? scopeMatch[1] : inferredScope;

core.info(`PR title : ${title}`);
core.info(`Raw scope: ${rawScope || '(none)'}`);
if (inferredScope) {
core.info('Inferred scope "ci" from bare "ci" PR title type.');
}

// ── Skip if reviewers already assigned ──────────────────
const pr = await github.rest.pulls.get({
Expand Down
16 changes: 7 additions & 9 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ plugins {
}

ext {
grpcVersion = "1.83.0"
grpcVersion = "1.83.1"
}

allprojects {
Expand Down Expand Up @@ -91,16 +91,14 @@ subprojects {
}

dependencies {
implementation group: 'org.slf4j', name: 'slf4j-api', version: '1.7.36'
implementation group: 'org.slf4j', name: 'jcl-over-slf4j', version: '1.7.36'
implementation group: 'org.slf4j', name: 'jul-to-slf4j', version: '1.7.36'
implementation group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.13'
implementation group: 'org.slf4j', name: 'slf4j-api', version: '2.0.17'
implementation group: 'org.slf4j', name: 'jcl-over-slf4j', version: '2.0.17'
implementation group: 'org.slf4j', name: 'jul-to-slf4j', version: '2.0.17'
implementation group: 'ch.qos.logback', name: 'logback-classic', version: '1.3.16'
implementation "com.google.code.findbugs:jsr305:3.0.0"
implementation group: 'org.springframework', name: 'spring-context', version: "${springVersion}"
implementation "org.apache.commons:commons-lang3:3.4"
implementation group: 'org.apache.commons', name: 'commons-math', version: '2.2'
implementation "org.apache.commons:commons-collections4:4.1"
implementation group: 'joda-time', name: 'joda-time', version: '2.3'
implementation "org.apache.commons:commons-lang3:3.20.0"
implementation "org.apache.commons:commons-collections4:4.6.0"
implementation group: 'org.bouncycastle', name: 'bcprov-jdk18on', version: '1.84'

compileOnly 'org.projectlombok:lombok:1.18.34'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@
import java.util.stream.IntStream;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.tron.common.parameter.CommonParameter;
import org.tron.common.utils.ByteArray;
import org.tron.common.utils.Sha256Hash;
import org.tron.common.utils.Time;
import org.tron.core.capsule.BytesCapsule;
import org.tron.core.config.Parameter.ChainConstant;
import org.tron.core.db.TronStoreWithRevoking;
Expand Down Expand Up @@ -2261,8 +2261,8 @@ public void updateNextMaintenanceTime(long blockTime) {
logger.info(
"Do update nextMaintenanceTime, currentMaintenanceTime: {}, blockTime: {}, "
+ "nextMaintenanceTime: {}.",
new DateTime(currentMaintenanceTime), new DateTime(blockTime),
new DateTime(nextMaintenanceTime)
Time.getIsoTimeString(currentMaintenanceTime), Time.getIsoTimeString(blockTime),
Time.getIsoTimeString(nextMaintenanceTime)
);
}

Expand Down
4 changes: 3 additions & 1 deletion common/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ sourceCompatibility = 1.8


dependencies {
api group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.18.6' // https://github.com/FasterXML/jackson-databind/issues/3627
// avoid x.y.z.w micro-patches, they may ship broken Gradle module metadata:
// https://github.com/FasterXML/jackson-databind/issues/3627
api group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.18.10'
api "com.cedarsoftware:java-util:3.2.0"
api group: 'org.apache.httpcomponents', name: 'httpasyncclient', version: '4.1.1'
api group: 'commons-codec', name: 'commons-codec', version: '1.11'
Expand Down
2 changes: 1 addition & 1 deletion common/src/main/java/org/tron/common/entity/NodeInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ public Protocol.NodeInfo transferToProtoEntity() {
peerInfoBuilder.setLastBlockUpdateTime(peerInfo.getLastBlockUpdateTime());
peerInfoBuilder.setSyncFlag(peerInfo.isSyncFlag());
peerInfoBuilder.setHeadBlockTimeWeBothHave(peerInfo.getHeadBlockTimeWeBothHave());
peerInfoBuilder.setNeedSyncFromPeer(peerInfo.isSyncFlag());
peerInfoBuilder.setNeedSyncFromPeer(peerInfo.isNeedSyncFromPeer());
peerInfoBuilder.setNeedSyncFromUs(peerInfo.isNeedSyncFromUs());
peerInfoBuilder.setHost(peerInfo.getHost());
peerInfoBuilder.setPort(peerInfo.getPort());
Expand Down
Loading
Loading