You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
363 lines
9.8 KiB
363 lines
9.8 KiB
#include "funding.h"
|
|
#include <assert.h>
|
|
#include <ccan/mem/mem.h>
|
|
#include <ccan/structeq/structeq.h>
|
|
#include <string.h>
|
|
|
|
uint64_t fee_by_feerate(size_t txsize, uint32_t fee_rate)
|
|
{
|
|
/* BOLT #2:
|
|
*
|
|
* The fee for a transaction MUST be calculated by multiplying this
|
|
* bytecount 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;
|
|
}
|
|
|
|
static uint64_t calculate_fee_msat(size_t num_nondust_htlcs,
|
|
uint32_t fee_rate)
|
|
{
|
|
uint64_t bytes;
|
|
|
|
/* 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;
|
|
|
|
/* milli-satoshis */
|
|
return fee_by_feerate(bytes, fee_rate) * 1000;
|
|
}
|
|
|
|
/* Total, in millisatoshi. */
|
|
static uint64_t htlcs_total(const struct channel_htlc *htlcs)
|
|
{
|
|
size_t i, n = tal_count(htlcs);
|
|
uint64_t total = 0;
|
|
|
|
for (i = 0; i < n; i++)
|
|
total += htlcs[i].msatoshis;
|
|
return total;
|
|
}
|
|
|
|
/* Pay this much fee, if possible. Return amount unpaid. */
|
|
static uint64_t pay_fee(struct channel_oneside *side, uint64_t fee_msat)
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
|
|
/* 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 remainder;
|
|
|
|
/* 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;
|
|
|
|
/* 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,
|
|
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);
|
|
cstate->fee_rate = fee_rate;
|
|
cstate->anchor = anchor_satoshis;
|
|
cstate->changes = 0;
|
|
|
|
/* Anchor must fit in 32 bit. */
|
|
if (anchor_satoshis >= (1ULL << 32) / 1000)
|
|
return tal_free(cstate);
|
|
|
|
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_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(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;
|
|
}
|
|
|
|
/* Dust is defined as an output < 546*minRelayTxFee/1000.
|
|
* minRelayTxFee defaults to 1000 satoshi. */
|
|
bool is_dust_amount(uint64_t satoshis)
|
|
{
|
|
return satoshis < 546;
|
|
}
|
|
|
|
static size_t count_nondust_htlcs(const struct channel_htlc *htlcs)
|
|
{
|
|
size_t i, n = tal_count(htlcs), nondust = 0;
|
|
|
|
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);
|
|
cstate->changes++;
|
|
}
|
|
|
|
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);
|
|
cstate->changes++;
|
|
return cstate->a.fee_msat + cstate->b.fee_msat == fee * 1000;
|
|
}
|
|
|
|
void invert_cstate(struct channel_state *cstate)
|
|
{
|
|
struct channel_oneside tmp;
|
|
|
|
tmp = cstate->a;
|
|
cstate->a = cstate->b;
|
|
cstate->b = tmp;
|
|
}
|
|
|
|
/* Add a HTLC to @creator if it can afford it. */
|
|
static bool add_htlc(struct channel_state *cstate,
|
|
struct channel_oneside *creator,
|
|
struct channel_oneside *recipient,
|
|
u32 msatoshis, const struct abs_locktime *expiry,
|
|
const struct sha256 *rhash, uint64_t id)
|
|
{
|
|
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;
|
|
creator->htlcs[n].expiry = *expiry;
|
|
creator->htlcs[n].rhash = *rhash;
|
|
creator->htlcs[n].id = id;
|
|
memcheck(&creator->htlcs[n].msatoshis,
|
|
sizeof(creator->htlcs[n].msatoshis));
|
|
memcheck(&creator->htlcs[n].rhash, sizeof(creator->htlcs[n].rhash));
|
|
cstate->changes++;
|
|
return true;
|
|
}
|
|
|
|
/* Remove htlc from creator, credit it to beneficiary. */
|
|
static void remove_htlc(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);
|
|
cstate->changes++;
|
|
}
|
|
|
|
bool funding_a_add_htlc(struct channel_state *cstate,
|
|
u32 msatoshis, const struct abs_locktime *expiry,
|
|
const struct sha256 *rhash, uint64_t id)
|
|
{
|
|
return add_htlc(cstate, &cstate->a, &cstate->b,
|
|
msatoshis, expiry, rhash, id);
|
|
}
|
|
|
|
bool funding_b_add_htlc(struct channel_state *cstate,
|
|
u32 msatoshis, const struct abs_locktime *expiry,
|
|
const struct sha256 *rhash, uint64_t id)
|
|
{
|
|
return add_htlc(cstate, &cstate->b, &cstate->a,
|
|
msatoshis, expiry, rhash, id);
|
|
}
|
|
|
|
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,
|
|
const struct sha256 *rhash)
|
|
{
|
|
size_t i;
|
|
|
|
for (i = 0; i < tal_count(creator->htlcs); i++) {
|
|
if (structeq(&creator->htlcs[i].rhash, rhash))
|
|
break;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
size_t funding_htlc_by_id(struct channel_oneside *creator, uint64_t id)
|
|
{
|
|
size_t i;
|
|
|
|
for (i = 0; i < tal_count(creator->htlcs); i++) {
|
|
if (creator->htlcs[i].id == id)
|
|
break;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
struct channel_state *copy_funding(const tal_t *ctx,
|
|
const struct channel_state *cstate)
|
|
{
|
|
struct channel_state *cs = tal_dup(ctx, struct channel_state, cstate);
|
|
|
|
cs->a.htlcs = tal_dup_arr(cs, struct channel_htlc, cs->a.htlcs,
|
|
tal_count(cs->a.htlcs), 0);
|
|
cs->b.htlcs = tal_dup_arr(cs, struct channel_htlc, cs->b.htlcs,
|
|
tal_count(cs->b.htlcs), 0);
|
|
return cs;
|
|
}
|
|
|