fix managed methods reusing old quorums
This commit is contained in:
@@ -229,7 +229,7 @@ open class NativeCall(
|
||||
.forMethod(method)
|
||||
.forLabels(Selector.convertToMatcher(request.selector))
|
||||
|
||||
val callQuorum = availableMethods.getQuorumFor(method) // can be null in tests
|
||||
val callQuorum = availableMethods.createQuorumFor(method) // can be null in tests
|
||||
callQuorum.init(upstream.getHead())
|
||||
|
||||
// for NotLaggingQuorum it makes sense to select compatible upstreams before the call
|
||||
|
||||
@@ -37,10 +37,10 @@ class AggregatedCallMethods(
|
||||
/**
|
||||
* Finds first delegate that has Allowed that method and returns its Quorum
|
||||
*/
|
||||
override fun getQuorumFor(method: String): CallQuorum {
|
||||
override fun createQuorumFor(method: String): CallQuorum {
|
||||
return delegates.find {
|
||||
it.isCallable(method) || it.isHardcoded(method)
|
||||
}?.getQuorumFor(method) ?: throw IllegalStateException("No executor delegate for $method")
|
||||
}?.createQuorumFor(method) ?: throw IllegalStateException("No executor delegate for $method")
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,9 +24,11 @@ import io.emeraldpay.dshackle.quorum.CallQuorum
|
||||
interface CallMethods {
|
||||
|
||||
/**
|
||||
* For a stateful CallQuorum it _MUST CREATE_ a new instance of each time to avoid using a shared state between different requests
|
||||
*
|
||||
* @return CallQuorum configured for the specified method
|
||||
*/
|
||||
fun getQuorumFor(method: String): CallQuorum
|
||||
fun createQuorumFor(method: String): CallQuorum
|
||||
|
||||
/**
|
||||
* Check if the method can be called on an upstream. Doesn't include Hardcoded methods
|
||||
|
||||
@@ -59,7 +59,7 @@ class DefaultBitcoinMethods : CallMethods {
|
||||
private val allowedMethods =
|
||||
(freshMethods + anyResponseMethods + headVerifiedMethods + broadcastMethods).sorted()
|
||||
|
||||
override fun getQuorumFor(method: String): CallQuorum {
|
||||
override fun createQuorumFor(method: String): CallQuorum {
|
||||
return when {
|
||||
Collections.binarySearch(hardcodedMethods, method) >= 0 -> AlwaysQuorum()
|
||||
Collections.binarySearch(anyResponseMethods, method) >= 0 -> NonEmptyQuorum()
|
||||
|
||||
@@ -112,7 +112,7 @@ class DefaultEthereumMethods(
|
||||
getChainSpecificMethods(chain)
|
||||
}
|
||||
|
||||
override fun getQuorumFor(method: String): CallQuorum {
|
||||
override fun createQuorumFor(method: String): CallQuorum {
|
||||
return when {
|
||||
filterMethods.contains(method) -> NotLaggingQuorum(1)
|
||||
hardcodedMethods.contains(method) -> AlwaysQuorum()
|
||||
|
||||
@@ -28,7 +28,7 @@ open class DirectCallMethods(private val methods: Set<String>) : CallMethods {
|
||||
constructor() : this(emptySet())
|
||||
constructor(methods: Collection<String>) : this(methods.toSet())
|
||||
|
||||
override fun getQuorumFor(method: String): CallQuorum {
|
||||
override fun createQuorumFor(method: String): CallQuorum {
|
||||
return AlwaysQuorum()
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ class EthereumCallSelector(
|
||||
"eth_getBalance",
|
||||
"eth_getCode",
|
||||
"eth_getTransactionCount",
|
||||
// no "eth_getStorageAt" because it's has different structure, and therefore separate logic
|
||||
// no "eth_getStorageAt" because it has different structure, and therefore separate logic
|
||||
"eth_call"
|
||||
).sorted()
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import io.emeraldpay.dshackle.quorum.AlwaysQuorum
|
||||
import io.emeraldpay.dshackle.quorum.CallQuorum
|
||||
import io.emeraldpay.dshackle.quorum.NonEmptyQuorum
|
||||
import io.emeraldpay.dshackle.quorum.NotLaggingQuorum
|
||||
import org.apache.commons.collections4.Factory
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.io.IOException
|
||||
import java.util.Collections
|
||||
@@ -38,14 +39,16 @@ class ManagedCallMethods(
|
||||
|
||||
companion object {
|
||||
private val log = LoggerFactory.getLogger(ManagedCallMethods::class.java)
|
||||
private val defaultQuorum = AlwaysQuorum()
|
||||
private val defaultQuorum: Factory<CallQuorum> = Factory<CallQuorum> {
|
||||
AlwaysQuorum()
|
||||
}
|
||||
}
|
||||
|
||||
private val delegated = delegate.getSupportedMethods().sorted()
|
||||
private val allAllowed: Set<String> = Collections.unmodifiableSet(
|
||||
enabled + delegated - disabled
|
||||
)
|
||||
private val quorum: MutableMap<String, CallQuorum> = HashMap()
|
||||
private val quorum: MutableMap<String, Factory<CallQuorum>> = HashMap()
|
||||
private val staticResponse: MutableMap<String, String> = HashMap()
|
||||
private val redefined = delegated.filter(enabled::contains).sorted()
|
||||
|
||||
@@ -57,9 +60,9 @@ class ManagedCallMethods(
|
||||
|
||||
fun setQuorum(method: String, quorumId: String) {
|
||||
val quorum = when (quorumId) {
|
||||
"always" -> AlwaysQuorum()
|
||||
"no-lag", "not-lagging", "no_lag", "not_lagging" -> NotLaggingQuorum(0)
|
||||
"not-empty", "not_empty", "non-empty", "non_empty" -> NonEmptyQuorum()
|
||||
"always" -> Factory<CallQuorum> { AlwaysQuorum() }
|
||||
"no-lag", "not-lagging", "no_lag", "not_lagging" -> Factory<CallQuorum> { NotLaggingQuorum(0) }
|
||||
"not-empty", "not_empty", "non-empty", "non_empty" -> Factory<CallQuorum> { NonEmptyQuorum() }
|
||||
else -> {
|
||||
log.warn("Unknown quorum: $quorumId for custom method $method")
|
||||
return
|
||||
@@ -72,13 +75,13 @@ class ManagedCallMethods(
|
||||
this.staticResponse[method] = response
|
||||
}
|
||||
|
||||
override fun getQuorumFor(method: String): CallQuorum {
|
||||
override fun createQuorumFor(method: String): CallQuorum {
|
||||
return when {
|
||||
isDelegated(method) && !isRedefined(method) -> delegate.getQuorumFor(method)
|
||||
enabled.contains(method) -> quorum[method] ?: defaultQuorum
|
||||
isDelegated(method) && !isRedefined(method) -> delegate.createQuorumFor(method)
|
||||
enabled.contains(method) -> quorum[method]?.create() ?: defaultQuorum.create()
|
||||
else -> {
|
||||
log.warn("Getting quorum for unknown method")
|
||||
defaultQuorum
|
||||
defaultQuorum.create()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,8 +132,12 @@ class EthereumDirectReader(
|
||||
*/
|
||||
private fun readWithQuorum(request: JsonRpcRequest): Mono<ByteArray> {
|
||||
return quorumReaderFactory
|
||||
// we do not use Signer for internal requests because it doesn't make much sense
|
||||
.create(up.getApiSource(Selector.empty), callMethodsFactory.create().getQuorumFor(request.method), null)
|
||||
.create(
|
||||
up.getApiSource(Selector.empty),
|
||||
callMethodsFactory.create().createQuorumFor(request.method),
|
||||
// we do not use Signer for internal requests because it doesn't make much sense
|
||||
null
|
||||
)
|
||||
.read(request)
|
||||
.map { it.value }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user