Skip to content

Commit 9fcf3c5

Browse files
committed
Merge remote-tracking branch 'upstream/develop' into feat/opt-api
2 parents ee83102 + 980c707 commit 9fcf3c5

68 files changed

Lines changed: 1305 additions & 1419 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

chainbase/src/main/java/org/tron/core/db/TronDatabase.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,25 @@ public void reset() {
7676
@Override
7777
public void close() {
7878
logger.info("******** Begin to close {}. ********", getName());
79+
doClose();
80+
logger.info("******** End to close {}. ********", getName());
81+
}
82+
83+
/**
84+
* Releases writeOptions and dbSource (best-effort, exceptions logged at WARN).
85+
* Subclasses with extra resources should override {@link #close()} and call
86+
* {@code doClose()} directly — not {@code super.close()} — to avoid duplicated logs.
87+
*/
88+
protected void doClose() {
7989
try {
8090
writeOptions.close();
91+
} catch (Exception e) {
92+
logger.warn("Failed to close writeOptions in {}.", getName(), e);
93+
}
94+
try {
8195
dbSource.closeDB();
8296
} catch (Exception e) {
83-
logger.warn("Failed to close {}.", getName(), e);
84-
} finally {
85-
logger.info("******** End to close {}. ********", getName());
97+
logger.warn("Failed to close dbSource in {}.", getName(), e);
8698
}
8799
}
88100

chainbase/src/main/java/org/tron/core/store/CheckPointV2Store.java

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,20 +62,16 @@ public void updateByBatch(Map<byte[], byte[]> rows) {
6262
this.dbSource.updateByBatch(rows, writeOptions);
6363
}
6464

65-
/**
66-
* close the database.
67-
*/
6865
@Override
6966
public void close() {
7067
logger.debug("******** Begin to close {}. ********", getName());
7168
try {
7269
writeOptions.close();
73-
dbSource.closeDB();
7470
} catch (Exception e) {
75-
logger.warn("Failed to close {}.", getName(), e);
76-
} finally {
77-
logger.debug("******** End to close {}. ********", getName());
71+
logger.warn("Failed to close writeOptions in {}.", getName(), e);
7872
}
73+
doClose();
74+
logger.debug("******** End to close {}. ********", getName());
7975
}
8076

8177
}

framework/src/main/java/org/tron/program/SolidityNode.java

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

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

