mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-02-22 22:45:27 +01:00
improves exponential smoothing of feerate estimates (#1699)
- fixes problem with polling interval > 150 * 0.9 - fixes log message 'feerate hit floor' at every feerate change - smoothed fee now reaches 90% of (exp weighted) fee estimates polled in last 120s, independent of polling interval - only apply smoothing when effect > 10 percent so it doesn't correct forever - fix indentation
This commit is contained in:
parent
e0c21debc2
commit
f2ffb6d03e
2 changed files with 22 additions and 14 deletions
|
@ -237,8 +237,11 @@ static void update_feerates(struct bitcoind *bitcoind,
|
||||||
{
|
{
|
||||||
u32 old_feerates[NUM_FEERATES];
|
u32 old_feerates[NUM_FEERATES];
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
/* Rate of change of the fee smoothing, depending on the poll-interval */
|
/* Smoothing factor alpha for simple exponential smoothing. The goal is to
|
||||||
double change_rate = (double)topo->poll_seconds / 150 * 0.9;
|
* have the feerate account for 90 percent of the values polled in the last
|
||||||
|
* 2 minutes. The following will do that in a polling interval
|
||||||
|
* independent manner. */
|
||||||
|
double alpha = 1 - pow(0.1,(double)topo->poll_seconds / 120);
|
||||||
|
|
||||||
for (size_t i = 0; i < NUM_FEERATES; i++) {
|
for (size_t i = 0; i < NUM_FEERATES; i++) {
|
||||||
u32 feerate = satoshi_per_kw[i];
|
u32 feerate = satoshi_per_kw[i];
|
||||||
|
@ -250,24 +253,28 @@ static void update_feerates(struct bitcoind *bitcoind,
|
||||||
if (!feerate)
|
if (!feerate)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Smooth the feerate to avoid spikes. The goal is to have the
|
/* Smooth the feerate to avoid spikes. */
|
||||||
* fee consist of 0.9 * feerate + 0.1 * old_feerate after 300
|
u32 feerate_smooth = feerate * alpha + old_feerates[i] * (1 - alpha);
|
||||||
* seconds. The following will do that in a polling interval
|
/* But to avoid updating forever, only apply smoothing when its
|
||||||
* independent manner. */
|
* effect is more then 10 percent */
|
||||||
feerate =
|
if (abs(feerate - feerate_smooth) > (0.1 * feerate)) {
|
||||||
feerate * (1 - change_rate) + old_feerates[i] * change_rate;
|
feerate = feerate_smooth;
|
||||||
|
log_debug(topo->log,
|
||||||
|
"...feerate %u smoothed to %u (alpha=%.2f)",
|
||||||
|
satoshi_per_kw[i], feerate, alpha);
|
||||||
|
}
|
||||||
|
|
||||||
if (feerate < feerate_floor())
|
if (feerate < feerate_floor()) {
|
||||||
feerate = feerate_floor();
|
feerate = feerate_floor();
|
||||||
|
log_debug(topo->log,
|
||||||
|
"...feerate %u hit floor %u",
|
||||||
|
satoshi_per_kw[i], feerate);
|
||||||
|
}
|
||||||
|
|
||||||
if (feerate != topo->feerate[i]) {
|
if (feerate != topo->feerate[i]) {
|
||||||
log_debug(topo->log, "%s feerate %u (was %u)",
|
log_debug(topo->log, "%s feerate %u (was %u)",
|
||||||
feerate_name(i),
|
feerate_name(i),
|
||||||
feerate, topo->feerate[i]);
|
feerate, topo->feerate[i]);
|
||||||
if (feerate != satoshi_per_kw[i])
|
|
||||||
log_debug(topo->log,
|
|
||||||
"...feerate %u hit floor %u",
|
|
||||||
satoshi_per_kw[i], feerate);
|
|
||||||
}
|
}
|
||||||
topo->feerate[i] = feerate;
|
topo->feerate[i] = feerate;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <ccan/time/time.h>
|
#include <ccan/time/time.h>
|
||||||
#include <jsmn.h>
|
#include <jsmn.h>
|
||||||
#include <lightningd/watch.h>
|
#include <lightningd/watch.h>
|
||||||
|
#include <math.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
struct bitcoin_tx;
|
struct bitcoin_tx;
|
||||||
|
|
Loading…
Add table
Reference in a new issue