support object params
This commit is contained in:
@@ -43,9 +43,12 @@ import io.emeraldpay.dshackle.upstream.Selector
|
||||
import io.emeraldpay.dshackle.upstream.calls.DefaultEthereumMethods
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.rpc.RpcException
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.rpc.RpcResponseError
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.CallParams
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcError
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcException
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ObjectParams
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.stream.Chunk
|
||||
import io.emeraldpay.dshackle.upstream.signature.ResponseSigner
|
||||
import io.micrometer.core.instrument.Metrics
|
||||
@@ -472,12 +475,16 @@ open class NativeCall(
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private fun extractParams(jsonParams: String): List<Any> {
|
||||
private fun extractParams(jsonParams: String): CallParams {
|
||||
if (StringUtils.isEmpty(jsonParams) || jsonParams == "null") {
|
||||
return emptyList()
|
||||
return ListParams()
|
||||
}
|
||||
if (jsonParams.trimStart().startsWith("{")) {
|
||||
val req = objectMapper.readValue(jsonParams, Map::class.java)
|
||||
return ObjectParams(req as Map<Any, Any>)
|
||||
}
|
||||
val req = objectMapper.readValue(jsonParams, List::class.java)
|
||||
return req as List<Any>
|
||||
return ListParams(req as List<Any>)
|
||||
}
|
||||
|
||||
abstract class CallContext(
|
||||
@@ -517,18 +524,21 @@ open class NativeCall(
|
||||
}
|
||||
|
||||
interface RequestDecorator {
|
||||
fun processRequest(request: List<Any>): List<Any>
|
||||
fun processRequest(request: CallParams): CallParams
|
||||
}
|
||||
|
||||
open class NoneRequestDecorator : RequestDecorator {
|
||||
override fun processRequest(request: List<Any>): List<Any> = request
|
||||
override fun processRequest(request: CallParams): CallParams = request
|
||||
}
|
||||
|
||||
open class WithFilterIdDecorator : RequestDecorator {
|
||||
override fun processRequest(request: List<Any>): List<Any> {
|
||||
val filterId = request.first().toString()
|
||||
val sanitized = filterId.substring(0, filterId.lastIndex - 1)
|
||||
return listOf(sanitized)
|
||||
override fun processRequest(request: CallParams): CallParams {
|
||||
if (request is ListParams) {
|
||||
val filterId = request.list.first().toString()
|
||||
val sanitized = filterId.substring(0, filterId.lastIndex - 1)
|
||||
return ListParams(listOf(sanitized))
|
||||
}
|
||||
return request
|
||||
}
|
||||
}
|
||||
|
||||
@@ -696,5 +706,5 @@ open class NativeCall(
|
||||
}
|
||||
|
||||
class RawCallDetails(val method: String, val params: String)
|
||||
class ParsedCallDetails(val method: String, val params: List<Any>)
|
||||
class ParsedCallDetails(val method: String, val params: CallParams)
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import io.emeraldpay.dshackle.upstream.Selector
|
||||
import io.emeraldpay.dshackle.upstream.bitcoin.data.SimpleUnspent
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import org.bitcoinj.core.Address
|
||||
import org.slf4j.LoggerFactory
|
||||
import reactor.core.publisher.Mono
|
||||
@@ -55,16 +56,16 @@ open class BitcoinReader(
|
||||
}
|
||||
|
||||
open fun getBlock(hash: String): Mono<Map<String, Any>> {
|
||||
return castedRead(JsonRpcRequest("getblock", listOf(hash)), Map::class.java).cast()
|
||||
return castedRead(JsonRpcRequest("getblock", ListParams(hash)), Map::class.java).cast()
|
||||
}
|
||||
|
||||
open fun getBlock(height: Long): Mono<Map<String, Any>> {
|
||||
return castedRead(JsonRpcRequest("getblockhash", listOf(height)), String::class.java)
|
||||
return castedRead(JsonRpcRequest("getblockhash", ListParams(height)), String::class.java)
|
||||
.flatMap(this@BitcoinReader::getBlock)
|
||||
}
|
||||
|
||||
open fun getTx(txid: String): Mono<Map<String, Any>> {
|
||||
return castedRead(JsonRpcRequest("getrawtransaction", listOf(txid, true)), Map::class.java).cast()
|
||||
return castedRead(JsonRpcRequest("getrawtransaction", ListParams(txid, true)), Map::class.java).cast()
|
||||
}
|
||||
|
||||
open fun listUnspent(address: Address): Mono<List<SimpleUnspent>> {
|
||||
|
||||
@@ -23,6 +23,7 @@ import io.emeraldpay.dshackle.upstream.Lifecycle
|
||||
import io.emeraldpay.dshackle.upstream.forkchoice.MostWorkForkChoice
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import org.springframework.scheduling.concurrent.CustomizableThreadFactory
|
||||
import reactor.core.Disposable
|
||||
import reactor.core.publisher.Flux
|
||||
@@ -59,13 +60,13 @@ class BitcoinRpcHead(
|
||||
val base = Flux.interval(interval)
|
||||
.publishOn(scheduler)
|
||||
.flatMap {
|
||||
api.read(JsonRpcRequest("getbestblockhash", emptyList()))
|
||||
api.read(JsonRpcRequest("getbestblockhash", ListParams()))
|
||||
.flatMap(JsonRpcResponse::requireStringResult)
|
||||
.timeout(Defaults.timeout, Mono.error(Exception("Best block hash is not received")))
|
||||
}
|
||||
.distinctUntilChanged()
|
||||
.flatMap { hash ->
|
||||
api.read(JsonRpcRequest("getblock", listOf(hash)))
|
||||
api.read(JsonRpcRequest("getblock", ListParams(hash)))
|
||||
.flatMap(JsonRpcResponse::requireResult)
|
||||
.map(extractBlock::extract)
|
||||
.timeout(Defaults.timeout, Mono.error(Exception("Block data is not received")))
|
||||
|
||||
@@ -20,6 +20,7 @@ import io.emeraldpay.dshackle.reader.JsonRpcReader
|
||||
import io.emeraldpay.dshackle.upstream.UpstreamAvailability
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.scheduling.concurrent.CustomizableThreadFactory
|
||||
import reactor.core.publisher.Flux
|
||||
@@ -40,7 +41,7 @@ class BitcoinUpstreamValidator(
|
||||
}
|
||||
|
||||
fun validate(): Mono<UpstreamAvailability> {
|
||||
return api.read(JsonRpcRequest("getconnectioncount", emptyList()))
|
||||
return api.read(JsonRpcRequest("getconnectioncount", ListParams()))
|
||||
.flatMap(JsonRpcResponse::requireResult)
|
||||
.map { Integer.parseInt(String(it)) }
|
||||
.map { count ->
|
||||
|
||||
@@ -9,6 +9,7 @@ import io.emeraldpay.dshackle.upstream.Lifecycle
|
||||
import io.emeraldpay.dshackle.upstream.forkchoice.MostWorkForkChoice
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import org.apache.commons.codec.binary.Hex
|
||||
import reactor.core.Disposable
|
||||
import reactor.core.publisher.Flux
|
||||
@@ -32,7 +33,7 @@ class BitcoinZMQHead(
|
||||
Hex.encodeHexString(it)
|
||||
}
|
||||
.flatMap { hash ->
|
||||
api.read(JsonRpcRequest("getblock", listOf(hash)))
|
||||
api.read(JsonRpcRequest("getblock", ListParams(hash)))
|
||||
.switchIfEmpty(Mono.error(IllegalStateException("Block $hash is not available on upstream")))
|
||||
.retryWhen(Retry.backoff(5, Duration.ofMillis(100)))
|
||||
.switchIfEmpty(Mono.fromCallable { log.warn("Block $hash is not available on upstream") }.then(Mono.empty()))
|
||||
|
||||
@@ -22,6 +22,7 @@ import io.emeraldpay.dshackle.upstream.Lifecycle
|
||||
import io.emeraldpay.dshackle.upstream.Selector
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import org.slf4j.LoggerFactory
|
||||
import reactor.core.Disposable
|
||||
import reactor.core.publisher.Mono
|
||||
@@ -65,7 +66,7 @@ open class CachingMempoolData(
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun fetchFromUpstream(): Mono<List<String>> {
|
||||
return upstreams.getDirectApi(Selector.empty).flatMap { api ->
|
||||
api.read(JsonRpcRequest("getrawmempool", emptyList()))
|
||||
api.read(JsonRpcRequest("getrawmempool", ListParams()))
|
||||
.flatMap(JsonRpcResponse::requireResult)
|
||||
.map { objectMapper.readValue(it, List::class.java) as List<String> }
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import io.emeraldpay.dshackle.upstream.ethereum.rpc.RpcException
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.rpc.RpcResponseError
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import org.bitcoinj.core.Address
|
||||
import org.slf4j.LoggerFactory
|
||||
import reactor.core.publisher.Mono
|
||||
@@ -63,16 +64,18 @@ class LocalCallRouter(
|
||||
*
|
||||
*/
|
||||
fun processUnspentRequest(key: JsonRpcRequest): Mono<JsonRpcResponse> {
|
||||
if (key.params.size < 3) {
|
||||
return Mono.error(SilentException("Invalid call to unspent. Address is missing"))
|
||||
}
|
||||
val addresses = key.params[2]
|
||||
if (addresses is List<*> && addresses.size > 0) {
|
||||
val address = addresses[0].toString().let { Address.fromString(null, it) }
|
||||
return reader.listUnspent(address).map {
|
||||
val rpc = it.map(convertUnspent(address))
|
||||
val json = Global.objectMapper.writeValueAsBytes(rpc)
|
||||
JsonRpcResponse.ok(json, JsonRpcResponse.NumberId(key.id))
|
||||
if (key.params is ListParams) {
|
||||
if (key.params.list.size < 3) {
|
||||
return Mono.error(SilentException("Invalid call to unspent. Address is missing"))
|
||||
}
|
||||
val addresses = key.params.list[2]
|
||||
if (addresses is List<*> && addresses.size > 0) {
|
||||
val address = addresses[0].toString().let { Address.fromString(null, it) }
|
||||
return reader.listUnspent(address).map {
|
||||
val rpc = it.map(convertUnspent(address))
|
||||
val json = Global.objectMapper.writeValueAsBytes(rpc)
|
||||
JsonRpcResponse.ok(json, JsonRpcResponse.NumberId(key.id))
|
||||
}
|
||||
}
|
||||
}
|
||||
return Mono.error(SilentException("Invalid call to unspent"))
|
||||
|
||||
@@ -23,6 +23,7 @@ import io.emeraldpay.dshackle.upstream.bitcoin.data.RpcUnspent
|
||||
import io.emeraldpay.dshackle.upstream.bitcoin.data.SimpleUnspent
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import org.bitcoinj.core.Address
|
||||
import org.slf4j.LoggerFactory
|
||||
import reactor.core.publisher.Mono
|
||||
@@ -50,7 +51,7 @@ class RpcUnspentReader(
|
||||
//
|
||||
val address = key.toString()
|
||||
return upstreams.getDirectApi(selector).flatMap { api ->
|
||||
api.read(JsonRpcRequest("listunspent", listOf(1, 9999999, listOf(address))))
|
||||
api.read(JsonRpcRequest("listunspent", ListParams(1, 9999999, listOf(address))))
|
||||
.flatMap(JsonRpcResponse::requireResult)
|
||||
.map {
|
||||
Global.objectMapper.readerFor(RpcUnspent::class.java).readValues<RpcUnspent>(it).readAll()
|
||||
|
||||
@@ -5,6 +5,7 @@ import io.emeraldpay.dshackle.reader.JsonRpcReader
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.hex.HexQuantity
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import reactor.core.publisher.Mono
|
||||
import kotlin.math.max
|
||||
|
||||
@@ -17,7 +18,7 @@ class EthereumArchiveBlockNumberReader(
|
||||
) {
|
||||
|
||||
fun readArchiveBlock(): Mono<String> =
|
||||
reader.read(JsonRpcRequest("eth_blockNumber", listOf()))
|
||||
reader.read(JsonRpcRequest("eth_blockNumber", ListParams()))
|
||||
.flatMap(JsonRpcResponse::requireResult)
|
||||
.map {
|
||||
HexQuantity
|
||||
|
||||
@@ -28,6 +28,7 @@ import io.emeraldpay.dshackle.upstream.generic.AbstractPollChainSpecific
|
||||
import io.emeraldpay.dshackle.upstream.generic.CachingReaderBuilder
|
||||
import io.emeraldpay.dshackle.upstream.generic.GenericUpstream
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import org.springframework.cloud.sleuth.Tracer
|
||||
import reactor.core.publisher.Mono
|
||||
import reactor.core.scheduler.Scheduler
|
||||
@@ -41,10 +42,10 @@ object EthereumChainSpecific : AbstractPollChainSpecific() {
|
||||
return parseBlock(data, upstreamId)
|
||||
}
|
||||
|
||||
override fun latestBlockRequest() = JsonRpcRequest("eth_getBlockByNumber", listOf("latest", false))
|
||||
override fun listenNewHeadsRequest(): JsonRpcRequest = JsonRpcRequest("eth_subscribe", listOf("newHeads"))
|
||||
override fun latestBlockRequest() = JsonRpcRequest("eth_getBlockByNumber", ListParams("latest", false))
|
||||
override fun listenNewHeadsRequest(): JsonRpcRequest = JsonRpcRequest("eth_subscribe", ListParams("newHeads"))
|
||||
override fun unsubscribeNewHeadsRequest(subId: String): JsonRpcRequest =
|
||||
JsonRpcRequest("eth_unsubscribe", listOf(subId))
|
||||
JsonRpcRequest("eth_unsubscribe", ListParams(subId))
|
||||
|
||||
override fun localReaderBuilder(
|
||||
cachingReader: CachingReader,
|
||||
|
||||
@@ -31,6 +31,7 @@ import io.emeraldpay.dshackle.upstream.ethereum.rpc.RpcException
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.rpc.RpcResponseError
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcException
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import org.apache.commons.collections4.Factory
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils
|
||||
import org.slf4j.LoggerFactory
|
||||
@@ -68,20 +69,20 @@ class EthereumDirectReader(
|
||||
init {
|
||||
blockReader = object : Reader<BlockHash, Result<BlockContainer>> {
|
||||
override fun read(key: BlockHash): Mono<Result<BlockContainer>> {
|
||||
val request = JsonRpcRequest("eth_getBlockByHash", listOf(key.toHex(), false))
|
||||
val request = JsonRpcRequest("eth_getBlockByHash", ListParams(key.toHex(), false))
|
||||
return readBlock(request, key.toHex())
|
||||
}
|
||||
}
|
||||
blockByHeightReader = object : Reader<Long, Result<BlockContainer>> {
|
||||
override fun read(key: Long): Mono<Result<BlockContainer>> {
|
||||
val heightMatcher = Selector.HeightMatcher(key)
|
||||
val request = JsonRpcRequest("eth_getBlockByNumber", listOf(HexQuantity.from(key).toHex(), false))
|
||||
val request = JsonRpcRequest("eth_getBlockByNumber", ListParams(HexQuantity.from(key).toHex(), false))
|
||||
return readBlock(request, key.toString(), heightMatcher)
|
||||
}
|
||||
}
|
||||
txReader = object : Reader<TransactionId, Result<TxContainer>> {
|
||||
override fun read(key: TransactionId): Mono<Result<TxContainer>> {
|
||||
val request = JsonRpcRequest("eth_getTransactionByHash", listOf(key.toHex()))
|
||||
val request = JsonRpcRequest("eth_getTransactionByHash", ListParams(key.toHex()))
|
||||
return readWithQuorum(request) // retries were removed because we use NotNullQuorum which handle errors too
|
||||
.timeout(Duration.ofSeconds(5), Mono.error(TimeoutException("Tx not read $key")))
|
||||
.flatMap { result ->
|
||||
@@ -106,7 +107,7 @@ class EthereumDirectReader(
|
||||
balanceReader = object : Reader<Address, Result<Wei>> {
|
||||
override fun read(key: Address): Mono<Result<Wei>> {
|
||||
val height = up.getHead().getCurrentHeight()?.let { HexQuantity.from(it).toHex() } ?: "latest"
|
||||
val request = JsonRpcRequest("eth_getBalance", listOf(key.toHex(), height))
|
||||
val request = JsonRpcRequest("eth_getBalance", ListParams(key.toHex(), height))
|
||||
return readWithQuorum(request)
|
||||
.timeout(Defaults.timeoutInternal, Mono.error(TimeoutException("Balance not read $key")))
|
||||
.map {
|
||||
@@ -130,7 +131,7 @@ class EthereumDirectReader(
|
||||
|
||||
receiptReader = object : Reader<TransactionId, Result<ByteArray>> {
|
||||
override fun read(key: TransactionId): Mono<Result<ByteArray>> {
|
||||
val request = JsonRpcRequest("eth_getTransactionReceipt", listOf(key.toHex()))
|
||||
val request = JsonRpcRequest("eth_getTransactionReceipt", ListParams(key.toHex()))
|
||||
return readWithQuorum(request)
|
||||
.timeout(Duration.ofSeconds(5), Mono.error(TimeoutException("Receipt not read $key")))
|
||||
.flatMap { result ->
|
||||
@@ -163,7 +164,7 @@ class EthereumDirectReader(
|
||||
override fun read(key: BlockId): Mono<Result<List<TransactionLogJson>>> {
|
||||
val request = JsonRpcRequest(
|
||||
"eth_getLogs",
|
||||
listOf(
|
||||
ListParams(
|
||||
mapOf(
|
||||
"blockHash" to key.toHexWithPrefix(),
|
||||
),
|
||||
|
||||
@@ -27,6 +27,7 @@ import io.emeraldpay.dshackle.upstream.ethereum.rpc.RpcException
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.rpc.RpcResponseError
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import reactor.core.publisher.Mono
|
||||
import reactor.kotlin.core.publisher.switchIfEmpty
|
||||
import java.math.BigInteger
|
||||
@@ -73,60 +74,68 @@ class EthereumLocalReader(
|
||||
fun commonRequests(key: JsonRpcRequest): Mono<Pair<ByteArray, String?>>? {
|
||||
val method = key.method
|
||||
val params = key.params
|
||||
return when {
|
||||
method == "eth_getTransactionByHash" -> {
|
||||
if (params.size != 1) {
|
||||
throw RpcException(RpcResponseError.CODE_INVALID_METHOD_PARAMS, "Must provide 1 parameter")
|
||||
if (params is ListParams) {
|
||||
return when {
|
||||
method == "eth_getTransactionByHash" -> {
|
||||
if (params.list.size != 1) {
|
||||
throw RpcException(RpcResponseError.CODE_INVALID_METHOD_PARAMS, "Must provide 1 parameter")
|
||||
}
|
||||
val hash: TxId
|
||||
try {
|
||||
hash = TxId.from(params.list[0].toString())
|
||||
} catch (e: IllegalArgumentException) {
|
||||
throw RpcException(RpcResponseError.CODE_INVALID_METHOD_PARAMS, "[0] must be transaction id")
|
||||
}
|
||||
reader.txByHashAsCont()
|
||||
.read(hash)
|
||||
.map { it.data.json!! to it.upstreamId }
|
||||
}
|
||||
val hash: TxId
|
||||
try {
|
||||
hash = TxId.from(params[0].toString())
|
||||
} catch (e: IllegalArgumentException) {
|
||||
throw RpcException(RpcResponseError.CODE_INVALID_METHOD_PARAMS, "[0] must be transaction id")
|
||||
|
||||
method == "eth_getBlockByHash" -> {
|
||||
if (params.list.size != 2) {
|
||||
throw RpcException(RpcResponseError.CODE_INVALID_METHOD_PARAMS, "Must provide 2 parameters")
|
||||
}
|
||||
val hash: BlockId
|
||||
try {
|
||||
hash = BlockId.from(params.list[0].toString())
|
||||
} catch (e: IllegalArgumentException) {
|
||||
throw RpcException(RpcResponseError.CODE_INVALID_METHOD_PARAMS, "[0] must be block hash")
|
||||
}
|
||||
val withTx = params.list[1].toString().toBoolean()
|
||||
if (withTx) {
|
||||
null
|
||||
} else {
|
||||
reader.blocksByIdAsCont().read(hash).map { it.data.json!! to it.upstreamId }
|
||||
}
|
||||
}
|
||||
reader.txByHashAsCont()
|
||||
.read(hash)
|
||||
.map { it.data.json!! to it.upstreamId }
|
||||
|
||||
method == "eth_getBlockByNumber" -> {
|
||||
getBlockByNumber(params.list)
|
||||
}
|
||||
|
||||
method == "eth_getTransactionReceipt" -> {
|
||||
if (params.list.size != 1) {
|
||||
throw RpcException(RpcResponseError.CODE_INVALID_METHOD_PARAMS, "Must provide 1 parameter")
|
||||
}
|
||||
val hash: TxId
|
||||
try {
|
||||
hash = TxId.from(params.list[0].toString())
|
||||
} catch (e: IllegalArgumentException) {
|
||||
throw RpcException(RpcResponseError.CODE_INVALID_METHOD_PARAMS, "[0] must be transaction id")
|
||||
}
|
||||
reader.receipts()
|
||||
.read(hash)
|
||||
.map { it.data to it.upstreamId }
|
||||
}
|
||||
|
||||
method == "drpc_getLogsEstimate" -> {
|
||||
getLogsEstimate(params.list)
|
||||
}
|
||||
|
||||
else -> null
|
||||
}
|
||||
method == "eth_getBlockByHash" -> {
|
||||
if (params.size != 2) {
|
||||
throw RpcException(RpcResponseError.CODE_INVALID_METHOD_PARAMS, "Must provide 2 parameters")
|
||||
}
|
||||
val hash: BlockId
|
||||
try {
|
||||
hash = BlockId.from(params[0].toString())
|
||||
} catch (e: IllegalArgumentException) {
|
||||
throw RpcException(RpcResponseError.CODE_INVALID_METHOD_PARAMS, "[0] must be block hash")
|
||||
}
|
||||
val withTx = params[1].toString().toBoolean()
|
||||
if (withTx) {
|
||||
null
|
||||
} else {
|
||||
reader.blocksByIdAsCont().read(hash).map { it.data.json!! to it.upstreamId }
|
||||
}
|
||||
}
|
||||
method == "eth_getBlockByNumber" -> {
|
||||
getBlockByNumber(params)
|
||||
}
|
||||
method == "eth_getTransactionReceipt" -> {
|
||||
if (params.size != 1) {
|
||||
throw RpcException(RpcResponseError.CODE_INVALID_METHOD_PARAMS, "Must provide 1 parameter")
|
||||
}
|
||||
val hash: TxId
|
||||
try {
|
||||
hash = TxId.from(params[0].toString())
|
||||
} catch (e: IllegalArgumentException) {
|
||||
throw RpcException(RpcResponseError.CODE_INVALID_METHOD_PARAMS, "[0] must be transaction id")
|
||||
}
|
||||
reader.receipts()
|
||||
.read(hash)
|
||||
.map { it.data to it.upstreamId }
|
||||
}
|
||||
method == "drpc_getLogsEstimate" -> {
|
||||
getLogsEstimate(params)
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun getBlockByNumber(params: List<Any?>): Mono<Pair<ByteArray, String?>>? {
|
||||
|
||||
@@ -5,6 +5,7 @@ import io.emeraldpay.dshackle.upstream.RecursiveLowerBoundBlockDetector
|
||||
import io.emeraldpay.dshackle.upstream.Upstream
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import io.emeraldpay.dshackle.upstream.toHex
|
||||
import reactor.core.publisher.Mono
|
||||
|
||||
@@ -46,7 +47,7 @@ class EthereumLowerBoundBlockDetector(
|
||||
return upstream.getIngressReader().read(
|
||||
JsonRpcRequest(
|
||||
"eth_getBalance",
|
||||
listOf("0x756F45E3FA69347A9A973A725E3C98bC4db0b5a0", blockNumber.toHex()),
|
||||
ListParams("0x756F45E3FA69347A9A973A725E3C98bC4db0b5a0", blockNumber.toHex()),
|
||||
),
|
||||
)
|
||||
.retryWhen(retrySpec(nonRetryableErrors))
|
||||
|
||||
@@ -32,6 +32,7 @@ import io.emeraldpay.dshackle.upstream.ethereum.json.SyncingJson
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.json.TransactionCallJson
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.scheduling.concurrent.CustomizableThreadFactory
|
||||
import reactor.core.publisher.Mono
|
||||
@@ -79,7 +80,7 @@ open class EthereumUpstreamValidator @JvmOverloads constructor(
|
||||
return Mono.just(UpstreamAvailability.OK)
|
||||
}
|
||||
return upstream.getIngressReader()
|
||||
.read(JsonRpcRequest("eth_syncing", listOf()))
|
||||
.read(JsonRpcRequest("eth_syncing", ListParams()))
|
||||
.flatMap(JsonRpcResponse::requireResult)
|
||||
.map { objectMapper.readValue(it, SyncingJson::class.java) }
|
||||
.timeout(
|
||||
@@ -106,7 +107,7 @@ open class EthereumUpstreamValidator @JvmOverloads constructor(
|
||||
}
|
||||
return upstream
|
||||
.getIngressReader()
|
||||
.read(JsonRpcRequest("net_peerCount", listOf()))
|
||||
.read(JsonRpcRequest("net_peerCount", ListParams()))
|
||||
.flatMap(JsonRpcResponse::requireStringResult)
|
||||
.map(Integer::decode)
|
||||
.timeout(
|
||||
@@ -179,7 +180,7 @@ open class EthereumUpstreamValidator @JvmOverloads constructor(
|
||||
.read(
|
||||
JsonRpcRequest(
|
||||
"eth_call",
|
||||
listOf(
|
||||
ListParams(
|
||||
TransactionCallJson(
|
||||
Address.from(config.callLimitContract),
|
||||
// calling contract with param 200_000, meaning it will generate 200k symbols or response
|
||||
@@ -223,7 +224,7 @@ open class EthereumUpstreamValidator @JvmOverloads constructor(
|
||||
.readArchiveBlock()
|
||||
.flatMap {
|
||||
upstream.getIngressReader()
|
||||
.read(JsonRpcRequest("eth_getBlockByNumber", listOf(it, false)))
|
||||
.read(JsonRpcRequest("eth_getBlockByNumber", ListParams(it, false)))
|
||||
.flatMap(JsonRpcResponse::requireResult)
|
||||
}
|
||||
.retryRandomBackoff(3, Duration.ofMillis(100), Duration.ofMillis(500)) { ctx ->
|
||||
@@ -249,7 +250,7 @@ open class EthereumUpstreamValidator @JvmOverloads constructor(
|
||||
|
||||
private fun chainId(): Mono<String> {
|
||||
return upstream.getIngressReader()
|
||||
.read(JsonRpcRequest("eth_chainId", emptyList()))
|
||||
.read(JsonRpcRequest("eth_chainId", ListParams()))
|
||||
.retryRandomBackoff(3, Duration.ofMillis(100), Duration.ofMillis(500)) { ctx ->
|
||||
log.warn(
|
||||
"error during chainId retrieving for ${upstream.getId()}, iteration ${ctx.iteration()}, " +
|
||||
@@ -262,7 +263,7 @@ open class EthereumUpstreamValidator @JvmOverloads constructor(
|
||||
|
||||
private fun netVersion(): Mono<String> {
|
||||
return upstream.getIngressReader()
|
||||
.read(JsonRpcRequest("net_version", emptyList()))
|
||||
.read(JsonRpcRequest("net_version", ListParams()))
|
||||
.retryRandomBackoff(3, Duration.ofMillis(100), Duration.ofMillis(500)) { ctx ->
|
||||
log.warn(
|
||||
"error during netVersion retrieving for ${upstream.getId()}, iteration ${ctx.iteration()}, " +
|
||||
|
||||
@@ -18,6 +18,7 @@ package io.emeraldpay.dshackle.upstream.ethereum
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcException
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import org.slf4j.LoggerFactory
|
||||
import reactor.core.publisher.Flux
|
||||
import reactor.core.publisher.Mono
|
||||
@@ -54,7 +55,8 @@ class WsSubscriptionsImpl(
|
||||
}
|
||||
|
||||
override fun unsubscribe(request: JsonRpcRequest): Mono<JsonRpcResponse> {
|
||||
if (request.params.isEmpty() || request.params.contains("")) {
|
||||
if (request.params is ListParams && (request.params.list.isEmpty() || request.params.list.contains(""))
|
||||
) {
|
||||
return Mono.empty()
|
||||
}
|
||||
return wsPool.getConnection()
|
||||
|
||||
@@ -9,6 +9,7 @@ import io.emeraldpay.dshackle.upstream.LabelsDetector
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.EthereumArchiveBlockNumberReader
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import org.slf4j.LoggerFactory
|
||||
import reactor.core.publisher.Flux
|
||||
import reactor.core.publisher.Mono
|
||||
@@ -32,7 +33,7 @@ class EthereumLabelsDetector(
|
||||
|
||||
private fun detectNodeType(): Flux<Pair<String, String>?> {
|
||||
return reader
|
||||
.read(JsonRpcRequest("web3_clientVersion", listOf()))
|
||||
.read(JsonRpcRequest("web3_clientVersion", ListParams()))
|
||||
.flatMap(JsonRpcResponse::requireResult)
|
||||
.map { objectMapper.readValue<JsonNode>(it) }
|
||||
.flatMapMany { node ->
|
||||
@@ -64,7 +65,7 @@ class EthereumLabelsDetector(
|
||||
return reader.read(
|
||||
JsonRpcRequest(
|
||||
"eth_getBalance",
|
||||
listOf("0x756F45E3FA69347A9A973A725E3C98bC4db0b5a0", blockNumber),
|
||||
ListParams("0x756F45E3FA69347A9A973A725E3C98bC4db0b5a0", blockNumber),
|
||||
),
|
||||
).flatMap(JsonRpcResponse::requireResult)
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import io.emeraldpay.dshackle.upstream.ethereum.EthereumEgressSubscription
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.WsSubscriptions
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.domain.TransactionId
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import org.slf4j.LoggerFactory
|
||||
import reactor.core.publisher.Flux
|
||||
import reactor.core.publisher.Mono
|
||||
@@ -34,7 +35,7 @@ class WebsocketPendingTxes(
|
||||
}
|
||||
|
||||
override fun createConnection(): Flux<TransactionId> {
|
||||
return wsSubscriptions.subscribe(JsonRpcRequest("eth_subscribe", listOf(EthereumEgressSubscription.METHOD_PENDING_TXES)))
|
||||
return wsSubscriptions.subscribe(JsonRpcRequest("eth_subscribe", ListParams(EthereumEgressSubscription.METHOD_PENDING_TXES)))
|
||||
.data
|
||||
.timeout(Duration.ofSeconds(60), Mono.empty())
|
||||
.map {
|
||||
|
||||
@@ -5,6 +5,7 @@ import io.emeraldpay.dshackle.upstream.SubscriptionConnect
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.WsSubscriptions
|
||||
import io.emeraldpay.dshackle.upstream.generic.subscribe.GenericPersistentConnect
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import reactor.core.publisher.Flux
|
||||
import reactor.core.publisher.Mono
|
||||
import java.time.Duration
|
||||
@@ -37,7 +38,7 @@ class GenericSubscriptionConnect(
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun createConnection(): Flux<Any> {
|
||||
return conn.subscribe(JsonRpcRequest(topic, getParams(params)))
|
||||
return conn.subscribe(JsonRpcRequest(topic, ListParams(getParams(params))))
|
||||
.data
|
||||
.timeout(Duration.ofSeconds(60), Mono.empty())
|
||||
.onErrorResume { Mono.empty() } as Flux<Any>
|
||||
|
||||
@@ -39,6 +39,7 @@ import io.emeraldpay.dshackle.upstream.forkchoice.MostWorkForkChoice
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcGrpcClient
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import org.reactivestreams.Publisher
|
||||
import reactor.core.publisher.Flux
|
||||
import reactor.core.publisher.Mono
|
||||
@@ -93,7 +94,7 @@ class BitcoinGrpcUpstream(
|
||||
private val reloadBlock: Function<BlockContainer, Publisher<BlockContainer>> = Function { existingBlock ->
|
||||
// head comes without transaction data
|
||||
// need to download transactions for the block
|
||||
defaultReader.read(JsonRpcRequest("getblock", listOf(existingBlock.hash.toHex())))
|
||||
defaultReader.read(JsonRpcRequest("getblock", ListParams(existingBlock.hash.toHex())))
|
||||
.flatMap(JsonRpcResponse::requireResult)
|
||||
.map(extractBlock::extract)
|
||||
.timeout(timeout, Mono.error(TimeoutException("Timeout from upstream")))
|
||||
|
||||
@@ -16,6 +16,8 @@ import io.emeraldpay.dshackle.upstream.UpstreamValidator
|
||||
import io.emeraldpay.dshackle.upstream.generic.AbstractPollChainSpecific
|
||||
import io.emeraldpay.dshackle.upstream.generic.GenericUpstreamValidator
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ObjectParams
|
||||
import java.math.BigInteger
|
||||
import java.time.Instant
|
||||
import java.util.concurrent.TimeUnit
|
||||
@@ -60,7 +62,7 @@ object NearChainSpecific : AbstractPollChainSpecific() {
|
||||
upstream,
|
||||
options,
|
||||
SingleCallValidator(
|
||||
JsonRpcRequest("status", listOf()),
|
||||
JsonRpcRequest("status", ListParams()),
|
||||
) { data ->
|
||||
validate(data)
|
||||
},
|
||||
@@ -80,8 +82,8 @@ object NearChainSpecific : AbstractPollChainSpecific() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun latestBlockRequest(): JsonRpcRequest =
|
||||
JsonRpcRequest("block", mapOf("finality" to "optimistic"))
|
||||
override fun latestBlockRequest(): JsonRpcRequest = // {...}
|
||||
JsonRpcRequest("block", ObjectParams("finality" to "optimistic"))
|
||||
}
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
|
||||
@@ -5,6 +5,7 @@ import io.emeraldpay.dshackle.Global
|
||||
import io.emeraldpay.dshackle.upstream.LowerBoundBlockDetector
|
||||
import io.emeraldpay.dshackle.upstream.Upstream
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import reactor.core.publisher.Mono
|
||||
|
||||
class NearLowerBoundBlockDetector(
|
||||
@@ -13,7 +14,7 @@ class NearLowerBoundBlockDetector(
|
||||
) : LowerBoundBlockDetector(chain, upstream) {
|
||||
|
||||
override fun lowerBlockDetect(): Mono<LowerBlockData> {
|
||||
return upstream.getIngressReader().read(JsonRpcRequest("status", listOf())).map {
|
||||
return upstream.getIngressReader().read(JsonRpcRequest("status", ListParams())).map {
|
||||
val resp = Global.objectMapper.readValue(it.getResult(), NearStatus::class.java)
|
||||
LowerBlockData(resp.syncInfo.earliestHeight, null, resp.syncInfo.earliestBlockTime.toEpochMilli())
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import io.emeraldpay.dshackle.upstream.generic.GenericIngressSubscription
|
||||
import io.emeraldpay.dshackle.upstream.generic.GenericUpstreamValidator
|
||||
import io.emeraldpay.dshackle.upstream.generic.LocalReader
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import org.slf4j.LoggerFactory
|
||||
import reactor.core.publisher.Mono
|
||||
import reactor.core.scheduler.Scheduler
|
||||
@@ -66,13 +67,13 @@ object PolkadotChainSpecific : AbstractPollChainSpecific() {
|
||||
}
|
||||
|
||||
override fun latestBlockRequest(): JsonRpcRequest =
|
||||
JsonRpcRequest("chain_getBlock", listOf())
|
||||
JsonRpcRequest("chain_getBlock", ListParams())
|
||||
|
||||
override fun listenNewHeadsRequest(): JsonRpcRequest =
|
||||
JsonRpcRequest("chain_subscribeNewHeads", listOf())
|
||||
JsonRpcRequest("chain_subscribeNewHeads", ListParams())
|
||||
|
||||
override fun unsubscribeNewHeadsRequest(subId: String): JsonRpcRequest =
|
||||
JsonRpcRequest("chain_unsubscribeNewHeads", listOf(subId))
|
||||
JsonRpcRequest("chain_unsubscribeNewHeads", ListParams(subId))
|
||||
|
||||
override fun localReaderBuilder(
|
||||
cachingReader: CachingReader,
|
||||
@@ -97,7 +98,7 @@ object PolkadotChainSpecific : AbstractPollChainSpecific() {
|
||||
upstream,
|
||||
options,
|
||||
SingleCallValidator(
|
||||
JsonRpcRequest("system_health", listOf()),
|
||||
JsonRpcRequest("system_health", ListParams()),
|
||||
) { data ->
|
||||
validate(data, options.minPeers, upstream.getId())
|
||||
},
|
||||
|
||||
@@ -5,6 +5,7 @@ import io.emeraldpay.dshackle.upstream.RecursiveLowerBoundBlockDetector
|
||||
import io.emeraldpay.dshackle.upstream.Upstream
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import io.emeraldpay.dshackle.upstream.toHex
|
||||
import reactor.core.publisher.Mono
|
||||
|
||||
@@ -23,7 +24,7 @@ class PolkadotLowerBoundBlockDetector(
|
||||
return upstream.getIngressReader().read(
|
||||
JsonRpcRequest(
|
||||
"chain_getBlockHash",
|
||||
listOf(blockNumber.toHex()), // in polkadot state methods work only with hash
|
||||
ListParams(blockNumber.toHex()), // in polkadot state methods work only with hash
|
||||
),
|
||||
)
|
||||
.flatMap(JsonRpcResponse::requireResult)
|
||||
@@ -34,7 +35,7 @@ class PolkadotLowerBoundBlockDetector(
|
||||
upstream.getIngressReader().read(
|
||||
JsonRpcRequest(
|
||||
"state_getMetadata",
|
||||
listOf(it),
|
||||
ListParams(it),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package io.emeraldpay.dshackle.upstream.rpcclient
|
||||
|
||||
sealed interface CallParams
|
||||
|
||||
data class ListParams(val list: List<Any>) : CallParams {
|
||||
constructor(vararg elements: Any) : this(listOf(*elements))
|
||||
constructor() : this(listOf())
|
||||
}
|
||||
data class ObjectParams(val obj: Map<Any, Any>) : CallParams {
|
||||
constructor(vararg pairs: Pair<Any, Any>) : this(mapOf(*pairs))
|
||||
}
|
||||
@@ -61,7 +61,16 @@ class JsonRpcGrpcClient(
|
||||
val reqItem = BlockchainOuterClass.NativeCallItem.newBuilder()
|
||||
.setId(1)
|
||||
.setMethod(key.method)
|
||||
.setPayload(ByteString.copyFrom(Global.objectMapper.writeValueAsBytes(key.params)))
|
||||
.setPayload(
|
||||
ByteString.copyFrom(
|
||||
Global.objectMapper.writeValueAsBytes(
|
||||
when (key.params) {
|
||||
is ListParams -> key.params.list
|
||||
is ObjectParams -> key.params.obj
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
if (key.nonce != null) {
|
||||
reqItem.nonce = key.nonce
|
||||
}
|
||||
|
||||
@@ -24,33 +24,30 @@ import io.emeraldpay.dshackle.Global
|
||||
|
||||
data class JsonRpcRequest(
|
||||
val method: String,
|
||||
val params: List<Any?>,
|
||||
val params: CallParams,
|
||||
val id: Int,
|
||||
val nonce: Long?,
|
||||
val selector: BlockchainOuterClass.Selector?,
|
||||
val isStreamed: Boolean = false,
|
||||
val objParams: Map<Any, Any>? = null,
|
||||
) {
|
||||
|
||||
@JvmOverloads constructor(
|
||||
method: String,
|
||||
params: List<Any?>,
|
||||
params: CallParams,
|
||||
nonce: Long? = null,
|
||||
selectors: BlockchainOuterClass.Selector? = null,
|
||||
isStreamed: Boolean = false,
|
||||
) : this(method, params, 1, nonce, selectors, isStreamed)
|
||||
|
||||
constructor(
|
||||
method: String,
|
||||
objParams: Map<Any, Any>,
|
||||
) : this(method, listOf(), 1, null, null, false, objParams)
|
||||
|
||||
fun toJson(): ByteArray {
|
||||
val json = mapOf(
|
||||
"jsonrpc" to "2.0",
|
||||
"id" to id,
|
||||
"method" to method,
|
||||
"params" to (objParams ?: params),
|
||||
"params" to when (params) {
|
||||
is ListParams -> params.list
|
||||
is ObjectParams -> params.obj
|
||||
},
|
||||
)
|
||||
return Global.objectMapper.writeValueAsBytes(json)
|
||||
}
|
||||
@@ -59,6 +56,7 @@ data class JsonRpcRequest(
|
||||
return String(this.toJson())
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
class Deserializer : JsonDeserializer<JsonRpcRequest>() {
|
||||
|
||||
override fun deserialize(p: JsonParser, ctxt: DeserializationContext): JsonRpcRequest {
|
||||
@@ -78,7 +76,7 @@ data class JsonRpcRequest(
|
||||
throw IllegalStateException("Unsupported param type: ${it.asToken()}")
|
||||
}
|
||||
}
|
||||
return JsonRpcRequest(method, params, id, null, null)
|
||||
return JsonRpcRequest(method, ListParams(params as List<Any>), id, null, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import io.emeraldpay.dshackle.upstream.generic.GenericEgressSubscription
|
||||
import io.emeraldpay.dshackle.upstream.generic.GenericIngressSubscription
|
||||
import io.emeraldpay.dshackle.upstream.generic.GenericUpstreamValidator
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import org.slf4j.LoggerFactory
|
||||
import reactor.core.publisher.Mono
|
||||
import reactor.core.scheduler.Scheduler
|
||||
@@ -36,12 +37,12 @@ object SolanaChainSpecific : AbstractChainSpecific() {
|
||||
private val log = LoggerFactory.getLogger(SolanaChainSpecific::class.java)
|
||||
|
||||
override fun getLatestBlock(api: JsonRpcReader, upstreamId: String): Mono<BlockContainer> {
|
||||
return api.read(JsonRpcRequest("getSlot", listOf())).flatMap {
|
||||
return api.read(JsonRpcRequest("getSlot", ListParams())).flatMap {
|
||||
val slot = it.getResultAsProcessedString().toLong()
|
||||
api.read(
|
||||
JsonRpcRequest(
|
||||
"getBlocks",
|
||||
listOf(
|
||||
ListParams(
|
||||
slot - 10,
|
||||
slot,
|
||||
),
|
||||
@@ -54,7 +55,7 @@ object SolanaChainSpecific : AbstractChainSpecific() {
|
||||
api.read(
|
||||
JsonRpcRequest(
|
||||
"getBlock",
|
||||
listOf(
|
||||
ListParams(
|
||||
response.max(),
|
||||
mapOf(
|
||||
"showRewards" to false,
|
||||
@@ -100,7 +101,7 @@ object SolanaChainSpecific : AbstractChainSpecific() {
|
||||
override fun listenNewHeadsRequest(): JsonRpcRequest {
|
||||
return JsonRpcRequest(
|
||||
"blockSubscribe",
|
||||
listOf(
|
||||
ListParams(
|
||||
"all",
|
||||
mapOf(
|
||||
"showRewards" to false,
|
||||
@@ -111,7 +112,7 @@ object SolanaChainSpecific : AbstractChainSpecific() {
|
||||
}
|
||||
|
||||
override fun unsubscribeNewHeadsRequest(subId: String): JsonRpcRequest {
|
||||
return JsonRpcRequest("blockUnsubscribe", listOf(subId))
|
||||
return JsonRpcRequest("blockUnsubscribe", ListParams(subId))
|
||||
}
|
||||
|
||||
override fun validator(
|
||||
@@ -124,7 +125,7 @@ object SolanaChainSpecific : AbstractChainSpecific() {
|
||||
upstream,
|
||||
options,
|
||||
SingleCallValidator(
|
||||
JsonRpcRequest("getHealth", listOf()),
|
||||
JsonRpcRequest("getHealth", ListParams()),
|
||||
) { data ->
|
||||
val resp = String(data)
|
||||
if (resp == "\"ok\"") {
|
||||
|
||||
@@ -6,6 +6,7 @@ import io.emeraldpay.dshackle.upstream.LowerBoundBlockDetector
|
||||
import io.emeraldpay.dshackle.upstream.Upstream
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import reactor.core.publisher.Mono
|
||||
import reactor.util.retry.Retry
|
||||
import java.time.Duration
|
||||
@@ -21,7 +22,7 @@ class SolanaLowerBoundBlockDetector(
|
||||
return Mono.just(reader)
|
||||
.flatMap {
|
||||
it.read(
|
||||
JsonRpcRequest("getFirstAvailableBlock", listOf()), // in case of solana we talk about the slot of the lowest confirmed block
|
||||
JsonRpcRequest("getFirstAvailableBlock", ListParams()), // in case of solana we talk about the slot of the lowest confirmed block
|
||||
)
|
||||
}
|
||||
.flatMap(JsonRpcResponse::requireResult)
|
||||
@@ -37,7 +38,7 @@ class SolanaLowerBoundBlockDetector(
|
||||
reader.read(
|
||||
JsonRpcRequest(
|
||||
"getBlock", // since getFirstAvailableBlock returns the slot of the lowest confirmed block we can directly call getBlock
|
||||
listOf(
|
||||
ListParams(
|
||||
it,
|
||||
mapOf(
|
||||
"showRewards" to false,
|
||||
|
||||
@@ -16,6 +16,7 @@ import io.emeraldpay.dshackle.upstream.UpstreamValidator
|
||||
import io.emeraldpay.dshackle.upstream.generic.AbstractPollChainSpecific
|
||||
import io.emeraldpay.dshackle.upstream.generic.GenericUpstreamValidator
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.math.BigInteger
|
||||
import java.time.Instant
|
||||
@@ -63,7 +64,7 @@ object StarknetChainSpecific : AbstractPollChainSpecific() {
|
||||
upstream,
|
||||
options,
|
||||
SingleCallValidator(
|
||||
JsonRpcRequest("starknet_syncing", listOf()),
|
||||
JsonRpcRequest("starknet_syncing", ListParams()),
|
||||
) { data ->
|
||||
validate(data, config.laggingLagSize, upstream.getId())
|
||||
},
|
||||
@@ -93,7 +94,7 @@ object StarknetChainSpecific : AbstractPollChainSpecific() {
|
||||
}
|
||||
|
||||
override fun latestBlockRequest(): JsonRpcRequest =
|
||||
JsonRpcRequest("starknet_getBlockWithTxHashes", listOf("latest"))
|
||||
JsonRpcRequest("starknet_getBlockWithTxHashes", ListParams("latest"))
|
||||
}
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
|
||||
@@ -24,6 +24,7 @@ import io.emeraldpay.dshackle.upstream.Upstream
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcException
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.rpc.RpcException
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.rpc.RpcResponseError
|
||||
import org.springframework.cloud.sleuth.Tracer
|
||||
@@ -42,7 +43,7 @@ class QuorumRpcReaderSpec extends Specification {
|
||||
_ * getId() >> "id"
|
||||
_ * getRole() >> UpstreamsConfig.UpstreamRole.PRIMARY
|
||||
1 * getIngressReader() >> Mock(Reader) {
|
||||
1 * read(new JsonRpcRequest("eth_test", [])) >> Mono.just(JsonRpcResponse.ok("1"))
|
||||
1 * read(new JsonRpcRequest("eth_test", new ListParams())) >> Mono.just(JsonRpcResponse.ok("1"))
|
||||
}
|
||||
}
|
||||
def apis = new FilteredApis(
|
||||
@@ -52,7 +53,7 @@ class QuorumRpcReaderSpec extends Specification {
|
||||
def reader = new QuorumRpcReader(apis, new AlwaysQuorum(), Stub(Tracer))
|
||||
|
||||
when:
|
||||
def act = reader.read(new JsonRpcRequest("eth_test", []))
|
||||
def act = reader.read(new JsonRpcRequest("eth_test", new ListParams()))
|
||||
.map {
|
||||
new String(it.value)
|
||||
}
|
||||
@@ -67,7 +68,7 @@ class QuorumRpcReaderSpec extends Specification {
|
||||
def "always-quorum - return upstream error returned"() {
|
||||
setup:
|
||||
def api = Mock(Reader) {
|
||||
1 * read(new JsonRpcRequest("eth_test", [])) >>> [
|
||||
1 * read(new JsonRpcRequest("eth_test", new ListParams())) >>> [
|
||||
Mono.just(JsonRpcResponse.error(1, "test"))
|
||||
]
|
||||
}
|
||||
@@ -84,7 +85,7 @@ class QuorumRpcReaderSpec extends Specification {
|
||||
def reader = new QuorumRpcReader(apis, new AlwaysQuorum(), Stub(Tracer))
|
||||
|
||||
when:
|
||||
def act = reader.read(new JsonRpcRequest("eth_test", []))
|
||||
def act = reader.read(new JsonRpcRequest("eth_test", new ListParams()))
|
||||
.map {
|
||||
new String(it.value)
|
||||
}
|
||||
@@ -100,7 +101,7 @@ class QuorumRpcReaderSpec extends Specification {
|
||||
def "always-quorum - return upstream error thrown"() {
|
||||
setup:
|
||||
def api = Mock(Reader) {
|
||||
1 * read(new JsonRpcRequest("eth_test", [])) >>> [
|
||||
1 * read(new JsonRpcRequest("eth_test", new ListParams())) >>> [
|
||||
Mono.error(
|
||||
new RpcException(
|
||||
RpcResponseError.CODE_UPSTREAM_CONNECTION_ERROR,
|
||||
@@ -122,7 +123,7 @@ class QuorumRpcReaderSpec extends Specification {
|
||||
def reader = new QuorumRpcReader(apis, new AlwaysQuorum(), Stub(Tracer))
|
||||
|
||||
when:
|
||||
def act = reader.read(new JsonRpcRequest("eth_test", []))
|
||||
def act = reader.read(new JsonRpcRequest("eth_test", new ListParams()))
|
||||
.map {
|
||||
new String(it.value)
|
||||
}
|
||||
@@ -142,7 +143,7 @@ class QuorumRpcReaderSpec extends Specification {
|
||||
_ * getId() >> "id"
|
||||
_ * getRole() >> UpstreamsConfig.UpstreamRole.PRIMARY
|
||||
_ * getIngressReader() >> Mock(Reader) {
|
||||
2 * read(new JsonRpcRequest("eth_test", [])) >>> [
|
||||
2 * read(new JsonRpcRequest("eth_test", new ListParams())) >>> [
|
||||
Mono.just(JsonRpcResponse.ok("null")),
|
||||
Mono.just(JsonRpcResponse.ok("1"))
|
||||
]
|
||||
@@ -155,7 +156,7 @@ class QuorumRpcReaderSpec extends Specification {
|
||||
def reader = new QuorumRpcReader(apis, new NotNullQuorum(), Stub(Tracer))
|
||||
|
||||
when:
|
||||
def act = reader.read(new JsonRpcRequest("eth_test", []))
|
||||
def act = reader.read(new JsonRpcRequest("eth_test", new ListParams()))
|
||||
.map {
|
||||
new String(it.value)
|
||||
}
|
||||
@@ -175,7 +176,7 @@ class QuorumRpcReaderSpec extends Specification {
|
||||
_ * getId() >> "id"
|
||||
_ * getRole() >> UpstreamsConfig.UpstreamRole.PRIMARY
|
||||
_ * getIngressReader() >> Mock(Reader) {
|
||||
2 * read(new JsonRpcRequest("eth_test", [])) >>> [
|
||||
2 * read(new JsonRpcRequest("eth_test", new ListParams())) >>> [
|
||||
Mono.just(JsonRpcResponse.error(1, "test")),
|
||||
Mono.just(JsonRpcResponse.ok("1"))
|
||||
]
|
||||
@@ -188,7 +189,7 @@ class QuorumRpcReaderSpec extends Specification {
|
||||
def reader = new QuorumRpcReader(apis, new NotNullQuorum(), Stub(Tracer))
|
||||
|
||||
when:
|
||||
def act = reader.read(new JsonRpcRequest("eth_test", []))
|
||||
def act = reader.read(new JsonRpcRequest("eth_test", new ListParams()))
|
||||
.map {
|
||||
new String(it.value)
|
||||
}
|
||||
@@ -203,7 +204,7 @@ class QuorumRpcReaderSpec extends Specification {
|
||||
def "non-empty-quorum - error if all failed"() {
|
||||
setup:
|
||||
def api = Mock(Reader) {
|
||||
2 * read(new JsonRpcRequest("eth_test", [])) >>> [
|
||||
2 * read(new JsonRpcRequest("eth_test", new ListParams())) >>> [
|
||||
Mono.just(JsonRpcResponse.error(1, "test")),
|
||||
Mono.just(JsonRpcResponse.error(1, "test")),
|
||||
]
|
||||
@@ -221,7 +222,7 @@ class QuorumRpcReaderSpec extends Specification {
|
||||
def reader = new QuorumRpcReader(apis, new NotNullQuorum(), Stub(Tracer))
|
||||
|
||||
when:
|
||||
def act = reader.read(new JsonRpcRequest("eth_test", []))
|
||||
def act = reader.read(new JsonRpcRequest("eth_test", new ListParams()))
|
||||
.map {
|
||||
new String(it.value)
|
||||
}
|
||||
@@ -235,7 +236,7 @@ class QuorumRpcReaderSpec extends Specification {
|
||||
def "always-quorum - error if failed"() {
|
||||
setup:
|
||||
def api = Mock(Reader) {
|
||||
1 * read(new JsonRpcRequest("eth_test", [])) >>> [
|
||||
1 * read(new JsonRpcRequest("eth_test", new ListParams())) >>> [
|
||||
Mono.just(JsonRpcResponse.error(1, "test error")),
|
||||
]
|
||||
}
|
||||
@@ -252,7 +253,7 @@ class QuorumRpcReaderSpec extends Specification {
|
||||
def reader = new QuorumRpcReader(apis, new AlwaysQuorum(), Stub(Tracer))
|
||||
|
||||
when:
|
||||
def act = reader.read(new JsonRpcRequest("eth_test", []))
|
||||
def act = reader.read(new JsonRpcRequest("eth_test", new ListParams()))
|
||||
.map {
|
||||
new String(it.value)
|
||||
}
|
||||
@@ -274,7 +275,7 @@ class QuorumRpcReaderSpec extends Specification {
|
||||
_ * isAvailable() >> true
|
||||
_ * getRole() >> UpstreamsConfig.UpstreamRole.PRIMARY
|
||||
_ * getIngressReader() >> Mock(Reader) {
|
||||
_ * read(new JsonRpcRequest("eth_test", [])) >>> [
|
||||
_ * read(new JsonRpcRequest("eth_test", new ListParams())) >>> [
|
||||
Mono.just(JsonRpcResponse.error(-3010, "test")),
|
||||
]
|
||||
}
|
||||
@@ -286,7 +287,7 @@ class QuorumRpcReaderSpec extends Specification {
|
||||
def reader = new QuorumRpcReader(apis, new NotLaggingQuorum(1), Stub(Tracer))
|
||||
|
||||
when:
|
||||
def act = reader.read(new JsonRpcRequest("eth_test", []))
|
||||
def act = reader.read(new JsonRpcRequest("eth_test", new ListParams()))
|
||||
|
||||
then:
|
||||
StepVerifier.create(act)
|
||||
@@ -312,7 +313,7 @@ class QuorumRpcReaderSpec extends Specification {
|
||||
def reader = new QuorumRpcReader(apis, new AlwaysQuorum(), Stub(Tracer))
|
||||
|
||||
when:
|
||||
def act = reader.read(new JsonRpcRequest("eth_test", []))
|
||||
def act = reader.read(new JsonRpcRequest("eth_test", new ListParams()))
|
||||
.map {
|
||||
new String(it.value)
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import io.emeraldpay.dshackle.upstream.Upstream
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcException
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import org.springframework.cloud.sleuth.Tracer
|
||||
import reactor.core.publisher.Mono
|
||||
import reactor.test.StepVerifier
|
||||
@@ -22,7 +23,7 @@ class BroadcastReaderSpec extends Specification {
|
||||
1 * isAvailable() >> true
|
||||
_ * getId() >> "id"
|
||||
1 * getIngressReader() >> Mock(Reader) {
|
||||
1 * read(new JsonRpcRequest("eth_sendRawTransaction", ["0x1"])) >>
|
||||
1 * read(new JsonRpcRequest("eth_sendRawTransaction", new ListParams(["0x1"]))) >>
|
||||
Mono.just(new JsonRpcResponse(result, null))
|
||||
}
|
||||
}
|
||||
@@ -30,7 +31,7 @@ class BroadcastReaderSpec extends Specification {
|
||||
1 * isAvailable() >> true
|
||||
_ * getId() >> "id"
|
||||
1 * getIngressReader() >> Mock(Reader) {
|
||||
1 * read(new JsonRpcRequest("eth_sendRawTransaction", ["0x1"])) >>
|
||||
1 * read(new JsonRpcRequest("eth_sendRawTransaction", new ListParams(["0x1"]))) >>
|
||||
Mono.just(new JsonRpcResponse(result, null))
|
||||
}
|
||||
}
|
||||
@@ -38,13 +39,13 @@ class BroadcastReaderSpec extends Specification {
|
||||
1 * isAvailable() >> true
|
||||
_ * getId() >> "id"
|
||||
1 * getIngressReader() >> Mock(Reader) {
|
||||
1 * read(new JsonRpcRequest("eth_sendRawTransaction", ["0x1"])) >>
|
||||
1 * read(new JsonRpcRequest("eth_sendRawTransaction", new ListParams(["0x1"]))) >>
|
||||
Mono.just(new JsonRpcResponse(result, null))
|
||||
}
|
||||
}
|
||||
def reader = new BroadcastReader([up, up1, up2], new Selector.EmptyMatcher(), null, new BroadcastQuorum(), Stub(Tracer))
|
||||
when:
|
||||
def act = reader.read(new JsonRpcRequest("eth_sendRawTransaction", ["0x1"]))
|
||||
def act = reader.read(new JsonRpcRequest("eth_sendRawTransaction", new ListParams(["0x1"])))
|
||||
then:
|
||||
StepVerifier.create(act)
|
||||
.expectNextMatches {
|
||||
@@ -61,7 +62,7 @@ class BroadcastReaderSpec extends Specification {
|
||||
1 * isAvailable() >> true
|
||||
_ * getId() >> "id"
|
||||
1 * getIngressReader() >> Mock(Reader) {
|
||||
1 * read(new JsonRpcRequest("eth_sendRawTransaction", ["0x1"])) >>
|
||||
1 * read(new JsonRpcRequest("eth_sendRawTransaction", new ListParams(["0x1"]))) >>
|
||||
Mono.just(new JsonRpcResponse(result, null))
|
||||
}
|
||||
}
|
||||
@@ -69,7 +70,7 @@ class BroadcastReaderSpec extends Specification {
|
||||
1 * isAvailable() >> true
|
||||
_ * getId() >> "id"
|
||||
1 * getIngressReader() >> Mock(Reader) {
|
||||
1 * read(new JsonRpcRequest("eth_sendRawTransaction", ["0x1"])) >>
|
||||
1 * read(new JsonRpcRequest("eth_sendRawTransaction", new ListParams(["0x1"]))) >>
|
||||
Mono.error(new JsonRpcException(1, "too low"))
|
||||
}
|
||||
}
|
||||
@@ -77,12 +78,12 @@ class BroadcastReaderSpec extends Specification {
|
||||
1 * isAvailable() >> true
|
||||
_ * getId() >> "id"
|
||||
1 * getIngressReader() >> Mock(Reader) {
|
||||
1 * read(new JsonRpcRequest("eth_sendRawTransaction", ["0x1"])) >>
|
||||
1 * read(new JsonRpcRequest("eth_sendRawTransaction", new ListParams(["0x1"]))) >>
|
||||
Mono.error(new JsonRpcException(1, "too low")) }
|
||||
}
|
||||
def reader = new BroadcastReader([up, up1, up2], new Selector.EmptyMatcher(), null, new BroadcastQuorum(), Stub(Tracer))
|
||||
when:
|
||||
def act = reader.read(new JsonRpcRequest("eth_sendRawTransaction", ["0x1"]))
|
||||
def act = reader.read(new JsonRpcRequest("eth_sendRawTransaction", new ListParams(["0x1"])))
|
||||
then:
|
||||
StepVerifier.create(act)
|
||||
.expectNextMatches {
|
||||
@@ -99,7 +100,7 @@ class BroadcastReaderSpec extends Specification {
|
||||
1 * isAvailable() >> true
|
||||
_ * getId() >> "id"
|
||||
1 * getIngressReader() >> Mock(Reader) {
|
||||
1 * read(new JsonRpcRequest("eth_sendRawTransaction", ["0x1"])) >>
|
||||
1 * read(new JsonRpcRequest("eth_sendRawTransaction", new ListParams(["0x1"]))) >>
|
||||
Mono.just(new JsonRpcResponse(result, null))
|
||||
}
|
||||
}
|
||||
@@ -115,7 +116,7 @@ class BroadcastReaderSpec extends Specification {
|
||||
}
|
||||
def reader = new BroadcastReader([up, up1, up2], new Selector.EmptyMatcher(), null, new BroadcastQuorum(), Stub(Tracer))
|
||||
when:
|
||||
def act = reader.read(new JsonRpcRequest("eth_sendRawTransaction", ["0x1"]))
|
||||
def act = reader.read(new JsonRpcRequest("eth_sendRawTransaction", new ListParams(["0x1"])))
|
||||
then:
|
||||
StepVerifier.create(act)
|
||||
.expectNextMatches {
|
||||
@@ -131,7 +132,7 @@ class BroadcastReaderSpec extends Specification {
|
||||
1 * isAvailable() >> true
|
||||
_ * getId() >> "id"
|
||||
1 * getIngressReader() >> Mock(Reader) {
|
||||
1 * read(new JsonRpcRequest("eth_sendRawTransaction", ["0x1"])) >>
|
||||
1 * read(new JsonRpcRequest("eth_sendRawTransaction", new ListParams(["0x1"]))) >>
|
||||
Mono.error(new JsonRpcException(1, "too low"))
|
||||
}
|
||||
}
|
||||
@@ -139,7 +140,7 @@ class BroadcastReaderSpec extends Specification {
|
||||
1 * isAvailable() >> true
|
||||
_ * getId() >> "id"
|
||||
1 * getIngressReader() >> Mock(Reader) {
|
||||
1 * read(new JsonRpcRequest("eth_sendRawTransaction", ["0x1"])) >>
|
||||
1 * read(new JsonRpcRequest("eth_sendRawTransaction", new ListParams(["0x1"]))) >>
|
||||
Mono.error(new JsonRpcException(1, "too low"))
|
||||
}
|
||||
}
|
||||
@@ -147,13 +148,13 @@ class BroadcastReaderSpec extends Specification {
|
||||
1 * isAvailable() >> true
|
||||
_ * getId() >> "id"
|
||||
1 * getIngressReader() >> Mock(Reader) {
|
||||
1 * read(new JsonRpcRequest("eth_sendRawTransaction", ["0x1"])) >>
|
||||
1 * read(new JsonRpcRequest("eth_sendRawTransaction", new ListParams(["0x1"]))) >>
|
||||
Mono.error(new JsonRpcException(1, "too low"))
|
||||
}
|
||||
}
|
||||
def reader = new BroadcastReader([up, up1, up2], new Selector.EmptyMatcher(), null, new BroadcastQuorum(), Stub(Tracer))
|
||||
when:
|
||||
def act = reader.read(new JsonRpcRequest("eth_sendRawTransaction", ["0x1"]))
|
||||
def act = reader.read(new JsonRpcRequest("eth_sendRawTransaction", new ListParams(["0x1"])))
|
||||
then:
|
||||
StepVerifier.create(act)
|
||||
.expectError(JsonRpcException.class)
|
||||
@@ -180,7 +181,7 @@ class BroadcastReaderSpec extends Specification {
|
||||
def reader = new BroadcastReader([up, up1, up2], new Selector.EmptyMatcher(), null, new BroadcastQuorum(), Stub(Tracer))
|
||||
when:
|
||||
def act = reader
|
||||
.read(new JsonRpcRequest("eth_sendRawTransaction", ["0x1"]))
|
||||
.read(new JsonRpcRequest("eth_sendRawTransaction", new ListParams(["0x1"])))
|
||||
.switchIfEmpty(Mono.just(new RpcReader.Result(new byte[0], null, 0, null, null)))
|
||||
then:
|
||||
StepVerifier.create(act)
|
||||
|
||||
@@ -39,6 +39,7 @@ import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcError
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcException
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import io.emeraldpay.dshackle.upstream.signature.ResponseSigner
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.rpc.RpcException
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.rpc.RpcResponseError
|
||||
@@ -75,7 +76,7 @@ class NativeCallSpec extends Specification {
|
||||
|
||||
def "Tries router first"() {
|
||||
def routedApi = Mock(Reader) {
|
||||
1 * read(new JsonRpcRequest("eth_test", [])) >> Mono.just(new JsonRpcResponse("1".bytes, null))
|
||||
1 * read(new JsonRpcRequest("eth_test", new ListParams())) >> Mono.just(new JsonRpcResponse("1".bytes, null))
|
||||
}
|
||||
def upstream = Mock(Multistream) {
|
||||
1 * getLocalReader() >> Mono.just(routedApi)
|
||||
@@ -84,7 +85,7 @@ class NativeCallSpec extends Specification {
|
||||
def nativeCall = nativeCall()
|
||||
def ctx = new NativeCall.ValidCallContext<NativeCall.ParsedCallDetails>(
|
||||
1, null, upstream, Selector.empty, new AlwaysQuorum(),
|
||||
new NativeCall.ParsedCallDetails("eth_test", []), "reqId", 1
|
||||
new NativeCall.ParsedCallDetails("eth_test", new ListParams()), "reqId", 1
|
||||
)
|
||||
|
||||
when:
|
||||
@@ -96,7 +97,7 @@ class NativeCallSpec extends Specification {
|
||||
|
||||
def "Return error if router denied the requests"() {
|
||||
def routedApi = Mock(Reader) {
|
||||
1 * read(new JsonRpcRequest("eth_test", [])) >> Mono.error(new RpcException(RpcResponseError.CODE_METHOD_NOT_EXIST, "Test message"))
|
||||
1 * read(new JsonRpcRequest("eth_test", new ListParams())) >> Mono.error(new RpcException(RpcResponseError.CODE_METHOD_NOT_EXIST, "Test message"))
|
||||
}
|
||||
def upstream = Mock(Multistream) {
|
||||
1 * getLocalReader() >> Mono.just(routedApi)
|
||||
@@ -105,7 +106,7 @@ class NativeCallSpec extends Specification {
|
||||
def nativeCall = nativeCall()
|
||||
def ctx = new NativeCall.ValidCallContext<NativeCall.ParsedCallDetails>(
|
||||
15, null, upstream, Selector.empty, new AlwaysQuorum(),
|
||||
new NativeCall.ParsedCallDetails("eth_test", []), "reqId", 1
|
||||
new NativeCall.ParsedCallDetails("eth_test", new ListParams()), "reqId", 1
|
||||
)
|
||||
|
||||
when:
|
||||
@@ -134,7 +135,7 @@ class NativeCallSpec extends Specification {
|
||||
}
|
||||
}
|
||||
def call = new NativeCall.ValidCallContext(1, 10, TestingCommons.multistream(TestingCommons.api()), Selector.empty, quorum,
|
||||
new NativeCall.ParsedCallDetails("eth_test", []), "reqId", 1)
|
||||
new NativeCall.ParsedCallDetails("eth_test", new ListParams()), "reqId", 1)
|
||||
|
||||
when:
|
||||
def resp = nativeCall.executeOnRemote(call).block(Duration.ofSeconds(1))
|
||||
@@ -152,11 +153,11 @@ class NativeCallSpec extends Specification {
|
||||
nativeCall.rpcReaderFactory = Mock(RpcReaderFactory) {
|
||||
1 * create(_) >> Mock(RpcReader) {
|
||||
1 * attempts() >> new AtomicInteger(1)
|
||||
1 * read(new JsonRpcRequest("eth_test", [], 10)) >> Mono.empty()
|
||||
1 * read(new JsonRpcRequest("eth_test", new ListParams(), 10)) >> Mono.empty()
|
||||
}
|
||||
}
|
||||
def call = new NativeCall.ValidCallContext(1, 10, TestingCommons.multistream(TestingCommons.api()), Selector.empty, quorum,
|
||||
new NativeCall.ParsedCallDetails("eth_test", []), "reqId", 1)
|
||||
new NativeCall.ParsedCallDetails("eth_test", new ListParams()), "reqId", 1)
|
||||
|
||||
when:
|
||||
def resp = nativeCall.executeOnRemote(call)
|
||||
@@ -176,13 +177,13 @@ class NativeCallSpec extends Specification {
|
||||
def nativeCall = nativeCall()
|
||||
nativeCall.rpcReaderFactory = Mock(RpcReaderFactory) {
|
||||
1 * create(_) >> Mock(RpcReader) {
|
||||
1 * read(new JsonRpcRequest("eth_test", [], 10)) >> Mono.error(
|
||||
1 * read(new JsonRpcRequest("eth_test", new ListParams(), 10)) >> Mono.error(
|
||||
new JsonRpcException(JsonRpcResponse.Id.from(12), new JsonRpcError(-32123, "Foo Bar", "Foo Bar Baz"), null, true, null)
|
||||
)
|
||||
}
|
||||
}
|
||||
def call = new NativeCall.ValidCallContext(12, 10, TestingCommons.multistream(TestingCommons.api()), Selector.empty, quorum,
|
||||
new NativeCall.ParsedCallDetails("eth_test", []), "reqId", 1)
|
||||
new NativeCall.ParsedCallDetails("eth_test", new ListParams()), "reqId", 1)
|
||||
|
||||
when:
|
||||
def resp = nativeCall.executeOnRemote(call).block(Duration.ofSeconds(1))
|
||||
@@ -536,7 +537,7 @@ class NativeCallSpec extends Specification {
|
||||
def act = nativeCall.parseParams(ctx)
|
||||
then:
|
||||
act.id == 1
|
||||
act.payload.params == []
|
||||
act.payload.params == new ListParams()
|
||||
act.payload.method == "eth_test"
|
||||
}
|
||||
|
||||
@@ -549,7 +550,7 @@ class NativeCallSpec extends Specification {
|
||||
def act = nativeCall.parseParams(ctx)
|
||||
then:
|
||||
act.id == 1
|
||||
act.payload.params == []
|
||||
act.payload.params == new ListParams()
|
||||
act.payload.method == "eth_test"
|
||||
}
|
||||
|
||||
@@ -562,7 +563,7 @@ class NativeCallSpec extends Specification {
|
||||
def act = nativeCall.parseParams(ctx)
|
||||
then:
|
||||
act.id == 1
|
||||
act.payload.params == [false]
|
||||
act.payload.params == new ListParams([false])
|
||||
act.payload.method == "eth_test"
|
||||
}
|
||||
|
||||
@@ -575,7 +576,7 @@ class NativeCallSpec extends Specification {
|
||||
def act = nativeCall.parseParams(ctx)
|
||||
then:
|
||||
act.id == 1
|
||||
act.payload.params == [false, 123]
|
||||
act.payload.params == new ListParams([false, 123])
|
||||
act.payload.method == "eth_test"
|
||||
}
|
||||
|
||||
@@ -589,7 +590,7 @@ class NativeCallSpec extends Specification {
|
||||
def act = nativeCall.parseParams(ctx)
|
||||
then:
|
||||
act.id == 1
|
||||
act.payload.params == ["0xab"]
|
||||
act.payload.params == new ListParams(["0xab"])
|
||||
act.payload.method == "eth_getFilterUpdates"
|
||||
}
|
||||
|
||||
@@ -618,7 +619,7 @@ class NativeCallSpec extends Specification {
|
||||
}
|
||||
}
|
||||
def call = new NativeCall.ValidCallContext(1, 10, multistream, Selector.empty, quorum,
|
||||
new NativeCall.ParsedCallDetails("eth_getFilterChanges", []),
|
||||
new NativeCall.ParsedCallDetails("eth_getFilterChanges", new ListParams()),
|
||||
new NativeCall.WithFilterIdDecorator(), new NativeCall.CreateFilterDecorator(), null, false, "reqId", 1)
|
||||
|
||||
when:
|
||||
@@ -654,7 +655,7 @@ class NativeCallSpec extends Specification {
|
||||
}
|
||||
}
|
||||
def call = new NativeCall.ValidCallContext(1, 10, multistream, Selector.empty, quorum,
|
||||
new NativeCall.ParsedCallDetails("eth_getFilterChanges", []),
|
||||
new NativeCall.ParsedCallDetails("eth_getFilterChanges", new ListParams()),
|
||||
new NativeCall.WithFilterIdDecorator(), new NativeCall.CreateFilterDecorator(), null, false, "reqId", 1)
|
||||
|
||||
when:
|
||||
@@ -676,7 +677,7 @@ class NativeCallSpec extends Specification {
|
||||
def ctx = new NativeCall.ValidCallContext<NativeCall.ParsedCallDetails>(10, null,
|
||||
upstream,
|
||||
Selector.empty, new AlwaysQuorum(),
|
||||
new NativeCall.ParsedCallDetails("eth_test", []), "reqId", 1)
|
||||
new NativeCall.ParsedCallDetails("eth_test", new ListParams()), "reqId", 1)
|
||||
when:
|
||||
nativeCall.fetch(ctx)
|
||||
then:
|
||||
@@ -693,7 +694,7 @@ class NativeCallSpec extends Specification {
|
||||
def ctx = new NativeCall.ValidCallContext<NativeCall.ParsedCallDetails>(10, null,
|
||||
upstream,
|
||||
Selector.empty, new AlwaysQuorum(),
|
||||
new NativeCall.ParsedCallDetails("eth_test", []), "reqId", 1)
|
||||
new NativeCall.ParsedCallDetails("eth_test", new ListParams()), "reqId", 1)
|
||||
when:
|
||||
def act = nativeCall.fetch(ctx)
|
||||
then:
|
||||
|
||||
@@ -81,7 +81,7 @@ class ApiReaderMock implements Reader<JsonRpcRequest, JsonRpcResponse> {
|
||||
@Override
|
||||
Mono<JsonRpcResponse> read(JsonRpcRequest request, boolean required = true) {
|
||||
Callable<JsonRpcResponse> call = {
|
||||
def predefined = predefined.find { it.isSame(request.method, request.params) }
|
||||
def predefined = predefined.find { it.isSame(request.method, request.params.list) }
|
||||
byte[] result = null
|
||||
JsonRpcError error = null
|
||||
calls.incrementAndGet()
|
||||
|
||||
@@ -18,6 +18,7 @@ package io.emeraldpay.dshackle.upstream.bitcoin
|
||||
import io.emeraldpay.dshackle.reader.Reader
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import reactor.core.publisher.Mono
|
||||
import reactor.core.scheduler.Schedulers
|
||||
import reactor.test.StepVerifier
|
||||
@@ -78,13 +79,13 @@ class BitcoinRpcHeadSpec extends Specification {
|
||||
"""
|
||||
|
||||
def api = Mock(Reader) {
|
||||
_ * read(new JsonRpcRequest("getbestblockhash", [])) >>> [
|
||||
_ * read(new JsonRpcRequest("getbestblockhash", new ListParams())) >>> [
|
||||
Mono.just(new JsonRpcResponse("\"$hash1\"".bytes, null)),
|
||||
Mono.just(new JsonRpcResponse("\"$hash1\"".bytes, null)),
|
||||
Mono.just(new JsonRpcResponse("\"$hash2\"".bytes, null))
|
||||
]
|
||||
_ * read(new JsonRpcRequest("getblock", [hash1])) >> Mono.just(new JsonRpcResponse(block1.bytes, null))
|
||||
_ * read(new JsonRpcRequest("getblock", [hash2])) >> Mono.just(new JsonRpcResponse(block2.bytes, null))
|
||||
_ * read(new JsonRpcRequest("getblock", new ListParams([hash1]))) >> Mono.just(new JsonRpcResponse(block1.bytes, null))
|
||||
_ * read(new JsonRpcRequest("getblock", new ListParams([hash2]))) >> Mono.just(new JsonRpcResponse(block2.bytes, null))
|
||||
}
|
||||
BitcoinRpcHead head = new BitcoinRpcHead(api, new ExtractBlock(), Duration.ofMillis(200), Schedulers.boundedElastic())
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ package io.emeraldpay.dshackle.upstream.bitcoin
|
||||
import io.emeraldpay.dshackle.reader.Reader
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import org.bitcoinj.core.Address
|
||||
import org.bitcoinj.params.MainNetParams
|
||||
import reactor.core.publisher.Mono
|
||||
@@ -29,7 +30,7 @@ class RpcUnspentReaderSpec extends Specification {
|
||||
setup:
|
||||
def json = this.class.getClassLoader().getResourceAsStream("bitcoin/unspent-one-addr.json").bytes
|
||||
def rpcReader = Mock(Reader) {
|
||||
1 * read(new JsonRpcRequest("listunspent", [1, 9999999, ["1K7xkspJg7DDKNwzXgoRSDCUxiFsRegsSK"]])) >> Mono.just(JsonRpcResponse.ok(json))
|
||||
1 * read(new JsonRpcRequest("listunspent", new ListParams([1, 9999999, ["1K7xkspJg7DDKNwzXgoRSDCUxiFsRegsSK"]]))) >> Mono.just(JsonRpcResponse.ok(json))
|
||||
}
|
||||
def upstreams = Mock(BitcoinMultistream) {
|
||||
1 * getDirectApi(_) >> Mono.just(rpcReader)
|
||||
@@ -63,7 +64,7 @@ class RpcUnspentReaderSpec extends Specification {
|
||||
setup:
|
||||
def json = this.class.getClassLoader().getResourceAsStream("bitcoin/unspent-two-addr.json").bytes
|
||||
def rpcReader = Mock(Reader) {
|
||||
1 * read(new JsonRpcRequest("listunspent", [1, 9999999, ["35hK24tcLEWcgNA4JxpvbkNkoAcDGqQPsP"]])) >> Mono.just(JsonRpcResponse.ok(json))
|
||||
1 * read(new JsonRpcRequest("listunspent", new ListParams([1, 9999999, ["35hK24tcLEWcgNA4JxpvbkNkoAcDGqQPsP"]]))) >> Mono.just(JsonRpcResponse.ok(json))
|
||||
}
|
||||
def upstreams = Mock(BitcoinMultistream) {
|
||||
1 * getDirectApi(_) >> Mono.just(rpcReader)
|
||||
|
||||
@@ -13,6 +13,7 @@ import io.emeraldpay.dshackle.upstream.*
|
||||
import io.emeraldpay.dshackle.upstream.calls.DefaultEthereumMethods
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.json.BlockJson
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.domain.Address
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.domain.BlockHash
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.domain.TransactionId
|
||||
@@ -52,7 +53,7 @@ class EthereumDirectReaderSpec extends Specification {
|
||||
)
|
||||
reader.rpcReaderFactory = Mock(RpcReaderFactory) {
|
||||
1 * create(_) >> Mock(RpcReader) {
|
||||
1 * read(new JsonRpcRequest("eth_getBlockByHash", [hash1, false])) >> Mono.just(
|
||||
1 * read(new JsonRpcRequest("eth_getBlockByHash", new ListParams([hash1, false]))) >> Mono.just(
|
||||
new RpcReader.Result(
|
||||
Global.objectMapper.writeValueAsBytes(json), null, 1, resolver, null)
|
||||
)
|
||||
@@ -79,7 +80,7 @@ class EthereumDirectReaderSpec extends Specification {
|
||||
)
|
||||
reader.rpcReaderFactory = Mock(RpcReaderFactory) {
|
||||
1 * create(_) >> Mock(RpcReader) {
|
||||
1 * read(new JsonRpcRequest("eth_getBlockByHash", [hash1, false])) >> Mono.just(
|
||||
1 * read(new JsonRpcRequest("eth_getBlockByHash", new ListParams([hash1, false]))) >> Mono.just(
|
||||
new RpcReader.Result(
|
||||
Global.objectMapper.writeValueAsBytes(null), null, 1, resolver, null
|
||||
)
|
||||
@@ -112,7 +113,7 @@ class EthereumDirectReaderSpec extends Specification {
|
||||
)
|
||||
reader.rpcReaderFactory = Mock(RpcReaderFactory) {
|
||||
1 * create(_) >> Mock(RpcReader) {
|
||||
1 * read(new JsonRpcRequest("eth_getBlockByNumber", ["0x64", false])) >> Mono.just(
|
||||
1 * read(new JsonRpcRequest("eth_getBlockByNumber", new ListParams(["0x64", false]))) >> Mono.just(
|
||||
new RpcReader.Result(
|
||||
Global.objectMapper.writeValueAsBytes(json), null, 1, resolver, null
|
||||
)
|
||||
@@ -144,7 +145,7 @@ class EthereumDirectReaderSpec extends Specification {
|
||||
)
|
||||
reader.rpcReaderFactory = Mock(RpcReaderFactory) {
|
||||
1 * create(_) >> Mock(RpcReader) {
|
||||
1 * read(new JsonRpcRequest("eth_getLogs", [Map.of("blockHash", hash1)])) >> Mono.just(
|
||||
1 * read(new JsonRpcRequest("eth_getLogs", new ListParams([Map.of("blockHash", hash1)]))) >> Mono.just(
|
||||
new RpcReader.Result(
|
||||
Global.objectMapper.writeValueAsBytes([json]), null, 1, resolver, null
|
||||
)
|
||||
@@ -177,7 +178,7 @@ class EthereumDirectReaderSpec extends Specification {
|
||||
)
|
||||
reader.rpcReaderFactory = Mock(RpcReaderFactory) {
|
||||
1 * create(_) >> Mock(RpcReader) {
|
||||
1 * read(new JsonRpcRequest("eth_getTransactionByHash", [hash1])) >> Mono.just(
|
||||
1 * read(new JsonRpcRequest("eth_getTransactionByHash", new ListParams([hash1]))) >> Mono.just(
|
||||
new RpcReader.Result(
|
||||
Global.objectMapper.writeValueAsBytes(json), null, 1, resolver, null
|
||||
)
|
||||
@@ -210,7 +211,7 @@ class EthereumDirectReaderSpec extends Specification {
|
||||
)
|
||||
reader.rpcReaderFactory = Mock(RpcReaderFactory) {
|
||||
1 * create(_) >> Mock(RpcReader) {
|
||||
1 * read(new JsonRpcRequest("eth_getTransactionReceipt", [hash1])) >> Mono.just(
|
||||
1 * read(new JsonRpcRequest("eth_getTransactionReceipt", new ListParams([hash1]))) >> Mono.just(
|
||||
new RpcReader.Result(
|
||||
Global.objectMapper.writeValueAsBytes(json), null, 1, resolver, null
|
||||
)
|
||||
@@ -244,7 +245,7 @@ class EthereumDirectReaderSpec extends Specification {
|
||||
)
|
||||
reader.rpcReaderFactory = Mock(RpcReaderFactory) {
|
||||
1 * create(_) >> Mock(RpcReader) {
|
||||
1 * read(new JsonRpcRequest("eth_getTransactionReceipt", [hash1])) >> Mono.just(
|
||||
1 * read(new JsonRpcRequest("eth_getTransactionReceipt", new ListParams([hash1]))) >> Mono.just(
|
||||
new RpcReader.Result(
|
||||
Global.objectMapper.writeValueAsBytes(json), null, 1, resolver, null
|
||||
)
|
||||
@@ -269,7 +270,7 @@ class EthereumDirectReaderSpec extends Specification {
|
||||
)
|
||||
reader.rpcReaderFactory = Mock(RpcReaderFactory) {
|
||||
1 * create(_) >> Mock(RpcReader) {
|
||||
1 * read(new JsonRpcRequest("eth_getTransactionByHash", [hash1])) >> Mono.just(
|
||||
1 * read(new JsonRpcRequest("eth_getTransactionByHash", new ListParams([hash1]))) >> Mono.just(
|
||||
new RpcReader.Result(
|
||||
Global.objectMapper.writeValueAsBytes(null), null, 1, resolver, null
|
||||
)
|
||||
@@ -299,7 +300,7 @@ class EthereumDirectReaderSpec extends Specification {
|
||||
)
|
||||
reader.rpcReaderFactory = Mock(RpcReaderFactory) {
|
||||
1 * create(_) >> Mock(RpcReader) {
|
||||
1 * read(new JsonRpcRequest("eth_getBalance", [address1, "latest"])) >> Mono.just(
|
||||
1 * read(new JsonRpcRequest("eth_getBalance", new ListParams([address1, "latest"]))) >> Mono.just(
|
||||
new RpcReader.Result(
|
||||
Global.objectMapper.writeValueAsBytes("0x100"), null, 1, resolver, null
|
||||
)
|
||||
@@ -330,7 +331,7 @@ class EthereumDirectReaderSpec extends Specification {
|
||||
)
|
||||
reader.rpcReaderFactory = Mock(RpcReaderFactory) {
|
||||
1 * create(_) >> Mock(RpcReader) {
|
||||
1 * read(new JsonRpcRequest("eth_getBalance", [address1, "0xa8c9bb"])) >> Mono.just(
|
||||
1 * read(new JsonRpcRequest("eth_getBalance", new ListParams([address1, "0xa8c9bb"]))) >> Mono.just(
|
||||
new RpcReader.Result(
|
||||
Global.objectMapper.writeValueAsBytes("0x100"), null, 1, resolver, null
|
||||
)
|
||||
@@ -368,11 +369,11 @@ class EthereumDirectReaderSpec extends Specification {
|
||||
)
|
||||
ethereumDirectReader.rpcReaderFactory = Mock(RpcReaderFactory) {
|
||||
2 * create(_) >> Mock(RpcReader) {
|
||||
2 * read(new JsonRpcRequest("eth_getBlockByHash", [hash1, false])) >>>
|
||||
2 * read(new JsonRpcRequest("eth_getBlockByHash", new ListParams([hash1, false]))) >>>
|
||||
[Mono.error(new RuntimeException()), Mono.error(new RuntimeException())]
|
||||
}
|
||||
1 * create(_) >> Mock(RpcReader) {
|
||||
1 * read(new JsonRpcRequest("eth_getBlockByHash", [hash1, false])) >> result
|
||||
1 * read(new JsonRpcRequest("eth_getBlockByHash", new ListParams([hash1, false]))) >> result
|
||||
}
|
||||
}
|
||||
when:
|
||||
@@ -408,11 +409,11 @@ class EthereumDirectReaderSpec extends Specification {
|
||||
)
|
||||
ethereumDirectReader.rpcReaderFactory = Mock(RpcReaderFactory) {
|
||||
2 * create(_) >> Mock(RpcReader) {
|
||||
2 * read(new JsonRpcRequest("eth_getBlockByNumber", ["0x64", false])) >>>
|
||||
2 * read(new JsonRpcRequest("eth_getBlockByNumber", new ListParams(["0x64", false]))) >>>
|
||||
[Mono.error(new RuntimeException()), Mono.error(new RuntimeException())]
|
||||
}
|
||||
1 * create(_) >> Mock(RpcReader) {
|
||||
1 * read(new JsonRpcRequest("eth_getBlockByNumber", ["0x64", false])) >> result
|
||||
1 * read(new JsonRpcRequest("eth_getBlockByNumber", new ListParams(["0x64", false]))) >> result
|
||||
}
|
||||
}
|
||||
when:
|
||||
@@ -441,7 +442,7 @@ class EthereumDirectReaderSpec extends Specification {
|
||||
)
|
||||
reader.rpcReaderFactory = Mock(RpcReaderFactory) {
|
||||
4 * create(_) >> Mock(RpcReader) {
|
||||
4 * read(new JsonRpcRequest("eth_getBalance", [address1, "latest"])) >>>
|
||||
4 * read(new JsonRpcRequest("eth_getBalance", new ListParams([address1, "latest"]))) >>>
|
||||
[Mono.error(new RuntimeException()), Mono.error(new RuntimeException()),
|
||||
Mono.error(new RuntimeException()), Mono.error(new RuntimeException())]
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import io.emeraldpay.dshackle.upstream.DefaultUpstream
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.subscribe.EthereumLabelsDetector
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import kotlin.Pair
|
||||
import reactor.core.publisher.Mono
|
||||
import reactor.test.StepVerifier
|
||||
@@ -52,13 +53,13 @@ class EthereumLabelsDetectorSpec extends Specification {
|
||||
setup:
|
||||
def up = Mock(DefaultUpstream) {
|
||||
1 * getIngressReader() >> Mock(Reader) {
|
||||
1 * read(new JsonRpcRequest("web3_clientVersion", [])) >>
|
||||
1 * read(new JsonRpcRequest("web3_clientVersion", new ListParams())) >>
|
||||
Mono.just(new JsonRpcResponse('no/v1.19.3+e8ac1da4/linux-x64/dotnet7.0.8'.getBytes(), null))
|
||||
1 * read(new JsonRpcRequest("eth_blockNumber", [])) >>
|
||||
1 * read(new JsonRpcRequest("eth_blockNumber", new ListParams())) >>
|
||||
Mono.just(new JsonRpcResponse("\"0x10df3e5\"".getBytes(), null))
|
||||
1 * read(new JsonRpcRequest("eth_getBalance", ["0x756F45E3FA69347A9A973A725E3C98bC4db0b5a0", "0x10dccd5"])) >>
|
||||
1 * read(new JsonRpcRequest("eth_getBalance", new ListParams(["0x756F45E3FA69347A9A973A725E3C98bC4db0b5a0", "0x10dccd5"]))) >>
|
||||
Mono.error(new RuntimeException())
|
||||
1 * read(new JsonRpcRequest("eth_getBalance", ["0x756F45E3FA69347A9A973A725E3C98bC4db0b5a0", "0x2710"])) >>
|
||||
1 * read(new JsonRpcRequest("eth_getBalance", new ListParams(["0x756F45E3FA69347A9A973A725E3C98bC4db0b5a0", "0x2710"]))) >>
|
||||
Mono.just(new JsonRpcResponse("".getBytes(), null))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import io.emeraldpay.dshackle.upstream.EmptyHead
|
||||
import io.emeraldpay.dshackle.upstream.Head
|
||||
import io.emeraldpay.dshackle.upstream.calls.DefaultEthereumMethods
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.json.BlockJson
|
||||
import org.apache.commons.collections4.functors.ConstantFactory
|
||||
import reactor.core.publisher.Mono
|
||||
@@ -34,7 +35,7 @@ class EthereumLocalReaderSpec extends Specification {
|
||||
null
|
||||
)
|
||||
when:
|
||||
def act = router.read(new JsonRpcRequest("eth_coinbase", [])).block(Duration.ofSeconds(1))
|
||||
def act = router.read(new JsonRpcRequest("eth_coinbase", new ListParams())).block(Duration.ofSeconds(1))
|
||||
then:
|
||||
act.resultAsProcessedString == "0x0000000000000000000000000000000000000000"
|
||||
}
|
||||
@@ -54,7 +55,7 @@ class EthereumLocalReaderSpec extends Specification {
|
||||
null
|
||||
)
|
||||
when:
|
||||
def act = router.read(new JsonRpcRequest("eth_getTransactionByHash", ["test"], 10))
|
||||
def act = router.read(new JsonRpcRequest("eth_getTransactionByHash", new ListParams(["test"]), 10))
|
||||
.block(Duration.ofSeconds(1))
|
||||
then:
|
||||
act == null
|
||||
|
||||
@@ -24,6 +24,7 @@ import io.emeraldpay.dshackle.upstream.Head
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcError
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import io.emeraldpay.dshackle.upstream.Upstream
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.domain.Address
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.hex.HexData
|
||||
@@ -41,7 +42,6 @@ import static io.emeraldpay.dshackle.upstream.UpstreamAvailability.*
|
||||
import static io.emeraldpay.dshackle.upstream.ValidateUpstreamSettingsResult.UPSTREAM_FATAL_SETTINGS_ERROR
|
||||
import static io.emeraldpay.dshackle.upstream.ValidateUpstreamSettingsResult.UPSTREAM_SETTINGS_ERROR
|
||||
import static io.emeraldpay.dshackle.upstream.ValidateUpstreamSettingsResult.UPSTREAM_VALID
|
||||
import static java.util.Collections.emptyList
|
||||
import io.emeraldpay.dshackle.config.ChainsConfig.ChainConfig
|
||||
|
||||
class EthereumUpstreamValidatorSpec extends Specification {
|
||||
@@ -280,8 +280,8 @@ class EthereumUpstreamValidatorSpec extends Specification {
|
||||
def up = Mock(Upstream) {
|
||||
2 * getIngressReader() >>
|
||||
Mock(Reader) {
|
||||
1 * read(new JsonRpcRequest("eth_blockNumber", [])) >> Mono.just(new JsonRpcResponse('"0x10ff9be"'.getBytes(), null))
|
||||
1 * read(new JsonRpcRequest("eth_getBlockByNumber", ["0x10fd2ae", false])) >>
|
||||
1 * read(new JsonRpcRequest("eth_blockNumber", new ListParams())) >> Mono.just(new JsonRpcResponse('"0x10ff9be"'.getBytes(), null))
|
||||
1 * read(new JsonRpcRequest("eth_getBlockByNumber", new ListParams(["0x10fd2ae", false]))) >>
|
||||
Mono.just(new JsonRpcResponse('"result"'.getBytes(), null))
|
||||
}
|
||||
}
|
||||
@@ -300,12 +300,12 @@ class EthereumUpstreamValidatorSpec extends Specification {
|
||||
}.buildOptions()
|
||||
def up = Mock(Upstream) {
|
||||
3 * getIngressReader() >> Mock(Reader) {
|
||||
1 * read(new JsonRpcRequest("eth_call", [new TransactionCallJson(
|
||||
1 * read(new JsonRpcRequest("eth_call", new ListParams([new TransactionCallJson(
|
||||
Address.from("0x32268860cAAc2948Ab5DdC7b20db5a420467Cf96"),
|
||||
HexData.from("0xd8a26e3a00000000000000000000000000000000000000000000000000000000000f4240")
|
||||
), "latest"])) >> Mono.just(new JsonRpcResponse("0x00000000000000000000".getBytes(), null))
|
||||
1 * read(new JsonRpcRequest("eth_blockNumber", [])) >> Mono.just(new JsonRpcResponse('"0x10ff9be"'.getBytes(), null))
|
||||
1 * read(new JsonRpcRequest("eth_getBlockByNumber", ["0x10fd2ae", false])) >>
|
||||
), "latest"]))) >> Mono.just(new JsonRpcResponse("0x00000000000000000000".getBytes(), null))
|
||||
1 * read(new JsonRpcRequest("eth_blockNumber", new ListParams())) >> Mono.just(new JsonRpcResponse('"0x10ff9be"'.getBytes(), null))
|
||||
1 * read(new JsonRpcRequest("eth_getBlockByNumber", new ListParams(["0x10fd2ae", false]))) >>
|
||||
Mono.just(new JsonRpcResponse('"result"'.getBytes(), null))
|
||||
}
|
||||
}
|
||||
@@ -324,12 +324,12 @@ class EthereumUpstreamValidatorSpec extends Specification {
|
||||
}.buildOptions()
|
||||
def up = Mock(Upstream) {
|
||||
3 * getIngressReader() >> Mock(Reader) {
|
||||
1 * read(new JsonRpcRequest("eth_call", [new TransactionCallJson(
|
||||
1 * read(new JsonRpcRequest("eth_call", new ListParams([new TransactionCallJson(
|
||||
Address.from("0x32268860cAAc2948Ab5DdC7b20db5a420467Cf96"),
|
||||
HexData.from("0xd8a26e3a00000000000000000000000000000000000000000000000000000000000f4240")
|
||||
), "latest"])) >> Mono.just(new JsonRpcResponse(null, new JsonRpcError(1, "Too long")))
|
||||
1 * read(new JsonRpcRequest("eth_blockNumber", [])) >> Mono.just(new JsonRpcResponse('"0x10ff9be"'.getBytes(), null))
|
||||
1 * read(new JsonRpcRequest("eth_getBlockByNumber", ["0x10fd2ae", false])) >>
|
||||
), "latest"]))) >> Mono.just(new JsonRpcResponse(null, new JsonRpcError(1, "Too long")))
|
||||
1 * read(new JsonRpcRequest("eth_blockNumber", new ListParams())) >> Mono.just(new JsonRpcResponse('"0x10ff9be"'.getBytes(), null))
|
||||
1 * read(new JsonRpcRequest("eth_getBlockByNumber", new ListParams(["0x10fd2ae", false]))) >>
|
||||
Mono.just(new JsonRpcResponse('"result"'.getBytes(), null))
|
||||
}
|
||||
}
|
||||
@@ -348,10 +348,10 @@ class EthereumUpstreamValidatorSpec extends Specification {
|
||||
}.buildOptions()
|
||||
def up = Mock(Upstream) {
|
||||
4 * getIngressReader() >> Mock(Reader) {
|
||||
1 * read(new JsonRpcRequest("eth_chainId", emptyList())) >> Mono.just(new JsonRpcResponse('"0x1"'.getBytes(), null))
|
||||
1 * read(new JsonRpcRequest("net_version", emptyList())) >> Mono.just(new JsonRpcResponse('"1"'.getBytes(), null))
|
||||
1 * read(new JsonRpcRequest("eth_blockNumber", [])) >> Mono.just(new JsonRpcResponse('"0x10ff9be"'.getBytes(), null))
|
||||
1 * read(new JsonRpcRequest("eth_getBlockByNumber", ["0x10fd2ae", false])) >>
|
||||
1 * read(new JsonRpcRequest("eth_chainId", new ListParams())) >> Mono.just(new JsonRpcResponse('"0x1"'.getBytes(), null))
|
||||
1 * read(new JsonRpcRequest("net_version", new ListParams())) >> Mono.just(new JsonRpcResponse('"1"'.getBytes(), null))
|
||||
1 * read(new JsonRpcRequest("eth_blockNumber", new ListParams())) >> Mono.just(new JsonRpcResponse('"0x10ff9be"'.getBytes(), null))
|
||||
1 * read(new JsonRpcRequest("eth_getBlockByNumber", new ListParams(["0x10fd2ae", false]))) >>
|
||||
Mono.just(new JsonRpcResponse('"result"'.getBytes(), null))
|
||||
}
|
||||
}
|
||||
@@ -370,10 +370,10 @@ class EthereumUpstreamValidatorSpec extends Specification {
|
||||
}.buildOptions()
|
||||
def up = Mock(Upstream) {
|
||||
4 * getIngressReader() >> Mock(Reader) {
|
||||
1 * read(new JsonRpcRequest("eth_chainId", emptyList())) >> Mono.just(new JsonRpcResponse('"0x1"'.getBytes(), null))
|
||||
1 * read(new JsonRpcRequest("net_version", emptyList())) >> Mono.just(new JsonRpcResponse('"1"'.getBytes(), null))
|
||||
1 * read(new JsonRpcRequest("eth_blockNumber", [])) >> Mono.just(new JsonRpcResponse('"0x10ff9be"'.getBytes(), null))
|
||||
1 * read(new JsonRpcRequest("eth_getBlockByNumber", ["0x10fd2ae", false])) >>
|
||||
1 * read(new JsonRpcRequest("eth_chainId", new ListParams())) >> Mono.just(new JsonRpcResponse('"0x1"'.getBytes(), null))
|
||||
1 * read(new JsonRpcRequest("net_version", new ListParams())) >> Mono.just(new JsonRpcResponse('"1"'.getBytes(), null))
|
||||
1 * read(new JsonRpcRequest("eth_blockNumber", new ListParams())) >> Mono.just(new JsonRpcResponse('"0x10ff9be"'.getBytes(), null))
|
||||
1 * read(new JsonRpcRequest("eth_getBlockByNumber", new ListParams(["0x10fd2ae", false]))) >>
|
||||
Mono.just(new JsonRpcResponse('"result"'.getBytes(), null))
|
||||
}
|
||||
}
|
||||
@@ -390,14 +390,14 @@ class EthereumUpstreamValidatorSpec extends Specification {
|
||||
def options = ChainOptions.PartialOptions.getDefaults().buildOptions()
|
||||
def up = Mock(Upstream) {
|
||||
5 * getIngressReader() >> Mock(Reader) {
|
||||
1 * read(new JsonRpcRequest("eth_chainId", emptyList())) >> Mono.just(new JsonRpcResponse('"0x1"'.getBytes(), null))
|
||||
1 * read(new JsonRpcRequest("net_version", emptyList())) >> Mono.just(new JsonRpcResponse('"1"'.getBytes(), null))
|
||||
1 * read(new JsonRpcRequest("eth_call", [new TransactionCallJson(
|
||||
1 * read(new JsonRpcRequest("eth_chainId", new ListParams())) >> Mono.just(new JsonRpcResponse('"0x1"'.getBytes(), null))
|
||||
1 * read(new JsonRpcRequest("net_version", new ListParams())) >> Mono.just(new JsonRpcResponse('"1"'.getBytes(), null))
|
||||
1 * read(new JsonRpcRequest("eth_call", new ListParams([new TransactionCallJson(
|
||||
Address.from("0x32268860cAAc2948Ab5DdC7b20db5a420467Cf96"),
|
||||
HexData.from("0xd8a26e3a00000000000000000000000000000000000000000000000000000000000f4240")
|
||||
), "latest"])) >> Mono.just(new JsonRpcResponse("0x00000000000000000000".getBytes(), null))
|
||||
1 * read(new JsonRpcRequest("eth_blockNumber", [])) >> Mono.just(new JsonRpcResponse('"0x10ff9be"'.getBytes(), null))
|
||||
1 * read(new JsonRpcRequest("eth_getBlockByNumber", ["0x10fd2ae", false])) >>
|
||||
), "latest"]))) >> Mono.just(new JsonRpcResponse("0x00000000000000000000".getBytes(), null))
|
||||
1 * read(new JsonRpcRequest("eth_blockNumber", new ListParams())) >> Mono.just(new JsonRpcResponse('"0x10ff9be"'.getBytes(), null))
|
||||
1 * read(new JsonRpcRequest("eth_getBlockByNumber", new ListParams(["0x10fd2ae", false]))) >>
|
||||
Mono.just(new JsonRpcResponse('"result"'.getBytes(), null))
|
||||
}
|
||||
}
|
||||
@@ -414,14 +414,14 @@ class EthereumUpstreamValidatorSpec extends Specification {
|
||||
def options = ChainOptions.PartialOptions.getDefaults().buildOptions()
|
||||
def up = Mock(Upstream) {
|
||||
5 * getIngressReader() >> Mock(Reader) {
|
||||
1 * read(new JsonRpcRequest("eth_chainId", emptyList())) >> Mono.just(new JsonRpcResponse(null, new JsonRpcError(1, "Too long")))
|
||||
1 * read(new JsonRpcRequest("net_version", emptyList())) >> Mono.just(new JsonRpcResponse(null, new JsonRpcError(1, "Too long")))
|
||||
1 * read(new JsonRpcRequest("eth_call", [new TransactionCallJson(
|
||||
1 * read(new JsonRpcRequest("eth_chainId", new ListParams())) >> Mono.just(new JsonRpcResponse(null, new JsonRpcError(1, "Too long")))
|
||||
1 * read(new JsonRpcRequest("net_version", new ListParams())) >> Mono.just(new JsonRpcResponse(null, new JsonRpcError(1, "Too long")))
|
||||
1 * read(new JsonRpcRequest("eth_call", new ListParams([new TransactionCallJson(
|
||||
Address.from("0x32268860cAAc2948Ab5DdC7b20db5a420467Cf96"),
|
||||
HexData.from("0xd8a26e3a00000000000000000000000000000000000000000000000000000000000f4240")
|
||||
), "latest"])) >> Mono.just(new JsonRpcResponse(null, new JsonRpcError(1, "Too long")))
|
||||
1 * read(new JsonRpcRequest("eth_blockNumber", [])) >> Mono.just(new JsonRpcResponse('"0x10ff9be"'.getBytes(), null))
|
||||
1 * read(new JsonRpcRequest("eth_getBlockByNumber", ["0x10fd2ae", false])) >>
|
||||
), "latest"]))) >> Mono.just(new JsonRpcResponse(null, new JsonRpcError(1, "Too long")))
|
||||
1 * read(new JsonRpcRequest("eth_blockNumber", new ListParams())) >> Mono.just(new JsonRpcResponse('"0x10ff9be"'.getBytes(), null))
|
||||
1 * read(new JsonRpcRequest("eth_getBlockByNumber", new ListParams(["0x10fd2ae", false]))) >>
|
||||
Mono.just(new JsonRpcResponse('"result"'.getBytes(), null))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import io.emeraldpay.dshackle.upstream.ethereum.json.BlockJson
|
||||
import io.emeraldpay.dshackle.upstream.forkchoice.AlwaysForkChoice
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.domain.BlockHash
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.json.TransactionRefJson
|
||||
import reactor.core.publisher.Flux
|
||||
@@ -61,7 +62,7 @@ class GenericWsHeadSpec extends Specification {
|
||||
}
|
||||
|
||||
def reader = Mock(Reader) {
|
||||
1 * it.read(new JsonRpcRequest("eth_getBlockByNumber", List.of("latest", false))) >> Mono.empty()
|
||||
1 * it.read(new JsonRpcRequest("eth_getBlockByNumber", new ListParams("latest", false))) >> Mono.empty()
|
||||
}
|
||||
|
||||
def ws = Mock(WsSubscriptions) {
|
||||
@@ -338,7 +339,7 @@ class GenericWsHeadSpec extends Specification {
|
||||
block.totalDifficulty = BigInteger.ONE
|
||||
|
||||
def reader = Mock(Reader) {
|
||||
1 * it.read(new JsonRpcRequest("eth_getBlockByNumber", List.of("latest", false))) >> Mono.empty()
|
||||
1 * it.read(new JsonRpcRequest("eth_getBlockByNumber", new ListParams("latest", false))) >> Mono.empty()
|
||||
}
|
||||
def subId = "subId"
|
||||
def ws = Mock(WsSubscriptions) {
|
||||
@@ -346,7 +347,7 @@ class GenericWsHeadSpec extends Specification {
|
||||
1 * it.subscribe(_) >> new WsSubscriptions.SubscribeData(
|
||||
Flux.error(new RuntimeException()), "id", new AtomicReference<String>(subId)
|
||||
)
|
||||
1 * it.unsubscribe(new JsonRpcRequest("eth_unsubscribe", List.of(subId), 2, null, null, false)) >>
|
||||
1 * it.unsubscribe(new JsonRpcRequest("eth_unsubscribe", new ListParams(subId), 2, null, null, false)) >>
|
||||
Mono.just(new JsonRpcResponse("".bytes, null))
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import io.emeraldpay.dshackle.test.MockWSServer
|
||||
import io.emeraldpay.dshackle.test.TestingCommons
|
||||
import io.emeraldpay.dshackle.upstream.DefaultUpstream
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import reactor.core.scheduler.Schedulers
|
||||
import reactor.test.StepVerifier
|
||||
import spock.lang.Shared
|
||||
@@ -55,7 +56,7 @@ class WsConnectionImplRealSpec extends Specification {
|
||||
def "Can make a RPC request"() {
|
||||
when:
|
||||
conn.connect()
|
||||
def resp = conn.callRpc(new JsonRpcRequest("foo_bar", []))
|
||||
def resp = conn.callRpc(new JsonRpcRequest("foo_bar", new ListParams()))
|
||||
then:
|
||||
StepVerifier.create(resp)
|
||||
.then {
|
||||
@@ -87,7 +88,7 @@ class WsConnectionImplRealSpec extends Specification {
|
||||
server.onNextReply('{"jsonrpc":"2.0","id":100,"result":1}')
|
||||
// reconnects in 2 seconds, give 1 extra
|
||||
Thread.sleep(3_000)
|
||||
def resp = conn.callRpc(new JsonRpcRequest("foo_bar", [])).block(Duration.ofSeconds(1))
|
||||
def resp = conn.callRpc(new JsonRpcRequest("foo_bar", new ListParams())).block(Duration.ofSeconds(1))
|
||||
def act = server.received
|
||||
|
||||
then:
|
||||
@@ -100,7 +101,7 @@ class WsConnectionImplRealSpec extends Specification {
|
||||
conn.connect()
|
||||
conn.reconnectIntervalSeconds = 2
|
||||
|
||||
def resp = conn.callRpc(new JsonRpcRequest("foo_bar", []))
|
||||
def resp = conn.callRpc(new JsonRpcRequest("foo_bar", new ListParams()))
|
||||
|
||||
then:
|
||||
StepVerifier.create(resp)
|
||||
@@ -121,7 +122,7 @@ class WsConnectionImplRealSpec extends Specification {
|
||||
server.onNextReply('{"jsonrpc":"2.0","id":100,"result":1}')
|
||||
Thread.sleep(3_000)
|
||||
|
||||
def resp = conn.callRpc(new JsonRpcRequest("foo_bar", [])).block(Duration.ofSeconds(1))
|
||||
def resp = conn.callRpc(new JsonRpcRequest("foo_bar", new ListParams())).block(Duration.ofSeconds(1))
|
||||
def act = server.received
|
||||
then:
|
||||
act.size() == 1
|
||||
@@ -140,7 +141,7 @@ class WsConnectionImplRealSpec extends Specification {
|
||||
// reconnects in 2 seconds, give 1 extra
|
||||
Thread.sleep(3_000)
|
||||
|
||||
def resp = conn.callRpc(new JsonRpcRequest("foo_bar", []))
|
||||
def resp = conn.callRpc(new JsonRpcRequest("foo_bar", new ListParams()))
|
||||
then:
|
||||
StepVerifier.create(resp)
|
||||
.then {
|
||||
|
||||
@@ -21,6 +21,7 @@ import io.emeraldpay.dshackle.test.GenericUpstreamMock
|
||||
import io.emeraldpay.dshackle.test.TestingCommons
|
||||
import io.emeraldpay.dshackle.upstream.DefaultUpstream
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.domain.TransactionId
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.rpc.RpcResponseError
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.json.TransactionJson
|
||||
@@ -58,7 +59,7 @@ class WsConnectionImplSpec extends Specification {
|
||||
|
||||
when:
|
||||
Flux.from(ws.handle(wsApiMock.inbound, wsApiMock.outbound)).subscribe()
|
||||
def act = ws.callRpc(new JsonRpcRequest("eth_getTransactionByHash", ["0x3ec2ebf5d0ec474d0ac6bc50d2770d8409ad76e119968e7919f85d5ec8915200"], 15, null, null, false))
|
||||
def act = ws.callRpc(new JsonRpcRequest("eth_getTransactionByHash", new ListParams(["0x3ec2ebf5d0ec474d0ac6bc50d2770d8409ad76e119968e7919f85d5ec8915200"]), 15, null, null, false))
|
||||
|
||||
then:
|
||||
StepVerifier.create(act)
|
||||
@@ -90,7 +91,7 @@ class WsConnectionImplSpec extends Specification {
|
||||
|
||||
when:
|
||||
Flux.from(ws.handle(wsApiMock.inbound, wsApiMock.outbound)).subscribe()
|
||||
def act = ws.callRpc(new JsonRpcRequest("eth_getTransactionByHash", ["0x3ec2ebf5d0ec474d0ac6bc50d2770d8409ad76e119968e7919f85d5ec8915200"], 15, null, null, false))
|
||||
def act = ws.callRpc(new JsonRpcRequest("eth_getTransactionByHash", new ListParams(["0x3ec2ebf5d0ec474d0ac6bc50d2770d8409ad76e119968e7919f85d5ec8915200"]), 15, null, null, false))
|
||||
|
||||
then:
|
||||
StepVerifier.create(act)
|
||||
@@ -124,7 +125,7 @@ class WsConnectionImplSpec extends Specification {
|
||||
|
||||
when:
|
||||
Flux.from(ws.handle(wsApiMock.inbound, wsApiMock.outbound)).subscribe()
|
||||
def act = ws.callRpc(new JsonRpcRequest("eth_getTransactionByHash", ["0x3ec2ebf5d0ec474d0ac6bc50d2770d8409ad76e119968e7919f85d5ec8915200"], 15, null, null, false))
|
||||
def act = ws.callRpc(new JsonRpcRequest("eth_getTransactionByHash", new ListParams(["0x3ec2ebf5d0ec474d0ac6bc50d2770d8409ad76e119968e7919f85d5ec8915200"]), 15, null, null, false))
|
||||
|
||||
then:
|
||||
StepVerifier.create(act)
|
||||
|
||||
@@ -18,6 +18,7 @@ package io.emeraldpay.dshackle.upstream.ethereum
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcWsMessage
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import reactor.core.publisher.Flux
|
||||
import reactor.core.publisher.Mono
|
||||
import spock.lang.Specification
|
||||
@@ -45,7 +46,7 @@ class WsSubscriptionsImplSpec extends Specification {
|
||||
def ws = new WsSubscriptionsImpl(pool)
|
||||
|
||||
when:
|
||||
def act = ws.subscribe(new JsonRpcRequest("eth_subscribe", ["foo_bar"]))
|
||||
def act = ws.subscribe(new JsonRpcRequest("eth_subscribe", new ListParams(["foo_bar"])))
|
||||
.data
|
||||
.map { new String(it) }
|
||||
.take(3)
|
||||
@@ -55,7 +56,7 @@ class WsSubscriptionsImplSpec extends Specification {
|
||||
act == ["100", "101", "102"]
|
||||
|
||||
1 * conn.callRpc({ JsonRpcRequest req ->
|
||||
req.method == "eth_subscribe" && req.params == ["foo_bar"]
|
||||
req.method == "eth_subscribe" && req.params == new ListParams(["foo_bar"])
|
||||
}) >> Mono.just(new JsonRpcResponse('"0xcff45d00e7"'.bytes, null))
|
||||
1 * conn.getSubscribeResponses() >> answers
|
||||
}
|
||||
@@ -83,7 +84,7 @@ class WsSubscriptionsImplSpec extends Specification {
|
||||
def ws = new WsSubscriptionsImpl(pool)
|
||||
|
||||
when:
|
||||
def act = ws.subscribe(new JsonRpcRequest("eth_subscribe", ["foo_bar"]))
|
||||
def act = ws.subscribe(new JsonRpcRequest("eth_subscribe", new ListParams(["foo_bar"])))
|
||||
.data
|
||||
.map { new String(it) }
|
||||
.take(3)
|
||||
@@ -93,7 +94,7 @@ class WsSubscriptionsImplSpec extends Specification {
|
||||
act == ["100", "101", "102"]
|
||||
|
||||
1 * conn.callRpc({ JsonRpcRequest req ->
|
||||
req.method == "eth_subscribe" && req.params == ["foo_bar"]
|
||||
req.method == "eth_subscribe" && req.params == new ListParams(["foo_bar"])
|
||||
}) >> Mono.just(new JsonRpcResponse('"0xcff45d00e7"'.bytes, null))
|
||||
1 * conn.getSubscribeResponses() >> answers
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package io.emeraldpay.dshackle.upstream.ethereum.subscribe
|
||||
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import io.emeraldpay.dshackle.upstream.Selector
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.WsSubscriptions
|
||||
import reactor.core.publisher.Flux
|
||||
@@ -42,7 +43,7 @@ class WebsocketPendingTxesSpec extends Specification {
|
||||
.collectList().block(Duration.ofSeconds(1))
|
||||
|
||||
then:
|
||||
1 * ws.subscribe(new JsonRpcRequest("eth_subscribe", ["newPendingTransactions"])) >> new WsSubscriptions.SubscribeData(
|
||||
1 * ws.subscribe(new JsonRpcRequest("eth_subscribe", new ListParams(["newPendingTransactions"]))) >> new WsSubscriptions.SubscribeData(
|
||||
Flux.fromIterable(responses), "id", new AtomicReference<String>("")
|
||||
)
|
||||
txes.collect {it.toHex() } == [
|
||||
|
||||
@@ -8,6 +8,7 @@ import io.emeraldpay.dshackle.Chain
|
||||
import io.emeraldpay.dshackle.test.MockGrpcServer
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.rpc.RpcException
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.rpc.RpcResponseError
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import io.grpc.stub.StreamObserver
|
||||
import spock.lang.Specification
|
||||
|
||||
@@ -39,7 +40,7 @@ class JsonRpcGrpcClientSpec extends Specification {
|
||||
|
||||
when:
|
||||
def act = client.read(
|
||||
new JsonRpcRequest("test", [])
|
||||
new JsonRpcRequest("test", new ListParams())
|
||||
).block(Duration.ofSeconds(1))
|
||||
|
||||
then:
|
||||
@@ -73,7 +74,7 @@ class JsonRpcGrpcClientSpec extends Specification {
|
||||
|
||||
when:
|
||||
client.read(
|
||||
new JsonRpcRequest("test", [])
|
||||
new JsonRpcRequest("test", new ListParams())
|
||||
).block(Duration.ofSeconds(1))
|
||||
|
||||
then:
|
||||
|
||||
@@ -18,6 +18,7 @@ package io.emeraldpay.dshackle.upstream.rpcclient
|
||||
|
||||
import io.emeraldpay.dshackle.test.TestingCommons
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.rpc.RpcResponseError
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import io.micrometer.core.instrument.Counter
|
||||
import io.micrometer.core.instrument.Timer
|
||||
import org.mockserver.integration.ClientAndServer
|
||||
@@ -61,7 +62,7 @@ class JsonRpcHttpClientSpec extends Specification {
|
||||
HttpResponse.response(resp)
|
||||
)
|
||||
when:
|
||||
def act = client.read(new JsonRpcRequest("test", [])).block()
|
||||
def act = client.read(new JsonRpcRequest("test", new ListParams())).block()
|
||||
then:
|
||||
act.error == null
|
||||
new String(act.result) == '"0x98de45"'
|
||||
@@ -80,7 +81,7 @@ class JsonRpcHttpClientSpec extends Specification {
|
||||
)
|
||||
when:
|
||||
def act = client.read(
|
||||
new JsonRpcRequest("ping", [])
|
||||
new JsonRpcRequest("ping", new ListParams())
|
||||
).block(Duration.ofSeconds(1))
|
||||
then:
|
||||
def t = thrown(RuntimeException) // reactor.core.Exceptions$ReactiveException
|
||||
@@ -108,7 +109,7 @@ class JsonRpcHttpClientSpec extends Specification {
|
||||
)
|
||||
when:
|
||||
def act = client.read(
|
||||
new JsonRpcRequest("ping", [])
|
||||
new JsonRpcRequest("ping", new ListParams())
|
||||
).block(Duration.ofSeconds(1))
|
||||
then:
|
||||
def t = thrown(RuntimeException) // reactor.core.Exceptions$ReactiveException
|
||||
|
||||
@@ -17,12 +17,13 @@ package io.emeraldpay.dshackle.upstream.rpcclient
|
||||
|
||||
|
||||
import spock.lang.Specification
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
|
||||
class JsonRpcRequestSpec extends Specification {
|
||||
|
||||
def "Serialize empty params"() {
|
||||
setup:
|
||||
def req = new JsonRpcRequest("test_foo", [])
|
||||
def req = new JsonRpcRequest("test_foo", new ListParams())
|
||||
when:
|
||||
def act = req.toJson()
|
||||
then:
|
||||
@@ -31,7 +32,7 @@ class JsonRpcRequestSpec extends Specification {
|
||||
|
||||
def "Serialize single param"() {
|
||||
setup:
|
||||
def req = new JsonRpcRequest("test_foo", ["0x0000"])
|
||||
def req = new JsonRpcRequest("test_foo", new ListParams(["0x0000"]))
|
||||
when:
|
||||
def act = req.toJson()
|
||||
then:
|
||||
@@ -40,7 +41,7 @@ class JsonRpcRequestSpec extends Specification {
|
||||
|
||||
def "Serialize two params"() {
|
||||
setup:
|
||||
def req = new JsonRpcRequest("test_foo", ["0x0000", false])
|
||||
def req = new JsonRpcRequest("test_foo", new ListParams(["0x0000", false]))
|
||||
when:
|
||||
def act = req.toJson()
|
||||
then:
|
||||
@@ -49,8 +50,8 @@ class JsonRpcRequestSpec extends Specification {
|
||||
|
||||
def "Same requests are equal"() {
|
||||
setup:
|
||||
def req1 = new JsonRpcRequest("test_foo", ["0x0000", false])
|
||||
def req2 = new JsonRpcRequest("test_foo", ["0x0000", false])
|
||||
def req1 = new JsonRpcRequest("test_foo", new ListParams(["0x0000", false]))
|
||||
def req2 = new JsonRpcRequest("test_foo", new ListParams(["0x0000", false]))
|
||||
when:
|
||||
def act = req1.equals(req2)
|
||||
then:
|
||||
|
||||
@@ -2,6 +2,7 @@ package io.emeraldpay.dshackle.upstream.rpcclient
|
||||
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.WsConnection
|
||||
import io.emeraldpay.dshackle.upstream.ethereum.WsConnectionPool
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import reactor.core.Exceptions
|
||||
import spock.lang.Specification
|
||||
|
||||
@@ -17,7 +18,7 @@ class JsonRpcWsClientSpec extends Specification {
|
||||
}
|
||||
def client = new JsonRpcWsClient(pool)
|
||||
when:
|
||||
client.read(new JsonRpcRequest("foo_bar", [], 1))
|
||||
client.read(new JsonRpcRequest("foo_bar", new ListParams([]), 1))
|
||||
.block(Duration.ofSeconds(1))
|
||||
then:
|
||||
def t = thrown(Exceptions.ReactiveException)
|
||||
|
||||
@@ -6,6 +6,7 @@ import io.emeraldpay.dshackle.upstream.ethereum.EthereumLowerBoundBlockDetector
|
||||
import io.emeraldpay.dshackle.upstream.polkadot.PolkadotLowerBoundBlockDetector
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.params.ParameterizedTest
|
||||
import org.junit.jupiter.params.provider.Arguments
|
||||
@@ -87,11 +88,11 @@ class RecursiveLowerBoundBlockDetectorTest {
|
||||
blocks.forEach {
|
||||
if (it == 17964844L) {
|
||||
on {
|
||||
read(JsonRpcRequest("eth_getBalance", listOf("0x756F45E3FA69347A9A973A725E3C98bC4db0b5a0", it.toHex())))
|
||||
read(JsonRpcRequest("eth_getBalance", ListParams("0x756F45E3FA69347A9A973A725E3C98bC4db0b5a0", it.toHex())))
|
||||
} doReturn Mono.just(JsonRpcResponse(ByteArray(0), null))
|
||||
} else {
|
||||
on {
|
||||
read(JsonRpcRequest("eth_getBalance", listOf("0x756F45E3FA69347A9A973A725E3C98bC4db0b5a0", it.toHex())))
|
||||
read(JsonRpcRequest("eth_getBalance", ListParams("0x756F45E3FA69347A9A973A725E3C98bC4db0b5a0", it.toHex())))
|
||||
} doReturn Mono.error(RuntimeException("missing trie node"))
|
||||
}
|
||||
}
|
||||
@@ -103,17 +104,17 @@ class RecursiveLowerBoundBlockDetectorTest {
|
||||
blocks.forEach {
|
||||
if (it == 17964844L) {
|
||||
on {
|
||||
read(JsonRpcRequest("chain_getBlockHash", listOf(it.toHex())))
|
||||
read(JsonRpcRequest("chain_getBlockHash", ListParams(it.toHex())))
|
||||
} doReturn Mono.just(JsonRpcResponse("\"$hash1\"".toByteArray(), null))
|
||||
on {
|
||||
read(JsonRpcRequest("state_getMetadata", listOf(hash1)))
|
||||
read(JsonRpcRequest("state_getMetadata", ListParams(hash1)))
|
||||
} doReturn Mono.just(JsonRpcResponse(ByteArray(0), null))
|
||||
} else {
|
||||
on {
|
||||
read(JsonRpcRequest("chain_getBlockHash", listOf(it.toHex())))
|
||||
read(JsonRpcRequest("chain_getBlockHash", ListParams(it.toHex())))
|
||||
} doReturn Mono.just(JsonRpcResponse("\"$hash2\"".toByteArray(), null))
|
||||
on {
|
||||
read(JsonRpcRequest("state_getMetadata", listOf(hash2)))
|
||||
read(JsonRpcRequest("state_getMetadata", ListParams(hash2)))
|
||||
} doReturn Mono.error(RuntimeException("State already discarded for"))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import io.emeraldpay.dshackle.reader.JsonRpcReader
|
||||
import io.emeraldpay.dshackle.upstream.Upstream
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ListParams
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.mockito.kotlin.doReturn
|
||||
@@ -19,13 +20,13 @@ class SolanaLowerBoundBlockDetectorTest {
|
||||
@Test
|
||||
fun `get solana lower block and slot`() {
|
||||
val reader = mock<JsonRpcReader> {
|
||||
on { read(JsonRpcRequest("getFirstAvailableBlock", listOf())) } doReturn
|
||||
on { read(JsonRpcRequest("getFirstAvailableBlock", ListParams())) } doReturn
|
||||
Mono.just(JsonRpcResponse("25000000".toByteArray(), null))
|
||||
on {
|
||||
read(
|
||||
JsonRpcRequest(
|
||||
"getBlock",
|
||||
listOf(
|
||||
ListParams(
|
||||
25000000L,
|
||||
mapOf(
|
||||
"showRewards" to false,
|
||||
|
||||
Reference in New Issue
Block a user