5+
import com.google.common.annotations.VisibleForTesting;
6+
import java.util.concurrent.ExecutorService;
57
import java.util.concurrent.LinkedBlockingDeque;
8+
import java.util.concurrent.TimeUnit;
69
import java.util.concurrent.atomic.AtomicLong;
710
import lombok.extern.slf4j.Slf4j;
811
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
@@ -11,6 +14,7 @@
1114
import org.tron.common.application.ApplicationFactory;
1215
import org.tron.common.application.TronApplicationContext;
1316
import org.tron.common.client.DatabaseGrpcClient;
17+
import org.tron.common.es.ExecutorServiceManager;
1418
import org.tron.common.parameter.CommonParameter;
1519
import org.tron.common.prometheus.Metrics;
1620
import org.tron.core.ChainBaseManager;
@@ -39,6 +43,9 @@ public class SolidityNode {
3943

4044
private volatile boolean flag = true;
4145

46+
private ExecutorService getBlockEs;
47+
private ExecutorService processBlockEs;
48+
4249
public SolidityNode(Manager dbManager) {
4350
this.dbManager = dbManager;
4451
this.chainBaseManager = dbManager.getChainBaseManager();
@@ -72,13 +79,26 @@ public static void start() {
7279
appT.startup();
7380
SolidityNode node = new SolidityNode(appT.getDbManager());
7481
node.run();
75-
appT.blockUntilShutdown();
82+
awaitShutdown(appT, node);
83+
}
84+
85+
@VisibleForTesting
86+
static void awaitShutdown(Application appT, SolidityNode node) {
87+
try {
88+
appT.blockUntilShutdown();
89+
} finally {
90+
// SolidityNode is created manually rather than managed by Spring/Application,
91+
// so its executors must be shut down explicitly on exit.
92+
node.shutdown();
93+
}
7694
}
7795

7896
private void run() {
7997
try {
80-
new Thread(this::getBlock).start();
81-
new Thread(this::processBlock).start();
98+
getBlockEs = ExecutorServiceManager.newSingleThreadExecutor("solid-get-block");
99+
processBlockEs = ExecutorServiceManager.newSingleThreadExecutor("solid-process-block");
100+
getBlockEs.execute(this::getBlock);
101+
processBlockEs.execute(this::processBlock);
82102
logger.info("Success to start solid node, ID: {}, remoteBlockNum: {}.", ID.get(),
83103
remoteBlockNum);
84104
} catch (Exception e) {
@@ -88,6 +108,15 @@ private void run() {
88108
}
89109
}
90110

111+
public void shutdown() {
112+
flag = false;
113+
// Signal both pools before awaiting either so they drain concurrently
114+
getBlockEs.shutdown();
115+
processBlockEs.shutdown();
116+
ExecutorServiceManager.shutdownAndAwaitTermination(getBlockEs, "solid-get-block");
117+
ExecutorServiceManager.shutdownAndAwaitTermination(processBlockEs, "solid-process-block");
118+
}
119+
91120
private void getBlock() {
92121
long blockNum = ID.incrementAndGet();
93122
while (flag) {
@@ -137,7 +166,7 @@ private void loopProcessBlock(Block block) {
137166
}
138167

139168
private Block getBlockByNum(long blockNum) {
140-
while (true) {
169+
while (flag) {
141170
try {
142171
long time = System.currentTimeMillis();
143172
Block block = databaseGrpcClient.getBlock(blockNum);
@@ -155,10 +184,11 @@ private Block getBlockByNum(long blockNum) {
155184
sleep(exceptionSleepTime);
156185
}
157186
}
187+
return null;
158188
}
159189

160190
private long getLastSolidityBlockNum() {
161-
while (true) {
191+
while (flag) {
162192
try {
163193
long time = System.currentTimeMillis();
164194
long blockNum = databaseGrpcClient.getDynamicProperties().getLastSolidityBlockNum();
@@ -171,6 +201,7 @@ private long getLastSolidityBlockNum() {
171201
sleep(exceptionSleepTime);
172202
}
173203
}
204+
return 0;
174205
}
175206

176207
public void sleep(long time) {
@@ -193,4 +224,4 @@ private void resolveCompatibilityIssueIfUsingFullNodeDatabase() {
193224
chainBaseManager.getDynamicPropertiesStore().saveLatestSolidifiedBlockNum(headBlockNum);
194225
}
195226
}
196-
}
227+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package org.tron.common;
2+
3+
import io.grpc.ManagedChannel;
4+
import java.util.concurrent.TimeUnit;
5+
import org.tron.common.application.ApplicationFactory;
6+
import org.tron.common.application.TronApplicationContext;
7+
import org.tron.core.config.DefaultConfig;
8+
9+
/**
10+
* Shared class-level fixture for tests that manually manage a TronApplicationContext.
11+
*/
12+
public class ClassLevelAppContextFixture {
13+
14+
private TronApplicationContext context;
15+
16+
public TronApplicationContext createContext() {
17+
context = new TronApplicationContext(DefaultConfig.class);
18+
return context;
19+
}
20+
21+
public TronApplicationContext createAndStart() {
22+
createContext();
23+
startApp();
24+
return context;
25+
}
26+
27+
public void startApp() {
28+
ApplicationFactory.create(context).startup();
29+
}
30+
31+
public TronApplicationContext getContext() {
32+
return context;
33+
}
34+
35+
public void close() {
36+
if (context != null) {
37+
context.close();
38+
context = null;
39+
}
40+
}
41+
42+
public static void shutdownChannel(ManagedChannel channel) {
43+
if (channel == null) {
44+
return;
45+
}
46+
try {
47+
channel.shutdown();
48+
if (!channel.awaitTermination(5, TimeUnit.SECONDS)) {
49+
channel.shutdownNow();
50+
}
51+
} catch (InterruptedException e) {
52+
channel.shutdownNow();
53+
Thread.currentThread().interrupt();
54+
}
55+
}
56+
57+
public static void shutdownChannels(ManagedChannel... channels) {
58+
for (ManagedChannel channel : channels) {
59+
shutdownChannel(channel);
60+
}
61+
}
62+
}

framework/src/test/java/org/tron/common/backup/BackupServerTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public void tearDown() {
4646
@Test(timeout = 60_000)
4747
public void test() throws InterruptedException {
4848
backupServer.initServer();
49-
// wait for the server to start
49+
// wait for the server to start so channel is assigned before close() is called
5050
Thread.sleep(1000);
5151
}
5252
}

framework/src/test/java/org/tron/common/logsfilter/EventParserJsonTest.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ public synchronized void testEventParser() {
6565

6666
for (int i = 0; i < entryArr.size(); i++) {
6767
JSONObject e = entryArr.getJSONObject(i);
68-
System.out.println(e.getString("name"));
6968
if (e.getString("name") != null) {
7069
if (e.getString("name").equalsIgnoreCase("eventBytesL")) {
7170
entry = e;

framework/src/test/java/org/tron/common/logsfilter/EventParserTest.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ public synchronized void testEventParser() {
6868

6969
ABI.Entry entry = null;
7070
for (ABI.Entry e : abi.getEntrysList()) {
71-
System.out.println(e.getName());
7271
if (e.getName().equalsIgnoreCase("eventBytesL")) {
7372
entry = e;
7473
break;

framework/src/test/java/org/tron/common/logsfilter/FilterQueryTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import java.util.List;
1818
import java.util.Map;
1919
import lombok.extern.slf4j.Slf4j;
20+
import org.junit.After;
2021
import org.junit.Assert;
2122
import org.junit.Test;
2223
import org.tron.common.logsfilter.capsule.ContractEventTriggerCapsule;
@@ -28,6 +29,11 @@
2829
@Slf4j
2930
public class FilterQueryTest {
3031

32+
@After
33+
public void tearDown() {
34+
EventPluginLoader.getInstance().setFilterQuery(null);
35+
}
36+
3137
@Test
3238
public synchronized void testParseFilterQueryBlockNumber() {
3339
assertEquals(LATEST_BLOCK_NUM, parseToBlockNumber(EMPTY));

framework/src/test/java/org/tron/common/logsfilter/NativeMessageQueueTest.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package org.tron.common.logsfilter;
22

3+
import java.util.concurrent.ExecutorService;
4+
import org.junit.After;
35
import org.junit.Assert;
46
import org.junit.Test;
7+
import org.tron.common.es.ExecutorServiceManager;
58
import org.tron.common.logsfilter.nativequeue.NativeMessageQueue;
69
import org.zeromq.SocketType;
710
import org.zeromq.ZContext;
@@ -13,6 +16,15 @@ public class NativeMessageQueueTest {
1316
public String dataToSend = "################";
1417
public String topic = "testTopic";
1518

19+
private ExecutorService subscriberExecutor;
20+
private final String zmqSubscriber = "zmq-subscriber";
21+
22+
@After
23+
public void tearDown() {
24+
ExecutorServiceManager.shutdownAndAwaitTermination(subscriberExecutor, zmqSubscriber);
25+
subscriberExecutor = null;
26+
}
27+
1628
@Test
1729
public void invalidBindPort() {
1830
boolean bRet = NativeMessageQueue.getInstance().start(-1111, 0);
@@ -39,22 +51,23 @@ public void publishTrigger() {
3951
try {
4052
Thread.sleep(1000);
4153
} catch (InterruptedException e) {
42-
e.printStackTrace();
54+
Thread.currentThread().interrupt();
4355
}
4456

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

4759
try {
4860
Thread.sleep(1000);
4961
} catch (InterruptedException e) {
50-
e.printStackTrace();
62+
Thread.currentThread().interrupt();
5163
}
5264

5365
NativeMessageQueue.getInstance().stop();
5466
}
5567

5668
public void startSubscribeThread() {
57-
Thread thread = new Thread(() -> {
69+
subscriberExecutor = ExecutorServiceManager.newSingleThreadExecutor(zmqSubscriber);
70+
subscriberExecutor.execute(() -> {
5871
try (ZContext context = new ZContext()) {
5972
ZMQ.Socket subscriber = context.createSocket(SocketType.SUB);
6073

@@ -70,6 +83,5 @@ public void startSubscribeThread() {
7083
// ZMQ.Socket will be automatically closed when ZContext is closed
7184
}
7285
});
73-
thread.start();
7486
}
7587
}

framework/src/test/java/org/tron/common/logsfilter/capsule/BlockFilterCapsuleTest.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ public void setUp() {
2222
public void testSetAndGetBlockHash() {
2323
blockFilterCapsule
2424
.setBlockHash("e58f33f9baf9305dc6f82b9f1934ea8f0ade2defb951258d50167028c780351f");
25-
System.out.println(blockFilterCapsule);
2625
Assert.assertEquals("e58f33f9baf9305dc6f82b9f1934ea8f0ade2defb951258d50167028c780351f",
2726
blockFilterCapsule.getBlockHash());
2827
}

0 commit comments

Comments
 (0)