Merge pull request #44 from p2p-org/add_eth_getFilterLogs
add eth_getFilterLogs support
This commit is contained in:
@@ -30,6 +30,7 @@ import io.emeraldpay.dshackle.quorum.QuorumRpcReader
|
|||||||
import io.emeraldpay.dshackle.startup.ConfiguredUpstreams
|
import io.emeraldpay.dshackle.startup.ConfiguredUpstreams
|
||||||
import io.emeraldpay.dshackle.startup.UpstreamChangeEvent
|
import io.emeraldpay.dshackle.startup.UpstreamChangeEvent
|
||||||
import io.emeraldpay.dshackle.upstream.*
|
import io.emeraldpay.dshackle.upstream.*
|
||||||
|
import io.emeraldpay.dshackle.upstream.calls.DefaultEthereumMethods
|
||||||
import io.emeraldpay.dshackle.upstream.calls.EthereumCallSelector
|
import io.emeraldpay.dshackle.upstream.calls.EthereumCallSelector
|
||||||
import io.emeraldpay.dshackle.upstream.ethereum.EthereumLikeMultistream
|
import io.emeraldpay.dshackle.upstream.ethereum.EthereumLikeMultistream
|
||||||
import io.emeraldpay.dshackle.upstream.ethereum.EthereumMultistream
|
import io.emeraldpay.dshackle.upstream.ethereum.EthereumMultistream
|
||||||
@@ -255,13 +256,13 @@ open class NativeCall(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getRequestDecorator(method: String): RequestDecorator =
|
private fun getRequestDecorator(method: String): RequestDecorator =
|
||||||
if (method == "eth_getFilterChanges" || method == "eth_uninstallFilter")
|
if (method in DefaultEthereumMethods.withFilterIdMethods)
|
||||||
GetFilterUpdatesDecorator()
|
WithFilterIdDecorator()
|
||||||
else
|
else
|
||||||
NoneRequestDecorator()
|
NoneRequestDecorator()
|
||||||
|
|
||||||
private fun getResultDecorator(method: String): ResultDecorator =
|
private fun getResultDecorator(method: String): ResultDecorator =
|
||||||
if (CreateFilterDecorator.createFilterMethods.contains(method)) CreateFilterDecorator() else NoneResultDecorator()
|
if (method in DefaultEthereumMethods.newFilterMethods) CreateFilterDecorator() else NoneResultDecorator()
|
||||||
|
|
||||||
fun fetch(ctx: ValidCallContext<ParsedCallDetails>): Mono<CallResult> {
|
fun fetch(ctx: ValidCallContext<ParsedCallDetails>): Mono<CallResult> {
|
||||||
return ctx.upstream.getRoutedApi(ctx.matcher)
|
return ctx.upstream.getRoutedApi(ctx.matcher)
|
||||||
@@ -381,11 +382,6 @@ open class NativeCall(
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val quoteCode = '"'.code.toByte()
|
const val quoteCode = '"'.code.toByte()
|
||||||
val createFilterMethods = listOf(
|
|
||||||
"eth_newFilter",
|
|
||||||
"eth_newBlockFilter",
|
|
||||||
"eth_newPendingTransactionFilter"
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
override fun processResult(result: QuorumRpcReader.Result): ByteArray {
|
override fun processResult(result: QuorumRpcReader.Result): ByteArray {
|
||||||
val bytes = result.value
|
val bytes = result.value
|
||||||
@@ -406,7 +402,7 @@ open class NativeCall(
|
|||||||
override fun processRequest(request: List<Any>): List<Any> = request
|
override fun processRequest(request: List<Any>): List<Any> = request
|
||||||
}
|
}
|
||||||
|
|
||||||
open class GetFilterUpdatesDecorator : RequestDecorator {
|
open class WithFilterIdDecorator : RequestDecorator {
|
||||||
override fun processRequest(request: List<Any>): List<Any> {
|
override fun processRequest(request: List<Any>): List<Any> {
|
||||||
val filterId = request.first().toString()
|
val filterId = request.first().toString()
|
||||||
val sanitized = filterId.substring(0, filterId.lastIndex - 1)
|
val sanitized = filterId.substring(0, filterId.lastIndex - 1)
|
||||||
|
|||||||
@@ -35,6 +35,20 @@ class DefaultEthereumMethods(
|
|||||||
|
|
||||||
private val version = "\"EmeraldDshackle/${Global.version}\""
|
private val version = "\"EmeraldDshackle/${Global.version}\""
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val withFilterIdMethods = listOf(
|
||||||
|
"eth_getFilterChanges",
|
||||||
|
"eth_getFilterLogs",
|
||||||
|
"eth_uninstallFilter"
|
||||||
|
)
|
||||||
|
|
||||||
|
val newFilterMethods = listOf(
|
||||||
|
"eth_newFilter",
|
||||||
|
"eth_newBlockFilter",
|
||||||
|
"eth_newPendingTransactionFilter",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private val anyResponseMethods = listOf(
|
private val anyResponseMethods = listOf(
|
||||||
"eth_gasPrice",
|
"eth_gasPrice",
|
||||||
"eth_call",
|
"eth_call",
|
||||||
@@ -70,13 +84,7 @@ class DefaultEthereumMethods(
|
|||||||
"eth_feeHistory"
|
"eth_feeHistory"
|
||||||
)
|
)
|
||||||
|
|
||||||
private val filterMethods = listOf(
|
private val filterMethods = withFilterIdMethods + newFilterMethods
|
||||||
"eth_getFilterChanges",
|
|
||||||
"eth_newFilter",
|
|
||||||
"eth_newBlockFilter",
|
|
||||||
"eth_newPendingTransactionFilter",
|
|
||||||
"eth_uninstallFilter"
|
|
||||||
)
|
|
||||||
|
|
||||||
private val allowedMethods = anyResponseMethods + firstValueMethods + specialMethods + headVerifiedMethods + filterMethods
|
private val allowedMethods = anyResponseMethods + firstValueMethods + specialMethods + headVerifiedMethods + filterMethods
|
||||||
|
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ class EthereumCallSelector(
|
|||||||
return blockTagSelector(params, 1, head)
|
return blockTagSelector(params, 1, head)
|
||||||
} else if (method == "eth_getStorageAt") {
|
} else if (method == "eth_getStorageAt") {
|
||||||
return blockTagSelector(params, 2, head)
|
return blockTagSelector(params, 2, head)
|
||||||
} else if (method == "eth_getFilterChanges" || method == "eth_uninstallFilter") {
|
} else if (method in DefaultEthereumMethods.withFilterIdMethods) {
|
||||||
return sameUpstreamMatcher(params)
|
return sameUpstreamMatcher(params)
|
||||||
}
|
}
|
||||||
return Mono.empty()
|
return Mono.empty()
|
||||||
|
|||||||
@@ -452,7 +452,7 @@ class NativeCallSpec extends Specification {
|
|||||||
.collectList().block(Duration.ofSeconds(1)).first()
|
.collectList().block(Duration.ofSeconds(1)).first()
|
||||||
then:
|
then:
|
||||||
act instanceof NativeCall.ValidCallContext
|
act instanceof NativeCall.ValidCallContext
|
||||||
act.requestDecorator instanceof NativeCall.GetFilterUpdatesDecorator
|
act.requestDecorator instanceof NativeCall.WithFilterIdDecorator
|
||||||
}
|
}
|
||||||
|
|
||||||
def "Prepare call adds decorator for eth_uninstallFilter"() {
|
def "Prepare call adds decorator for eth_uninstallFilter"() {
|
||||||
@@ -483,7 +483,7 @@ class NativeCallSpec extends Specification {
|
|||||||
.collectList().block(Duration.ofSeconds(1)).first()
|
.collectList().block(Duration.ofSeconds(1)).first()
|
||||||
then:
|
then:
|
||||||
act instanceof NativeCall.ValidCallContext
|
act instanceof NativeCall.ValidCallContext
|
||||||
act.requestDecorator instanceof NativeCall.GetFilterUpdatesDecorator
|
act.requestDecorator instanceof NativeCall.WithFilterIdDecorator
|
||||||
}
|
}
|
||||||
|
|
||||||
def "Parse empty params"() {
|
def "Parse empty params"() {
|
||||||
@@ -543,7 +543,7 @@ class NativeCallSpec extends Specification {
|
|||||||
def nativeCall = nativeCall()
|
def nativeCall = nativeCall()
|
||||||
def ctx = new NativeCall.ValidCallContext(1, null, Stub(Multistream), Selector.empty, new AlwaysQuorum(),
|
def ctx = new NativeCall.ValidCallContext(1, null, Stub(Multistream), Selector.empty, new AlwaysQuorum(),
|
||||||
new NativeCall.RawCallDetails("eth_getFilterUpdates", '["0xabcd"]'),
|
new NativeCall.RawCallDetails("eth_getFilterUpdates", '["0xabcd"]'),
|
||||||
new NativeCall.GetFilterUpdatesDecorator(), new NativeCall.NoneResultDecorator())
|
new NativeCall.WithFilterIdDecorator(), new NativeCall.NoneResultDecorator())
|
||||||
when:
|
when:
|
||||||
def act = nativeCall.parseParams(ctx)
|
def act = nativeCall.parseParams(ctx)
|
||||||
then:
|
then:
|
||||||
@@ -564,7 +564,7 @@ class NativeCallSpec extends Specification {
|
|||||||
}
|
}
|
||||||
def call = new NativeCall.ValidCallContext(1, 10, TestingCommons.multistream(TestingCommons.api()), Selector.empty, quorum,
|
def call = new NativeCall.ValidCallContext(1, 10, TestingCommons.multistream(TestingCommons.api()), Selector.empty, quorum,
|
||||||
new NativeCall.ParsedCallDetails("eth_getFilterChanges", []),
|
new NativeCall.ParsedCallDetails("eth_getFilterChanges", []),
|
||||||
new NativeCall.GetFilterUpdatesDecorator(), new NativeCall.CreateFilterDecorator())
|
new NativeCall.WithFilterIdDecorator(), new NativeCall.CreateFilterDecorator())
|
||||||
|
|
||||||
when:
|
when:
|
||||||
def resp = nativeCall.executeOnRemote(call).block(Duration.ofSeconds(1))
|
def resp = nativeCall.executeOnRemote(call).block(Duration.ofSeconds(1))
|
||||||
@@ -586,7 +586,7 @@ class NativeCallSpec extends Specification {
|
|||||||
}
|
}
|
||||||
def call = new NativeCall.ValidCallContext(1, 10, TestingCommons.multistream(TestingCommons.api()), Selector.empty, quorum,
|
def call = new NativeCall.ValidCallContext(1, 10, TestingCommons.multistream(TestingCommons.api()), Selector.empty, quorum,
|
||||||
new NativeCall.ParsedCallDetails("eth_getFilterChanges", []),
|
new NativeCall.ParsedCallDetails("eth_getFilterChanges", []),
|
||||||
new NativeCall.GetFilterUpdatesDecorator(), new NativeCall.CreateFilterDecorator())
|
new NativeCall.WithFilterIdDecorator(), new NativeCall.CreateFilterDecorator())
|
||||||
|
|
||||||
when:
|
when:
|
||||||
def resp = nativeCall.executeOnRemote(call).block(Duration.ofSeconds(1))
|
def resp = nativeCall.executeOnRemote(call).block(Duration.ofSeconds(1))
|
||||||
|
|||||||
Reference in New Issue
Block a user