Create FallbackFeeRateApi (#3974)

* Create AggregateFeeRateApi

* Rename, add docs
This commit is contained in:
benthecarman 2022-01-13 05:43:05 -06:00 committed by GitHub
parent e095a1b225
commit 5f4053b2e4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 0 deletions

View file

@ -99,6 +99,18 @@ class FeeRateProviderTest extends BitcoinSAsyncTest {
}
}
it must "use an aggregate of fee providers" in {
val expected = SatoshisPerByte(Satoshis(4))
val providerA = ConstantFeeRateProvider(expected)
val providerB = ConstantFeeRateProvider(SatoshisPerByte(Satoshis(2)))
val provider = FallbackFeeRateApi(Vector(providerA, providerB))
provider.getFeeRate().map { feeRate =>
assert(feeRate == expected)
}
}
private def testProvider(provider: FeeRateApi): Future[Assertion] = {
provider.getFeeRate().map { feeRate =>
assert(feeRate.toLong > 0)

View file

@ -0,0 +1,37 @@
package org.bitcoins.feeprovider
import org.bitcoins.core.api.feeprovider.FeeRateApi
import org.bitcoins.core.util.FutureUtil
import org.bitcoins.core.wallet.fee.FeeUnit
import scala.concurrent.{ExecutionContext, Future}
import scala.util.control.NonFatal
/** Takes multiple [[FeeRateApi FeeRateApis]] and attempts to get a fee rate from
* one in order until one succeeds.
*/
case class FallbackFeeRateApi(providers: Vector[FeeRateApi])(implicit
ec: ExecutionContext)
extends FeeRateApi {
override def getFeeRate(): Future[FeeUnit] = {
val init: Option[FeeUnit] = None
val retOptF = FutureUtil.foldLeftAsync(init, providers) {
case (ret, provider) =>
ret match {
case Some(value) => Future.successful(value).map(Some(_))
case None =>
provider
.getFeeRate()
.map(Some(_))
.recover { case NonFatal(_) => None }
}
}
retOptF.map {
case Some(ret) => ret
case None =>
sys.error("Failed to get fee rate from any provider")
}
}
}