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
2 changes: 0 additions & 2 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
./*
!docker-entrypoint.sh

56 changes: 56 additions & 0 deletions .github/workflows/docker-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: Docker Check

on:
push:
branches: [ 'master', 'release_**' ]
paths:
- 'docker/docker.sh'
- 'docker/Dockerfile'
- 'docker/arm64/Dockerfile'
- '.github/workflows/docker-check.yml'
pull_request:
branches: [ 'master', 'develop', 'release_**' ]
paths:
- 'docker/docker.sh'
- 'docker/Dockerfile'
- 'docker/arm64/Dockerfile'
- '.github/workflows/docker-check.yml'
workflow_dispatch:

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
docker-check:
name: Docker Static Check
runs-on: ubuntu-24.04
timeout-minutes: 5

steps:
- uses: actions/checkout@v5

- name: Check shell syntax
run: bash -n docker/docker.sh

- name: Run ShellCheck
run: shellcheck docker/docker.sh

- name: Check amd64 Dockerfile
run: >
docker buildx build
--check
--platform linux/amd64
--file docker/Dockerfile
docker

- name: Check ARM64 Dockerfile
run: >
docker buildx build
--check
--platform linux/arm64
--file docker/arm64/Dockerfile
docker
8 changes: 4 additions & 4 deletions .github/workflows/pr-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ jobs:
debian11-x86_64-gradle-

- name: Build
run: ./gradlew clean build --no-daemon --no-build-cache
run: ./gradlew clean build --no-daemon

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

- name: Test with RocksDB engine
run: ./gradlew :framework:testWithRocksDb --no-daemon --no-build-cache
run: ./gradlew :framework:testWithRocksDb --no-daemon

- name: Generate module coverage reports
run: ./gradlew jacocoTestReport --no-daemon
Expand Down Expand Up @@ -265,11 +265,11 @@ jobs:
# 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
run: ./gradlew clean build --no-daemon

- name: Test with RocksDB engine (base)
continue-on-error: true
run: ./gradlew :framework:testWithRocksDb --no-daemon --no-build-cache
run: ./gradlew :framework:testWithRocksDb --no-daemon

- name: Generate module coverage reports (base)
run: ./gradlew jacocoTestReport --no-daemon
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
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.rocksdb.BlockBasedTableConfig;
import org.rocksdb.BloomFilter;
import org.rocksdb.ComparatorOptions;
import org.rocksdb.InfoLogLevel;
import org.rocksdb.LRUCache;
Expand Down Expand Up @@ -211,13 +210,7 @@ protected void log(InfoLogLevel infoLogLevel, String logMsg) {
options.setTargetFileSizeBase(settings.getTargetFileSizeBase());

// table options
final BlockBasedTableConfig tableCfg;
options.setTableFormatConfig(tableCfg = new BlockBasedTableConfig());
tableCfg.setBlockSize(settings.getBlockSize());
tableCfg.setBlockCache(RocksDbSettings.getCache());
tableCfg.setCacheIndexAndFilterBlocks(true);
tableCfg.setPinL0FilterAndIndexBlocksInCache(true);
tableCfg.setFilter(new BloomFilter(10, false));
options.setTableFormatConfig(new BlockBasedTableConfig());
if (Constant.MARKET_PAIR_PRICE_TO_ORDER.equals(dbName)) {
ComparatorOptions comparatorOptions = new ComparatorOptions();
options.setComparator(new MarketOrderPriceComparatorForRocksDB(comparatorOptions));
Expand Down
12 changes: 12 additions & 0 deletions common/src/main/java/org/tron/common/utils/Time.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,26 @@
package org.tron.common.utils;

import java.sql.Timestamp;
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;

public class Time {

// Matches joda-time's DateTime.toString() output, byte for byte: fixed
// 3-digit millis, offset as +08:00, and Z when the system zone is UTC.
private static final DateTimeFormatter ISO_MILLIS_FORMAT =
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");

public static long getCurrentMillis() {
return System.currentTimeMillis();
}

public static String getTimeString(long time) {
return new Timestamp(time).toString();
}

public static String getIsoTimeString(long time) {
return Instant.ofEpochMilli(time).atZone(ZoneId.systemDefault()).format(ISO_MILLIS_FORMAT);
}
}
2 changes: 1 addition & 1 deletion common/src/main/resources/reference.conf
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ storage {
dbSettings = {
levelNumber = 7 // Number of RocksDB levels.
compactThreads = 0 // 0 = auto: max(availableProcessors, 1)
blocksize = 16 // n * KB
blocksize = 16 // n * KB. Currently retained for compatibility but not applied to native RocksDB table options.
maxBytesForLevelBase = 256 // n * MB
maxBytesForLevelMultiplier = 10 // Level size multiplier.
level0FileNumCompactionTrigger = 2 // L0 files that trigger compaction.
Expand Down
58 changes: 58 additions & 0 deletions common/src/test/java/org/tron/common/entity/NodeInfoTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package org.tron.common.entity;

import java.util.ArrayList;
import java.util.List;
import org.junit.Assert;
import org.junit.Test;
import org.tron.protos.Protocol;

public class NodeInfoTest {

private PeerInfo newPeerInfo(boolean syncFlag, boolean needSyncFromPeer,
boolean needSyncFromUs) {
PeerInfo peerInfo = new PeerInfo();
peerInfo.setSyncFlag(syncFlag);
peerInfo.setNeedSyncFromPeer(needSyncFromPeer);
peerInfo.setNeedSyncFromUs(needSyncFromUs);
// string fields must be non-null, otherwise the protobuf setters throw NPE
peerInfo.setLastSyncBlock("");
peerInfo.setHost("127.0.0.1");
peerInfo.setNodeId("");
peerInfo.setHeadBlockWeBothHave("");
peerInfo.setLocalDisconnectReason("");
peerInfo.setRemoteDisconnectReason("");
return peerInfo;
}

/**
* The protobuf conversion must map each peer flag from its own source field. A previous
* copy-and-paste defect populated needSyncFromPeer from isSyncFlag(); distinct values for
* syncFlag and needSyncFromPeer are required so that such a mismatch is detected.
*/
@Test
public void testPeerFlagMappingIsIndependent() {
NodeInfo nodeInfo = new NodeInfo();
nodeInfo.setBlock("");
nodeInfo.setSolidityBlock("");
List<PeerInfo> peerList = new ArrayList<>();
// syncFlag != needSyncFromPeer so the two fields cannot be confused
peerList.add(newPeerInfo(false, true, false));
peerList.add(newPeerInfo(true, false, true));
nodeInfo.setPeerList(peerList);
nodeInfo.setCheatWitnessInfoMap(new java.util.HashMap<>());

Protocol.NodeInfo proto = nodeInfo.transferToProtoEntity();

Assert.assertEquals(2, proto.getPeerInfoListCount());

Protocol.NodeInfo.PeerInfo peer0 = proto.getPeerInfoList(0);
Assert.assertFalse(peer0.getSyncFlag());
Assert.assertTrue(peer0.getNeedSyncFromPeer());
Assert.assertFalse(peer0.getNeedSyncFromUs());

Protocol.NodeInfo.PeerInfo peer1 = proto.getPeerInfoList(1);
Assert.assertTrue(peer1.getSyncFlag());
Assert.assertFalse(peer1.getNeedSyncFromPeer());
Assert.assertTrue(peer1.getNeedSyncFromUs());
}
}
Loading
Loading