Skip to content

Commit 29ee4db

Browse files
committed
Merge upstream/release_v4.8.2 to pick up tronprotocol#6757 (--es fix)
2 parents cb1e267 + 9d28fa7 commit 29ee4db

8 files changed

Lines changed: 122 additions & 20 deletions

File tree

common/src/main/java/org/tron/core/config/args/EventConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public class EventConfig {
4343
@Getter
4444
@Setter
4545
public static class NativeConfig {
46-
private boolean useNativeQueue = true;
46+
private boolean useNativeQueue = false;
4747
private int bindport = 5555;
4848
private int sendqueuelength = 1000;
4949
}

common/src/main/resources/reference.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -758,7 +758,7 @@ event.subscribe = {
758758
enable = false
759759

760760
native = {
761-
useNativeQueue = true
761+
useNativeQueue = false
762762
bindport = 5555
763763
sendqueuelength = 1000
764764
}

framework/src/main/java/org/tron/common/logsfilter/EventPluginLoader.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.beust.jcommander.internal.Sets;
44
import com.fasterxml.jackson.core.JsonProcessingException;
55
import com.fasterxml.jackson.databind.ObjectMapper;
6+
import com.google.common.base.Strings;
67
import java.io.File;
78
import java.util.HashSet;
89
import java.util.List;
@@ -14,8 +15,10 @@
1415
import org.bouncycastle.util.encoders.Hex;
1516
import org.pf4j.CompoundPluginDescriptorFinder;
1617
import org.pf4j.DefaultPluginManager;
18+
import org.pf4j.DefaultVersionManager;
1719
import org.pf4j.ManifestPluginDescriptorFinder;
1820
import org.pf4j.PluginManager;
21+
import org.pf4j.VersionManager;
1922
import org.springframework.util.StringUtils;
2023
import org.tron.common.logsfilter.nativequeue.NativeMessageQueue;
2124
import org.tron.common.logsfilter.trigger.BlockLogTrigger;
@@ -29,6 +32,16 @@
2932
@Slf4j
3033
public class EventPluginLoader {
3134

35+
/**
36+
* Minimum event-plugin Plugin-Version compatible with this node. Bumped to 3.0.0 to
37+
* reject pre-fastjson-removal builds whose worker threads would fail with
38+
* NoClassDefFoundError on com.alibaba.fastjson at runtime. The previous event-plugin
39+
* release is 2.2.0, so 3.0.0 is the first version that ships the Jackson replacement.
40+
*/
41+
static final String MIN_PLUGIN_VERSION = "3.0.0";
42+
43+
private static final VersionManager VERSION_MANAGER = new DefaultVersionManager();
44+
3245
private static EventPluginLoader instance;
3346

3447
private long MAX_PENDING_SIZE = 50000;
@@ -457,6 +470,10 @@ protected CompoundPluginDescriptorFinder createPluginDescriptorFinder() {
457470
return false;
458471
}
459472

473+
if (!isPluginVersionSupported(pluginManager, pluginId)) {
474+
return false;
475+
}
476+
460477
pluginManager.startPlugins();
461478

462479
eventListeners = pluginManager.getExtensions(IPluginEventListener.class);
@@ -471,6 +488,21 @@ protected CompoundPluginDescriptorFinder createPluginDescriptorFinder() {
471488
return true;
472489
}
473490

491+
static boolean isPluginVersionSupported(PluginManager pm, String pluginId) {
492+
String pluginVersion = pm.getPlugin(pluginId).getDescriptor().getVersion();
493+
if (Strings.isNullOrEmpty(pluginVersion)) {
494+
return false;
495+
}
496+
boolean isSupported = VERSION_MANAGER.compareVersions(pluginVersion, MIN_PLUGIN_VERSION) >= 0;
497+
498+
if (!isSupported) {
499+
logger.error(
500+
"event-plugin '{}' version {} is older than required {}, please upgrade event-plugin",
501+
pluginId, pluginVersion, MIN_PLUGIN_VERSION);
502+
}
503+
return isSupported;
504+
}
505+
474506
public void stopPlugin() {
475507
if (Objects.nonNull(pluginManager)) {
476508
pluginManager.stopPlugins();

framework/src/main/java/org/tron/core/config/args/Args.java

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -167,16 +167,19 @@ public static void setParam(final String[] args, final String confFileName) {
167167
? cmd.shellConfFileName : confFileName;
168168
Config config = Configuration.getByFileName(configFilePath);
169169

170-
// 2. Config overrides defaults
170+
// 2. Config overrides defaults (event config bean is read here but not yet applied)
171171
applyConfigParams(config);
172172

173-
// 3. CLI overrides Config (highest priority)
173+
// 3. CLI overrides Config (highest priority, including --es → eventSubscribe)
174174
applyCLIParams(cmd, jc);
175175

176-
// 4. Apply platform constraints (e.g. ARM64 forces RocksDB)
176+
// 4. Apply event config after CLI
177+
applyEventConfig(eventConfig);
178+
179+
// 5. Apply platform constraints (e.g. ARM64 forces RocksDB)
177180
applyPlatformConstraints();
178181

179-
// 5. Init witness (depends on CLI witness flag)
182+
// 6. Init witness (depends on CLI witness flag)
180183
initLocalWitnesses(config, cmd);
181184
}
182185

@@ -217,7 +220,7 @@ private static void applyStorageConfig(StorageConfig sc) {
217220
PARAMETER.storage.setIndexSwitch(
218221
org.apache.commons.lang3.StringUtils.isNotEmpty(indexSwitch) ? indexSwitch : "on");
219222
PARAMETER.storage.setTransactionHistorySwitch(sc.getTransHistory().getSwitch());
220-
// contractParse is set in applyEventConfig — it belongs to event.subscribe domain
223+
// contractParse is set in applyConfigParams alongside event config, not here
221224
PARAMETER.storage.setCheckpointVersion(sc.getCheckpoint().getVersion());
222225
PARAMETER.storage.setCheckpointSync(sc.getCheckpoint().isSync());
223226

@@ -343,21 +346,21 @@ private static void applyRateLimiterConfig(RateLimiterConfig rl) {
343346
PARAMETER.rateLimiterInitialization = initialization;
344347
}
345348

349+
/**
350+
* Package-private entry point only for tests
351+
*/
352+
static void applyEventConfig() {
353+
applyEventConfig(eventConfig);
354+
}
355+
346356
/**
347357
* Bridge EventConfig bean values to CommonParameter fields.
348358
* Converts EventConfig (raw bean) into EventPluginConfig and FilterQuery (business objects).
349359
*/
350360
private static void applyEventConfig(EventConfig ec) {
351-
PARAMETER.eventSubscribe = ec.isEnable();
352-
// contractParse belongs to event.subscribe but Storage object holds it
353-
PARAMETER.storage.setContractParseSwitch(ec.isContractParse());
354-
355-
// PARAMETER.eventPluginConfig and PARAMETER.eventFilter are only consumed by
356-
// Manager.startEventSubscribing(), which itself is gated by isEventSubscribe()
357-
// (= ec.isEnable()) at Manager.java:564. When subscribe is disabled, building
358-
// these objects has no observable effect — skip both early so PARAMETER stays
359-
// consistent with the runtime intent.
360-
if (!ec.isEnable()) {
361+
// cmd parameter has higher priority
362+
PARAMETER.eventSubscribe = PARAMETER.eventSubscribe || ec.isEnable();
363+
if (!PARAMETER.eventSubscribe) {
361364
return;
362365
}
363366

@@ -770,9 +773,12 @@ public static void applyConfigParams(
770773

771774
// node.shutdown — handled in applyNodeConfig
772775

773-
// Event config: bind from config.conf "event.subscribe" section
776+
// Event config: read bean here; applyEventConfig() is called once in setParam()
777+
// after applyCLIParams() so that --es is already reflected in eventSubscribe.
774778
eventConfig = EventConfig.fromConfig(config);
775-
applyEventConfig(eventConfig);
779+
// contractParse is event-domain but must be set from config before CLI can
780+
// override it with --contract-parse-enable (which runs in applyCLIParams).
781+
PARAMETER.storage.setContractParseSwitch(eventConfig.isContractParse());
776782

777783
logConfig();
778784
}

framework/src/main/java/org/tron/core/net/peer/PeerConnection.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,8 @@ public class PeerConnection {
170170

171171
public void setChannel(Channel channel) {
172172
this.channel = channel;
173-
if (relayNodes.stream().anyMatch(n -> n.getAddress().equals(channel.getInetAddress()))) {
173+
if (relayNodes != null
174+
&& relayNodes.stream().anyMatch(n -> n.getAddress().equals(channel.getInetAddress()))) {
174175
this.isRelayPeer = true;
175176
}
176177
this.nodeStatistics = TronStatsManager.getNodeStatistics(channel.getInetAddress());

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

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,16 @@
33
import static org.junit.Assert.assertEquals;
44
import static org.junit.Assert.assertFalse;
55
import static org.junit.Assert.assertTrue;
6+
import static org.mockito.Mockito.mock;
7+
import static org.mockito.Mockito.when;
68

79
import java.util.ArrayList;
810
import java.util.List;
911
import org.junit.Assert;
1012
import org.junit.Test;
13+
import org.pf4j.PluginDescriptor;
14+
import org.pf4j.PluginManager;
15+
import org.pf4j.PluginWrapper;
1116
import org.tron.common.logsfilter.trigger.BlockLogTrigger;
1217
import org.tron.common.logsfilter.trigger.TransactionLogTrigger;
1318

@@ -48,6 +53,32 @@ public void launchNativeQueue() {
4853
EventPluginLoader.getInstance().stopPlugin();
4954
}
5055

56+
@Test
57+
public void testIsPluginVersionSupported() {
58+
assertEquals("3.0.0", EventPluginLoader.MIN_PLUGIN_VERSION);
59+
// last releases before fastjson removal — must be rejected
60+
assertFalse(checkVersion("1.0.0"));
61+
assertFalse(checkVersion("2.2.0"));
62+
assertFalse(checkVersion("2.9.9"));
63+
// 3.0.0 onward — must be accepted
64+
assertTrue(checkVersion("3.0.0"));
65+
assertTrue(checkVersion("3.1.5"));
66+
assertTrue(checkVersion("10.0.0"));
67+
// empty/null version — reject
68+
assertFalse(checkVersion(""));
69+
assertFalse(checkVersion(null));
70+
}
71+
72+
private static boolean checkVersion(String version) {
73+
PluginManager pm = mock(PluginManager.class);
74+
PluginWrapper wrapper = mock(PluginWrapper.class);
75+
PluginDescriptor desc = mock(PluginDescriptor.class);
76+
when(pm.getPlugin("test")).thenReturn(wrapper);
77+
when(wrapper.getDescriptor()).thenReturn(desc);
78+
when(desc.getVersion()).thenReturn(version);
79+
return EventPluginLoader.isPluginVersionSupported(pm, "test");
80+
}
81+
5182
@Test
5283
public void testBlockLogTrigger() {
5384
BlockLogTrigger blt = new BlockLogTrigger();

framework/src/test/java/org/tron/core/config/args/ArgsTest.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,21 @@ public void testCliEsOverridesConfig() {
344344
Args.clearParam();
345345
}
346346

347+
/**
348+
* Regression: when --es is the sole source of event.subscribe.enable=true
349+
* (config has it disabled), eventPluginConfig must be built.
350+
* Previously applyEventConfig() ran before applyCLIParams() and returned
351+
* early (both flags false), leaving eventPluginConfig=null; Manager then
352+
* called EventPluginLoader.start(null) and threw "Failed to load eventPlugin."
353+
*/
354+
@Test
355+
public void testCliEsBuildsEventPluginConfig() {
356+
Args.setParam(new String[] {"--es"}, TestConstants.TEST_CONF);
357+
Assert.assertTrue(Args.getInstance().isEventSubscribe());
358+
Assert.assertNotNull(Args.getInstance().getEventPluginConfig());
359+
Args.clearParam();
360+
}
361+
347362
/**
348363
* Verify that config file storage values are applied when no CLI override is present.
349364
*
@@ -454,6 +469,7 @@ public void testEventConfigDisabledSkipsEpcAndFilter() {
454469
Config config = ConfigFactory.parseMap(override)
455470
.withFallback(ConfigFactory.defaultReference());
456471
Args.applyConfigParams(config);
472+
Args.applyEventConfig();
457473
Assert.assertNull(Args.getInstance().getEventPluginConfig());
458474
Assert.assertNull(Args.getInstance().getEventFilter());
459475
Args.clearParam();
@@ -467,6 +483,7 @@ public void testEventConfigEnabledBuildsEpcAndFilter() {
467483
Config config = ConfigFactory.parseMap(override)
468484
.withFallback(ConfigFactory.defaultReference());
469485
Args.applyConfigParams(config);
486+
Args.applyEventConfig();
470487
Assert.assertNotNull(Args.getInstance().getEventPluginConfig());
471488
Assert.assertNotNull(Args.getInstance().getEventFilter());
472489
Args.clearParam();
@@ -481,6 +498,7 @@ public void testEventConfigEnabledWithInvalidFromBlockLeavesFilterNull() {
481498
Config config = ConfigFactory.parseMap(override)
482499
.withFallback(ConfigFactory.defaultReference());
483500
Args.applyConfigParams(config);
501+
Args.applyEventConfig();
484502
// epc still built; filter rejected
485503
Assert.assertNotNull(Args.getInstance().getEventPluginConfig());
486504
Assert.assertNull(Args.getInstance().getEventFilter());

framework/src/test/java/org/tron/core/net/messagehandler/ChainInventoryMsgHandlerTest.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,32 @@
33
import java.util.ArrayList;
44
import java.util.LinkedList;
55
import java.util.List;
6+
import org.junit.AfterClass;
67
import org.junit.Assert;
8+
import org.junit.BeforeClass;
79
import org.junit.Test;
10+
import org.tron.common.TestConstants;
811
import org.tron.common.utils.Pair;
912
import org.tron.core.capsule.BlockCapsule.BlockId;
1013
import org.tron.core.config.Parameter.NetConstants;
14+
import org.tron.core.config.args.Args;
1115
import org.tron.core.exception.P2pException;
1216
import org.tron.core.net.message.keepalive.PingMessage;
1317
import org.tron.core.net.message.sync.ChainInventoryMessage;
1418
import org.tron.core.net.peer.PeerConnection;
1519

1620
public class ChainInventoryMsgHandlerTest {
1721

22+
@BeforeClass
23+
public static void init() {
24+
Args.setParam(new String[]{}, TestConstants.TEST_CONF);
25+
}
26+
27+
@AfterClass
28+
public static void destroy() {
29+
Args.clearParam();
30+
}
31+
1832
private ChainInventoryMsgHandler handler = new ChainInventoryMsgHandler();
1933
private PeerConnection peer = new PeerConnection();
2034
private ChainInventoryMessage msg = new ChainInventoryMessage(new ArrayList<>(), 0L);

0 commit comments

Comments
 (0)