Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
5d4db4d
test(framework): fix test quality issues in framework unit tests
Little-Peony Apr 6, 2026
ea477ce
test(plugins): fix test quality issues in plugins unit tests
Little-Peony Apr 6, 2026
4321e3d
test(actuator): remove obsolete moreThanFrozenNumber test in FreezeBa…
Little-Peony Apr 6, 2026
d92db81
test(framework): fix test cleanup and solidity node shutdown
Little-Peony Apr 7, 2026
61aadd4
test(framework): replace bare Executors with ExecutorServiceManager a…
Little-Peony Apr 7, 2026
f3dfd3c
test(framework): unify app context fixtures in service tests
Little-Peony Apr 7, 2026
8b721fc
style(test): fix import order to satisfy checkstyle
Little-Peony Apr 8, 2026
85dddb6
chore(config): remove /.dev/ from .gitignore
Little-Peony Apr 8, 2026
ed551ee
style(test): fix import order in SolidityNodeTest
Little-Peony Apr 8, 2026
50998e6
test(framework): use assertSame for exception identity check in Solid…
Little-Peony Apr 8, 2026
036abb9
fix(net): guard relay nodes in peer connection
Little-Peony Apr 8, 2026
c4bb315
test(framework,plugins): fix flaky tests in bandwidth, stats and db-move
Little-Peony Apr 8, 2026
e9cdd01
refactor(framework): promote relayNodes to instance field in PeerConn…
Little-Peony Apr 8, 2026
b173311
refactor(tvm): optimize energy cost calculation for vote witness opcode
yanghang8612 Mar 31, 2026
21b16ea
fix(framework): replace while(true) with while(flag) in SolidityNode
Little-Peony Apr 13, 2026
669b1f2
fix(framework): add null/0 return after while(flag) loops in Solidity…
Little-Peony Apr 13, 2026
ed42e92
fix(test): add comments
Little-Peony Apr 13, 2026
f5a42f8
test(framework): address PR review comments on test code quality
Little-Peony Apr 14, 2026
bb8894a
fix: use Assert.assertThrows to replace try/catch
Little-Peony Apr 14, 2026
3881b87
fix: pr review
Little-Peony Apr 14, 2026
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
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class BackupServer implements AutoCloseable {

private BackupManager backupManager;

private Channel channel;
private volatile Channel channel;

private volatile boolean shutdown = false;

Expand Down Expand Up @@ -77,6 +77,10 @@ public void initChannel(NioDatagramChannel ch)

logger.info("Backup server started, bind port {}", port);

// If close() was called while bind() was in progress, channel was not yet visible
if (shutdown) {
break;
}
channel.closeFuture().sync();
if (shutdown) {
logger.info("Shutdown backup BackupServer");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,6 @@
@Scope("prototype")
public class PeerConnection {

private static List<InetSocketAddress> relayNodes = Args.getInstance().getFastForwardNodes();

@Getter
private PeerStatistics peerStatistics = new PeerStatistics();

Expand Down Expand Up @@ -163,10 +161,16 @@ public class PeerConnection {
private volatile boolean needSyncFromUs = true;
@Getter
private P2pRateLimiter p2pRateLimiter = new P2pRateLimiter();
@Getter
private List<InetSocketAddress> relayNodes;

public void setChannel(Channel channel) {
this.channel = channel;
if (relayNodes.stream().anyMatch(n -> n.getAddress().equals(channel.getInetAddress()))) {
if (this.relayNodes == null) {
this.relayNodes = Args.getInstance().getFastForwardNodes();
}
if (relayNodes != null
&& relayNodes.stream().anyMatch(n -> n.getAddress().equals(channel.getInetAddress()))) {
this.isRelayPeer = true;
}
this.nodeStatistics = TronStatsManager.getNodeStatistics(channel.getInetAddress());
Expand Down
38 changes: 32 additions & 6 deletions framework/src/main/java/org/tron/program/SolidityNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import static org.tron.core.config.Parameter.ChainConstant.BLOCK_PRODUCED_INTERVAL;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
Expand All @@ -11,6 +13,7 @@
import org.tron.common.application.ApplicationFactory;
import org.tron.common.application.TronApplicationContext;
import org.tron.common.client.DatabaseGrpcClient;
import org.tron.common.es.ExecutorServiceManager;
import org.tron.common.parameter.CommonParameter;
import org.tron.common.prometheus.Metrics;
import org.tron.core.ChainBaseManager;
Expand Down Expand Up @@ -39,6 +42,9 @@ public class SolidityNode {

private volatile boolean flag = true;

private ExecutorService getBlockEs;
private ExecutorService processBlockEs;

public SolidityNode(Manager dbManager) {
this.dbManager = dbManager;
this.chainBaseManager = dbManager.getChainBaseManager();
Expand Down Expand Up @@ -72,13 +78,25 @@ public static void start() {
appT.startup();
SolidityNode node = new SolidityNode(appT.getDbManager());
node.run();
appT.blockUntilShutdown();
awaitShutdown(appT, node);
}

static void awaitShutdown(Application appT, SolidityNode node) {
try {
appT.blockUntilShutdown();
} finally {
// SolidityNode is created manually rather than managed by Spring/Application,
// so its executors must be shut down explicitly on exit.
node.shutdown();
}
}

private void run() {
try {
new Thread(this::getBlock).start();
new Thread(this::processBlock).start();
getBlockEs = ExecutorServiceManager.newSingleThreadExecutor("solid-get-block");
processBlockEs = ExecutorServiceManager.newSingleThreadExecutor("solid-process-block");
getBlockEs.execute(this::getBlock);
processBlockEs.execute(this::processBlock);
logger.info("Success to start solid node, ID: {}, remoteBlockNum: {}.", ID.get(),
remoteBlockNum);
} catch (Exception e) {
Expand All @@ -88,6 +106,12 @@ private void run() {
}
}

public void shutdown() {
flag = false;
ExecutorServiceManager.shutdownAndAwaitTermination(getBlockEs, "solid-get-block");
ExecutorServiceManager.shutdownAndAwaitTermination(processBlockEs, "solid-process-block");
}

private void getBlock() {
long blockNum = ID.incrementAndGet();
while (flag) {
Expand Down Expand Up @@ -137,7 +161,7 @@ private void loopProcessBlock(Block block) {
}

private Block getBlockByNum(long blockNum) {
while (true) {
while (flag) {
try {
long time = System.currentTimeMillis();
Block block = databaseGrpcClient.getBlock(blockNum);
Expand All @@ -155,10 +179,11 @@ private Block getBlockByNum(long blockNum) {
sleep(exceptionSleepTime);
}
}
return null;
}

private long getLastSolidityBlockNum() {
while (true) {
while (flag) {
try {
long time = System.currentTimeMillis();
long blockNum = databaseGrpcClient.getDynamicProperties().getLastSolidityBlockNum();
Expand All @@ -171,6 +196,7 @@ private long getLastSolidityBlockNum() {
sleep(exceptionSleepTime);
}
}
return 0;
}

public void sleep(long time) {
Expand All @@ -193,4 +219,4 @@ private void resolveCompatibilityIssueIfUsingFullNodeDatabase() {
chainBaseManager.getDynamicPropertiesStore().saveLatestSolidifiedBlockNum(headBlockNum);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package org.tron.common;

import io.grpc.ManagedChannel;
import java.util.concurrent.TimeUnit;
import org.tron.common.application.ApplicationFactory;
import org.tron.common.application.TronApplicationContext;
import org.tron.core.config.DefaultConfig;

/**
* Shared class-level fixture for tests that manually manage a TronApplicationContext.
*/
public class ClassLevelAppContextFixture {

private TronApplicationContext context;

public TronApplicationContext createContext() {
context = new TronApplicationContext(DefaultConfig.class);
return context;
}

public TronApplicationContext createAndStart() {
createContext();
startApp();
return context;
}

public void startApp() {
ApplicationFactory.create(context).startup();
}

public TronApplicationContext getContext() {
return context;
}

public void close() {
if (context != null) {
context.close();
context = null;
}
}

public static void shutdownChannel(ManagedChannel channel) {
if (channel == null) {
return;
}
try {
channel.shutdown();
if (!channel.awaitTermination(5, TimeUnit.SECONDS)) {
channel.shutdownNow();
}
} catch (InterruptedException e) {
channel.shutdownNow();
Thread.currentThread().interrupt();
}
}

public static void shutdownChannels(ManagedChannel... channels) {
for (ManagedChannel channel : channels) {
shutdownChannel(channel);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public class BackupServerTest {
public TemporaryFolder temporaryFolder = new TemporaryFolder();

@Rule
public Timeout globalTimeout = Timeout.seconds(60);
public Timeout globalTimeout = Timeout.seconds(90);
private BackupServer backupServer;

@Before
Expand All @@ -43,7 +43,7 @@ public void tearDown() {
Args.clearParam();
}

@Test(timeout = 60_000)
@Test
public void test() throws InterruptedException {
backupServer.initServer();
// wait for the server to start
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ public synchronized void testEventParser() {

for (int i = 0; i < entryArr.size(); i++) {
JSONObject e = entryArr.getJSONObject(i);
System.out.println(e.getString("name"));
if (e.getString("name") != null) {
if (e.getString("name").equalsIgnoreCase("eventBytesL")) {
entry = e;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ public synchronized void testEventParser() {

ABI.Entry entry = null;
for (ABI.Entry e : abi.getEntrysList()) {
System.out.println(e.getName());
if (e.getName().equalsIgnoreCase("eventBytesL")) {
entry = e;
break;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package org.tron.common.logsfilter;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import org.junit.After;
import org.junit.Assert;
import org.junit.Test;
import org.tron.common.es.ExecutorServiceManager;
import org.tron.common.logsfilter.nativequeue.NativeMessageQueue;
import org.zeromq.SocketType;
import org.zeromq.ZContext;
Expand All @@ -13,6 +17,21 @@ public class NativeMessageQueueTest {
public String dataToSend = "################";
public String topic = "testTopic";

private ExecutorService subscriberExecutor;

@After
public void tearDown() {
if (subscriberExecutor != null) {
subscriberExecutor.shutdownNow();
try {
subscriberExecutor.awaitTermination(2, TimeUnit.SECONDS);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
subscriberExecutor = null;
}
}

@Test
public void invalidBindPort() {
boolean bRet = NativeMessageQueue.getInstance().start(-1111, 0);
Expand All @@ -39,22 +58,23 @@ public void publishTrigger() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}

NativeMessageQueue.getInstance().publishTrigger(dataToSend, topic);

try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}

NativeMessageQueue.getInstance().stop();
}

public void startSubscribeThread() {
Thread thread = new Thread(() -> {
subscriberExecutor = ExecutorServiceManager.newSingleThreadExecutor("zmq-subscriber");
subscriberExecutor.execute(() -> {
try (ZContext context = new ZContext()) {
ZMQ.Socket subscriber = context.createSocket(SocketType.SUB);

Expand All @@ -70,6 +90,5 @@ public void startSubscribeThread() {
// ZMQ.Socket will be automatically closed when ZContext is closed
}
});
thread.start();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ public void setUp() {
public void testSetAndGetBlockHash() {
blockFilterCapsule
.setBlockHash("e58f33f9baf9305dc6f82b9f1934ea8f0ade2defb951258d50167028c780351f");
System.out.println(blockFilterCapsule);
Assert.assertEquals("e58f33f9baf9305dc6f82b9f1934ea8f0ade2defb951258d50167028c780351f",
blockFilterCapsule.getBlockHash());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.junit.BeforeClass;
import org.junit.Test;
import org.tron.common.BaseTest;
import org.tron.common.parameter.CommonParameter;
import org.tron.common.runtime.RuntimeImpl;
import org.tron.common.runtime.TvmTestUtils;
import org.tron.common.utils.Commons;
Expand Down Expand Up @@ -153,8 +154,13 @@ public void testSuccess() {

@Test
public void testSuccessNoBandd() {
boolean originalDebug = CommonParameter.getInstance().isDebug();
try {
byte[] contractAddress = createContract();
// Enable debug mode to bypass CPU time limit check in Program.checkCPUTimeLimit().
// Without this, the heavy contract execution (setCoin) may exceed the time threshold
// on slow machines and cause the test to fail non-deterministically.
CommonParameter.getInstance().setDebug(true);
TriggerSmartContract triggerContract = TvmTestUtils.createTriggerContract(contractAddress,
"setCoin(uint256)", "50", false,
0, Commons.decodeFromBase58Check(TriggerOwnerTwoAddress));
Expand Down Expand Up @@ -185,6 +191,8 @@ public void testSuccessNoBandd() {
balance);
} catch (TronException e) {
Assert.assertNotNull(e);
} finally {
CommonParameter.getInstance().setDebug(originalDebug);
}
}

Expand Down Expand Up @@ -254,4 +262,4 @@ public void testMaxContractResultSize() {
}
Assert.assertEquals(2, maxSize);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -289,17 +289,9 @@ public void testWithCallerEnergyChangedInTx() throws Exception {

TVMTestResult result = freezeForOther(userA, contractAddr, userA, frozenBalance, 1);

System.out.println(result.getReceipt().getEnergyUsageTotal());
System.out.println(accountStore.get(userA));
System.out.println(accountStore.get(owner));

clearDelegatedExpireTime(contractAddr, userA);

result = unfreezeForOther(userA, contractAddr, userA, 1);

System.out.println(result.getReceipt().getEnergyUsageTotal());
System.out.println(accountStore.get(userA));
System.out.println(accountStore.get(owner));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,6 @@ public void testZeroLengthOneArray() {
// witness array zero, amount array non-zero
Program program = mockProgram(0, 0, 64, 1, 0);
long cost = EnergyCost.getVoteWitnessCost3(program);
// witnessArraySize = 0 * 32 + 32 = 32, witnessMemNeeded = 0 + 32 = 32
// amountArraySize = 1 * 32 + 32 = 64, amountMemNeeded = 64 + 64 = 128
// memWords = 128 / 32 = 4
// memEnergy = 3 * 4 + 4 * 4 / 512 = 12
assertEquals(30012, cost);
Expand Down
Loading
Loading