solution: hardcode some methods for ethereum
This commit is contained in:
@@ -23,29 +23,7 @@ class NativeCall(
|
|||||||
|
|
||||||
private val log = LoggerFactory.getLogger(NativeCall::class.java)
|
private val log = LoggerFactory.getLogger(NativeCall::class.java)
|
||||||
|
|
||||||
private val allowedMethods = listOf(
|
|
||||||
"eth_gasPrice",
|
|
||||||
"eth_blockNumber",
|
|
||||||
"eth_getBalance",
|
|
||||||
"eth_getStorageAt",
|
|
||||||
"eth_getTransactionCount",
|
|
||||||
"eth_getBlockTransactionCountByHash",
|
|
||||||
"eth_getBlockTransactionCountByNumber",
|
|
||||||
"eth_getUncleCountByBlockHash",
|
|
||||||
"eth_getUncleCountByBlockNumber",
|
|
||||||
"eth_getCode",
|
|
||||||
"eth_sendRawTransaction",
|
|
||||||
"eth_call",
|
|
||||||
"eth_estimateGas",
|
|
||||||
"eth_getBlockByHash",
|
|
||||||
"eth_getBlockByNumber",
|
|
||||||
"eth_getTransactionByHash",
|
|
||||||
"eth_getTransactionByBlockHashAndIndex",
|
|
||||||
"eth_getTransactionByBlockNumberAndIndex",
|
|
||||||
"eth_getTransactionReceipt",
|
|
||||||
"eth_getUncleByBlockHashAndIndex",
|
|
||||||
"eth_getUncleByBlockNumberAndIndex"
|
|
||||||
)
|
|
||||||
|
|
||||||
open fun nativeCall(request: BlockchainOuterClass.CallBlockchainRequest, responseObserver: StreamObserver<BlockchainOuterClass.CallBlockchainReplyItem>) {
|
open fun nativeCall(request: BlockchainOuterClass.CallBlockchainRequest, responseObserver: StreamObserver<BlockchainOuterClass.CallBlockchainReplyItem>) {
|
||||||
val chain= Chain.byId(request.chain.number)
|
val chain= Chain.byId(request.chain.number)
|
||||||
|
|||||||
@@ -1,29 +1,75 @@
|
|||||||
package io.emeraldpay.dshackle.upstream
|
package io.emeraldpay.dshackle.upstream
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
|
import io.emeraldpay.grpc.Chain
|
||||||
import io.infinitape.etherjar.rpc.RpcCall
|
import io.infinitape.etherjar.rpc.RpcCall
|
||||||
import io.infinitape.etherjar.rpc.RpcClient
|
import io.infinitape.etherjar.rpc.RpcClient
|
||||||
import io.infinitape.etherjar.rpc.RpcException
|
import io.infinitape.etherjar.rpc.RpcException
|
||||||
import io.infinitape.etherjar.rpc.RpcResponseError
|
|
||||||
import io.infinitape.etherjar.rpc.json.ResponseJson
|
import io.infinitape.etherjar.rpc.json.ResponseJson
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import reactor.core.publisher.Mono
|
import reactor.core.publisher.Mono
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
class EthereumUpstream(
|
class EthereumUpstream(
|
||||||
private val rpcClient: RpcClient,
|
private val rpcClient: RpcClient,
|
||||||
private val objectMapper: ObjectMapper
|
private val objectMapper: ObjectMapper,
|
||||||
|
private val chain: Chain
|
||||||
) {
|
) {
|
||||||
|
|
||||||
private val timeout = Duration.ofSeconds(5)
|
private val timeout = Duration.ofSeconds(5)
|
||||||
private val log = LoggerFactory.getLogger(EthereumUpstream::class.java)
|
private val log = LoggerFactory.getLogger(EthereumUpstream::class.java)
|
||||||
|
|
||||||
|
private val allowedMethods = listOf(
|
||||||
|
"eth_gasPrice",
|
||||||
|
"eth_blockNumber",
|
||||||
|
"eth_getBalance",
|
||||||
|
"eth_getStorageAt",
|
||||||
|
"eth_getTransactionCount",
|
||||||
|
"eth_getBlockTransactionCountByHash",
|
||||||
|
"eth_getBlockTransactionCountByNumber",
|
||||||
|
"eth_getUncleCountByBlockHash",
|
||||||
|
"eth_getUncleCountByBlockNumber",
|
||||||
|
"eth_getCode",
|
||||||
|
"eth_sendRawTransaction",
|
||||||
|
"eth_call",
|
||||||
|
"eth_estimateGas",
|
||||||
|
"eth_getBlockByHash",
|
||||||
|
"eth_getBlockByNumber",
|
||||||
|
"eth_getTransactionByHash",
|
||||||
|
"eth_getTransactionByBlockHashAndIndex",
|
||||||
|
"eth_getTransactionByBlockNumberAndIndex",
|
||||||
|
"eth_getTransactionReceipt",
|
||||||
|
"eth_getUncleByBlockHashAndIndex",
|
||||||
|
"eth_getUncleByBlockNumberAndIndex"
|
||||||
|
)
|
||||||
|
|
||||||
|
private val hardcodedMethods = listOf(
|
||||||
|
"net_version",
|
||||||
|
"net_peerCount",
|
||||||
|
"net_listening",
|
||||||
|
"web3_clientVersion",
|
||||||
|
"eth_protocolVersion",
|
||||||
|
"eth_syncing",
|
||||||
|
"eth_coinbase",
|
||||||
|
"eth_mining",
|
||||||
|
"eth_hashrate",
|
||||||
|
"eth_accounts"
|
||||||
|
)
|
||||||
|
|
||||||
fun execute(id: Int, method: String, params: List<Any>): Mono<ByteArray> {
|
fun execute(id: Int, method: String, params: List<Any>): Mono<ByteArray> {
|
||||||
return Mono
|
val result: Mono<Any> = if (hardcodedMethods.contains(method)) {
|
||||||
.fromCompletionStage(
|
Mono.just(method)
|
||||||
|
.map{ hardcoded(it) }
|
||||||
|
} else if (allowedMethods.contains(method)) {
|
||||||
|
Mono.fromCompletionStage(
|
||||||
rpcClient.execute(RpcCall.create(method, Any::class.java, params))
|
rpcClient.execute(RpcCall.create(method, Any::class.java, params))
|
||||||
)
|
)
|
||||||
.timeout(timeout)
|
.timeout(timeout)
|
||||||
|
} else {
|
||||||
|
Mono.error(RpcException(-32601, "Method not allowed or not found"))
|
||||||
|
}
|
||||||
|
return result
|
||||||
.doOnError { t ->
|
.doOnError { t ->
|
||||||
log.warn("Upstream error: ${t.message}")
|
log.warn("Upstream error: ${t.message}")
|
||||||
}
|
}
|
||||||
@@ -49,4 +95,46 @@ class EthereumUpstream(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun hardcoded(method: String): Any {
|
||||||
|
if ("net_version" == method) {
|
||||||
|
if (Chain.ETHEREUM == chain) {
|
||||||
|
return "1"
|
||||||
|
}
|
||||||
|
if (Chain.ETHEREUM_CLASSIC == chain) {
|
||||||
|
return "1"
|
||||||
|
}
|
||||||
|
if (Chain.MORDEN == chain) {
|
||||||
|
return "2"
|
||||||
|
}
|
||||||
|
throw RpcException(-32602, "Invalid chain")
|
||||||
|
}
|
||||||
|
if ("net_peerCount" == method) {
|
||||||
|
return "0x2a"
|
||||||
|
}
|
||||||
|
if ("net_listening" == method) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if ("web3_clientVersion" == method) {
|
||||||
|
return "EmeraldDshackle/v0.1"
|
||||||
|
}
|
||||||
|
if ("eth_protocolVersion" == method) {
|
||||||
|
return "0x3f"
|
||||||
|
}
|
||||||
|
if ("eth_syncing" == method) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if ("eth_coinbase" == method) {
|
||||||
|
return "0x0000000000000000000000000000000000000000"
|
||||||
|
}
|
||||||
|
if ("eth_mining" == method) {
|
||||||
|
return "false"
|
||||||
|
}
|
||||||
|
if ("eth_hashrate" == method) {
|
||||||
|
return "0x0"
|
||||||
|
}
|
||||||
|
if ("eth_accounts" == method) {
|
||||||
|
return Collections.emptyList<String>()
|
||||||
|
}
|
||||||
|
throw RpcException(-32601, "Method not found")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -22,20 +22,21 @@ class Upstreams(
|
|||||||
@PostConstruct
|
@PostConstruct
|
||||||
fun start() {
|
fun start() {
|
||||||
env.getProperty("upstream.ethereum")?.let {
|
env.getProperty("upstream.ethereum")?.let {
|
||||||
chainMapping[Chain.ETHEREUM] = listOf(buildClient(it))
|
chainMapping[Chain.ETHEREUM] = listOf(buildClient(it, Chain.ETHEREUM))
|
||||||
}
|
}
|
||||||
env.getProperty("upstream.ethereumclassic")?.let {
|
env.getProperty("upstream.ethereumclassic")?.let {
|
||||||
chainMapping[Chain.ETHEREUM_CLASSIC] = listOf(buildClient(it))
|
chainMapping[Chain.ETHEREUM_CLASSIC] = listOf(buildClient(it, Chain.ETHEREUM_CLASSIC))
|
||||||
}
|
}
|
||||||
env.getProperty("upstream.morden")?.let {
|
env.getProperty("upstream.morden")?.let {
|
||||||
chainMapping[Chain.MORDEN] = listOf(buildClient(it))
|
chainMapping[Chain.MORDEN] = listOf(buildClient(it, Chain.MORDEN))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildClient(url: String): EthereumUpstream {
|
private fun buildClient(url: String, chain: Chain): EthereumUpstream {
|
||||||
return EthereumUpstream(
|
return EthereumUpstream(
|
||||||
DefaultRpcClient(DefaultRpcTransport(URI(url))),
|
DefaultRpcClient(DefaultRpcTransport(URI(url))),
|
||||||
objectMapper
|
objectMapper,
|
||||||
|
chain
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user