Autodetect methods (#562)
* Autodetect methods * add polkadot magic method detection * fix lint * change config.methods writing * fix log * change Flux to Mono.zip * change block to subscribe * split chain method detectors * eth method detector use rpc_modules * rm UpstreamRpcModulesDetector.kt * add tests * getAllMethods for eth * prefer enable/disable methods from config * update tests * whiter list & full is not available error check * prefer config method group * mv notAvailableRegexps to class variable
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
package io.emeraldpay.dshackle.upstream.ethereum
|
||||
|
||||
import io.emeraldpay.dshackle.Chain
|
||||
import io.emeraldpay.dshackle.config.UpstreamsConfig
|
||||
import io.emeraldpay.dshackle.reader.ChainReader
|
||||
import io.emeraldpay.dshackle.upstream.ChainCallError
|
||||
import io.emeraldpay.dshackle.upstream.ChainRequest
|
||||
import io.emeraldpay.dshackle.upstream.ChainResponse
|
||||
import io.emeraldpay.dshackle.upstream.Upstream
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import org.assertj.core.api.Assertions
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.mockito.kotlin.doReturn
|
||||
import org.mockito.kotlin.mock
|
||||
import reactor.core.publisher.Mono
|
||||
|
||||
class BasicEthUpstreamRpcMethodsDetectorTest {
|
||||
@Test
|
||||
fun `rpc_modules without web3 and eth_getBlockReceipts`() {
|
||||
val reader =
|
||||
mock<ChainReader> {
|
||||
on {
|
||||
read(ChainRequest("rpc_modules", ListParams()))
|
||||
} doReturn
|
||||
Mono.just(
|
||||
ChainResponse(
|
||||
"""{"net": "1.0","debug": "1.0","txpool": "1.0","drpc": "1.0","erigon": "1.0","eth": "1.0","trace": "1.0"}"""
|
||||
.toByteArray(),
|
||||
null,
|
||||
),
|
||||
)
|
||||
on {
|
||||
read(ChainRequest("eth_getBlockReceipts", ListParams("latest")))
|
||||
} doReturn
|
||||
Mono.just(
|
||||
ChainResponse(
|
||||
"""[{"blockHash": "0xd12897f54acaa79f4824aa4f8e1d0f045b5568f5b942073555e9977202c5c474","blockNumber": "0x13c1108"}]"""
|
||||
.toByteArray(),
|
||||
null,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
val upstream =
|
||||
mock<Upstream> {
|
||||
on { getIngressReader() } doReturn reader
|
||||
on { getChain() } doReturn Chain.ETHEREUM__MAINNET
|
||||
}
|
||||
val config = mock<UpstreamsConfig.Upstream<*>> { }
|
||||
val detector = BasicEthUpstreamRpcMethodsDetector(upstream, config)
|
||||
Assertions.assertThat(detector.detectRpcMethods().block()).apply {
|
||||
isNotNull()
|
||||
size().isGreaterThanOrEqualTo(2)
|
||||
containsEntry("web3_clientVersion", false)
|
||||
containsValues(true)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `rpc_modules disabled and eth_getBlockReceipts`() {
|
||||
val reader =
|
||||
mock<ChainReader> {
|
||||
on {
|
||||
read(ChainRequest("rpc_modules", ListParams()))
|
||||
} doReturn
|
||||
Mono.just(
|
||||
ChainResponse(
|
||||
null,
|
||||
ChainCallError(32601, "the method rpc_modules does not exist/is not available"),
|
||||
),
|
||||
)
|
||||
on {
|
||||
read(ChainRequest("eth_getBlockReceipts", ListParams("latest")))
|
||||
} doReturn
|
||||
Mono.just(
|
||||
ChainResponse(
|
||||
"""[{"blockHash": "0xd12897f54acaa79f4824aa4f8e1d0f045b5568f5b942073555e9977202c5c474","blockNumber": "0x13c1108"}]"""
|
||||
.toByteArray(),
|
||||
null,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
val upstream =
|
||||
mock<Upstream> {
|
||||
on { getIngressReader() } doReturn reader
|
||||
on { getChain() } doReturn Chain.ETHEREUM__MAINNET
|
||||
}
|
||||
val config = mock<UpstreamsConfig.Upstream<*>> { }
|
||||
val detector = BasicEthUpstreamRpcMethodsDetector(upstream, config)
|
||||
Assertions.assertThat(detector.detectRpcMethods().block()).apply {
|
||||
isNotNull()
|
||||
hasSize(1)
|
||||
containsEntry("eth_getBlockReceipts", true)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `prefer local config methods group`() {
|
||||
val reader =
|
||||
mock<ChainReader> {
|
||||
on {
|
||||
read(ChainRequest("rpc_modules", ListParams()))
|
||||
} doReturn
|
||||
Mono.just(
|
||||
ChainResponse(
|
||||
"""{"net": "1.0","debug": "1.0","txpool": "1.0","drpc": "1.0","erigon": "1.0","eth": "1.0","trace": "1.0"}"""
|
||||
.toByteArray(),
|
||||
null,
|
||||
),
|
||||
)
|
||||
on {
|
||||
read(ChainRequest("eth_getBlockReceipts", ListParams("latest")))
|
||||
} doReturn
|
||||
Mono.just(
|
||||
ChainResponse(
|
||||
"""[{"blockHash": "0xd12897f54acaa79f4824aa4f8e1d0f045b5568f5b942073555e9977202c5c474","blockNumber": "0x13c1108"}]"""
|
||||
.toByteArray(),
|
||||
null,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
val upstream =
|
||||
mock<Upstream> {
|
||||
on { getIngressReader() } doReturn reader
|
||||
on { getChain() } doReturn Chain.ETHEREUM__MAINNET
|
||||
}
|
||||
val config =
|
||||
mock<UpstreamsConfig.Upstream<*>> {
|
||||
on { methodGroups } doReturn
|
||||
UpstreamsConfig.MethodGroups(
|
||||
emptySet(),
|
||||
setOf("eth"),
|
||||
)
|
||||
}
|
||||
val detector = BasicEthUpstreamRpcMethodsDetector(upstream, config)
|
||||
Assertions.assertThat(detector.detectRpcMethods().block()).apply {
|
||||
isNotNull()
|
||||
containsEntry("eth_getBlockByNumber", false)
|
||||
containsEntry("eth_getBlockReceipts", true)
|
||||
containsEntry("debug_traceBlock", true)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package io.emeraldpay.dshackle.upstream.polkadot
|
||||
|
||||
import io.emeraldpay.dshackle.Chain
|
||||
import io.emeraldpay.dshackle.reader.ChainReader
|
||||
import io.emeraldpay.dshackle.upstream.ChainCallError
|
||||
import io.emeraldpay.dshackle.upstream.ChainRequest
|
||||
import io.emeraldpay.dshackle.upstream.ChainResponse
|
||||
import io.emeraldpay.dshackle.upstream.Upstream
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import org.assertj.core.api.Assertions
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.mockito.kotlin.doReturn
|
||||
import org.mockito.kotlin.mock
|
||||
import reactor.core.publisher.Mono
|
||||
|
||||
class BasicPolkadotUpstreamRpcMethodsDetectorTest {
|
||||
@Test
|
||||
fun `rpc_methods enabled`() {
|
||||
val reader =
|
||||
mock<ChainReader> {
|
||||
on {
|
||||
read(ChainRequest("rpc_methods", ListParams()))
|
||||
} doReturn
|
||||
Mono.just(
|
||||
ChainResponse(
|
||||
""" {"methods": ["account_nextIndex","archive_unstable_body","archive_unstable_call"]}"""
|
||||
.toByteArray(),
|
||||
null,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
val upstream =
|
||||
mock<Upstream> {
|
||||
on { getIngressReader() } doReturn reader
|
||||
on { getChain() } doReturn Chain.POLKADOT__MAINNET
|
||||
}
|
||||
val detector = BasicPolkadotUpstreamRpcMethodsDetector(upstream)
|
||||
Assertions.assertThat(detector.detectRpcMethods().block()).apply {
|
||||
isNotNull()
|
||||
hasSize(3)
|
||||
containsKeys("account_nextIndex", "archive_unstable_body", "archive_unstable_call")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `rpc_methods disabled`() {
|
||||
val reader =
|
||||
mock<ChainReader> {
|
||||
on {
|
||||
read(ChainRequest("rpc_methods", ListParams()))
|
||||
} doReturn
|
||||
Mono.just(
|
||||
ChainResponse(
|
||||
null,
|
||||
ChainCallError(32601, "the method rpc_methods does not exist/is not available"),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
val upstream =
|
||||
mock<Upstream> {
|
||||
on { getIngressReader() } doReturn reader
|
||||
on { getChain() } doReturn Chain.POLKADOT__MAINNET
|
||||
}
|
||||
val detector = BasicPolkadotUpstreamRpcMethodsDetector(upstream)
|
||||
Assertions.assertThat(detector.detectRpcMethods().block()).isNull()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user