We sanitize feerates if necessary to put them in descending order. */
| 329 | |
| 330 | /* We sanitize feerates if necessary to put them in descending order. */ |
| 331 | static void update_feerates(struct bitcoind *bitcoind, |
| 332 | const u32 *satoshi_per_kw, |
| 333 | struct chain_topology *topo) |
| 334 | { |
| 335 | u32 old_feerates[NUM_FEERATES]; |
| 336 | /* Smoothing factor alpha for simple exponential smoothing. The goal is to |
| 337 | * have the feerate account for 90 percent of the values polled in the last |
| 338 | * 2 minutes. The following will do that in a polling interval |
| 339 | * independent manner. */ |
| 340 | double alpha = 1 - pow(0.1,(double)topo->poll_seconds / 120); |
| 341 | bool notify_feerate_changed = false; |
| 342 | |
| 343 | for (size_t i = 0; i < NUM_FEERATES; i++) { |
| 344 | u32 feerate = satoshi_per_kw[i]; |
| 345 | |
| 346 | /* Takes into account override_fee_rate */ |
| 347 | old_feerates[i] = try_get_feerate(topo, i); |
| 348 | |
| 349 | /* If estimatefee failed, don't do anything. */ |
| 350 | if (!feerate) |
| 351 | continue; |
| 352 | |
| 353 | /* Initial smoothed feerate is the polled feerate */ |
| 354 | if (!old_feerates[i]) { |
| 355 | notify_feerate_changed = true; |
| 356 | old_feerates[i] = feerate; |
| 357 | init_feerate_history(topo, i, feerate); |
| 358 | |
| 359 | log_debug(topo->log, |
| 360 | "Smoothed feerate estimate for %s initialized to polled estimate %u", |
| 361 | feerate_name(i), feerate); |
| 362 | } else { |
| 363 | add_feerate_history(topo, i, feerate); |
| 364 | } |
| 365 | |
| 366 | /* Smooth the feerate to avoid spikes. */ |
| 367 | u32 feerate_smooth = feerate * alpha + old_feerates[i] * (1 - alpha); |
| 368 | /* But to avoid updating forever, only apply smoothing when its |
| 369 | * effect is more then 10 percent */ |
| 370 | if (abs((int)feerate - (int)feerate_smooth) > (0.1 * feerate)) { |
| 371 | feerate = feerate_smooth; |
| 372 | log_debug(topo->log, |
| 373 | "... polled feerate estimate for %s (%u) smoothed to %u (alpha=%.2f)", |
| 374 | feerate_name(i), satoshi_per_kw[i], |
| 375 | feerate, alpha); |
| 376 | } |
| 377 | |
| 378 | if (feerate < feerate_floor()) { |
| 379 | feerate = feerate_floor(); |
| 380 | log_debug(topo->log, |
| 381 | "... feerate estimate for %s hit floor %u", |
| 382 | feerate_name(i), feerate); |
| 383 | } |
| 384 | |
| 385 | if (feerate != topo->feerate[i]) { |
| 386 | log_debug(topo->log, "Feerate estimate for %s set to %u (was %u)", |
| 387 | feerate_name(i), |
| 388 | feerate, topo->feerate[i]); |
nothing calls this directly
no test coverage detected