From a7dfbae1e1e12a827a00e9379bfc283d38d8fc2d Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Fri, 26 Dec 2025 11:34:48 +0800 Subject: [PATCH 01/13] add log for LogsFilterCapsule --- .../org/tron/common/logsfilter/capsule/LogsFilterCapsule.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/framework/src/main/java/org/tron/common/logsfilter/capsule/LogsFilterCapsule.java b/framework/src/main/java/org/tron/common/logsfilter/capsule/LogsFilterCapsule.java index 8a8e122d9a0..2a882e7d60d 100644 --- a/framework/src/main/java/org/tron/common/logsfilter/capsule/LogsFilterCapsule.java +++ b/framework/src/main/java/org/tron/common/logsfilter/capsule/LogsFilterCapsule.java @@ -45,6 +45,9 @@ public LogsFilterCapsule(long blockNumber, String blockHash, Bloom bloom, @Override public void processFilterTrigger() { + long t1 = System.currentTimeMillis(); handleLogsFilter(this); + long t2 = System.currentTimeMillis(); + logger.info("processFilterTrigger cost {}", t2 -t1); } } \ No newline at end of file From 4bd44533f8ccfbec3b0e30224569aa5d48f46b6d Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Fri, 26 Dec 2025 12:57:33 +0800 Subject: [PATCH 02/13] use parallelStream for handleLogsFilter --- .../logsfilter/capsule/LogsFilterCapsule.java | 2 +- .../services/jsonrpc/TronJsonRpcImpl.java | 34 ++++++++++--------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/framework/src/main/java/org/tron/common/logsfilter/capsule/LogsFilterCapsule.java b/framework/src/main/java/org/tron/common/logsfilter/capsule/LogsFilterCapsule.java index 2a882e7d60d..fbef7c5ee45 100644 --- a/framework/src/main/java/org/tron/common/logsfilter/capsule/LogsFilterCapsule.java +++ b/framework/src/main/java/org/tron/common/logsfilter/capsule/LogsFilterCapsule.java @@ -48,6 +48,6 @@ public void processFilterTrigger() { long t1 = System.currentTimeMillis(); handleLogsFilter(this); long t2 = System.currentTimeMillis(); - logger.info("processFilterTrigger cost {}", t2 -t1); + logger.info("processFilterTrigger cost {}", t2 - t1); } } \ No newline at end of file diff --git a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java index de939bdfff4..f92ae7c0ba4 100644 --- a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java +++ b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java @@ -222,41 +222,42 @@ public static void handleBLockFilter(BlockFilterCapsule blockFilterCapsule) { * append LogsFilterCapsule's LogFilterElement list to each filter if matched */ public static void handleLogsFilter(LogsFilterCapsule logsFilterCapsule) { - Iterator> it; + Map eventFilterMap; if (logsFilterCapsule.isSolidified()) { - it = getEventFilter2ResultSolidity().entrySet().iterator(); + eventFilterMap = getEventFilter2ResultSolidity(); } else { - it = getEventFilter2ResultFull().entrySet().iterator(); + eventFilterMap = getEventFilter2ResultFull(); } - while (it.hasNext()) { - Entry entry = it.next(); - if (entry.getValue().isExpire()) { - it.remove(); - continue; - } + eventFilterMap.entrySet().parallelStream().forEach(entry -> { LogFilterAndResult logFilterAndResult = entry.getValue(); + if (logFilterAndResult.isExpire()) { + eventFilterMap.remove(entry.getKey()); + return; + } + + long blockNumber = logsFilterCapsule.getBlockNumber(); long fromBlock = logFilterAndResult.getLogFilterWrapper().getFromBlock(); long toBlock = logFilterAndResult.getLogFilterWrapper().getToBlock(); - if (!(fromBlock <= logsFilterCapsule.getBlockNumber() - && logsFilterCapsule.getBlockNumber() <= toBlock)) { - continue; + if (!(fromBlock <= blockNumber && blockNumber <= toBlock)) { + return; } if (logsFilterCapsule.getBloom() != null && !logFilterAndResult.getLogFilterWrapper().getLogFilter() .matchBloom(logsFilterCapsule.getBloom())) { - continue; + return; } LogFilter logFilter = logFilterAndResult.getLogFilterWrapper().getLogFilter(); List elements = - LogMatch.matchBlock(logFilter, logsFilterCapsule.getBlockNumber(), + LogMatch.matchBlock(logFilter, blockNumber, logsFilterCapsule.getBlockHash(), logsFilterCapsule.getTxInfoList(), logsFilterCapsule.isRemoved()); + List localResults = new ArrayList<>(elements.size()); for (LogFilterElement element : elements) { LogFilterElement cachedElement; try { @@ -266,9 +267,10 @@ public static void handleLogsFilter(LogsFilterCapsule logsFilterCapsule) { logger.error("Getting/loading LogFilterElement from cache fails", e); // never happen cachedElement = element; } - logFilterAndResult.getResult().add(cachedElement); + localResults.add(cachedElement); } - } + logFilterAndResult.getResult().addAll(localResults); + }); } @Override From 0a28a38fa1ffbd2f26b6dbf2d47ea01070701f3e Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Fri, 26 Dec 2025 18:37:12 +0800 Subject: [PATCH 03/13] add number of log filter limit --- .../java/org/tron/core/services/jsonrpc/TronJsonRpc.java | 3 ++- .../org/tron/core/services/jsonrpc/TronJsonRpcImpl.java | 7 +++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpc.java b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpc.java index 115df6ef9da..42da36a7811 100644 --- a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpc.java +++ b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpc.java @@ -291,9 +291,10 @@ CompilationResult ethSubmitHashrate(String hashrate, String id) @JsonRpcErrors({ @JsonRpcError(exception = JsonRpcMethodNotFoundException.class, code = -32601, data = "{}"), @JsonRpcError(exception = JsonRpcInvalidParamsException.class, code = -32602, data = "{}"), + @JsonRpcError(exception = JsonRpcExceedLimitException.class, code = -32005, data = "{}"), }) String newFilter(FilterRequest fr) throws JsonRpcInvalidParamsException, - JsonRpcMethodNotFoundException; + JsonRpcMethodNotFoundException, JsonRpcExceedLimitException; @JsonRpcMethod("eth_newBlockFilter") @JsonRpcErrors({ diff --git a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java index f92ae7c0ba4..c808ddb08c6 100644 --- a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java +++ b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java @@ -1408,7 +1408,7 @@ public CompilationResult ethSubmitHashrate(String hashrate, String id) @Override public String newFilter(FilterRequest fr) throws JsonRpcInvalidParamsException, - JsonRpcMethodNotFoundException { + JsonRpcMethodNotFoundException, JsonRpcExceedLimitException { disableInPBFT("eth_newFilter"); // not supports finalized as block parameter @@ -1423,7 +1423,10 @@ public String newFilter(FilterRequest fr) throws JsonRpcInvalidParamsException, } else { eventFilter2Result = eventFilter2ResultSolidity; } - + if (eventFilter2Result.size() > maxBlockFilterNum) { + throw new JsonRpcExceedLimitException( + "exceed max log filters: " + maxBlockFilterNum + ", try again later"); + } long currentMaxFullNum = wallet.getNowBlock().getBlockHeader().getRawData().getNumber(); LogFilterAndResult logFilterAndResult = new LogFilterAndResult(fr, currentMaxFullNum, wallet); String filterID = generateFilterId(); From aeac1723ebaeb541a941200c7648f1101b52164a Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Fri, 26 Dec 2025 19:04:52 +0800 Subject: [PATCH 04/13] add map size --- .../org/tron/common/logsfilter/capsule/LogsFilterCapsule.java | 3 --- .../java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/framework/src/main/java/org/tron/common/logsfilter/capsule/LogsFilterCapsule.java b/framework/src/main/java/org/tron/common/logsfilter/capsule/LogsFilterCapsule.java index fbef7c5ee45..8a8e122d9a0 100644 --- a/framework/src/main/java/org/tron/common/logsfilter/capsule/LogsFilterCapsule.java +++ b/framework/src/main/java/org/tron/common/logsfilter/capsule/LogsFilterCapsule.java @@ -45,9 +45,6 @@ public LogsFilterCapsule(long blockNumber, String blockHash, Bloom bloom, @Override public void processFilterTrigger() { - long t1 = System.currentTimeMillis(); handleLogsFilter(this); - long t2 = System.currentTimeMillis(); - logger.info("processFilterTrigger cost {}", t2 - t1); } } \ No newline at end of file diff --git a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java index c808ddb08c6..2396a482a3c 100644 --- a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java +++ b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java @@ -222,6 +222,7 @@ public static void handleBLockFilter(BlockFilterCapsule blockFilterCapsule) { * append LogsFilterCapsule's LogFilterElement list to each filter if matched */ public static void handleLogsFilter(LogsFilterCapsule logsFilterCapsule) { + long t1 = System.currentTimeMillis(); Map eventFilterMap; if (logsFilterCapsule.isSolidified()) { @@ -271,6 +272,8 @@ public static void handleLogsFilter(LogsFilterCapsule logsFilterCapsule) { } logFilterAndResult.getResult().addAll(localResults); }); + long t2 = System.currentTimeMillis(); + logger.info("handleLogsFilter cost {}, filter size {}", t2 - t1, eventFilterMap.size()); } @Override From 406fe7ecfd1f3e600e3436573adebe1721004e6e Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Fri, 26 Dec 2025 19:31:39 +0800 Subject: [PATCH 05/13] use serial map --- .../services/jsonrpc/TronJsonRpcImpl.java | 39 ++++++++++--------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java index 2396a482a3c..f8a7de444d2 100644 --- a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java +++ b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java @@ -223,42 +223,44 @@ public static void handleBLockFilter(BlockFilterCapsule blockFilterCapsule) { */ public static void handleLogsFilter(LogsFilterCapsule logsFilterCapsule) { long t1 = System.currentTimeMillis(); - Map eventFilterMap; + long filterSize; + Iterator> it; if (logsFilterCapsule.isSolidified()) { - eventFilterMap = getEventFilter2ResultSolidity(); + it = getEventFilter2ResultSolidity().entrySet().iterator(); + filterSize = getEventFilter2ResultSolidity().size(); } else { - eventFilterMap = getEventFilter2ResultFull(); + it = getEventFilter2ResultFull().entrySet().iterator(); + filterSize = getEventFilter2ResultFull().size(); } - eventFilterMap.entrySet().parallelStream().forEach(entry -> { - - LogFilterAndResult logFilterAndResult = entry.getValue(); - if (logFilterAndResult.isExpire()) { - eventFilterMap.remove(entry.getKey()); - return; + while (it.hasNext()) { + Entry entry = it.next(); + if (entry.getValue().isExpire()) { + it.remove(); + continue; } - long blockNumber = logsFilterCapsule.getBlockNumber(); + LogFilterAndResult logFilterAndResult = entry.getValue(); long fromBlock = logFilterAndResult.getLogFilterWrapper().getFromBlock(); long toBlock = logFilterAndResult.getLogFilterWrapper().getToBlock(); - if (!(fromBlock <= blockNumber && blockNumber <= toBlock)) { - return; + if (!(fromBlock <= logsFilterCapsule.getBlockNumber() + && logsFilterCapsule.getBlockNumber() <= toBlock)) { + continue; } if (logsFilterCapsule.getBloom() != null && !logFilterAndResult.getLogFilterWrapper().getLogFilter() .matchBloom(logsFilterCapsule.getBloom())) { - return; + continue; } LogFilter logFilter = logFilterAndResult.getLogFilterWrapper().getLogFilter(); List elements = - LogMatch.matchBlock(logFilter, blockNumber, + LogMatch.matchBlock(logFilter, logsFilterCapsule.getBlockNumber(), logsFilterCapsule.getBlockHash(), logsFilterCapsule.getTxInfoList(), logsFilterCapsule.isRemoved()); - List localResults = new ArrayList<>(elements.size()); for (LogFilterElement element : elements) { LogFilterElement cachedElement; try { @@ -268,12 +270,11 @@ public static void handleLogsFilter(LogsFilterCapsule logsFilterCapsule) { logger.error("Getting/loading LogFilterElement from cache fails", e); // never happen cachedElement = element; } - localResults.add(cachedElement); + logFilterAndResult.getResult().add(cachedElement); } - logFilterAndResult.getResult().addAll(localResults); - }); + } long t2 = System.currentTimeMillis(); - logger.info("handleLogsFilter cost {}, filter size {}", t2 - t1, eventFilterMap.size()); + logger.info("handleLogsFilter cost {}, filter size {}", t2 - t1, filterSize); } @Override From 203588f122948d0206a7ed864a9d23b476798ac9 Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Fri, 26 Dec 2025 19:44:41 +0800 Subject: [PATCH 06/13] use parallel --- .../services/jsonrpc/TronJsonRpcImpl.java | 39 +++++++++---------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java index f8a7de444d2..2396a482a3c 100644 --- a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java +++ b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java @@ -223,44 +223,42 @@ public static void handleBLockFilter(BlockFilterCapsule blockFilterCapsule) { */ public static void handleLogsFilter(LogsFilterCapsule logsFilterCapsule) { long t1 = System.currentTimeMillis(); - long filterSize; - Iterator> it; + Map eventFilterMap; if (logsFilterCapsule.isSolidified()) { - it = getEventFilter2ResultSolidity().entrySet().iterator(); - filterSize = getEventFilter2ResultSolidity().size(); + eventFilterMap = getEventFilter2ResultSolidity(); } else { - it = getEventFilter2ResultFull().entrySet().iterator(); - filterSize = getEventFilter2ResultFull().size(); + eventFilterMap = getEventFilter2ResultFull(); } - while (it.hasNext()) { - Entry entry = it.next(); - if (entry.getValue().isExpire()) { - it.remove(); - continue; - } + eventFilterMap.entrySet().parallelStream().forEach(entry -> { LogFilterAndResult logFilterAndResult = entry.getValue(); + if (logFilterAndResult.isExpire()) { + eventFilterMap.remove(entry.getKey()); + return; + } + + long blockNumber = logsFilterCapsule.getBlockNumber(); long fromBlock = logFilterAndResult.getLogFilterWrapper().getFromBlock(); long toBlock = logFilterAndResult.getLogFilterWrapper().getToBlock(); - if (!(fromBlock <= logsFilterCapsule.getBlockNumber() - && logsFilterCapsule.getBlockNumber() <= toBlock)) { - continue; + if (!(fromBlock <= blockNumber && blockNumber <= toBlock)) { + return; } if (logsFilterCapsule.getBloom() != null && !logFilterAndResult.getLogFilterWrapper().getLogFilter() .matchBloom(logsFilterCapsule.getBloom())) { - continue; + return; } LogFilter logFilter = logFilterAndResult.getLogFilterWrapper().getLogFilter(); List elements = - LogMatch.matchBlock(logFilter, logsFilterCapsule.getBlockNumber(), + LogMatch.matchBlock(logFilter, blockNumber, logsFilterCapsule.getBlockHash(), logsFilterCapsule.getTxInfoList(), logsFilterCapsule.isRemoved()); + List localResults = new ArrayList<>(elements.size()); for (LogFilterElement element : elements) { LogFilterElement cachedElement; try { @@ -270,11 +268,12 @@ public static void handleLogsFilter(LogsFilterCapsule logsFilterCapsule) { logger.error("Getting/loading LogFilterElement from cache fails", e); // never happen cachedElement = element; } - logFilterAndResult.getResult().add(cachedElement); + localResults.add(cachedElement); } - } + logFilterAndResult.getResult().addAll(localResults); + }); long t2 = System.currentTimeMillis(); - logger.info("handleLogsFilter cost {}, filter size {}", t2 - t1, filterSize); + logger.info("handleLogsFilter cost {}, filter size {}", t2 - t1, eventFilterMap.size()); } @Override From 252ec8a4eefa02f4686f55618962c0af6c8aae7e Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Mon, 29 Dec 2025 10:08:30 +0800 Subject: [PATCH 07/13] set parallelism as 3 --- .../services/jsonrpc/TronJsonRpcImpl.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java index 2396a482a3c..6fb2797bb83 100644 --- a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java +++ b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java @@ -27,6 +27,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; +import java.util.concurrent.ForkJoinPool; import java.util.concurrent.TimeUnit; import java.util.regex.Pattern; import lombok.Getter; @@ -231,7 +232,8 @@ public static void handleLogsFilter(LogsFilterCapsule logsFilterCapsule) { eventFilterMap = getEventFilter2ResultFull(); } - eventFilterMap.entrySet().parallelStream().forEach(entry -> { + ForkJoinPool pool = new ForkJoinPool(2); //parallelStream default num(CPU) -1 + pool.submit(() -> eventFilterMap.entrySet().parallelStream().forEach(entry -> { LogFilterAndResult logFilterAndResult = entry.getValue(); if (logFilterAndResult.isExpire()) { @@ -246,17 +248,15 @@ public static void handleLogsFilter(LogsFilterCapsule logsFilterCapsule) { return; } - if (logsFilterCapsule.getBloom() != null - && !logFilterAndResult.getLogFilterWrapper().getLogFilter() - .matchBloom(logsFilterCapsule.getBloom())) { + if (logsFilterCapsule.getBloom() != null && !logFilterAndResult.getLogFilterWrapper() + .getLogFilter().matchBloom(logsFilterCapsule.getBloom())) { return; } LogFilter logFilter = logFilterAndResult.getLogFilterWrapper().getLogFilter(); List elements = - LogMatch.matchBlock(logFilter, blockNumber, - logsFilterCapsule.getBlockHash(), logsFilterCapsule.getTxInfoList(), - logsFilterCapsule.isRemoved()); + LogMatch.matchBlock(logFilter, blockNumber, logsFilterCapsule.getBlockHash(), + logsFilterCapsule.getTxInfoList(), logsFilterCapsule.isRemoved()); List localResults = new ArrayList<>(elements.size()); for (LogFilterElement element : elements) { @@ -271,9 +271,10 @@ public static void handleLogsFilter(LogsFilterCapsule logsFilterCapsule) { localResults.add(cachedElement); } logFilterAndResult.getResult().addAll(localResults); - }); + })).join(); long t2 = System.currentTimeMillis(); - logger.info("handleLogsFilter cost {}, filter size {}", t2 - t1, eventFilterMap.size()); + logger.info("handleLogsFilter {} cost {}, filter size {}", + logsFilterCapsule.isSolidified() ? "Solidity" : "Full", t2 - t1, eventFilterMap.size()); } @Override From 5ab9eb16d8f4062a23cfb5bf672b6216a89a2af4 Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Mon, 29 Dec 2025 10:19:49 +0800 Subject: [PATCH 08/13] add config item node.jsonrpc.maxLogFilterNum --- .../main/java/org/tron/common/parameter/CommonParameter.java | 3 +++ framework/src/main/java/org/tron/core/config/args/Args.java | 5 +++++ .../src/main/java/org/tron/core/config/args/ConfigKey.java | 2 ++ .../java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java | 5 +++-- framework/src/main/resources/config.conf | 2 ++ framework/src/test/resources/config-localtest.conf | 1 + framework/src/test/resources/config-test-mainnet.conf | 1 + framework/src/test/resources/config-test.conf | 1 + 8 files changed, 18 insertions(+), 2 deletions(-) diff --git a/common/src/main/java/org/tron/common/parameter/CommonParameter.java b/common/src/main/java/org/tron/common/parameter/CommonParameter.java index a73158a718a..2638c3e8c90 100644 --- a/common/src/main/java/org/tron/common/parameter/CommonParameter.java +++ b/common/src/main/java/org/tron/common/parameter/CommonParameter.java @@ -459,6 +459,9 @@ public class CommonParameter { @Getter @Setter public int jsonRpcMaxBlockFilterNum = 50000; + @Getter + @Setter + public int jsonRpcMaxLogFilterNum = 20000; @Getter @Setter 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 83d7fd2c63d..11e8063b4ab 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 @@ -265,6 +265,11 @@ public static void applyConfigParams( config.getInt(ConfigKey.NODE_JSONRPC_MAX_BLOCK_FILTER_NUM); } + if (config.hasPath(ConfigKey.NODE_JSONRPC_MAX_LOG_FILTER_NUM)) { + PARAMETER.jsonRpcMaxLogFilterNum = + config.getInt(ConfigKey.NODE_JSONRPC_MAX_LOG_FILTER_NUM); + } + if (config.hasPath(ConfigKey.VM_MIN_TIME_RATIO)) { PARAMETER.minTimeRatio = config.getDouble(ConfigKey.VM_MIN_TIME_RATIO); } diff --git a/framework/src/main/java/org/tron/core/config/args/ConfigKey.java b/framework/src/main/java/org/tron/core/config/args/ConfigKey.java index b21c9c440a4..9d2751fa825 100644 --- a/framework/src/main/java/org/tron/core/config/args/ConfigKey.java +++ b/framework/src/main/java/org/tron/core/config/args/ConfigKey.java @@ -150,6 +150,8 @@ private ConfigKey() { public static final String NODE_JSONRPC_MAX_SUB_TOPICS = "node.jsonrpc.maxSubTopics"; public static final String NODE_JSONRPC_MAX_BLOCK_FILTER_NUM = "node.jsonrpc.maxBlockFilterNum"; + public static final String NODE_JSONRPC_MAX_LOG_FILTER_NUM = + "node.jsonrpc.maxLogFilterNum"; // node - dns public static final String NODE_DNS_TREE_URLS = "node.dns.treeUrls"; diff --git a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java index 6fb2797bb83..b5868997cc8 100644 --- a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java +++ b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java @@ -116,6 +116,7 @@ public enum RequestSource { private static final String FILTER_NOT_FOUND = "filter not found"; public static final int EXPIRE_SECONDS = 5 * 60; private static final int maxBlockFilterNum = Args.getInstance().getJsonRpcMaxBlockFilterNum(); + private static final int maxLogFilterNum = Args.getInstance().getJsonRpcMaxLogFilterNum(); private static final Cache logElementCache = CacheBuilder.newBuilder() .maximumSize(300_000L) // 300s * tps(1000) * 1 log/tx ≈ 300_000 @@ -1427,9 +1428,9 @@ public String newFilter(FilterRequest fr) throws JsonRpcInvalidParamsException, } else { eventFilter2Result = eventFilter2ResultSolidity; } - if (eventFilter2Result.size() > maxBlockFilterNum) { + if (eventFilter2Result.size() > maxLogFilterNum) { throw new JsonRpcExceedLimitException( - "exceed max log filters: " + maxBlockFilterNum + ", try again later"); + "exceed max log filters: " + maxLogFilterNum + ", try again later"); } long currentMaxFullNum = wallet.getNowBlock().getBlockHeader().getRawData().getNumber(); LogFilterAndResult logFilterAndResult = new LogFilterAndResult(fr, currentMaxFullNum, wallet); diff --git a/framework/src/main/resources/config.conf b/framework/src/main/resources/config.conf index 369924074bc..2e2418cbe47 100644 --- a/framework/src/main/resources/config.conf +++ b/framework/src/main/resources/config.conf @@ -375,6 +375,8 @@ node { maxSubTopics = 1000 # Allowed maximum number for blockFilter maxBlockFilterNum = 50000 + # Allowed maximum number for newFilter + maxLogFilterNum = 20000 } # Disabled api list, it will work for http, rpc and pbft, both FullNode and SolidityNode, diff --git a/framework/src/test/resources/config-localtest.conf b/framework/src/test/resources/config-localtest.conf index f1f40dead76..1f3b8a6f3af 100644 --- a/framework/src/test/resources/config-localtest.conf +++ b/framework/src/test/resources/config-localtest.conf @@ -168,6 +168,7 @@ node { # maxBlockRange = 5000 # maxSubTopics = 1000 # maxBlockFilterNum = 30000 + # maxLogFilterNum = 20000 } } diff --git a/framework/src/test/resources/config-test-mainnet.conf b/framework/src/test/resources/config-test-mainnet.conf index d39f432ac36..9f968c5628d 100644 --- a/framework/src/test/resources/config-test-mainnet.conf +++ b/framework/src/test/resources/config-test-mainnet.conf @@ -95,6 +95,7 @@ node { # maxBlockRange = 5000 # maxSubTopics = 1000 # maxBlockFilterNum = 50000 + # maxLogFilterNum = 20000 } rpc { diff --git a/framework/src/test/resources/config-test.conf b/framework/src/test/resources/config-test.conf index 71e93f84db5..21cebbfeef4 100644 --- a/framework/src/test/resources/config-test.conf +++ b/framework/src/test/resources/config-test.conf @@ -119,6 +119,7 @@ node { # maxBlockRange = 5000 # maxSubTopics = 1000 # maxBlockFilterNum = 30000 + # maxLogFilterNum = 20000 } # use your ipv6 address for node discovery and tcp connection, default false From 6323ea8a83d9cced566b6887ef0499f7f05ad113 Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Fri, 17 Apr 2026 19:16:48 +0800 Subject: [PATCH 09/13] add missing EventBloomException for switchFork; throw exception before addAll matchedLog instead after --- framework/src/main/java/org/tron/core/db/Manager.java | 3 ++- .../tron/core/services/jsonrpc/filters/LogMatch.java | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/framework/src/main/java/org/tron/core/db/Manager.java b/framework/src/main/java/org/tron/core/db/Manager.java index cd1a61c01fe..6c07763fe9c 100644 --- a/framework/src/main/java/org/tron/core/db/Manager.java +++ b/framework/src/main/java/org/tron/core/db/Manager.java @@ -1155,7 +1155,8 @@ private void switchFork(BlockCapsule newHead) | ValidateScheduleException | VMIllegalException | ZksnarkException - | BadBlockException e) { + | BadBlockException + | EventBloomException e) { logger.warn(e.getMessage(), e); exception = e; throw e; diff --git a/framework/src/main/java/org/tron/core/services/jsonrpc/filters/LogMatch.java b/framework/src/main/java/org/tron/core/services/jsonrpc/filters/LogMatch.java index cf958d1e2cb..c69e8e138f1 100644 --- a/framework/src/main/java/org/tron/core/services/jsonrpc/filters/LogMatch.java +++ b/framework/src/main/java/org/tron/core/services/jsonrpc/filters/LogMatch.java @@ -93,14 +93,14 @@ public LogFilterElement[] matchBlockOneByOne() String blockHash = manager.getChainBaseManager().getBlockIdByNum(blockNum).toString(); List matchedLog = matchBlock(logFilterWrapper.getLogFilter(), blockNum, blockHash, transactionInfoList, false); + if (!matchedLog.isEmpty()) { + if (logFilterElementList.size() + matchedLog.size() > LogBlockQuery.MAX_RESULT) { + throw new JsonRpcTooManyResultException( + "query returned more than " + LogBlockQuery.MAX_RESULT + " results"); + } logFilterElementList.addAll(matchedLog); } - - if (logFilterElementList.size() > LogBlockQuery.MAX_RESULT) { - throw new JsonRpcTooManyResultException( - "query returned more than " + LogBlockQuery.MAX_RESULT + " results"); - } } return logFilterElementList.toArray(new LogFilterElement[0]); From 9897ea89aa2457f6d73fee11be28f08ba67d471f Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Fri, 17 Apr 2026 19:57:33 +0800 Subject: [PATCH 10/13] use ForkJoinPool as necessary --- .../services/jsonrpc/TronJsonRpcImpl.java | 88 +++++++++++-------- 1 file changed, 50 insertions(+), 38 deletions(-) diff --git a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java index b5868997cc8..fa3d23c4f14 100644 --- a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java +++ b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java @@ -171,6 +171,8 @@ public enum RequestSource { private static final String NO_BLOCK_HEADER_BY_HASH = "header for hash not found"; private static final String ERROR_SELECTOR = "08c379a0"; // Function selector for Error(string) + private static final int FILTER_PARALLEL_THRESHOLD = 10000; + private static final ForkJoinPool LOGS_FILTER_POOL = new ForkJoinPool(2); /** * thread pool of query section bloom store */ @@ -233,49 +235,59 @@ public static void handleLogsFilter(LogsFilterCapsule logsFilterCapsule) { eventFilterMap = getEventFilter2ResultFull(); } - ForkJoinPool pool = new ForkJoinPool(2); //parallelStream default num(CPU) -1 - pool.submit(() -> eventFilterMap.entrySet().parallelStream().forEach(entry -> { + if (eventFilterMap.size() <= FILTER_PARALLEL_THRESHOLD) { + eventFilterMap.entrySet().forEach( + entry -> processLogFilterEntry(entry, eventFilterMap, logsFilterCapsule)); + } else { + LOGS_FILTER_POOL.submit(() -> eventFilterMap.entrySet().parallelStream() + .forEach(entry -> processLogFilterEntry(entry, eventFilterMap, logsFilterCapsule)) + ).join(); + } + long t2 = System.currentTimeMillis(); + logger.info("handleLogsFilter {} cost {}, filter size {}", + logsFilterCapsule.isSolidified() ? "Solidity" : "Full", t2 - t1, eventFilterMap.size()); + } - LogFilterAndResult logFilterAndResult = entry.getValue(); - if (logFilterAndResult.isExpire()) { - eventFilterMap.remove(entry.getKey()); - return; - } + private static void processLogFilterEntry( + Map.Entry entry, + Map eventFilterMap, + LogsFilterCapsule logsFilterCapsule) { + LogFilterAndResult logFilterAndResult = entry.getValue(); + if (logFilterAndResult.isExpire()) { + eventFilterMap.remove(entry.getKey()); + return; + } - long blockNumber = logsFilterCapsule.getBlockNumber(); - long fromBlock = logFilterAndResult.getLogFilterWrapper().getFromBlock(); - long toBlock = logFilterAndResult.getLogFilterWrapper().getToBlock(); - if (!(fromBlock <= blockNumber && blockNumber <= toBlock)) { - return; - } + long blockNumber = logsFilterCapsule.getBlockNumber(); + long fromBlock = logFilterAndResult.getLogFilterWrapper().getFromBlock(); + long toBlock = logFilterAndResult.getLogFilterWrapper().getToBlock(); + if (!(fromBlock <= blockNumber && blockNumber <= toBlock)) { + return; + } - if (logsFilterCapsule.getBloom() != null && !logFilterAndResult.getLogFilterWrapper() - .getLogFilter().matchBloom(logsFilterCapsule.getBloom())) { - return; - } + if (logsFilterCapsule.getBloom() != null && !logFilterAndResult.getLogFilterWrapper() + .getLogFilter().matchBloom(logsFilterCapsule.getBloom())) { + return; + } - LogFilter logFilter = logFilterAndResult.getLogFilterWrapper().getLogFilter(); - List elements = - LogMatch.matchBlock(logFilter, blockNumber, logsFilterCapsule.getBlockHash(), - logsFilterCapsule.getTxInfoList(), logsFilterCapsule.isRemoved()); + LogFilter logFilter = logFilterAndResult.getLogFilterWrapper().getLogFilter(); + List elements = + LogMatch.matchBlock(logFilter, blockNumber, logsFilterCapsule.getBlockHash(), + logsFilterCapsule.getTxInfoList(), logsFilterCapsule.isRemoved()); - List localResults = new ArrayList<>(elements.size()); - for (LogFilterElement element : elements) { - LogFilterElement cachedElement; - try { - // compare with hashcode() first, then with equals(). If not exist, put it. - cachedElement = logElementCache.get(element, () -> element); - } catch (ExecutionException e) { - logger.error("Getting/loading LogFilterElement from cache fails", e); // never happen - cachedElement = element; - } - localResults.add(cachedElement); + List localResults = new ArrayList<>(elements.size()); + for (LogFilterElement element : elements) { + LogFilterElement cachedElement; + try { + // compare with hashcode() first, then with equals(). If not exist, put it. + cachedElement = logElementCache.get(element, () -> element); + } catch (ExecutionException e) { + logger.error("Getting/loading LogFilterElement from cache fails", e); // never happen + cachedElement = element; } - logFilterAndResult.getResult().addAll(localResults); - })).join(); - long t2 = System.currentTimeMillis(); - logger.info("handleLogsFilter {} cost {}, filter size {}", - logsFilterCapsule.isSolidified() ? "Solidity" : "Full", t2 - t1, eventFilterMap.size()); + localResults.add(cachedElement); + } + logFilterAndResult.getResult().addAll(localResults); } @Override @@ -1428,7 +1440,7 @@ public String newFilter(FilterRequest fr) throws JsonRpcInvalidParamsException, } else { eventFilter2Result = eventFilter2ResultSolidity; } - if (eventFilter2Result.size() > maxLogFilterNum) { + if (eventFilter2Result.size() >= maxLogFilterNum) { throw new JsonRpcExceedLimitException( "exceed max log filters: " + maxLogFilterNum + ", try again later"); } From 27cdfa4721b180761f42dd765e6f0e0b0f10ee41 Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Thu, 23 Apr 2026 17:09:48 +0800 Subject: [PATCH 11/13] set handleLogsFilter to debug --- .../java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java index fa3d23c4f14..0fa19fabe8c 100644 --- a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java +++ b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java @@ -172,7 +172,7 @@ public enum RequestSource { private static final String ERROR_SELECTOR = "08c379a0"; // Function selector for Error(string) private static final int FILTER_PARALLEL_THRESHOLD = 10000; - private static final ForkJoinPool LOGS_FILTER_POOL = new ForkJoinPool(2); + private static final ForkJoinPool LOGS_FILTER_POOL = new ForkJoinPool(); /** * thread pool of query section bloom store */ @@ -244,7 +244,7 @@ public static void handleLogsFilter(LogsFilterCapsule logsFilterCapsule) { ).join(); } long t2 = System.currentTimeMillis(); - logger.info("handleLogsFilter {} cost {}, filter size {}", + logger.debug("handleLogsFilter {} cost {}, filter size {}", logsFilterCapsule.isSolidified() ? "Solidity" : "Full", t2 - t1, eventFilterMap.size()); } @@ -1595,6 +1595,7 @@ public static Object[] getFilterResult(String filterId, Map Date: Fri, 24 Apr 2026 22:37:58 +0800 Subject: [PATCH 12/13] give name to LOGS_FILTER_POOL --- .../java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java | 4 ++-- .../src/test/java/org/tron/core/jsonrpc/WalletCursorTest.java | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java index 0fa19fabe8c..8fe7d3cb1b7 100644 --- a/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java +++ b/framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java @@ -172,7 +172,7 @@ public enum RequestSource { private static final String ERROR_SELECTOR = "08c379a0"; // Function selector for Error(string) private static final int FILTER_PARALLEL_THRESHOLD = 10000; - private static final ForkJoinPool LOGS_FILTER_POOL = new ForkJoinPool(); + private static final ForkJoinPool LOGS_FILTER_POOL = new ForkJoinPool(2); /** * thread pool of query section bloom store */ @@ -1595,7 +1595,7 @@ public static Object[] getFilterResult(String filterId, Map Date: Fri, 24 Apr 2026 23:04:13 +0800 Subject: [PATCH 13/13] remove EventBloomException --- framework/src/main/java/org/tron/core/db/Manager.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/framework/src/main/java/org/tron/core/db/Manager.java b/framework/src/main/java/org/tron/core/db/Manager.java index 6c07763fe9c..cd1a61c01fe 100644 --- a/framework/src/main/java/org/tron/core/db/Manager.java +++ b/framework/src/main/java/org/tron/core/db/Manager.java @@ -1155,8 +1155,7 @@ private void switchFork(BlockCapsule newHead) | ValidateScheduleException | VMIllegalException | ZksnarkException - | BadBlockException - | EventBloomException e) { + | BadBlockException e) { logger.warn(e.getMessage(), e); exception = e; throw e;