Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
073771e
add log for LogsFilterCapsule
317787106 Dec 26, 2025
2c9b59d
use parallelStream for handleLogsFilter
317787106 Dec 26, 2025
440582b
add number of log filter limit
317787106 Dec 26, 2025
0016f13
add map size
317787106 Dec 26, 2025
0b80861
use serial map
317787106 Dec 26, 2025
6620708
use parallel
317787106 Dec 26, 2025
5f03ddb
set parallelism as 3
317787106 Dec 29, 2025
1b1a081
add config item node.jsonrpc.maxLogFilterNum
317787106 Dec 29, 2025
bf1f100
add missing EventBloomException for switchFork; throw exception befor…
317787106 Apr 17, 2026
6dd2d44
use ForkJoinPool as necessary
317787106 Apr 17, 2026
9259d2b
set handleLogsFilter to debug
317787106 Apr 23, 2026
46c9629
give name to LOGS_FILTER_POOL
317787106 Apr 24, 2026
732d66a
remove EventBloomException
317787106 Apr 24, 2026
938533a
extract SecureRandom
317787106 Apr 28, 2026
5d15ea2
format code
317787106 Apr 28, 2026
9493ecf
add testcase HandleLogsFilterTest,LogMatchOverLimitTest
317787106 Apr 29, 2026
e99045d
add comment of config file
317787106 Apr 29, 2026
ad0d688
fix the comment of maxLogFilterNum in reference.conf
317787106 Apr 29, 2026
a48b3b2
drop static modifier of some varibles in TronJsonRpcImpl
317787106 Apr 30, 2026
0f48bda
optimize testcase
317787106 Apr 30, 2026
2666f98
fix checkstyle
317787106 Apr 30, 2026
2f2e11a
add the reason why choose 3 threads for ForkJoinPool
317787106 Apr 30, 2026
44266d6
optimze config file
317787106 Apr 30, 2026
481130d
remove Lazy tronJsonRpcImpl in Manager
317787106 May 6, 2026
7c4b941
optimize some testcases
317787106 May 6, 2026
a209e45
remove modifier static of getFilterResult
317787106 May 7, 2026
4bf108a
add @Lazy for tronJsonRpcImpl in Manager
317787106 May 7, 2026
5ba9053
optimize FilterTriggerCapsule
317787106 May 7, 2026
584b53e
Merge branch 'develop' into hotfix/fix_newFilter
317787106 May 8, 2026
0cce053
fix the bug of JsonRpcCallAndEstimateGasTest
317787106 May 8, 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 @@ -4,11 +4,14 @@
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinWorkerThread;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import lombok.extern.slf4j.Slf4j;
import org.tron.common.exit.ExitManager;

Expand All @@ -35,6 +38,22 @@ public static ScheduledExecutorService newSingleThreadScheduledExecutor(String n
new ThreadFactoryBuilder().setNameFormat(name).setDaemon(isDaemon).build());
}

public static ForkJoinPool newForkJoinPool(String name, int parallelism) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[NIT] Add isDaemon overload to newForkJoinPool to match sibling factories

All the other factories in this class come in pairs — newSingleThreadExecutor(name) / newSingleThreadExecutor(name, isDaemon), same for newSingleThreadScheduledExecutor and newFixedThreadPool. The new newForkJoinPool(String, int) only has the single-arg form, with no way to opt into daemon threads.

Suggestion: Add newForkJoinPool(String name, int parallelism, boolean isDaemon) that calls thread.setDaemon(isDaemon) inside the worker factory; have the two-arg form delegate with isDaemon=false (matching newFixedThreadPool's default).

Copy link
Copy Markdown
Collaborator Author

@317787106 317787106 May 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add following in ExecutorServiceManager:

public static ForkJoinPool newForkJoinPool(String name, int parallelism, boolean isDaemon) {...}

isDaemon is false default.

return newForkJoinPool(name, parallelism, false);
}

