Implement retry of fetching bitcoind version when calling clientF (#4760)

* Implement retry of fetching bitcoind version when calling clientF

* Change BitcoindRpcClient.version to be a method rather than val
This commit is contained in:
Chris Stewart 2022-09-10 11:11:21 -05:00 committed by GitHub
parent fae1a53579
commit 61d4882efd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 35 additions and 4 deletions

View file

@ -70,7 +70,7 @@ class BitcoindRpcClient(override val instance: BitcoindInstance)(implicit
private val syncing = new AtomicBoolean(false) private val syncing = new AtomicBoolean(false)
override lazy val version: Future[BitcoindVersion] = { override def version: Future[BitcoindVersion] = {
instance match { instance match {
case _: BitcoindInstanceRemote => case _: BitcoindInstanceRemote =>
getNetworkInfo.map(info => getNetworkInfo.map(info =>

View file

@ -156,7 +156,7 @@ trait Client
* cannot be started * cannot be started
*/ */
override def start(): Future[BitcoindRpcClient] = { override def start(): Future[BitcoindRpcClient] = {
logger.info(s"Client.start() instance=$instance")
// if we're doing cookie based authentication, we might attempt // if we're doing cookie based authentication, we might attempt
// to read the cookie file before it's written. this ensures // to read the cookie file before it's written. this ensures
// we avoid that // we avoid that

View file

@ -2,7 +2,9 @@ package org.bitcoins.rpc.config
import akka.actor.ActorSystem import akka.actor.ActorSystem
import com.typesafe.config.Config import com.typesafe.config.Config
import org.bitcoins.asyncutil.AsyncUtil
import org.bitcoins.commons.config.{AppConfig, ConfigOps} import org.bitcoins.commons.config.{AppConfig, ConfigOps}
import org.bitcoins.rpc.BitcoindException.InWarmUp
import org.bitcoins.rpc.client.common.{BitcoindRpcClient, BitcoindVersion} import org.bitcoins.rpc.client.common.{BitcoindRpcClient, BitcoindVersion}
import org.bitcoins.rpc.util.AppConfigFactoryActorSystem import org.bitcoins.rpc.util.AppConfigFactoryActorSystem
import org.bitcoins.tor.Socks5ProxyParams import org.bitcoins.tor.Socks5ProxyParams
@ -11,7 +13,8 @@ import org.bitcoins.tor.config.TorAppConfig
import java.io.File import java.io.File
import java.net.{InetSocketAddress, URI} import java.net.{InetSocketAddress, URI}
import java.nio.file._ import java.nio.file._
import scala.concurrent.Future import scala.concurrent.duration.DurationInt
import scala.concurrent.{Future, Promise}
/** Configuration for a BitcoindRpcClient /** Configuration for a BitcoindRpcClient
* @param directory The data directory of the Bitcoin-S instance * @param directory The data directory of the Bitcoin-S instance
@ -173,7 +176,7 @@ case class BitcoindRpcAppConfig(
//first get a generic rpc client so we can retrieve //first get a generic rpc client so we can retrieve
//the proper version of the remote running bitcoind //the proper version of the remote running bitcoind
val noVersionRpc = new BitcoindRpcClient(bitcoindInstance) val noVersionRpc = new BitcoindRpcClient(bitcoindInstance)
val versionF = noVersionRpc.version val versionF = getBitcoindVersion(noVersionRpc)
//if we don't retrieve the proper version, we can //if we don't retrieve the proper version, we can
//end up with exceptions on an rpc client that actually supports //end up with exceptions on an rpc client that actually supports
@ -185,6 +188,34 @@ case class BitcoindRpcAppConfig(
} }
} }
} }
private def getBitcoindVersion(
client: BitcoindRpcClient): Future[BitcoindVersion] = {
val promise = Promise[BitcoindVersion]()
val interval = 1.second
val maxTries = 300 //5 minutes
for {
_ <- AsyncUtil.retryUntilSatisfiedF(
conditionF = { () =>
val infoF = client.version
val res = infoF.map(promise.success).map(_ => true)
res.recover { case _: InWarmUp =>
logger.info(s"Bitcoind still in warmup, trying again in $interval")
false
}
},
// retry for approximately 5 minutes
mode = AsyncUtil.Linear,
interval = interval,
maxTries = maxTries
)
version <- promise.future
} yield {
logger.info(s"Retrieved bitcoind version=$version")
version
}
}
} }
object BitcoindRpcAppConfig object BitcoindRpcAppConfig