Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Try to use all RPC hosts for BSC iteratively if a host doesn't respond #205

Merged
merged 1 commit into from
Dec 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Try to use all RPC hosts for BSC iteratively if a host doesn't respond
  • Loading branch information
omurovch committed Dec 9, 2021
commit 4efbf45b2fbbba57fcb082e242466f8776e5fb7a
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import java.net.URL
import java.util.logging.Logger

class NodeApiProvider(
private val url: URL,
private val urls: List<URL>,
override val blockTime: Long,
private val gson: Gson,
auth: String? = null
Expand All @@ -30,11 +30,8 @@ class NodeApiProvider(
private val service: InfuraService

init {
val loggingInterceptor = HttpLoggingInterceptor(object : HttpLoggingInterceptor.Logger {
override fun log(message: String) {
logger.info(message)
}
}).setLevel(HttpLoggingInterceptor.Level.BASIC)
val loggingInterceptor = HttpLoggingInterceptor { message -> logger.info(message) }
.setLevel(HttpLoggingInterceptor.Level.BASIC)

val headersInterceptor = Interceptor { chain ->
val requestBuilder = chain.request().newBuilder()
Expand All @@ -49,7 +46,7 @@ class NodeApiProvider(
.addInterceptor(headersInterceptor)

val retrofit = Retrofit.Builder()
.baseUrl("$url/")
.baseUrl("${urls.first()}/")
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(gson))
Expand All @@ -59,19 +56,35 @@ class NodeApiProvider(
service = retrofit.create(InfuraService::class.java)
}

override val source: String = url.host
override val source: String = urls.first().host

override fun <T> single(rpc: JsonRpc<T>): Single<T> =
Single.create { emitter ->
var error: Throwable = ApiProviderError.ApiUrlNotFound

override fun <T> single(rpc: JsonRpc<T>): Single<T> {
return service.single(url.toURI(), gson.toJson(rpc))
.map { response ->
rpc.parseResponse(response, gson)
urls.forEach { url ->
try {
val response = service.single(url.toURI(), gson.toJson(rpc))
.map { response -> rpc.parseResponse(response, gson) }
.blockingGet()

emitter.onSuccess(response)
return@create
} catch (throwable: Throwable) {
error = throwable
}
}
}
emitter.onError(error)
}

private interface InfuraService {
@POST
@Headers("Content-Type: application/json", "Accept: application/json")
fun single(@Url uri: URI, @Body jsonRpc: String): Single<RpcResponse>
}

sealed class ApiProviderError : Throwable() {
object ApiUrlNotFound : ApiProviderError()
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ class EthereumKit(
webSocketRpcSyncer
}
is SyncSource.Http -> {
val apiProvider = NodeApiProvider(syncSource.url, syncSource.blockTime, gson, syncSource.auth)
val apiProvider = NodeApiProvider(syncSource.urls, syncSource.blockTime, gson, syncSource.auth)
ApiRpcSyncer(apiProvider, connectionManager)
}
}
Expand Down Expand Up @@ -470,15 +470,29 @@ class EthereumKit(
fun infuraHttpSyncSource(networkType: NetworkType, projectId: String, projectSecret: String?): SyncSource? =
infuraDomain(networkType)?.let { infuraDomain ->
val url = URL("https://$infuraDomain/v3/$projectId")
SyncSource.Http(url, networkType.blockTime, projectSecret)
SyncSource.Http(listOf(url), networkType.blockTime, projectSecret)
}

fun defaultBscWebSocketSyncSource(): SyncSource =
SyncSource.WebSocket(URL("https://bsc-ws-node.nariox.org:443"), null)


fun defaultBscHttpSyncSource(): SyncSource =
SyncSource.Http(URL("https://bsc-dataseed.binance.org"), NetworkType.BscMainNet.blockTime, null)
SyncSource.Http(listOf(
URL("https://bsc-dataseed.binance.org"),
URL("https://bsc-dataseed1.defibit.io"),
URL("https://bsc-dataseed1.ninicoin.io"),
URL("https://bsc-dataseed2.defibit.io"),
URL("https://bsc-dataseed3.defibit.io"),
URL("https://bsc-dataseed4.defibit.io"),
URL("https://bsc-dataseed2.ninicoin.io"),
URL("https://bsc-dataseed3.ninicoin.io"),
URL("https://bsc-dataseed4.ninicoin.io"),
URL("https://bsc-dataseed1.binance.org"),
URL("https://bsc-dataseed2.binance.org"),
URL("https://bsc-dataseed3.binance.org"),
URL("https://bsc-dataseed4.binance.org")),
NetworkType.BscMainNet.blockTime, null)

private fun infuraDomain(networkType: NetworkType): String? =
when (networkType) {
Expand All @@ -499,7 +513,7 @@ class EthereumKit(

sealed class SyncSource {
class WebSocket(val url: URL, val auth: String?) : SyncSource()
class Http(val url: URL, val blockTime: Long, val auth: String?) : SyncSource()
class Http(val urls: List<URL>, val blockTime: Long, val auth: String?) : SyncSource()
}

enum class NetworkType(
Expand Down