diff --git a/src/main/kotlin/io/emeraldpay/dshackle/rpc/NativeCall.kt b/src/main/kotlin/io/emeraldpay/dshackle/rpc/NativeCall.kt index 78ec44ac..956b187d 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/rpc/NativeCall.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/rpc/NativeCall.kt @@ -255,7 +255,10 @@ open class NativeCall( } private fun getRequestDecorator(method: String): RequestDecorator = - if (method == "eth_getFilterChanges") GetFilterUpdatesDecorator() else NoneRequestDecorator() + if (method == "eth_getFilterChanges" || method == "eth_uninstallFilter") + GetFilterUpdatesDecorator() + else + NoneRequestDecorator() private fun getResultDecorator(method: String): ResultDecorator = if (CreateFilterDecorator.createFilterMethods.contains(method)) CreateFilterDecorator() else NoneResultDecorator() @@ -378,7 +381,11 @@ open class NativeCall( companion object { const val quoteCode = '"'.code.toByte() - val createFilterMethods = listOf("eth_getFilterChanges", "eth_newFilter", "eth_newBlockFilter") + val createFilterMethods = listOf( + "eth_newFilter", + "eth_newBlockFilter", + "eth_newPendingTransactionFilter" + ) } override fun processResult(result: QuorumRpcReader.Result): ByteArray { val bytes = result.value diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/calls/DefaultEthereumMethods.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/calls/DefaultEthereumMethods.kt index 45067a48..6f78cfe0 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/calls/DefaultEthereumMethods.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/calls/DefaultEthereumMethods.kt @@ -75,6 +75,7 @@ class DefaultEthereumMethods( "eth_newFilter", "eth_newBlockFilter", "eth_newPendingTransactionFilter", + "eth_uninstallFilter" ) private val allowedMethods = anyResponseMethods + firstValueMethods + specialMethods + headVerifiedMethods + filterMethods diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/calls/EthereumCallSelector.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/calls/EthereumCallSelector.kt index 79748acf..abf684de 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/calls/EthereumCallSelector.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/calls/EthereumCallSelector.kt @@ -57,7 +57,7 @@ class EthereumCallSelector( return blockTagSelector(params, 1, head) } else if (method == "eth_getStorageAt") { return blockTagSelector(params, 2, head) - } else if (method == "eth_getFilterChanges") { + } else if (method == "eth_getFilterChanges" || method == "eth_uninstallFilter") { return sameUpstreamMatcher(params) } return Mono.empty() diff --git a/src/test/groovy/io/emeraldpay/dshackle/rpc/NativeCallSpec.groovy b/src/test/groovy/io/emeraldpay/dshackle/rpc/NativeCallSpec.groovy index 604e561f..43352b51 100644 --- a/src/test/groovy/io/emeraldpay/dshackle/rpc/NativeCallSpec.groovy +++ b/src/test/groovy/io/emeraldpay/dshackle/rpc/NativeCallSpec.groovy @@ -457,6 +457,37 @@ class NativeCallSpec extends Specification { act.requestDecorator instanceof NativeCall.GetFilterUpdatesDecorator } + def "Prepare call adds decorator for eth_uninstallFilter"() { + setup: + def methods = new ManagedCallMethods( + new DefaultEthereumMethods(Chain.ETHEREUM), + ["eth_uninstallFilter"] as Set, [] as Set + ) + methods.setQuorum("eth_uninstallFilter", "always") + def multistream = new MultistreamHolderMock.EthereumMultistreamMock(Chain.ETHEREUM, TestingCommons.upstream()) + multistream.customMethods = methods + multistream.customHead = Mock(Head) + def multistreamHolder = Mock(MultistreamHolder) { + _ * it.observeChains() >> Flux.empty() + } + def nativeCall = nativeCall(multistreamHolder) + + def req = BlockchainOuterClass.NativeCallRequest.newBuilder() + .setChain(Common.ChainRef.CHAIN_ETHEREUM) + .addItems( + BlockchainOuterClass.NativeCallItem.newBuilder() + .setId(1) + .setMethod("eth_uninstallFilter") + ) + .build() + when: + def act = nativeCall.prepareCall(req, multistream) + .collectList().block(Duration.ofSeconds(1)).first() + then: + act instanceof NativeCall.ValidCallContext + act.requestDecorator instanceof NativeCall.GetFilterUpdatesDecorator + } + def "Parse empty params"() { setup: def nativeCall = nativeCall()