solution: describe available methods per chain
This commit is contained in:
@@ -26,12 +26,13 @@ class Describe(
|
|||||||
chainUpstreams.getAll().let { ups ->
|
chainUpstreams.getAll().let { ups ->
|
||||||
if (ups.isNotEmpty()) {
|
if (ups.isNotEmpty()) {
|
||||||
val status = subscribeStatus.chainStatus(chain, ups)
|
val status = subscribeStatus.chainStatus(chain, ups)
|
||||||
resp.addChains(
|
val targets = chainUpstreams.getSupportedTargets()
|
||||||
BlockchainOuterClass.DescribeChain.newBuilder()
|
val chainDescription = BlockchainOuterClass.DescribeChain.newBuilder()
|
||||||
.setChain(Common.ChainRef.forNumber(chain.id))
|
.setChain(Common.ChainRef.forNumber(chain.id))
|
||||||
.setStatus(status)
|
.addAllSupportedTargets(targets)
|
||||||
.build()
|
.setStatus(status)
|
||||||
)
|
.build()
|
||||||
|
resp.addChains(chainDescription)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ class NativeCall(
|
|||||||
if (chain == Chain.UNSPECIFIED) {
|
if (chain == Chain.UNSPECIFIED) {
|
||||||
throw Exception("Invalid chain id: ${request.chain.number}")
|
throw Exception("Invalid chain id: ${request.chain.number}")
|
||||||
}
|
}
|
||||||
|
// TODO send error to all requests?
|
||||||
val upstream = upstreams.getUpstream(chain)?.getApi() ?: throw Exception("Chain ${chain.id} is unavailable")
|
val upstream = upstreams.getUpstream(chain)?.getApi() ?: throw Exception("Chain ${chain.id} is unavailable")
|
||||||
request.itemsList.toFlux().map {
|
request.itemsList.toFlux().map {
|
||||||
val method = it.target
|
val method = it.target
|
||||||
|
|||||||
@@ -20,6 +20,14 @@ abstract class AggregatedUpstreams: Upstream {
|
|||||||
.map { it.status }
|
.map { it.status }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getSupportedTargets(): Set<String> {
|
||||||
|
val list = HashSet<String>()
|
||||||
|
getAll().forEach {
|
||||||
|
list.addAll(it.getSupportedTargets())
|
||||||
|
}
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
override fun isAvailable(): Boolean {
|
override fun isAvailable(): Boolean {
|
||||||
return getAll().any { it.isAvailable() }
|
return getAll().any { it.isAvailable() }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -167,4 +167,8 @@ open class EthereumApi(
|
|||||||
}
|
}
|
||||||
throw RpcException(-32601, "Method not found")
|
throw RpcException(-32601, "Method not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getSupportedMethods(): Set<String> {
|
||||||
|
return allowedMethods.plus(hardcodedMethods).toSortedSet()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -16,6 +16,10 @@ class EthereumUpstream(
|
|||||||
private val options: UpstreamsConfig.Options
|
private val options: UpstreamsConfig.Options
|
||||||
): Upstream {
|
): Upstream {
|
||||||
|
|
||||||
|
override fun getSupportedTargets(): Set<String> {
|
||||||
|
return api.getSupportedMethods()
|
||||||
|
}
|
||||||
|
|
||||||
private val log = LoggerFactory.getLogger(EthereumUpstream::class.java)
|
private val log = LoggerFactory.getLogger(EthereumUpstream::class.java)
|
||||||
|
|
||||||
private val head: EthereumHead = if (ethereumWs != null) {
|
private val head: EthereumHead = if (ethereumWs != null) {
|
||||||
|
|||||||
@@ -20,8 +20,10 @@ import reactor.core.publisher.toMono
|
|||||||
import java.lang.Exception
|
import java.lang.Exception
|
||||||
import java.math.BigInteger
|
import java.math.BigInteger
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
|
import java.util.*
|
||||||
import java.util.concurrent.atomic.AtomicReference
|
import java.util.concurrent.atomic.AtomicReference
|
||||||
import java.util.function.Function
|
import java.util.function.Function
|
||||||
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
open class GrpcUpstream(
|
open class GrpcUpstream(
|
||||||
private val chain: Chain,
|
private val chain: Chain,
|
||||||
@@ -41,6 +43,7 @@ open class GrpcUpstream(
|
|||||||
private val head = Head(this)
|
private val head = Head(this)
|
||||||
private val api: EthereumApi
|
private val api: EthereumApi
|
||||||
private val statusStream: TopicProcessor<UpstreamAvailability> = TopicProcessor.create()
|
private val statusStream: TopicProcessor<UpstreamAvailability> = TopicProcessor.create()
|
||||||
|
private val supportedMethods = HashSet<String>()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val grpcTransport = EthereumGrpcTransport(chain, client, objectMapper)
|
val grpcTransport = EthereumGrpcTransport(chain, client, objectMapper)
|
||||||
@@ -93,6 +96,7 @@ open class GrpcUpstream(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun init(conf: BlockchainOuterClass.DescribeChain) {
|
fun init(conf: BlockchainOuterClass.DescribeChain) {
|
||||||
|
supportedMethods.addAll(conf.supportedTargetsList)
|
||||||
conf.status?.let { status -> onStatus(status) }
|
conf.status?.let { status -> onStatus(status) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,6 +114,9 @@ open class GrpcUpstream(
|
|||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
override fun getSupportedTargets(): Set<String> {
|
||||||
|
return supportedMethods
|
||||||
|
}
|
||||||
|
|
||||||
override fun isAvailable(): Boolean {
|
override fun isAvailable(): Boolean {
|
||||||
return headBlock.get() != null
|
return headBlock.get() != null
|
||||||
|
|||||||
@@ -56,6 +56,9 @@ class GrpcUpstreams(
|
|||||||
}
|
}
|
||||||
chains as List<Chain>
|
chains as List<Chain>
|
||||||
}
|
}
|
||||||
|
.doOnError { t ->
|
||||||
|
log.error("Failed to get description from $host:$port", t)
|
||||||
|
}
|
||||||
//TODO subscribe only after receiving details
|
//TODO subscribe only after receiving details
|
||||||
client.subscribeStatus(BlockchainOuterClass.StatusRequest.newBuilder().build())
|
client.subscribeStatus(BlockchainOuterClass.StatusRequest.newBuilder().build())
|
||||||
.subscribe { value ->
|
.subscribe { value ->
|
||||||
|
|||||||
@@ -10,4 +10,5 @@ interface Upstream {
|
|||||||
fun getHead(): EthereumHead
|
fun getHead(): EthereumHead
|
||||||
fun getApi(): EthereumApi
|
fun getApi(): EthereumApi
|
||||||
fun getOptions(): UpstreamsConfig.Options
|
fun getOptions(): UpstreamsConfig.Options
|
||||||
|
fun getSupportedTargets(): Set<String>
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user