problem: eth_chainId is not available
This commit is contained in:
@@ -163,7 +163,7 @@ open class NativeCall(
|
||||
val params = requestItem.payload.toStringUtf8()
|
||||
val availableMethods = upstream.getMethods()
|
||||
|
||||
if (!availableMethods.isAllowed(method)) {
|
||||
if (!availableMethods.isAvailable(method)) {
|
||||
val errorMessage = "The method $method does not exist/is not available"
|
||||
return Mono.just(
|
||||
InvalidCallContext(
|
||||
@@ -222,7 +222,7 @@ open class NativeCall(
|
||||
}
|
||||
|
||||
fun executeOnRemote(ctx: ValidCallContext<ParsedCallDetails>): Mono<CallResult> {
|
||||
if (!ctx.upstream.getMethods().isAllowed(ctx.payload.method)) {
|
||||
if (!ctx.upstream.getMethods().isCallable(ctx.payload.method)) {
|
||||
return Mono.error(RpcException(RpcResponseError.CODE_METHOD_NOT_EXIST, "Unsupported method"))
|
||||
}
|
||||
val reader = quorumReaderFactory.create(ctx.getApis(), ctx.callQuorum)
|
||||
|
||||
@@ -157,7 +157,7 @@ class Selector {
|
||||
val method: String
|
||||
) : Matcher {
|
||||
override fun matches(up: Upstream): Boolean {
|
||||
return up.getMethods().isAllowed(method)
|
||||
return up.getMethods().isCallable(method)
|
||||
}
|
||||
|
||||
override fun describeInternal(): String {
|
||||
|
||||
@@ -44,7 +44,7 @@ class LocalCallRouter(
|
||||
return Mono.just(methods.executeHardcoded(key.method))
|
||||
.map { JsonRpcResponse(it, null) }
|
||||
}
|
||||
if (!methods.isAllowed(key.method)) {
|
||||
if (!methods.isCallable(key.method)) {
|
||||
return Mono.error(RpcException(RpcResponseError.CODE_METHOD_NOT_EXIST, "Unsupported method"))
|
||||
}
|
||||
return Mono.empty()
|
||||
|
||||
@@ -39,15 +39,15 @@ class AggregatedCallMethods(
|
||||
*/
|
||||
override fun getQuorumFor(method: String): CallQuorum {
|
||||
return delegates.find {
|
||||
it.isAllowed(method) || it.isHardcoded(method)
|
||||
it.isCallable(method) || it.isHardcoded(method)
|
||||
}?.getQuorumFor(method) ?: throw IllegalStateException("No executor delegate for $method")
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if ANY of delegates supports the method
|
||||
*/
|
||||
override fun isAllowed(method: String): Boolean {
|
||||
return delegates.any { it.isAllowed(method) }
|
||||
override fun isCallable(method: String): Boolean {
|
||||
return delegates.any { it.isCallable(method) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,9 +29,13 @@ interface CallMethods {
|
||||
fun getQuorumFor(method: String): CallQuorum
|
||||
|
||||
/**
|
||||
* @return false is call for that method is not allowed. Allowed method may be also Hardcoded
|
||||
* Check if the method can be called on an upstream. Doesn't include Hardcoded methods
|
||||
*
|
||||
* @return false if call for that method is not allowed.
|
||||
* @see isHardcoded
|
||||
* @see isAvailable
|
||||
*/
|
||||
fun isAllowed(method: String): Boolean
|
||||
fun isCallable(method: String): Boolean
|
||||
|
||||
/**
|
||||
* @return list of all allowed methods.
|
||||
@@ -47,4 +51,11 @@ interface CallMethods {
|
||||
* Read [supposed to be predefined] method from this config
|
||||
*/
|
||||
fun executeHardcoded(method: String): ByteArray
|
||||
|
||||
/**
|
||||
* Check if the method is available either by an upstream or as a hardcoded response
|
||||
*/
|
||||
fun isAvailable(method: String): Boolean {
|
||||
return isCallable(method) || isHardcoded(method)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ class DefaultBitcoinMethods : CallMethods {
|
||||
).sorted()
|
||||
|
||||
private val allowedMethods =
|
||||
(freshMethods + anyResponseMethods + headVerifiedMethods + hardcodedMethods + broadcastMethods).sorted()
|
||||
(freshMethods + anyResponseMethods + headVerifiedMethods + broadcastMethods).sorted()
|
||||
|
||||
override fun getQuorumFor(method: String): CallQuorum {
|
||||
return when {
|
||||
@@ -70,12 +70,12 @@ class DefaultBitcoinMethods : CallMethods {
|
||||
}
|
||||
}
|
||||
|
||||
override fun isAllowed(method: String): Boolean {
|
||||
override fun isCallable(method: String): Boolean {
|
||||
return Collections.binarySearch(allowedMethods, method) >= 0
|
||||
}
|
||||
|
||||
override fun getSupportedMethods(): Set<String> {
|
||||
return allowedMethods.toSortedSet()
|
||||
return allowedMethods.plus(hardcodedMethods).toSortedSet()
|
||||
}
|
||||
|
||||
override fun isHardcoded(method: String): Boolean {
|
||||
|
||||
@@ -104,7 +104,7 @@ class DefaultEthereumMethods(
|
||||
}
|
||||
}
|
||||
|
||||
override fun isAllowed(method: String): Boolean {
|
||||
override fun isCallable(method: String): Boolean {
|
||||
return allowedMethods.contains(method)
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ open class DirectCallMethods(private val methods: Set<String>) : CallMethods {
|
||||
return AlwaysQuorum()
|
||||
}
|
||||
|
||||
override fun isAllowed(method: String): Boolean {
|
||||
override fun isCallable(method: String): Boolean {
|
||||
return methods.contains(method)
|
||||
}
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ class ManagedCallMethods(
|
||||
}
|
||||
}
|
||||
|
||||
override fun isAllowed(method: String): Boolean {
|
||||
override fun isCallable(method: String): Boolean {
|
||||
return allAllowed.contains(method)
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ class LocalCallRouter(
|
||||
return Mono.just(methods.executeHardcoded(key.method))
|
||||
.map { JsonRpcResponse(it, null) }
|
||||
}
|
||||
if (!methods.isAllowed(key.method)) {
|
||||
if (!methods.isCallable(key.method)) {
|
||||
return Mono.error(RpcException(RpcResponseError.CODE_METHOD_NOT_EXIST, "Unsupported method"))
|
||||
}
|
||||
val common = commonRequests(key)
|
||||
|
||||
@@ -45,9 +45,9 @@ class MultistreamSpec extends Specification {
|
||||
aggr.onUpstreamsUpdated()
|
||||
def act = aggr.getMethods()
|
||||
then:
|
||||
act.isAllowed("eth_test1")
|
||||
act.isAllowed("eth_test2")
|
||||
act.isAllowed("eth_test3")
|
||||
act.isCallable("eth_test1")
|
||||
act.isCallable("eth_test2")
|
||||
act.isCallable("eth_test3")
|
||||
act.getQuorumFor("eth_test1") instanceof AlwaysQuorum
|
||||
act.getQuorumFor("eth_test2") instanceof AlwaysQuorum
|
||||
act.getQuorumFor("eth_test3") instanceof AlwaysQuorum
|
||||
|
||||
@@ -17,9 +17,6 @@
|
||||
package io.emeraldpay.dshackle.upstream.calls
|
||||
|
||||
import io.emeraldpay.dshackle.quorum.AlwaysQuorum
|
||||
import io.emeraldpay.dshackle.upstream.calls.AggregatedCallMethods
|
||||
import io.emeraldpay.dshackle.upstream.calls.CallMethods
|
||||
import io.emeraldpay.dshackle.upstream.calls.DirectCallMethods
|
||||
import spock.lang.Specification
|
||||
|
||||
class AggregatedCallMethodsSpec extends Specification {
|
||||
@@ -29,11 +26,11 @@ class AggregatedCallMethodsSpec extends Specification {
|
||||
def quorum = new AlwaysQuorum()
|
||||
def delegate1 = Mock(CallMethods) {
|
||||
_ * getSupportedMethods() >> ["eth_no_test", "foo_bar"]
|
||||
1 * isAllowed("eth_test") >> false
|
||||
1 * isCallable("eth_test") >> false
|
||||
}
|
||||
def delegate2 = Mock(CallMethods) {
|
||||
_ * getSupportedMethods() >> ["eth_test", "foo_bar"]
|
||||
1 * isAllowed("eth_test") >> true
|
||||
1 * isCallable("eth_test") >> true
|
||||
1 * getQuorumFor("eth_test") >> quorum
|
||||
}
|
||||
def aggregate = new AggregatedCallMethods([delegate1, delegate2])
|
||||
@@ -49,22 +46,22 @@ class AggregatedCallMethodsSpec extends Specification {
|
||||
def delegate2 = new DirectCallMethods(["eth_test", "foo_bar"] as Set)
|
||||
def aggregate = new AggregatedCallMethods([delegate1, delegate2])
|
||||
when:
|
||||
def act = aggregate.isAllowed("eth_test")
|
||||
def act = aggregate.isCallable("eth_test")
|
||||
then:
|
||||
act
|
||||
|
||||
when:
|
||||
act = aggregate.isAllowed("eth_no_test")
|
||||
act = aggregate.isCallable("eth_no_test")
|
||||
then:
|
||||
act
|
||||
|
||||
when:
|
||||
act = aggregate.isAllowed("foo_bar")
|
||||
act = aggregate.isCallable("foo_bar")
|
||||
then:
|
||||
act
|
||||
|
||||
when:
|
||||
act = aggregate.isAllowed("nothing")
|
||||
act = aggregate.isCallable("nothing")
|
||||
then:
|
||||
!act
|
||||
}
|
||||
@@ -106,12 +103,12 @@ class AggregatedCallMethodsSpec extends Specification {
|
||||
setup:
|
||||
def delegate1 = Mock(CallMethods) {
|
||||
_ * getSupportedMethods() >> ["eth_no_test", "foo_bar"]
|
||||
_ * isAllowed(_) >> false
|
||||
_ * isCallable(_) >> false
|
||||
1 * isHardcoded("eth_no_test") >> false
|
||||
}
|
||||
def delegate2 = Mock(CallMethods) {
|
||||
_ * getSupportedMethods() >> ["eth_test", "foo_bar"]
|
||||
_ * isAllowed(_) >> false
|
||||
_ * isCallable(_) >> false
|
||||
1 * isHardcoded("eth_test") >> true
|
||||
}
|
||||
def aggregate = new AggregatedCallMethods([delegate1, delegate2])
|
||||
|
||||
@@ -5,6 +5,15 @@ import spock.lang.Specification
|
||||
|
||||
class DefaultEthereumMethodsSpec extends Specification {
|
||||
|
||||
def "eth_chainId is available"() {
|
||||
setup:
|
||||
def methods = new DefaultEthereumMethods(Chain.ETHEREUM)
|
||||
when:
|
||||
def act = methods.isAvailable("eth_chainId")
|
||||
then:
|
||||
act
|
||||
}
|
||||
|
||||
def "eth_chainId is hardcoded"() {
|
||||
setup:
|
||||
def methods = new DefaultEthereumMethods(Chain.ETHEREUM)
|
||||
@@ -14,6 +23,15 @@ class DefaultEthereumMethodsSpec extends Specification {
|
||||
act
|
||||
}
|
||||
|
||||
def "eth_chainId is not callable"() {
|
||||
setup:
|
||||
def methods = new DefaultEthereumMethods(Chain.ETHEREUM)
|
||||
when:
|
||||
def act = methods.isCallable("eth_chainId")
|
||||
then:
|
||||
!act
|
||||
}
|
||||
|
||||
def "Provides hardcoded correct chainId"() {
|
||||
expect:
|
||||
new String(new DefaultEthereumMethods(chain).executeHardcoded("eth_chainId")) == id
|
||||
|
||||
Reference in New Issue
Block a user