diff --git a/daemon/lightningd.c b/daemon/lightningd.c index 1c92ac87e..679848935 100644 --- a/daemon/lightningd.c +++ b/daemon/lightningd.c @@ -82,15 +82,15 @@ static void config_register_opts(struct lightningd_state *dstate) opt_register_arg("--forever-confirms", opt_set_u32, opt_show_u32, &dstate->config.forever_confirms, "Confirmations after which we consider a reorg impossible"); - opt_register_arg("--commit-fee", opt_set_u64, opt_show_u64, - &dstate->config.commitment_fee, - "Satoshis to offer for commitment transaction fee"); - opt_register_arg("--min-commit-fee", opt_set_u64, opt_show_u64, - &dstate->config.commitment_fee_min, - "Minimum satoshis to accept for commitment transaction fee"); - opt_register_arg("--closing-fee", opt_set_u64, opt_show_u64, - &dstate->config.closing_fee, - "Satoshis to use for mutual close transaction fee"); + opt_register_arg("--commit-fee-rate", opt_set_u64, opt_show_u64, + &dstate->config.commitment_fee_rate, + "Satoshis to offer for commitment transaction fee (per kb)"); + opt_register_arg("--min-commit-fee-rate", opt_set_u64, opt_show_u64, + &dstate->config.commitment_fee_rate_min, + "Minimum satoshis to accept for commitment transaction fee (per kb)"); + opt_register_arg("--closing-fee-rate", opt_set_u64, opt_show_u64, + &dstate->config.closing_fee_rate, + "Satoshis to use for mutual close transaction fee (per kb)"); opt_register_arg("--min-expiry", opt_set_u32, opt_show_u32, &dstate->config.min_expiry, "Minimum number of seconds to accept an HTLC before expiry"); @@ -128,14 +128,14 @@ static void default_config(struct config *config) /* FIXME: These should float with bitcoind's recommendations! */ - /* Pay hefty fee (10x current suggested minimum). */ - config->commitment_fee = 50000; + /* Pay hefty fee (double historic high of ~100k). */ + config->commitment_fee_rate = 200000; - /* Don't accept less than double the current standard fee. */ - config->commitment_fee_min = 10000; + /* Don't accept less than double the average 2-block fee. */ + config->commitment_fee_rate_min = 50000; /* Use this for mutual close. */ - config->closing_fee = 10000; + config->closing_fee_rate = 20000; /* Don't bother me unless I have 6 hours to collect. */ config->min_expiry = 6 * HOURS; @@ -149,24 +149,22 @@ static void check_config(struct lightningd_state *dstate) { /* BOLT #2: * The sender MUST set `close_fee` lower than or equal to the - * fee of the final commitment transaction, and MUST set - * `close_fee` to an even number of satoshis. + * fee of the final commitment transaction. */ - if (dstate->config.closing_fee > dstate->config.commitment_fee) - fatal("Closing fee %"PRIu64 - " can't exceed commitment fee %"PRIu64, - dstate->config.closing_fee, - dstate->config.commitment_fee); - if (dstate->config.closing_fee & 1) - fatal("Closing fee %"PRIu64 "must be even.", - dstate->config.closing_fee); + /* We do this by ensuring it's less than the minimum we would accept. */ + if (dstate->config.closing_fee_rate > dstate->config.commitment_fee_rate_min) + fatal("Closing fee rate %"PRIu64 + " can't exceed minimum commitment fee rate %"PRIu64, + dstate->config.closing_fee_rate, + dstate->config.commitment_fee_rate_min); - if (dstate->config.commitment_fee_min > dstate->config.commitment_fee) - fatal("Minumum fee %"PRIu64 - " can't exceed commitment fee %"PRIu64, - dstate->config.commitment_fee_min, - dstate->config.commitment_fee); + if (dstate->config.commitment_fee_rate_min + > dstate->config.commitment_fee_rate) + fatal("Minumum fee rate %"PRIu64 + " can't exceed commitment fee rate %"PRIu64, + dstate->config.commitment_fee_rate_min, + dstate->config.commitment_fee_rate); } static struct lightningd_state *lightningd_state(void) diff --git a/daemon/lightningd.h b/daemon/lightningd.h index 39e462abe..b1494ce06 100644 --- a/daemon/lightningd.h +++ b/daemon/lightningd.h @@ -29,14 +29,14 @@ struct config { /* How many blocks until we stop watching a close commit? */ u32 forever_confirms; - /* What are we prepared to pay in commitment fee (satoshis). */ - u64 commitment_fee; + /* What are we prepared to pay in commitment fee (satoshis/kb). */ + u64 commitment_fee_rate; /* How little are we prepared to have them pay? */ - u64 commitment_fee_min; + u64 commitment_fee_rate_min; - /* What fee we use for the closing transaction (satoshis) */ - u64 closing_fee; + /* What fee we use for the closing transaction (satoshis/kb) */ + u64 closing_fee_rate; /* Minimum/maximum time for an expiring HTLC (seconds). */ u32 min_expiry, max_expiry; diff --git a/daemon/packets.c b/daemon/packets.c index 8dec9cbea..d89395225 100644 --- a/daemon/packets.c +++ b/daemon/packets.c @@ -81,7 +81,7 @@ Pkt *pkt_open(const tal_t *ctx, const struct peer *peer, locktime__init(o->delay); o->delay->locktime_case = LOCKTIME__LOCKTIME_SECONDS; o->delay->seconds = rel_locktime_to_seconds(&peer->us.locktime); - o->commitment_fee = peer->us.commit_fee; + o->initial_fee_rate = peer->us.commit_fee_rate; if (anchor == OPEN_CHANNEL__ANCHOR_OFFER__WILL_CREATE_ANCHOR) assert(peer->us.offer_anchor == CMD_OPEN_WITH_ANCHOR); else { @@ -289,8 +289,8 @@ Pkt *accept_pkt_open(const tal_t *ctx, return pkt_err(ctx, "Delay too great"); if (o->min_depth > peer->dstate->config.anchor_confirms_max) return pkt_err(ctx, "min_depth too great"); - if (o->commitment_fee < peer->dstate->config.commitment_fee_min) - return pkt_err(ctx, "Commitment fee too low"); + if (o->initial_fee_rate < peer->dstate->config.commitment_fee_rate_min) + return pkt_err(ctx, "Commitment fee rate too low"); if (o->anch == OPEN_CHANNEL__ANCHOR_OFFER__WILL_CREATE_ANCHOR) peer->them.offer_anchor = CMD_OPEN_WITH_ANCHOR; else if (o->anch == OPEN_CHANNEL__ANCHOR_OFFER__WONT_CREATE_ANCHOR) @@ -304,7 +304,7 @@ Pkt *accept_pkt_open(const tal_t *ctx, if (!proto_to_rel_locktime(o->delay, &peer->them.locktime)) return pkt_err(ctx, "Malformed locktime"); peer->them.mindepth = o->min_depth; - peer->them.commit_fee = o->commitment_fee; + peer->them.commit_fee_rate = o->initial_fee_rate; if (!proto_to_pubkey(peer->dstate->secpctx, o->commit_key, &peer->them.commitkey)) return pkt_err(ctx, "Bad commitkey"); @@ -326,7 +326,6 @@ Pkt *accept_pkt_anchor(const tal_t *ctx, const Pkt *pkt) { const OpenAnchor *a = pkt->open_anchor; - u64 commitfee; /* They must be offering anchor for us to try accepting */ assert(peer->us.offer_anchor == CMD_OPEN_WITHOUT_ANCHOR); @@ -336,15 +335,13 @@ Pkt *accept_pkt_anchor(const tal_t *ctx, peer->anchor.index = a->output_index; peer->anchor.satoshis = a->amount; - /* Create funder's cstate, invert to get ours. */ - commitfee = commit_fee(peer->them.commit_fee, peer->us.commit_fee); + /* Create our cstate. */ peer->cstate = initial_funding(peer, - peer->us.offer_anchor, + peer->us.offer_anchor == CMD_OPEN_WITH_ANCHOR, peer->anchor.satoshis, - commitfee); + peer->us.commit_fee_rate); if (!peer->cstate) return pkt_err(ctx, "Insufficient funds for fee"); - invert_cstate(peer->cstate); /* Now we can make initial (unsigned!) commit txs. */ make_commit_txs(peer, peer, @@ -449,18 +446,14 @@ Pkt *accept_pkt_htlc_add(const tal_t *ctx, } cur->cstate = copy_funding(cur, peer->cstate); - if (!funding_delta(peer->anchor.satoshis, - 0, cur->stage.add.htlc.msatoshis, - &cur->cstate->b, &cur->cstate->a)) { + if (!funding_b_add_htlc(cur->cstate, + cur->stage.add.htlc.msatoshis, + &cur->stage.add.htlc.expiry, + &cur->stage.add.htlc.rhash)) { err = pkt_err(ctx, "Cannot afford %"PRIu64" milli-satoshis", cur->stage.add.htlc.msatoshis); goto fail; } - /* Add the htlc to their side of channel. */ - funding_add_htlc(&cur->cstate->b, - cur->stage.add.htlc.msatoshis, - &cur->stage.add.htlc.expiry, - &cur->stage.add.htlc.rhash); peer_add_htlc_expiry(peer, &cur->stage.add.htlc.expiry); peer_get_revocation_hash(peer, peer->commit_tx_counter+1, @@ -498,7 +491,6 @@ Pkt *accept_pkt_htlc_fail(const tal_t *ctx, struct peer *peer, const Pkt *pkt) Pkt *err; size_t i; struct sha256 rhash; - struct channel_htlc *htlc; proto_to_sha256(f->revocation_hash, &cur->their_revocation_hash); proto_to_sha256(f->r_hash, &rhash); @@ -511,17 +503,10 @@ Pkt *accept_pkt_htlc_fail(const tal_t *ctx, struct peer *peer, const Pkt *pkt) cur->stage.fail.fail = HTLC_FAIL; cur->stage.fail.index = i; - htlc = &peer->cstate->a.htlcs[i]; - /* Removing it should not fail: we regain HTLC amount */ + /* We regain HTLC amount */ cur->cstate = copy_funding(cur, peer->cstate); - if (!funding_delta(peer->anchor.satoshis, - 0, -htlc->msatoshis, - &cur->cstate->a, &cur->cstate->b)) { - fatal("Unexpected failure fulfilling HTLC of %"PRIu64 - " milli-satoshis", htlc->msatoshis); - } - funding_remove_htlc(&cur->cstate->a, i); + funding_a_fail_htlc(cur->cstate, i); /* FIXME: Remove timer. */ peer_get_revocation_hash(peer, peer->commit_tx_counter+1, @@ -550,7 +535,6 @@ Pkt *accept_pkt_htlc_fulfill(const tal_t *ctx, Pkt *err; size_t i; struct sha256 rhash; - struct channel_htlc *htlc; cur->stage.fulfill.fulfill = HTLC_FULFILL; proto_to_sha256(f->r, &cur->stage.fulfill.r); @@ -564,19 +548,10 @@ Pkt *accept_pkt_htlc_fulfill(const tal_t *ctx, } cur->stage.fulfill.index = i; - htlc = &peer->cstate->a.htlcs[i]; - - /* Removing it should not fail: they gain HTLC amount */ + /* Removing it: they gain HTLC amount */ cur->cstate = copy_funding(cur, peer->cstate); - if (!funding_delta(peer->anchor.satoshis, - -htlc->msatoshis, - -htlc->msatoshis, - &cur->cstate->a, &cur->cstate->b)) { - fatal("Unexpected failure fulfilling HTLC of %"PRIu64 - " milli-satoshis", htlc->msatoshis); - } - funding_remove_htlc(&cur->cstate->a, i); - + funding_a_fulfill_htlc(cur->cstate, i); + peer_get_revocation_hash(peer, peer->commit_tx_counter+1, &cur->our_revocation_hash); @@ -729,13 +704,16 @@ Pkt *accept_pkt_close_sig(const tal_t *ctx, struct peer *peer, const Pkt *pkt, struct bitcoin_signature theirsig; /* BOLT #2: - + * * The sender MUST set `close_fee` lower than or equal to the fee of the * final commitment transaction, and MUST set `close_fee` to an even * number of satoshis. */ - if (c->close_fee & 1 || c->close_fee > peer->them.commit_fee) + if ((c->close_fee & 1) + || c->close_fee > commit_tx_fee(peer->them.commit, + peer->anchor.satoshis)) { return pkt_err(ctx, "Invalid close fee"); + } /* FIXME: Don't accept tiny fee at all? */ diff --git a/daemon/peer.c b/daemon/peer.c index aa27335e9..0b936e0a7 100644 --- a/daemon/peer.c +++ b/daemon/peer.c @@ -376,8 +376,7 @@ static struct peer *new_peer(struct lightningd_state *dstate, fatal("Invalid locktime configuration %u", dstate->config.rel_locktime); peer->us.mindepth = dstate->config.anchor_confirms; - /* FIXME: Make this dynamic. */ - peer->us.commit_fee = dstate->config.commitment_fee; + peer->us.commit_fee_rate = dstate->config.commitment_fee_rate; peer->us.commit = peer->them.commit = NULL; @@ -831,6 +830,17 @@ static void spend_tx_done(struct peer *peer, int depth, state_event(peer, ptr2int(done), NULL); } +uint64_t commit_tx_fee(const struct bitcoin_tx *commit, uint64_t anchor_satoshis) +{ + uint64_t i, total = 0; + + for (i = 0; i < commit->output_count; i++) + total += commit->output[i].amount; + + assert(anchor_satoshis >= total); + return anchor_satoshis - total; +} + /* Watch this tx until it's buried enough to be forgotten. */ void peer_watch_tx(struct peer *peer, const struct bitcoin_tx *tx, @@ -855,9 +865,12 @@ struct bitcoin_tx *peer_create_close_tx(const tal_t *ctx, /* We don't need a deep copy here, just fee levels. */ cstate = *peer->cstate; - if (!adjust_fee(peer->anchor.satoshis, fee, - &cstate.a, &cstate.b)) + if (!force_fee(&cstate, fee)) { + log_unusual(peer->log, + "peer_create_close_tx: can't afford fee %"PRIu64, + fee); return NULL; + } log_debug(peer->log, "creating close-tx with fee %"PRIu64": to %02x%02x%02x%02x/%02x%02x%02x%02x, amounts %u/%u", @@ -881,14 +894,36 @@ struct bitcoin_tx *peer_create_close_tx(const tal_t *ctx, void peer_calculate_close_fee(struct peer *peer) { + /* Use actual worst-case length of close tx: based on BOLT#02's + * commitment tx numbers, but only 1 byte for output count */ + const uint64_t txsize = 41 + 221 + 10 + 32 + 32; + uint64_t maxfee; + + /* FIXME: Dynamic fee */ + peer->closing.our_fee + = fee_by_feerate(txsize, peer->dstate->config.closing_fee_rate); + /* BOLT #2: * The sender MUST set `close_fee` lower than or equal to the - * fee of the final commitment transaction, and MUST set + * fee of the final commitment transaction and MUST set * `close_fee` to an even number of satoshis. */ + maxfee = commit_tx_fee(peer->us.commit, peer->anchor.satoshis); + if (peer->closing.our_fee > maxfee) { + /* This shouldn't happen: we never accept a commit fee + * less than the min_rate, which is greater than the + * closing_fee_rate. Also, our txsize estimate for + * the closing tx is 2 bytes smaller than the commitment tx. */ + log_unusual(peer->log, + "Closing fee %"PRIu64" exceeded commit fee %"PRIu64", reducing.", + peer->closing.our_fee, maxfee); + peer->closing.our_fee = maxfee; - /* FIXME: Dynamic fee! */ - peer->closing.our_fee = peer->dstate->config.closing_fee; + /* This can happen if actual commit txfee is odd. */ + if (peer->closing.our_fee & 1) + peer->closing.our_fee--; + } + assert(!(peer->closing.our_fee & 1)); } bool peer_has_close_sig(const struct peer *peer) @@ -1056,7 +1091,7 @@ const struct bitcoin_tx *bitcoin_close(const tal_t *ctx, struct peer *peer) const struct bitcoin_tx *bitcoin_spend_ours(const tal_t *ctx, const struct peer *peer) { - u8 *redeemscript; + u8 *redeemscript, *linear; const struct bitcoin_tx *commit = peer->us.commit; struct bitcoin_signature sig; struct bitcoin_tx *tx; @@ -1075,30 +1110,46 @@ const struct bitcoin_tx *bitcoin_spend_ours(const tal_t *ctx, p2sh_out = find_p2sh_out(commit, redeemscript); tx->input[0].index = p2sh_out; tx->input[0].input_amount = commit->output[p2sh_out].amount; - /* FIXME: Dynamic fee! */ - tx->fee = peer->dstate->config.closing_fee; - tx->input[0].sequence_number = bitcoin_nsequence(&peer->them.locktime); - /* FIXME: In this case, we shouldn't do anything (not worth - * collecting) */ - if (commit->output[p2sh_out].amount <= tx->fee) - fatal("Amount of %"PRIu64" won't cover fee", - commit->output[p2sh_out].amount); - - tx->output[0].amount = commit->output[p2sh_out].amount - tx->fee; + tx->output[0].amount = commit->output[p2sh_out].amount; tx->output[0].script = scriptpubkey_p2sh(tx, bitcoin_redeem_single(tx, &peer->us.finalkey)); tx->output[0].script_length = tal_count(tx->output[0].script); - /* Now get signature, to set up input script. */ + /* Use signature, until we have fee. */ sig.stype = SIGHASH_ALL; peer_sign_spend(peer, tx, redeemscript, &sig.sig); + tx->input[0].script = scriptsig_p2sh_secret(tx, NULL, 0, &sig, redeemscript, tal_count(redeemscript)); tx->input[0].script_length = tal_count(tx->input[0].script); + /* FIXME: Figure out length first, then calc fee! */ + + /* Now, calculate the fee, given length. */ + /* FIXME: Dynamic fees! */ + linear = linearize_tx(ctx, tx); + tx->fee = fee_by_feerate(tal_count(linear), + peer->dstate->config.closing_fee_rate); + + /* FIXME: Fail gracefully in these cases (not worth collecting) */ + if (tx->fee > tx->output[0].amount + || is_dust_amount(tx->output[0].amount - tx->fee)) + fatal("Amount of %"PRIu64" won't cover fee %"PRIu64, + tx->output[0].amount, tx->fee); + + /* Re-sign with the real values. */ + tx->input[0].script_length = 0; + tx->output[0].amount -= tx->fee; + peer_sign_spend(peer, tx, redeemscript, &sig.sig); + + tx->input[0].script = scriptsig_p2sh_secret(tx, NULL, 0, &sig, + redeemscript, + tal_count(redeemscript)); + tx->input[0].script_length = tal_count(tx->input[0].script); + return tx; } @@ -1161,19 +1212,17 @@ static void created_anchor(struct lightningd_state *dstate, const struct bitcoin_tx *tx, struct peer *peer) { - size_t commitfee; - bitcoin_txid(tx, &peer->anchor.txid); peer->anchor.index = find_p2sh_out(tx, peer->anchor.redeemscript); assert(peer->anchor.satoshis == tx->output[peer->anchor.index].amount); /* We'll need this later, when we're told to broadcast it. */ peer->anchor.tx = tal_steal(peer, tx); - commitfee = commit_fee(peer->them.commit_fee, peer->us.commit_fee); + /* FIXME: Check their cstate too (different fee rate!) */ peer->cstate = initial_funding(peer, - peer->us.offer_anchor, + peer->us.offer_anchor == CMD_OPEN_WITH_ANCHOR, peer->anchor.satoshis, - commitfee); + peer->us.commit_fee_rate); if (!peer->cstate) fatal("Insufficient anchor funds for commitfee"); @@ -1245,8 +1294,10 @@ void make_commit_txs(const tal_t *ctx, our_revocation_hash, cstate); + /* Shallow copy: we don't touch HTLCs, just amounts and fees. */ their_cstate = *cstate; invert_cstate(&their_cstate); + adjust_fee(&their_cstate, peer->them.commit_fee_rate); *theirs = create_commit_tx(ctx, &peer->them.finalkey, &peer->us.finalkey, @@ -1377,16 +1428,7 @@ static void check_htlc_expiry(struct peer *peer, void *unused) continue; cstate = copy_funding(peer, peer->cstate); - - /* This should never fail! */ - if (!funding_delta(peer->anchor.satoshis, - 0, - -htlc->msatoshis, - &cstate->b, &cstate->a)) { - fatal("Unexpected failure expirint HTLC of %"PRIu64 - " milli-satoshis", htlc->msatoshis); - } - funding_remove_htlc(&cstate->b, i); + funding_b_fail_htlc(cstate, i); stage.fail.index = i; set_htlc_command(peer, cstate, NULL, CMD_SEND_HTLC_FAIL, &stage); @@ -1430,9 +1472,8 @@ static void do_newhtlc(struct peer *peer, struct newhtlc *newhtlc) /* Can we even offer this much? We check now, just before we * execute. */ cstate = copy_funding(newhtlc, peer->cstate); - if (!funding_delta(peer->anchor.satoshis, - 0, newhtlc->htlc.msatoshis, - &cstate->a, &cstate->b)) { + if (!funding_a_add_htlc(cstate, newhtlc->htlc.msatoshis, + &newhtlc->htlc.expiry, &newhtlc->htlc.rhash)) { command_fail(newhtlc->jsoncmd, "Cannot afford %"PRIu64" milli-satoshis", newhtlc->htlc.msatoshis); @@ -1440,10 +1481,6 @@ static void do_newhtlc(struct peer *peer, struct newhtlc *newhtlc) } /* FIXME: Never propose duplicate rvalues? */ - - /* Add the htlc to our side of channel. */ - funding_add_htlc(&cstate->a, newhtlc->htlc.msatoshis, - &newhtlc->htlc.expiry, &newhtlc->htlc.rhash); peer_add_htlc_expiry(peer, &newhtlc->htlc.expiry); set_htlc_command(peer, cstate, newhtlc->jsoncmd, @@ -1541,7 +1578,6 @@ static void do_fullfill(struct peer *peer, struct channel_state *cstate; struct sha256 rhash; size_t i; - struct channel_htlc *htlc; union htlc_staging stage; stage.fulfill.fulfill = HTLC_FULFILL; @@ -1556,20 +1592,8 @@ static void do_fullfill(struct peer *peer, return; } stage.fulfill.index = i; - /* Point at current one, since we remove from new cstate. */ - htlc = &peer->cstate->b.htlcs[i]; - cstate = copy_funding(fulfillhtlc, peer->cstate); - /* This should never fail! */ - if (!funding_delta(peer->anchor.satoshis, - -htlc->msatoshis, - -htlc->msatoshis, - &cstate->b, &cstate->a)) { - fatal("Unexpected failure fulfilling HTLC of %"PRIu64 - " milli-satoshis", htlc->msatoshis); - return; - } - funding_remove_htlc(&cstate->b, i); + funding_b_fulfill_htlc(cstate, i); set_htlc_command(peer, cstate, fulfillhtlc->jsoncmd, CMD_SEND_HTLC_FULFILL, &stage); @@ -1628,7 +1652,6 @@ static void do_failhtlc(struct peer *peer, { struct channel_state *cstate; size_t i; - struct channel_htlc *htlc; union htlc_staging stage; stage.fail.fail = HTLC_FAIL; @@ -1639,21 +1662,9 @@ static void do_failhtlc(struct peer *peer, return; } stage.fail.index = i; - /* Point to current one, since we remove from new cstate. */ - htlc = &peer->cstate->b.htlcs[i]; cstate = copy_funding(failhtlc, peer->cstate); - - /* This should never fail! */ - if (!funding_delta(peer->anchor.satoshis, - 0, - -htlc->msatoshis, - &cstate->b, &cstate->a)) { - fatal("Unexpected failure routefailing HTLC of %"PRIu64 - " milli-satoshis", htlc->msatoshis); - return; - } - funding_remove_htlc(&cstate->b, i); + funding_b_fail_htlc(cstate, i); set_htlc_command(peer, cstate, failhtlc->jsoncmd, CMD_SEND_HTLC_FAIL, &stage); diff --git a/daemon/peer.h b/daemon/peer.h index 190570d18..bcf882fc4 100644 --- a/daemon/peer.h +++ b/daemon/peer.h @@ -52,7 +52,7 @@ struct peer_visible_state { /* Minimum depth of anchor before channel usable. */ unsigned int mindepth; /* Commitment fee they're offering (satoshi). */ - u64 commit_fee; + u64 commit_fee_rate; /* Revocation hash for latest commit tx. */ struct sha256 revocation_hash; /* Revocation hash for next commit tx. */ @@ -187,4 +187,6 @@ void peer_add_htlc_expiry(struct peer *peer, struct bitcoin_tx *peer_create_close_tx(const tal_t *ctx, const struct peer *peer, u64 fee); +uint64_t commit_tx_fee(const struct bitcoin_tx *commit, + uint64_t anchor_satoshis); #endif /* LIGHTNING_DAEMON_PEER_H */ diff --git a/daemon/test/test.sh b/daemon/test/test.sh index a47060983..0c25b7df2 100755 --- a/daemon/test/test.sh +++ b/daemon/test/test.sh @@ -16,6 +16,17 @@ REDIRERR1="$DIR1/errors" REDIRERR2="$DIR2/errors" FGREP="fgrep -q" +# setup.sh gives us 0.00999999 bitcoin, = 999999 satoshi = 999999000 millisatoshi +AMOUNT=999999000 + +# Default fee rate per kb. +FEE_RATE=200000 + +# Fee in millisatoshi if we have no htlcs (note rounding to make it even) +NO_HTLCS_FEE=$((338 * $FEE_RATE / 2000 * 2000)) +ONE_HTLCS_FEE=$(( (338 + 32) * $FEE_RATE / 2000 * 2000)) +EXTRA_FEE=$(($ONE_HTLCS_FEE - $NO_HTLCS_FEE)) + # Always use valgrind. PREFIX="valgrind -q --error-exitcode=7" @@ -240,7 +251,11 @@ sleep 2 lcli1 getpeers | $FGREP STATE_NORMAL_HIGHPRIO lcli2 getpeers | $FGREP STATE_NORMAL_LOWPRIO -check_status 949999000 50000000 "" 0 0 "" +A_AMOUNT=$(($AMOUNT - $NO_HTLCS_FEE)) +A_FEE=$NO_HTLCS_FEE +B_AMOUNT=0 +B_FEE=0 +check_status $A_AMOUNT $A_FEE "" $B_AMOUNT $B_FEE "" EXPIRY=$(( $(date +%s) + 1000)) SECRET=1de08917a61cb2b62ed5937d38577f6a7bfe59c176781c6d8128018e8b5ccdfd @@ -248,29 +263,43 @@ RHASH=`lcli1 dev-rhash $SECRET | sed 's/.*"\([0-9a-f]*\)".*/\1/'` lcli1 newhtlc $ID2 1000000 $EXPIRY $RHASH # Check channel status -check_status 948999000 50000000 '{ "msatoshis" : 1000000, "expiry" : { "second" : '$EXPIRY' }, "rhash" : "'$RHASH'" } ' 0 0 "" +A_AMOUNT=$(($A_AMOUNT - $EXTRA_FEE - 1000000)) +A_FEE=$(($A_FEE + $EXTRA_FEE)) +check_status $A_AMOUNT $A_FEE '{ "msatoshis" : 1000000, "expiry" : { "second" : '$EXPIRY' }, "rhash" : "'$RHASH'" } ' $B_AMOUNT $B_FEE "" lcli2 fulfillhtlc $ID1 $SECRET -# We've transferred the HTLC amount to 2, who now has to pay fees. -check_status 949999000 49000000 "" 0 1000000 "" +# We've transferred the HTLC amount to 2, who now has to pay fees, +# so no net change for A who saves on fees. +B_FEE=1000000 +# With no HTLCs, extra fee no longer required. +A_FEE=$(($A_FEE - $EXTRA_FEE - $B_FEE)) +A_AMOUNT=$(($A_AMOUNT + $EXTRA_FEE + 1000000)) + +check_status $A_AMOUNT $A_FEE "" $B_AMOUNT $B_FEE "" # A new one, at 10x the amount. lcli1 newhtlc $ID2 10000000 $EXPIRY $RHASH # Check channel status -check_status 939999000 49000000 '{ "msatoshis" : 10000000, "expiry" : { "second" : '$EXPIRY' }, "rhash" : "'$RHASH'" } ' 0 1000000 "" +A_AMOUNT=$(($A_AMOUNT - $EXTRA_FEE - 10000000)) +A_FEE=$(($A_FEE + $EXTRA_FEE)) +check_status $A_AMOUNT $A_FEE '{ "msatoshis" : 10000000, "expiry" : { "second" : '$EXPIRY' }, "rhash" : "'$RHASH'" } ' $B_AMOUNT $B_FEE "" lcli2 failhtlc $ID1 $RHASH # Back to how we were before. -check_status 949999000 49000000 "" 0 1000000 "" +A_AMOUNT=$(($A_AMOUNT + $EXTRA_FEE + 10000000)) +A_FEE=$(($A_FEE - $EXTRA_FEE)) +check_status $A_AMOUNT $A_FEE "" $B_AMOUNT $B_FEE "" # Same again, but this time it expires. lcli1 newhtlc $ID2 10000000 $EXPIRY $RHASH # Check channel status -check_status 939999000 49000000 '{ "msatoshis" : 10000000, "expiry" : { "second" : '$EXPIRY' }, "rhash" : "'$RHASH'" } ' 0 1000000 "" +A_AMOUNT=$(($A_AMOUNT - $EXTRA_FEE - 10000000)) +A_FEE=$(($A_FEE + $EXTRA_FEE)) +check_status $A_AMOUNT $A_FEE '{ "msatoshis" : 10000000, "expiry" : { "second" : '$EXPIRY' }, "rhash" : "'$RHASH'" } ' $B_AMOUNT $B_FEE "" # Make sure node1 accepts the expiry packet. lcli1 dev-mocktime $(($EXPIRY)) @@ -280,7 +309,9 @@ lcli2 dev-mocktime $(($EXPIRY + 31)) sleep 1 # Back to how we were before. -check_status 949999000 49000000 "" 0 1000000 "" +A_AMOUNT=$(($A_AMOUNT + $EXTRA_FEE + 10000000)) +A_FEE=$(($A_FEE - $EXTRA_FEE)) +check_status $A_AMOUNT $A_FEE "" $B_AMOUNT $B_FEE "" lcli1 close $ID2 diff --git a/funding.c b/funding.c index e3f00ad71..5abd5f8b3 100644 --- a/funding.c +++ b/funding.c @@ -4,34 +4,35 @@ #include #include -static bool subtract_fees(uint64_t *funder, uint64_t *non_funder, - uint64_t *funder_fee, uint64_t *non_funder_fee, - bool non_funder_paying, uint64_t fee) +uint64_t fee_by_feerate(size_t txsize, uint32_t fee_rate) { - /* Funder gets 1 millisatsoshi rounding benefit! */ - *non_funder_fee = fee - fee / 2; + /* BOLT #2: + * + * The fee for a commitment transaction MUST be calculated by + * the multiplying this bytescount by the fee rate, dividing + * by 1000 and truncating (rounding down) the result to an + * even number of satoshis. + */ + return txsize * fee_rate / 2000 * 2; +} - if (*non_funder < *non_funder_fee) { - /* - * This happens initially, as funder has all the money. - * That's OK, but don't let non-funder spend if they can't - * cover fee. - */ - if (non_funder_paying) - return false; +static uint64_t calculate_fee_msat(size_t num_nondust_htlcs, + uint32_t fee_rate) +{ + uint64_t bytes; - /* Pay everything they can, funder pays rest. */ - *non_funder_fee = *non_funder; - } + /* BOLT #2: + * + * A node MUST use the formula 338 + 32 bytes for every + * non-dust HTLC as the bytecount for calculating commitment + * transaction fees. Note that the fee requirement is + * unchanged, even if the elimination of dust HTLC outputs has + * caused a non-zero fee already. + */ + bytes = 338 + 32 * num_nondust_htlcs; - /* Funder must always ensure they can pay their share. */ - *funder_fee = fee - *non_funder_fee; - if (*funder < *funder_fee) - return false; - - *non_funder -= *non_funder_fee; - *funder -= *funder_fee; - return true; + /* milli-satoshis */ + return fee_by_feerate(bytes, fee_rate) * 1000; } /* Total, in millisatoshi. */ @@ -45,130 +46,170 @@ static uint64_t htlcs_total(const struct channel_htlc *htlcs) return total; } -static bool change_funding(uint64_t anchor_satoshis, - int64_t delta_a_msat, - int64_t htlc_msat, - uint64_t a, uint64_t b, uint64_t fee, - struct channel_oneside *a_side, - struct channel_oneside *b_side) +/* Pay this much fee, if possible. Return amount unpaid. */ +static uint64_t pay_fee(struct channel_oneside *side, uint64_t fee_msat) { - uint64_t a_fee, b_fee; - int64_t delta_b_msat; - bool got_fees; - - assert(a + b + htlcs_total(a_side->htlcs) + htlcs_total(b_side->htlcs) - == anchor_satoshis * 1000); - assert(a_side->offered_anchor != b_side->offered_anchor); - - /* B gets whatever A gives. */ - delta_b_msat = -delta_a_msat; - /* A also pays for the htlc (if any). */ - delta_a_msat -= htlc_msat; - - /* Transferring more than we have? */ - if (delta_b_msat < 0 && -delta_b_msat > b) - return false; - if (delta_a_msat < 0 && -delta_a_msat > a) - return false; - - /* Adjust amounts. */ - a += delta_a_msat; - b += delta_b_msat; - - /* Take off fee from both parties if possible. */ - if (a_side->offered_anchor) - got_fees = subtract_fees(&a, &b, &a_fee, &b_fee, - delta_b_msat < 0, fee); - else - got_fees = subtract_fees(&b, &a, &b_fee, &a_fee, - delta_a_msat < 0, fee); - - if (!got_fees) - return false; - - /* Now we know we're succeeding, update caller's state */ - a_side->pay_msat = a; - b_side->pay_msat = b; - a_side->fee_msat = a_fee; - b_side->fee_msat = b_fee; - return true; + if (side->pay_msat >= fee_msat) { + side->pay_msat -= fee_msat; + side->fee_msat += fee_msat; + return 0; + } else { + uint64_t remainder = fee_msat - side->pay_msat; + side->fee_msat += side->pay_msat; + side->pay_msat = 0; + return remainder; + } } -bool funding_delta(uint64_t anchor_satoshis, - int64_t delta_a_msat, - int64_t htlc_msat, - struct channel_oneside *a_side, - struct channel_oneside *b_side) +/* Charge the fee as per BOLT #2 */ +static void recalculate_fees(struct channel_oneside *a, + struct channel_oneside *b, + uint64_t fee_msat) { - uint64_t a, b; - uint64_t fee; + uint64_t remainder; - /* Start with A and B's current contributions, and maintain fee. */ - a = a_side->pay_msat + a_side->fee_msat; - b = b_side->pay_msat + b_side->fee_msat; - fee = a_side->fee_msat + b_side->fee_msat; + /* Fold in fees, to recalcuate again below. */ + a->pay_msat += a->fee_msat; + b->pay_msat += b->fee_msat; + a->fee_msat = b->fee_msat = 0; - return change_funding(anchor_satoshis, - delta_a_msat, htlc_msat, - a, b, fee, - a_side, b_side); + /* BOLT #2: + * + * 1. If each nodes can afford half the fee from their + * to-`final_key` output, reduce the two to-`final_key` + * outputs accordingly. + * + * 2. Otherwise, reduce the to-`final_key` output of one node + * which cannot afford the fee to zero (resulting in that + * entire output paying fees). If the remaining + * to-`final_key` output is greater than the fee remaining, + * reduce it accordingly, otherwise reduce it to zero to + * pay as much fee as possible. + */ + remainder = pay_fee(a, fee_msat / 2) + pay_fee(b, fee_msat / 2); + + /* If there's anything left, the other side tries to pay for it. */ + remainder = pay_fee(a, remainder); + pay_fee(b, remainder); +} + +/* a transfers htlc_msat to a HTLC (gains it, if -ve) */ +static bool change_funding(uint64_t anchor_satoshis, + uint32_t fee_rate, + int64_t htlc_msat, + struct channel_oneside *a, + struct channel_oneside *b, + size_t num_nondust_htlcs) +{ + uint64_t fee_msat; + + assert(a->pay_msat + a->fee_msat + + b->pay_msat + b->fee_msat + + htlcs_total(a->htlcs) + htlcs_total(b->htlcs) + == anchor_satoshis * 1000); + + fee_msat = calculate_fee_msat(num_nondust_htlcs, fee_rate); + + /* If A is paying, can it afford it? */ + if (htlc_msat > 0) { + if (htlc_msat + fee_msat / 2 > a->pay_msat + a->fee_msat) + return false; + } + + /* OK, now adjust funds for A, then recalculate fees. */ + a->pay_msat -= htlc_msat; + recalculate_fees(a, b, fee_msat); + + assert(a->pay_msat + a->fee_msat + + b->pay_msat + b->fee_msat + + htlcs_total(a->htlcs) + htlcs_total(b->htlcs) + htlc_msat + == anchor_satoshis * 1000); + return true; } struct channel_state *initial_funding(const tal_t *ctx, bool am_funder, uint64_t anchor_satoshis, - uint64_t fee) + uint32_t fee_rate) { + uint64_t fee_msat; struct channel_state *cstate = talz(ctx, struct channel_state); cstate->a.htlcs = tal_arr(cstate, struct channel_htlc, 0); cstate->b.htlcs = tal_arr(cstate, struct channel_htlc, 0); - - if (fee > anchor_satoshis) + cstate->fee_rate = fee_rate; + cstate->anchor = anchor_satoshis; + + /* Anchor must fit in 32 bit. */ + if (anchor_satoshis >= (1ULL << 32) / 1000) return tal_free(cstate); - if (anchor_satoshis > (1ULL << 32) / 1000) + fee_msat = calculate_fee_msat(0, fee_rate); + if (fee_msat > anchor_satoshis * 1000) return tal_free(cstate); - + /* Initially, all goes back to funder. */ - cstate->a.pay_msat = anchor_satoshis * 1000 - fee * 1000; - cstate->a.fee_msat = fee * 1000; - cstate->a.offered_anchor = true; - cstate->b.offered_anchor = false; + cstate->a.pay_msat = anchor_satoshis * 1000 - fee_msat; + cstate->a.fee_msat = fee_msat; /* If B (not A) is funder, invert. */ if (!am_funder) invert_cstate(cstate); /* Make sure it checks out. */ - assert(funding_delta(anchor_satoshis, 0, 0, &cstate->a, &cstate->b)); + assert(change_funding(anchor_satoshis, fee_rate, 0, + &cstate->a, &cstate->b, 0)); + if (am_funder) { + assert(cstate->a.fee_msat == fee_msat); + assert(cstate->b.fee_msat == 0); + } else { + assert(cstate->b.fee_msat == fee_msat); + assert(cstate->a.fee_msat == 0); + } return cstate; } -bool adjust_fee(uint64_t anchor_satoshis, - uint64_t fee_satoshis, - struct channel_oneside *a_side, - struct channel_oneside *b_side) +/* Dust is defined as an output < 546*minRelayTxFee/1000. + * minRelayTxFee defaults to 1000 satoshi. */ +bool is_dust_amount(uint64_t satoshis) { - uint64_t a, b; + return satoshis < 546; +} - a = a_side->pay_msat + a_side->fee_msat; - b = b_side->pay_msat + b_side->fee_msat; +static size_t count_nondust_htlcs(const struct channel_htlc *htlcs) +{ + size_t i, n = tal_count(htlcs), nondust = 0; - /* No HTLC or delta, just fee recalculate. */ - return change_funding(anchor_satoshis, - 0, 0, a, b, fee_satoshis * 1000, - a_side, b_side); + for (i = 0; i < n; i++) + if (!is_dust_amount(htlcs[i].msatoshis / 1000)) + nondust++; + return nondust; +} + +static size_t total_nondust_htlcs(const struct channel_state *cstate) +{ + return count_nondust_htlcs(cstate->a.htlcs) + + count_nondust_htlcs(cstate->b.htlcs); +} + +void adjust_fee(struct channel_state *cstate, uint32_t fee_rate) +{ + uint64_t fee_msat; + + fee_msat = calculate_fee_msat(total_nondust_htlcs(cstate), fee_rate); + + recalculate_fees(&cstate->a, &cstate->b, fee_msat); +} + +bool force_fee(struct channel_state *cstate, uint64_t fee) +{ + /* Beware overflow! */ + if (fee > 0xFFFFFFFFFFFFFFFFULL / 1000) + return false; + recalculate_fees(&cstate->a, &cstate->b, fee * 1000); + return cstate->a.fee_msat + cstate->b.fee_msat == fee * 1000; } -/* We take the minimum. If one side offers too little, it should be rejected */ -uint64_t commit_fee(uint64_t a_satoshis, uint64_t b_satoshis) -{ - if (a_satoshis < b_satoshis) - return a_satoshis; - return b_satoshis; -} - void invert_cstate(struct channel_state *cstate) { struct channel_oneside tmp; @@ -178,11 +219,28 @@ void invert_cstate(struct channel_state *cstate) cstate->b = tmp; } -void funding_add_htlc(struct channel_oneside *creator, - u32 msatoshis, const struct abs_locktime *expiry, - const struct sha256 *rhash) +/* Add a HTLC to @creator if it can afford it. */ +static bool add_htlc(const struct channel_state *cstate, + struct channel_oneside *creator, + struct channel_oneside *recipient, + u32 msatoshis, const struct abs_locktime *expiry, + const struct sha256 *rhash) { - size_t n = tal_count(creator->htlcs); + size_t n, nondust; + + assert((creator == &cstate->a && recipient == &cstate->b) + || (creator == &cstate->b && recipient == &cstate->a)); + + /* Remember to count the new one in total txsize if not dust! */ + nondust = total_nondust_htlcs(cstate); + if (!is_dust_amount(msatoshis / 1000)) + nondust++; + + if (!change_funding(cstate->anchor, cstate->fee_rate, + msatoshis, creator, recipient, nondust)) + return false; + + n = tal_count(creator->htlcs); tal_resize(&creator->htlcs, n+1); creator->htlcs[n].msatoshis = msatoshis; @@ -191,6 +249,77 @@ void funding_add_htlc(struct channel_oneside *creator, memcheck(&creator->htlcs[n].msatoshis, sizeof(creator->htlcs[n].msatoshis)); memcheck(&creator->htlcs[n].rhash, sizeof(creator->htlcs[n].rhash)); + return true; +} + +/* Remove htlc from creator, credit it to beneficiary. */ +static void remove_htlc(const struct channel_state *cstate, + struct channel_oneside *creator, + struct channel_oneside *beneficiary, + struct channel_oneside *non_beneficiary, + size_t i) +{ + size_t n = tal_count(creator->htlcs); + size_t nondust; + + assert(i < n); + assert(creator == &cstate->a || creator == &cstate->b); + assert((beneficiary == &cstate->a && non_beneficiary == &cstate->b) + || (beneficiary == &cstate->b && non_beneficiary == &cstate->a)); + + /* Remember to remove this one in total txsize if not dust! */ + nondust = total_nondust_htlcs(cstate); + if (!is_dust_amount(creator->htlcs[i].msatoshis / 1000)) { + assert(nondust > 0); + nondust--; + } + + /* Can't fail since msatoshis is positive. */ + if (!change_funding(cstate->anchor, cstate->fee_rate, + -(int64_t)creator->htlcs[i].msatoshis, + beneficiary, non_beneficiary, nondust)) + abort(); + + /* Actually remove the HTLC. */ + memmove(creator->htlcs + i, creator->htlcs + i + 1, + (n - i - 1) * sizeof(*creator->htlcs)); + tal_resize(&creator->htlcs, n-1); +} + +bool funding_a_add_htlc(struct channel_state *cstate, + u32 msatoshis, const struct abs_locktime *expiry, + const struct sha256 *rhash) +{ + return add_htlc(cstate, &cstate->a, &cstate->b, + msatoshis, expiry, rhash); +} + +bool funding_b_add_htlc(struct channel_state *cstate, + u32 msatoshis, const struct abs_locktime *expiry, + const struct sha256 *rhash) +{ + return add_htlc(cstate, &cstate->b, &cstate->a, + msatoshis, expiry, rhash); +} + +void funding_a_fail_htlc(struct channel_state *cstate, size_t index) +{ + remove_htlc(cstate, &cstate->a, &cstate->a, &cstate->b, index); +} + +void funding_b_fail_htlc(struct channel_state *cstate, size_t index) +{ + remove_htlc(cstate, &cstate->b, &cstate->b, &cstate->a, index); +} + +void funding_a_fulfill_htlc(struct channel_state *cstate, size_t index) +{ + remove_htlc(cstate, &cstate->a, &cstate->b, &cstate->a, index); +} + +void funding_b_fulfill_htlc(struct channel_state *cstate, size_t index) +{ + remove_htlc(cstate, &cstate->b, &cstate->a, &cstate->b, index); } size_t funding_find_htlc(struct channel_oneside *creator, @@ -205,15 +334,6 @@ size_t funding_find_htlc(struct channel_oneside *creator, return i; } -void funding_remove_htlc(struct channel_oneside *creator, size_t i) -{ - size_t n = tal_count(creator->htlcs); - assert(i < n); - memmove(creator->htlcs + i, creator->htlcs + i + 1, - (n - i - 1) * sizeof(*creator->htlcs)); - tal_resize(&creator->htlcs, n-1); -} - struct channel_state *copy_funding(const tal_t *ctx, const struct channel_state *cstate) { diff --git a/funding.h b/funding.h index 66dac8f6d..09fc328a0 100644 --- a/funding.h +++ b/funding.h @@ -15,13 +15,15 @@ struct channel_htlc { struct channel_oneside { /* Payment and fee is in millisatoshi. */ uint32_t pay_msat, fee_msat; - /* Did we offer the anchor? */ - bool offered_anchor; /* Use tal_count to get the number */ struct channel_htlc *htlcs; }; struct channel_state { + /* Satoshis paid by anchor. */ + uint64_t anchor; + /* Satoshis per 1000 bytes. */ + uint32_t fee_rate; struct channel_oneside a, b; }; @@ -30,14 +32,14 @@ struct channel_state { * @ctx: tal context to allocate return value from. * @am_funder: am I paying for the anchor? * @anchor_satoshis: The anchor amount. - * @fee: amount to pay in fees (in satoshi). + * @fee_rate: amount to pay in fees per kb (in satoshi). * * Returns state, or NULL if malformed. */ struct channel_state *initial_funding(const tal_t *ctx, bool am_funder, uint64_t anchor_satoshis, - uint64_t fee); + uint32_t fee_rate); /** * copy_funding: Make a deep copy of channel_state @@ -48,37 +50,64 @@ struct channel_state *copy_funding(const tal_t *ctx, const struct channel_state *cstate); /** - * funding_delta: With this change, what's the new state? - * @anchor_satoshis: The anchor amount. - * @delta_a: How many millisatoshi A changes (-ve => A pay B, +ve => B pays A) - * @htlc: Millisatoshi A is putting into a HTLC (-ve if htlc is cancelled) - * @a_side: channel a's state to update. - * @b_side: channel b's state to update. + * funding_a_add_htlc: append an HTLC to A's side of cstate if it can afford it + * @cstate: The channel state + * @msatoshis: Millisatoshi A is putting into a HTLC + * @expiry: time it expires + * @rhash: hash of redeem secret + * + * If A can't afford the HTLC (or still owes its half of the fees), + * this will return false and leave @cstate unchanged. Otherwise + * cstate->a.htlcs will have the HTLC appended, and pay_msat and + * fee_msat are adjusted accordingly. */ -bool funding_delta(uint64_t anchor_satoshis, - int64_t delta_a_msat, - int64_t htlc_msat, - struct channel_oneside *a_side, - struct channel_oneside *b_side); +bool funding_a_add_htlc(struct channel_state *cstate, + u32 msatoshis, const struct abs_locktime *expiry, + const struct sha256 *rhash); + +bool funding_b_add_htlc(struct channel_state *cstate, + u32 msatoshis, const struct abs_locktime *expiry, + const struct sha256 *rhash); /** - * adjust_fee: Change fee. - * @anchor_satoshis: The anchor amount. - * @fee_satoshis: The new fee amount. - * @a_side: channel a's state to update. - * @b_side: channel b's state to update. + * funding_a_fail_htlc: remove an HTLC from A's side of cstate, funds to A + * @cstate: The channel state + * @index: the index into cstate->a.htlcs[]. + * + * This will remove the @index'th entry in cstate->a.htlcs[], and credit + * the value of the HTLC (back) to A. */ -bool adjust_fee(uint64_t anchor_satoshis, - uint64_t fee_satoshis, - struct channel_oneside *a_side, - struct channel_oneside *b_side); +void funding_a_fail_htlc(struct channel_state *cstate, size_t index); +void funding_b_fail_htlc(struct channel_state *cstate, size_t index); /** - * commit_fee: Fee amount for commit tx. - * @a_satoshis: A's openchannel->commitment_fee offer - * @b_satoshis: B's openchannel->commitment_fee offer + * funding_a_fulfill_htlc: remove an HTLC from A's side of cstate, funds to B + * @cstate: The channel state + * @index: the index into cstate->a.htlcs[]. + * + * This will remove the @index'th entry in cstate->a.htlcs[], and credit + * the value of the HTLC to B. */ -uint64_t commit_fee(uint64_t a_satoshis, uint64_t b_satoshis); +void funding_a_fulfill_htlc(struct channel_state *cstate, size_t index); +void funding_b_fulfill_htlc(struct channel_state *cstate, size_t index); + +/** + * adjust_fee: Change fee rate. + * @cstate: The channel state + * @fee_rate: fee in satoshi per 1000 bytes. + */ +void adjust_fee(struct channel_state *cstate, uint32_t fee_rate); + +/** + * force_fee: Change fee to a specific value. + * @cstate: The channel state + * @fee: fee in satoshi. + * + * This is used for the close transaction, which specifies an exact fee. + * If the fee cannot be paid in full, this return false (but cstate will + * still be altered). + */ +bool force_fee(struct channel_state *cstate, uint64_t fee); /** * invert_cstate: Get the other side's state. @@ -86,17 +115,6 @@ uint64_t commit_fee(uint64_t a_satoshis, uint64_t b_satoshis); */ void invert_cstate(struct channel_state *cstate); -/** - * funding_add_htlc: append an HTLC to this side of the channel. - * @creator: channel_state->a or channel_state->b, whichever originated htlc - * @msatoshis: amount in millisatoshi - * @expiry: time it expires - * @rhash: hash of redeem secret - */ -void funding_add_htlc(struct channel_oneside *creator, - u32 msatoshis, const struct abs_locktime *expiry, - const struct sha256 *rhash); - /** * funding_find_htlc: find an HTLC on this side of the channel. * @creator: channel_state->a or channel_state->b, whichever originated htlc @@ -109,10 +127,19 @@ size_t funding_find_htlc(struct channel_oneside *creator, const struct sha256 *rhash); /** - * funding_remove_htlc: remove an HTLC from this side of the channel. - * @creator: channel_state->a or channel_state->b, whichever originated htlc - * @i: index returned from funding_find_htlc. + * fee_for_feerate: calculate the fee (in satoshi) for a given fee_rate. + * @txsize: transaction size in bytes. + * @fee_rate: satoshi per 1000 bytes. */ -void funding_remove_htlc(struct channel_oneside *creator, size_t i); +uint64_t fee_by_feerate(size_t txsize, uint32_t fee_rate); + +/** + * is_dust_amount: is an output of this value considered dust? + * @satoshis: number of satoshis. + * + * Transactions with dust outputs will not be relayed by the bitcoin + * network. It's not an exact definition, unfortunately. + */ +bool is_dust_amount(uint64_t satoshis); #endif /* LIGHTNING_FUNDING_H */ diff --git a/lightning.pb-c.c b/lightning.pb-c.c index 0bb2eb3e2..84d3e2903 100644 --- a/lightning.pb-c.c +++ b/lightning.pb-c.c @@ -1413,12 +1413,12 @@ static const ProtobufCFieldDescriptor open_channel__field_descriptors[8] = 0,NULL,NULL /* reserved1,reserved2, etc */ }, { - "commitment_fee", + "initial_fee_rate", 7, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_UINT64, 0, /* quantifier_offset */ - offsetof(OpenChannel, commitment_fee), + offsetof(OpenChannel, initial_fee_rate), NULL, NULL, 0, /* flags */ @@ -1440,9 +1440,9 @@ static const ProtobufCFieldDescriptor open_channel__field_descriptors[8] = static const unsigned open_channel__field_indices_by_name[] = { 4, /* field[4] = anch */ 2, /* field[2] = commit_key */ - 6, /* field[6] = commitment_fee */ 0, /* field[0] = delay */ 3, /* field[3] = final_key */ + 6, /* field[6] = initial_fee_rate */ 5, /* field[5] = min_depth */ 7, /* field[7] = next_revocation_hash */ 1, /* field[1] = revocation_hash */ diff --git a/lightning.pb-c.h b/lightning.pb-c.h index 16f0ab7c9..451bc76d8 100644 --- a/lightning.pb-c.h +++ b/lightning.pb-c.h @@ -200,7 +200,7 @@ struct _OpenChannel /* * How much fee would I like on commitment tx? */ - uint64_t commitment_fee; + uint64_t initial_fee_rate; }; #define OPEN_CHANNEL__INIT \ { PROTOBUF_C_MESSAGE_INIT (&open_channel__descriptor) \ diff --git a/lightning.proto b/lightning.proto index e2d2909da..5c1424f00 100644 --- a/lightning.proto +++ b/lightning.proto @@ -84,7 +84,7 @@ message open_channel { optional uint32 min_depth = 6 [ default = 0 ]; // How much fee would I like on commitment tx? - required uint64 commitment_fee = 7; + required uint64 initial_fee_rate = 7; } // Whoever is supplying anchor sends this.