daemon: use fee rates rather than absolute fees (BOLT #2)

And divide fees as specified there.

We still use fixed values rather than floating, and we don't send or
handle update_fee messages.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2016-03-24 12:12:43 +10:30
parent ba2854e835
commit 8c468c1e15
11 changed files with 497 additions and 330 deletions

View File

@ -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)

View File

@ -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;

View File

@ -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? */

View File

@ -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);

View File

@ -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 */

View File

@ -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

374
funding.c
View File

@ -4,34 +4,35 @@
#include <ccan/structeq/structeq.h>
#include <string.h>
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)
{

113
funding.h
View File

@ -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 */

View File

@ -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 */

View File

@ -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) \

View File

@ -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.