Filter Not Found
Filters - Error Recovery
Sometimes I can see the following exception
2021-03-24 19:27:37.581 WARN 6 --- [pool-1-thread-2] org.web3j.protocol.core.filters.Filter : The filter has not been found. Filter id: 55748555346051731603238387605648791524
2021-03-24 19:27:37.627 ERROR 6 --- [pool-1-thread-1] org.web3j.protocol.core.filters.Filter : Error sending request
org.web3j.protocol.core.filters.FilterException: Error sending request
at org.web3j.protocol.core.filters.Filter.throwException(Filter.java:194) ~[core-4.6.3.jar!/:na]
at org.web3j.protocol.core.filters.Filter.run(Filter.java:104) ~[core-4.6.3.jar!/:na]
at org.web3j.protocol.core.filters.Filter.reinstallFilter(Filter.java:155) ~[core-4.6.3.jar!/:na]
at org.web3j.protocol.core.filters.Filter.pollFilter(Filter.java:137) ~[core-4.6.3.jar!/:na]
at org.web3j.protocol.core.filters.Filter.lambda$run$0(Filter.java:92) ~[core-4.6.3.jar!/:na]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[na:1.8.0_111-internal]
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) ~[na:1.8.0_111-internal]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) ~[na:1.8.0_111-internal]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) ~[na:1.8.0_111-internal]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[na:1.8.0_111-internal]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[na:1.8.0_111-internal]
at java.lang.Thread.run(Thread.java:745) ~[na:1.8.0_111-internal]
After which I cannot poll the filter changes anymore.
Issue_description
It appears that once the filter is removed due to any error (network, eth node or any other) there is no way to recover from the error, anything that works for me is to restart the web3j application.
@ffarhanaamin Hey could you place a code snippet to help with debugging this issue, please?
Refer my solution here: https://github.com/ethereum/go-ethereum/issues/21386#issuecomment-723992023
The root cause of the issue is still not found. But the above solution works like a charm. It basically stores the last synced block number in your database every time an exception occurs. Then it restarts the method and checks DB, if last sync block number is present in the database, it will start sync from there. This work around makes sure no blocks are missed due to exception. I had struggled for almost 4 months to resolve this error. Just to let you know.
I think I might have found the cause of the issue.
In org.web3j.protocol.core.filters.Filter.java, within reinstallFilter(), the ScheduledFuture that periodically calls pollFilter() is cancelled with the flag set to true, meaning that the thread it is running on will be interrupted. But reinstallFilter() was called from an execution of the scheduled task. This causes the method call to sendRequest() from within this.run() to throw an InterruptedIOException because the thread has been interrupted.
private void reinstallFilter() {
log.warn("The filter has not been found. Filter id: " + filterId);
schedule.cancel(true);
this.run(scheduledExecutorService, blockTime);
}
Changing the boolean within schedule.cancel(true) to false seems to fix this, since the ScheduledFuture will then only be cancelled when the current execution of it is complete.
Created a PR for this #1507
@wxker95 you saved my day, thank you very much. Important info for others, I had version 5.0.0 and there is for some reason schedule.cancel(true) again. And it does not work of course. You have to use web3j version 4.9.3 to get it with @wxker95 fix and it will finally work as expected.
@Tilseroz @ffarhanaamin it appears that this no longer an issue