diff --git a/framework/src/main/java/org/tron/core/config/args/Args.java b/framework/src/main/java/org/tron/core/config/args/Args.java index 62786b23927..d669cb8b50c 100644 --- a/framework/src/main/java/org/tron/core/config/args/Args.java +++ b/framework/src/main/java/org/tron/core/config/args/Args.java @@ -376,82 +376,84 @@ private static void applyEventConfig(EventConfig ec) { // contractParse belongs to event.subscribe but Storage object holds it PARAMETER.storage.setContractParseSwitch(ec.isContractParse()); + // PARAMETER.eventPluginConfig and PARAMETER.eventFilter are only consumed by + // Manager.startEventSubscribing(), which itself is gated by isEventSubscribe() + // (= ec.isEnable()) at Manager.java:564. When subscribe is disabled, building + // these objects has no observable effect — skip both early so PARAMETER stays + // consistent with the runtime intent. + if (!ec.isEnable()) { + return; + } + // Build EventPluginConfig from EventConfig bean - // If event.subscribe was configured, bean will have non-default values - if (ec.isEnable() || ec.getVersion() != 0 || !ec.getTopics().isEmpty() - || StringUtils.isNotEmpty(ec.getPath()) || StringUtils.isNotEmpty(ec.getServer())) { - EventPluginConfig epc = new EventPluginConfig(); - epc.setVersion(ec.getVersion()); - epc.setStartSyncBlockNum(ec.getStartSyncBlockNum()); - - // native queue - EventConfig.NativeConfig nq = ec.getNativeQueue(); - epc.setUseNativeQueue(nq.isUseNativeQueue()); - epc.setBindPort(nq.getBindport()); - epc.setSendQueueLength(nq.getSendqueuelength()); - - if (!nq.isUseNativeQueue()) { - if (StringUtils.isNotEmpty(ec.getPath())) { - epc.setPluginPath(ec.getPath().trim()); - } - if (StringUtils.isNotEmpty(ec.getServer())) { - epc.setServerAddress(ec.getServer().trim()); - } - if (StringUtils.isNotEmpty(ec.getDbconfig())) { - epc.setDbConfig(ec.getDbconfig().trim()); - } + EventPluginConfig epc = new EventPluginConfig(); + epc.setVersion(ec.getVersion()); + epc.setStartSyncBlockNum(ec.getStartSyncBlockNum()); + + // native queue + EventConfig.NativeConfig nq = ec.getNativeQueue(); + epc.setUseNativeQueue(nq.isUseNativeQueue()); + epc.setBindPort(nq.getBindport()); + epc.setSendQueueLength(nq.getSendqueuelength()); + + if (!nq.isUseNativeQueue()) { + if (StringUtils.isNotEmpty(ec.getPath())) { + epc.setPluginPath(ec.getPath().trim()); } - - // topics - List triggerConfigs = new ArrayList<>(); - for (EventConfig.TopicConfig tc : ec.getTopics()) { - TriggerConfig trig = new TriggerConfig(); - trig.setTriggerName(tc.getTriggerName()); - trig.setEnabled(tc.isEnable()); - trig.setTopic(tc.getTopic()); - trig.setSolidified(tc.isSolidified()); - trig.setEthCompatible(tc.isEthCompatible()); - trig.setRedundancy(tc.isRedundancy()); - triggerConfigs.add(trig); + if (StringUtils.isNotEmpty(ec.getServer())) { + epc.setServerAddress(ec.getServer().trim()); + } + if (StringUtils.isNotEmpty(ec.getDbconfig())) { + epc.setDbConfig(ec.getDbconfig().trim()); } - epc.setTriggerConfigList(triggerConfigs); + } - PARAMETER.eventPluginConfig = epc; + // topics + List triggerConfigs = new ArrayList<>(); + for (EventConfig.TopicConfig tc : ec.getTopics()) { + TriggerConfig trig = new TriggerConfig(); + trig.setTriggerName(tc.getTriggerName()); + trig.setEnabled(tc.isEnable()); + trig.setTopic(tc.getTopic()); + trig.setSolidified(tc.isSolidified()); + trig.setEthCompatible(tc.isEthCompatible()); + trig.setRedundancy(tc.isRedundancy()); + triggerConfigs.add(trig); } + epc.setTriggerConfigList(triggerConfigs); + + PARAMETER.eventPluginConfig = epc; // Build FilterQuery from EventConfig.FilterConfig bean EventConfig.FilterConfig fc = ec.getFilter(); - if (StringUtils.isNotEmpty(fc.getFromblock()) || StringUtils.isNotEmpty(fc.getToblock()) - || !fc.getContractAddress().isEmpty()) { - FilterQuery filter = new FilterQuery(); + FilterQuery filter = new FilterQuery(); - try { - filter.setFromBlock(FilterQuery.parseFromBlockNumber(fc.getFromblock().trim())); - } catch (Exception e) { - logger.error("invalid filter: fromBlockNumber: {}", fc.getFromblock(), e); - PARAMETER.eventFilter = null; - return; - } + try { + filter.setFromBlock(FilterQuery.parseFromBlockNumber(fc.getFromblock().trim())); + } catch (Exception e) { + logger.error("invalid filter: fromBlockNumber: {}", fc.getFromblock(), e); + PARAMETER.eventFilter = null; + return; + } - try { - filter.setToBlock(FilterQuery.parseToBlockNumber(fc.getToblock().trim())); - } catch (Exception e) { - logger.error("invalid filter: toBlockNumber: {}", fc.getToblock(), e); - PARAMETER.eventFilter = null; - return; - } + try { + filter.setToBlock(FilterQuery.parseToBlockNumber(fc.getToblock().trim())); + } catch (Exception e) { + logger.error("invalid filter: toBlockNumber: {}", fc.getToblock(), e); + PARAMETER.eventFilter = null; + return; + } - filter.setContractAddressList( - fc.getContractAddress().stream() - .filter(StringUtils::isNotEmpty) - .collect(Collectors.toList())); - filter.setContractTopicList( - fc.getContractTopic().stream() - .filter(StringUtils::isNotEmpty) - .collect(Collectors.toList())); + filter.setContractAddressList( + fc.getContractAddress().stream() + .filter(StringUtils::isNotEmpty) + .collect(Collectors.toList())); + filter.setContractTopicList( + fc.getContractTopic().stream() + .filter(StringUtils::isNotEmpty) + .collect(Collectors.toList())); - PARAMETER.eventFilter = filter; - } + PARAMETER.eventFilter = filter; } /** diff --git a/framework/src/test/java/org/tron/core/config/args/ArgsTest.java b/framework/src/test/java/org/tron/core/config/args/ArgsTest.java index 45bc7c049e3..6b960c58b23 100644 --- a/framework/src/test/java/org/tron/core/config/args/ArgsTest.java +++ b/framework/src/test/java/org/tron/core/config/args/ArgsTest.java @@ -416,6 +416,54 @@ public void testFetchBlockTimeoutInRangeUnchanged() { Args.clearParam(); } + // =========================================================================== + // event.subscribe gating: PARAMETER.eventPluginConfig and PARAMETER.eventFilter + // are only consumed by Manager.startEventSubscribing(), which is gated by + // isEventSubscribe() (= ec.isEnable()). When subscribe is disabled, these + // objects must not be built — building them would be dead state. + // =========================================================================== + + @Test + public void testEventConfigDisabledSkipsEpcAndFilter() { + Map override = new HashMap<>(); + override.put("storage.db.directory", "database"); + override.put("event.subscribe.enable", "false"); + Config config = ConfigFactory.parseMap(override) + .withFallback(ConfigFactory.defaultReference()); + Args.applyConfigParams(config); + Assert.assertNull(Args.getInstance().getEventPluginConfig()); + Assert.assertNull(Args.getInstance().getEventFilter()); + Args.clearParam(); + } + + @Test + public void testEventConfigEnabledBuildsEpcAndFilter() { + Map override = new HashMap<>(); + override.put("storage.db.directory", "database"); + override.put("event.subscribe.enable", "true"); + Config config = ConfigFactory.parseMap(override) + .withFallback(ConfigFactory.defaultReference()); + Args.applyConfigParams(config); + Assert.assertNotNull(Args.getInstance().getEventPluginConfig()); + Assert.assertNotNull(Args.getInstance().getEventFilter()); + Args.clearParam(); + } + + @Test + public void testEventConfigEnabledWithInvalidFromBlockLeavesFilterNull() { + Map override = new HashMap<>(); + override.put("storage.db.directory", "database"); + override.put("event.subscribe.enable", "true"); + override.put("event.subscribe.filter.fromblock", "not-a-number"); + Config config = ConfigFactory.parseMap(override) + .withFallback(ConfigFactory.defaultReference()); + Args.applyConfigParams(config); + // epc still built; filter rejected + Assert.assertNotNull(Args.getInstance().getEventPluginConfig()); + Assert.assertNull(Args.getInstance().getEventFilter()); + Args.clearParam(); + } + @Test public void testAllowShieldedTransactionApiDefault() { Args.setParam(new String[]{}, TestConstants.TEST_CONF);