Skip to content

Commit 2e687b9

Browse files
rustyrussellcdecker
authored andcommitted
chaintopology: set a fee floor to avoid creating unrelayable txs.
Naively, this would be 250 satoshi per sipa, but it's not since bitcoind's fee calculation was not rewritten to deal with weight, but instead bolted on using vbytes. The resulting calculations made me cry; I dried my tears on the thorns of BUILD_ASSERT (I know that makes no sense, but bear with me here as I'm trying not to swear at my bitcoind colleagues right now). Fixes: #1194 Signed-off-by: Rusty Russell <[email protected]>
1 parent 044705a commit 2e687b9

File tree

1 file changed

+50
-3
lines changed

1 file changed

+50
-3
lines changed

lightningd/chaintopology.c

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,48 @@ static const char *feerate_name(enum feerate feerate)
268268
/* Mutual recursion via timer. */
269269
static void next_updatefee_timer(struct chain_topology *topo);
270270

271+
/* bitcoind considers 250 satoshi per kw to be the minimum acceptable fee:
272+
* less than this won't even relay.
273+
*/
274+
#define BITCOIND_MINRELAYTXFEE_PER_KW 250
275+
/*
276+
* But bitcoind uses vbytes (ie. (weight + 3) / 4) for this
277+
* calculation, rather than weight, meaning we can disagree since we do
278+
* it sanely (as specified in BOLT #3).
279+
*/
280+
#define FEERATE_BITCOIND_SEES(feerate, weight) \
281+
(((feerate) * (weight)) / 1000 * 1000 / ((weight) + 3))
282+
/* ie. fee = (feerate * weight) // 1000
283+
* bitcoind needs (worst-case): fee * 1000 / (weight + 3) >= 4000
284+
*
285+
* (feerate * weight) // 1000 * 1000 // (weight + 3) >= 4000
286+
*
287+
* The feerate needs to be higher for lower weight, and our minimum tx weight
288+
* is 464 (version (4) + count_tx_in (1) + tx_in (32 + 4 + 1 + 4) +
289+
* count_tx_out (1) + amount (8) + P2WSH (1 + 1 + 32) + witness 1 + 1 + <sig>
290+
* + 1 + <key>). Assume it's 400 to give a significant safety margin (it
291+
* only makes 1 difference in the result anyway).
292+
*/
293+
#define MINIMUM_TX_WEIGHT 400
294+
/*
295+
* This formula is satisfied by a feerate of 4030 (hand-search).
296+
*/
297+
#define FEERATE_FLOOR 253
298+
static u32 feerate_floor(void)
299+
{
300+
/* Assert that bitcoind will see this as above minRelayTxFee */
301+
BUILD_ASSERT(FEERATE_BITCOIND_SEES(FEERATE_FLOOR, MINIMUM_TX_WEIGHT)
302+
>= BITCOIND_MINRELAYTXFEE_PER_KW);
303+
/* And a lesser value won't do */
304+
BUILD_ASSERT(FEERATE_BITCOIND_SEES(FEERATE_FLOOR-1, MINIMUM_TX_WEIGHT)
305+
< BITCOIND_MINRELAYTXFEE_PER_KW);
306+
/* And I'm right about it being OK for larger txs, too */
307+
BUILD_ASSERT(FEERATE_BITCOIND_SEES(FEERATE_FLOOR, (MINIMUM_TX_WEIGHT*2))
308+
>= BITCOIND_MINRELAYTXFEE_PER_KW);
309+
310+
return FEERATE_FLOOR;
311+
}
312+
271313
/* We sanitize feerates if necessary to put them in descending order. */
272314
static void update_feerates(struct bitcoind *bitcoind,
273315
const u32 *satoshi_per_kw,
@@ -277,12 +319,17 @@ static void update_feerates(struct bitcoind *bitcoind,
277319
bool changed = false;
278320

279321
for (size_t i = 0; i < NUM_FEERATES; i++) {
280-
if (satoshi_per_kw[i] != topo->feerate[i])
322+
u32 feerate = satoshi_per_kw[i];
323+
324+
if (feerate < feerate_floor())
325+
feerate = feerate_floor();
326+
327+
if (feerate != topo->feerate[i])
281328
log_debug(topo->log, "%s feerate %u (was %u)",
282329
feerate_name(i),
283-
satoshi_per_kw[i], topo->feerate[i]);
330+
feerate, topo->feerate[i]);
284331
old_feerates[i] = topo->feerate[i];
285-
topo->feerate[i] = satoshi_per_kw[i];
332+
topo->feerate[i] = feerate;
286333
}
287334

288335
for (size_t i = 0; i < NUM_FEERATES; i++) {

0 commit comments

Comments
 (0)