public static ForkJoinPool newForkJoinPool(String name, int parallelism, boolean isDaemon) {
AtomicInteger counter = new AtomicInteger(0);
ForkJoinPool.ForkJoinWorkerThreadFactory factory = pool -> {
ForkJoinWorkerThread thread =
ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool);
thread.setName(name + "-" + counter.getAndIncrement());
thread.setDaemon(isDaemon);
return thread;
};
return new ForkJoinPool(parallelism, factory, null, false);
}

public static ExecutorService newFixedThreadPool(String name, int fixThreads) {
return newFixedThreadPool(name, fixThreads, false);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,9 @@ public class CommonParameter {
@Getter
@Setter
public int jsonRpcMaxBlockFilterNum = 50000;
@Getter
@Setter
public int jsonRpcMaxLogFilterNum = 20000;

@Getter
@Setter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ public void setHttpPBFTPort(int v) {
private int maxBlockRange = 5000;
private int maxSubTopics = 1000;
private int maxBlockFilterNum = 50000;
private int maxLogFilterNum = 20000;
private long maxMessageSize = 4194304;
}

Expand Down
5 changes: 4 additions & 1 deletion common/src/main/resources/reference.conf
Original file line number Diff line number Diff line change
Expand Up @@ -393,9 +393,12 @@ node {
# Maximum topics within a topic criteria, >0 otherwise no limit
maxSubTopics = 1000

# Maximum number for blockFilter
# Maximum number for blockFilter. >0 otherwise no limit
maxBlockFilterNum = 50000
Comment thread
317787106 marked this conversation as resolved.

# Maximum number of concurrent eth_newFilter registrations, >0 otherwise no limit
maxLogFilterNum = 20000

# Maximum JSON-RPC request body size, default 4MB. Independent from rpc.maxMessageSize.
maxMessageSize = 4M
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package org.tron.common.logsfilter.capsule;

import static org.tron.core.services.jsonrpc.TronJsonRpcImpl.handleBLockFilter;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
Expand All @@ -20,19 +18,12 @@ public class BlockFilterCapsule extends FilterTriggerCapsule {
private boolean solidified;

public BlockFilterCapsule(BlockCapsule block, boolean solidified) {
blockHash = block.getBlockId().toString();
this.solidified = solidified;
this(block.getBlockId().toString(), solidified);
}

public BlockFilterCapsule(String blockHash, boolean solidified) {
this.blockHash = blockHash;
this.solidified = solidified;
}

@Override
public void processFilterTrigger() {
handleBLockFilter(this);
}

}

Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
package org.tron.common.logsfilter.capsule;

public class FilterTriggerCapsule extends TriggerCapsule {
public class FilterTriggerCapsule {

public void processFilterTrigger() {
throw new UnsupportedOperationException();
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package org.tron.common.logsfilter.capsule;

import static org.tron.core.services.jsonrpc.TronJsonRpcImpl.handleLogsFilter;

import java.util.List;
import lombok.Getter;
import lombok.Setter;
Expand Down Expand Up @@ -43,8 +41,4 @@ public LogsFilterCapsule(long blockNumber, String blockHash, Bloom bloom,
this.removed = removed;
}

@Override
public void processFilterTrigger() {
handleLogsFilter(this);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,7 @@ private static void applyNodeConfig(NodeConfig nc) {
PARAMETER.jsonRpcMaxBlockRange = jsonrpc.getMaxBlockRange();
PARAMETER.jsonRpcMaxSubTopics = jsonrpc.getMaxSubTopics();
PARAMETER.jsonRpcMaxBlockFilterNum = jsonrpc.getMaxBlockFilterNum();
PARAMETER.jsonRpcMaxLogFilterNum = jsonrpc.getMaxLogFilterNum();
PARAMETER.jsonRpcMaxMessageSize = jsonrpc.getMaxMessageSize();

// ---- P2P sub-bean ----
Expand Down
15 changes: 12 additions & 3 deletions framework/src/main/java/org/tron/core/db/Manager.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
import org.apache.commons.collections4.CollectionUtils;
import org.bouncycastle.util.encoders.Hex;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.tron.api.GrpcAPI;
import org.tron.api.GrpcAPI.TransactionInfoList;
Expand Down Expand Up @@ -142,6 +143,7 @@
import org.tron.core.service.MortgageService;
import org.tron.core.service.RewardViCalService;
import org.tron.core.services.event.exception.EventException;
import org.tron.core.services.jsonrpc.TronJsonRpcImpl;
import org.tron.core.store.AccountAssetStore;
import org.tron.core.store.AccountIdIndexStore;
import org.tron.core.store.AccountIndexStore;
Expand Down Expand Up @@ -277,6 +279,10 @@ public class Manager {
@Autowired
private RewardViCalService rewardViCalService;

@Lazy
@Autowired
private TronJsonRpcImpl tronJsonRpcImpl;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[SHOULD] Avoid @lazy circular dependency from Manager into TronJsonRpcImpl

Manager is the core db / block-processing component of java-tron. Its dependency graph is supposed to be inbound-only (other components depend on Manager). This PR reverses that by injecting TronJsonRpcImpl (an API-layer @component) into Manager, forming a cycle that can only be resolved with @Lazy. The cycle exists because the new BlockFilterCapsule / LogsFilterCapsule carry a TronJsonRpcImpl reference, so Manager has to obtain that reference before constructing each capsule.

Why this matters even though it compiles:

  • @Lazy is a band-aid for circular dependencies, not a fix. It defers bean resolution to first method call and hides container init-order problems.
  • Spring 6 / Spring Boot 3 default spring.main.allow-circular-references=false. Any Spring upgrade can fail on this exact cycle.
  • Once Manager accepts a reverse dependency on the API layer, future capsule types follow the same path — the breach is contagious.
  • postBlockFilter is on a hot path; if TronJsonRpcImpl is mid-initialization (e.g. during a restart), the proxy can throw BeanCurrentlyInCreationException.

Two options to resolve before merge:

Option A — drop the reverse dependency (smallest change, matches the hotfix/fix_newFilter branch name):

  • Revert capsules to plain POJOs (no TronJsonRpcImpl field, original ctor signature).
  • Drop @Lazy @Autowired TronJsonRpcImpl from Manager.
  • Keep the three real fixes — maxLogFilterNum cap, LogMatch.matchBlockOneByOne MAX_RESULT check, and forEach + ForkJoinPool performance — none of them require static→instance.
  • For test isolation, expose a static clearAllFilters() helper (or use @Before / @After to clear the four maps).
  • Pros: minimal blast radius for a hotfix; production cache stays cross-instance; no @Lazy.
  • Cons: test isolation depends on test discipline; multi-instance scenarios still share state (not an issue today since the bean is a singleton).

Option C — Visitor / Dispatcher (cleanest, may warrant splitting from this PR):

  • Keep capsules as POJOs (no service reference).
  • Dispatch in Manager.filterProcessLoop directly, e.g.:
    FilterTriggerCapsule c = filterCapsuleQueue.poll(...);
    if (c instanceof LogsFilterCapsule)  tronJsonRpcImpl.handleLogsFilter((LogsFilterCapsule) c);
    else if (c instanceof BlockFilterCapsule) tronJsonRpcImpl.handleBLockFilter((BlockFilterCapsule) c);
    
    Or — preferred — introduce @Component FilterTriggerDispatcher that holds TronJsonRpcImpl (forward dep). Manager @Autowireds the dispatcher (also forward), so all edges Manager → Dispatcher → JsonRpcImpl are forward. Cycle gone.
  • Pros: capsules become genuinely independent, testable, serializable; Manager has no API-layer awareness; future capsule types just extend the dispatcher.
  • Cons: slightly more code than the current PR (one extra bean or one instanceof block).

Suggestion: pick A or C. If A, this PR is lighter than today; if C, the architecture is durable and the @Lazy ban is enforced naturally.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very good suggestion. To keep durable, @lazy is removed and use instanceof.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

It don't works if remove @lazy so i add it back. FullNode.java:50 disables Spring circular dependency resolution:

beanFactory.setAllowCircularReferences(false);

After removing @Lazy, Spring detects the following dependency cycle during startup and rejects it directly:

Manager → TronJsonRpcImpl (required by constructor ↓)
               NodeInfoService → @Autowired Manager  ← cycle!
               Wallet          → @Autowired Manager  ← cycle!

Why FilterTriggerDispatcher Alone Does Not Break the Cycle ?

The Proposed Dependency Graph

 Manager  ──field──▶  FilterTriggerDispatcher  ──field──▶  TronJsonRpcImpl                                                                                                                                                        

At first glance, all three edges point in one direction — no cycle.

The Hidden Transitive Dependencies

TronJsonRpcImpl uses constructor injection for two dependencies:

@Autowired
public TronJsonRpcImpl(NodeInfoService nodeInfoService, Wallet wallet) { … }
                                                                                                                                                                                                                                 
Both of those beans carry a hard dependency back to Manager:
                                                                                                                                                                                                                                 
// NodeInfoService.java    
@Autowired private Manager dbManager;

// Wallet.java
@Autowired private Manager dbManager;

Expanding the full graph:

Manager                                                                                                                                                                                                                          
  └─field──▶ FilterTriggerDispatcher
               └─field──▶ TronJsonRpcImpl
                            ├─ctor──▶ NodeInfoService ──field──▶ Manager  ✗
                            └─ctor──▶ Wallet          ──field──▶ Manager  ✗                                                                                                                                                      

Why Spring Rejects This

FullNode.java explicitly disables circular-reference resolution:

beanFactory.setAllowCircularReferences(false);   // FullNode.java:50

With this flag, Spring does not expose an early singleton reference for beans that are
still being created. The creation sequence becomes:

  1. Spring begins creating Manager → added to "currently in creation" set.
  2. Manager needs FilterTriggerDispatcher → Spring creates it.
  3. FilterTriggerDispatcher needs TronJsonRpcImpl → Spring creates it.
  4. TronJsonRpcImpl's constructor requires NodeInfoService → Spring creates it.
  5. NodeInfoService needs Manager → already in "currently in creation", no early reference available.
  6. Spring attempts to create Manager again → BeanCurrentlyInCreationException.

The new class does not appear anywhere in the cycle; the cycle runs entirely through
TronJsonRpcImpl → NodeInfoService/Wallet → Manager.

What Would Actually Fix It

The FilterTriggerDispatcher design only eliminates the cycle if one of the following is
also true:

  │                                         Additional Change                                          │                                          Effect                                          │
  ├────────────────────────────────────────────────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────┤
  │ FilterTriggerDispatcher injects TronJsonRpcImpl with @Lazy                                         │ Defers creation past Manager's init; equivalent to the current @Lazy fix, just relocated │
  ├────────────────────────────────────────────────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────┤
  │ TronJsonRpcImpl switches NodeInfoService and Wallet to setter injection                            │ Constructor no longer forces eager creation of Manager-dependent beans                   │                                
  ├────────────────────────────────────────────────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────┤
  │ FilterTriggerDispatcher looks up TronJsonRpcImpl via ApplicationContext.getBean() at dispatch time │ Bypasses Spring DI for this edge entirely                                                │                                
  └────────────────────────────────────────────────────────────────────────────────────────────────────┴──────────────────────────────────────────────────────────────────────────────────────────┘                                

Without one of these additions, introducing FilterTriggerDispatcher changes only the
name of the path through which the cycle travels, not the cycle itself.

What to do next ?

If a more systematic architectural refactor is planned in the future, FilterTriggerDispatcher is worth tracking in a separate issue and addressing together with changing NodeInfoService / Wallet to setter injection.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the detailed analysis — you are right that introducing FilterTriggerDispatcher alone does not break the cycle, because the cycle actually runs through TronJsonRpcImpl → NodeInfoService / Wallet → Manager regardless of whether a Dispatcher sits in between. My original suggestion was incomplete on that point.

But I think the conversation we're having so far is still framed at the wrong level. The three workarounds you listed (@Lazy on the Dispatcher edge, switching NodeInfoService / Wallet to setter injection, ApplicationContext.getBean() lookup) are all techniques to make Spring tolerate the cycle. None of them remove the underlying design problem, which is:

Manager should not depend on TronJsonRpcImpl at all.

The reason this dependency exists today is that Manager is hosting both the producer side (postBlockFilter / postLogsFilterqueue.offer(...)) and the consumer side (filterProcessLoop → calls into TronJsonRpcImpl) of the same queue. The consumer side is where the reverse edge comes from. Move it out and the entire cycle disappears — no @Lazy, no setter-injection rewrite, no ApplicationContext.getBean().

Concrete plan: move filterProcessLoop into TronJsonRpcImpl

Manager keeps only the producer role:

@Component
public class Manager {
    private final BlockingQueue<FilterTriggerCapsule> filterCapsuleQueue =
        new LinkedBlockingQueue<>();

    public BlockingQueue<FilterTriggerCapsule> getFilterCapsuleQueue() {
        return filterCapsuleQueue;
    }

    private void postBlockFilter(...) { filterCapsuleQueue.offer(new BlockFilterCapsule(blk, sol)); }
    private void postLogsFilter(...)  { filterCapsuleQueue.offer(new LogsFilterCapsule(...));    }

    // delete: @Lazy @Autowired private TronJsonRpcImpl tronJsonRpcImpl;
    // delete: filterProcessLoop Runnable
    // delete: filterEs / filterEsName / isRunFilterProcessThread
}

TronJsonRpcImpl owns the consumer role:

@Component
public class TronJsonRpcImpl implements TronJsonRpc, Closeable {
    private final Manager manager;  // back to ctor injection (forward edge)
    private volatile boolean running = true;
    private ExecutorService filterEs;

    @Autowired
    public TronJsonRpcImpl(NodeInfoService nodeInfoService, Wallet wallet, Manager manager) { ... }

    @PostConstruct
    public void start() {
        if (!CommonParameter.getInstance().isJsonRpcFilterEnabled()) return;
        filterEs = ExecutorServiceManager.newSingleThreadExecutor("filter-process");
        ExecutorServiceManager.submit(filterEs, this::filterProcessLoop);
    }

    private void filterProcessLoop() {
        BlockingQueue<FilterTriggerCapsule> queue = manager.getFilterCapsuleQueue();
        while (running) {
            try {
                FilterTriggerCapsule c = queue.poll(1, TimeUnit.SECONDS);
                if (c instanceof LogsFilterCapsule)        handleLogsFilter((LogsFilterCapsule) c);
                else if (c instanceof BlockFilterCapsule)  handleBLockFilter((BlockFilterCapsule) c);
            } catch (InterruptedException e) { Thread.currentThread().interrupt(); }
              catch (Throwable t) { logger.error("filterProcessLoop error", t); }
        }
    }

    @Override public void close() {
        running = false;
        ExecutorServiceManager.shutdownAndAwaitTermination(filterEs, "filter-process");
        // existing logsFilterPool / sectionExecutor shutdown
    }
}

Resulting Spring graph (all edges forward, no cycle):

TronJsonRpcImpl ──► Manager
TronJsonRpcImpl ──► NodeInfoService ──► Manager
TronJsonRpcImpl ──► Wallet          ──► Manager
Manager ──► (nothing in jsonrpc)

Why this cycle showed up now, and why it is worth fixing properly

Before this PR, BlockFilterCapsule / LogsFilterCapsule called TronJsonRpcImpl.handleBLockFilter / handleLogsFilter via import static. Those are Java static dispatches, not Spring bean references — Spring's container had no idea Manager depended on TronJsonRpcImpl. The cycle existed in the call graph the whole time; Spring just couldn't see it.

This PR turning those methods into instance methods (which is the right thing to do for test isolation of the filter maps) forces the dependency to be expressed as @Autowired, and only then does Spring complain. So the cycle isn't introduced here — it's exposed here. Adding @Lazy papers over an existing layering issue that the previous static-import pattern was hiding.

If we ship @Lazy as the final state, the next time someone does the same cleanup on another piece of jsonrpc state (a counter, a metrics object, another cache), they'll add another @Lazy field for the same reason, and the layering breach compounds.

Suggestion

For this PR: consider Plan X above. The diff is small (~30 lines net), the cycle is genuinely removed (no @Lazy), and the fix matches the existing branch name (hotfix/fix_newFilter).

If the PR is already too large in scope to add this: leave the current @Lazy and open a follow-up issue framed as "Move filterProcessLoop into TronJsonRpcImpl so Manager no longer depends on jsonrpc" rather than "switch NodeInfoService / Wallet to setter injection". The latter only quiets Spring; the former actually fixes the layering.

Copy link
Copy Markdown
Collaborator Author

@317787106 317787106 May 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very good suggestion. The PR is enough large now, maybe need to refactor TronJsonRpcImpl ( including remove @Lazy) in next ISSUE or PR. The main goal of removing modifier static from four ConcurrentHashMap is to solve 10 testcase failure that happens in parallel test introduced by PR t.maxParallelForks https://github.com/tronprotocol/java-tron/pull/6447/changes, so TronJsonRpcImpl needs to be optimized in current PR.


/**
* Cycle thread to rePush Transactions
*/
Expand Down Expand Up @@ -333,8 +339,10 @@ public class Manager {
while (isRunFilterProcessThread) {
try {
FilterTriggerCapsule filterCapsule = filterCapsuleQueue.poll(1, TimeUnit.SECONDS);
if (filterCapsule != null) {
filterCapsule.processFilterTrigger();
if (filterCapsule instanceof LogsFilterCapsule) {
tronJsonRpcImpl.handleLogsFilter((LogsFilterCapsule) filterCapsule);
} else if (filterCapsule instanceof BlockFilterCapsule) {
tronJsonRpcImpl.handleBLockFilter((BlockFilterCapsule) filterCapsule);
}
Comment thread
317787106 marked this conversation as resolved.
} catch (InterruptedException e) {
logger.error("FilterProcessLoop get InterruptedException, error is {}.",
Expand Down Expand Up @@ -2279,7 +2287,8 @@ private void reOrgLogsFilter() {
}

private void postBlockFilter(final BlockCapsule blockCapsule, boolean solidified) {
BlockFilterCapsule blockFilterCapsule = new BlockFilterCapsule(blockCapsule, solidified);
BlockFilterCapsule blockFilterCapsule =
new BlockFilterCapsule(blockCapsule, solidified);
if (!filterCapsuleQueue.offer(blockFilterCapsule)) {
logger.info("Too many filters, block filter lost: {}.", blockCapsule.getBlockId());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ public class JsonRpcApiUtil {
public static final String TAG_SAFE_SUPPORT_ERROR = "TAG safe not supported";
public static final String BLOCK_NUM_ERROR = "invalid block number";

private static final SecureRandom random = new SecureRandom();

public static byte[] convertToTronAddress(byte[] address) {
byte[] newAddress = new byte[21];
byte[] temp = new byte[] {Wallet.getAddressPreFixByte()};
Expand Down Expand Up @@ -647,7 +649,6 @@ public static long parseBlockNumber(String blockNumOrTag, Wallet wallet)
}

public static String generateFilterId() {
SecureRandom random = new SecureRandom();
byte[] uid = new byte[16]; // 128 bits are converted to 16 bytes
random.nextBytes(uid);
return ByteArray.toHexString(uid);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand Down
Loading
Loading