Skip to content

Commit

Permalink
fix: fix the estimation of the fee in pruning mode
Browse files Browse the repository at this point in the history
On my node I find a very nasty error that estimates the fee in the wrong way,
now this PR will bring the estimation fee in pruning mode equal to the core lightning one.

Signed-off-by: Vincenzo Palazzo <[email protected]>
  • Loading branch information
vincenzopalazzo committed Mar 29, 2023
1 parent de360fa commit 76d9823
Showing 1 changed file with 75 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,67 @@ import jrpc.clightning.plugins.CLightningPlugin
import jrpc.clightning.plugins.log.PluginLog
import jrpc.service.converters.jsonwrapper.CLightningJsonObject

class EstimateFeeParams(val lnmode: String, val target: Int, val mode: String)

class FeeManager {
private val feesEstimation: HashMap<String, EstimateFeeBitcoin> = HashMap()
private val params = listOf(
EstimateFeeParams("FEERATE_HIGHEST", 2, "CONSERVATIVE"),
EstimateFeeParams("FEERATE_URGENT", 6, "ECONOMICAL"),
EstimateFeeParams("FEERATE_NORMAL", 12, "ECONOMICAL"),
EstimateFeeParams("FEERATE_SLOW", 100, "ECONOMICAL")
)

private fun estimateFee(rpc: LiteBitcoinRPC, param: EstimateFeeParams): EstimateFeeBitcoin {
// TODO: try to use this transaction getmempoolinfo
// read this issue https://github.com/ElementsProject/lightning/issues/4473#issue-853325816
val params = Parameters("estimatesmartfee")
params.addParameter("conf_target", param.target)
params.addParameter("estimate_mode", param.mode)
return rpc.makeBitcoinRequest(params, EstimateFeeBitcoin::class.java)
}

fun estimate(rpc: LiteBitcoinRPC, plugin: CLightningPlugin): Boolean {
params.forEach {
val estimateFee = this.estimateFee(rpc, it)
if (estimateFee.errors?.isNotEmpty() == true) {
plugin.log(PluginLog.ERROR, "Error during the fee estimation")
for (error in estimateFee.errors!!) {
plugin.log(PluginLog.ERROR, "EstimateFeeBtc: %s".format(error))
}
return false
}
estimateFee.convertBtcToSat()
plugin.log(
PluginLog.DEBUG,
"EstimateFeeBtc: Estimate fee (target: %d mode: %s) calculation from bitcoin core: %d".format(
it.target,
it.target,
estimateFee.feeRate!!.toInt()
)
)
feesEstimation[it.lnmode] = estimateFee
}
return true
}

fun urgentFee(): EstimateFeeBitcoin {
return feesEstimation["FEERATE_URGENT"]!!
}

fun highestFee(): EstimateFeeBitcoin {
return feesEstimation["FEERATE_HIGHEST"]!!
}

fun normalFee(): EstimateFeeBitcoin {
return feesEstimation["FEERATE_NORMAL"]!!
}

fun slowFee(): EstimateFeeBitcoin {
return feesEstimation["FEERATE_SLOW"]!!
}
}

/**
* @author https://github.com/vincenzopalazzo
*/
Expand All @@ -44,47 +105,34 @@ class EstimateFeeBtc(
return
}
try {
// TODO: try to use this transaction getmempoolinfo
// read this issue https://github.com/ElementsProject/lightning/issues/4473#issue-853325816
val params = Parameters("estimatesmartfee")
params.addParameter("conf_target", 6)
// params.addParameter("estimate_mode", "CONSERVATIVE")

val estimateFee = bitcoinRPC.makeBitcoinRequest(params, EstimateFeeBitcoin::class.java)

if (estimateFee.errors?.isNotEmpty() == true) {
// TODO this can cause a loop? maybe
plugin.log(PluginLog.ERROR, "Error during the fee estimation")
for (error in estimateFee.errors!!) {
plugin.log(PluginLog.ERROR, "EstimateFeeBtc: %s".format(error))
}
this.returnNullFeee(response)
val estimator = FeeManager()
if (!estimator.estimate(bitcoinRPC, plugin)) {
// FIXME this can cause a loop? maybe
this.returnNullFee(response)
return
}

estimateFee.convertBtcToSat()
plugin.log(PluginLog.DEBUG, "EstimateFeeBtc: Estimate fee calculation from bitcoin core: %d".format(estimateFee.feeRate!!.toInt()))
response.apply {
add("opening", estimateFee.feeRate!!.toInt())
add("mutual_close", estimateFee.feeRate!!.toInt())
add("unilateral_close", estimateFee.feeRate!!.toInt())
add("delayed_to_us", estimateFee.feeRate!!.toInt())
add("htlc_resolution", estimateFee.feeRate!!.toInt())
add("penalty", estimateFee.feeRate!!.toInt())
add("min_acceptable", estimateFee.feeRate!!.toInt() / 2)
add("max_acceptable", estimateFee.feeRate!!.toInt() * 10)
add("opening", estimator.normalFee().feeRate!!.toInt())
add("mutual_close", estimator.slowFee().feeRate!!.toInt())
add("unilateral_close", estimator.urgentFee().feeRate!!.toInt())
add("delayed_to_us", estimator.normalFee().feeRate!!.toInt())
add("htlc_resolution", estimator.urgentFee().feeRate!!.toInt())
add("penalty", estimator.normalFee().feeRate!!.toInt())
add("min_acceptable", estimator.slowFee().feeRate!!.toInt() / 2)
add("max_acceptable", estimator.highestFee().feeRate!!.toInt() * 10)
}
} catch (bitcoinEx: BitcoinCoreException) {
plugin.log(PluginLog.ERROR, "EstimateFeeBtc: terminate bitcoin core with error: %s".format(bitcoinEx.message))
this.returnNullFeee(response)
this.returnNullFee(response)
} catch (ex: LiteBitcoinRPCException) {
plugin.log(PluginLog.ERROR, ex.stackTraceToString())
plugin.log(PluginLog.DEBUG, "EstimateFeeBtc: Share message to esplora")
alternative.run(plugin, request, response)
}
}

private fun returnNullFeee(response: CLightningJsonObject) {
private fun returnNullFee(response: CLightningJsonObject) {
response.apply {
add("opening", null)
add("mutual_close", null)
Expand Down

0 comments on commit 76d9823

Please sign in to comment.