Browse Source

daemons: use amount_msat/amount_sat in all internal wire transfers.

As a side-effect of using amount_msat in gossipd/routing.c, we explicitly
handle overflows and don't need to pre-prune ridiculous-fee channels.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
confirmed-only
Rusty Russell 6 years ago
parent
commit
3ac0e814d0
  1. 6
      channeld/channel_wire.csv
  2. 19
      channeld/channeld.c
  3. 10
      channeld/full_channel.c
  4. 14
      closingd/closing_wire.csv
  5. 257
      closingd/closingd.c
  6. 21
      common/close_tx.c
  7. 8
      common/close_tx.h
  8. 4
      common/htlc_wire.c
  9. 3
      common/htlc_wire.h
  10. 4
      common/sphinx.c
  11. 2
      common/sphinx.h
  12. 12
      common/test/run-sphinx.c
  13. 9
      devtools/dump-gossipstore.c
  14. 2
      devtools/onion.c
  15. 6
      gossipd/gossip_peerd_wire.csv
  16. 6
      gossipd/gossip_store.c
  17. 4
      gossipd/gossip_store.csv
  18. 4
      gossipd/gossip_wire.csv
  19. 58
      gossipd/gossipd.c
  20. 252
      gossipd/routing.c
  21. 22
      gossipd/routing.h
  22. 1
      gossipd/test/Makefile
  23. 16
      gossipd/test/run-bench-find_route.c
  24. 43
      gossipd/test/run-find_route-specific.c
  25. 34
      gossipd/test/run-find_route.c
  26. 24
      hsmd/hsm_wire.csv
  27. 67
      hsmd/hsmd.c
  28. 20
      lightningd/channel.c
  29. 19
      lightningd/channel.h
  30. 4
      lightningd/channel_control.c
  31. 83
      lightningd/closing_control.c
  32. 17
      lightningd/gossip_control.c
  33. 4
      lightningd/gossip_msg.c
  34. 2
      lightningd/gossip_msg.h
  35. 22
      lightningd/htlc_end.c
  36. 10
      lightningd/htlc_end.h
  37. 27
      lightningd/invoice.c
  38. 23
      lightningd/onchain_control.c
  39. 80
      lightningd/opening_control.c
  40. 6
      lightningd/pay.c
  41. 47
      lightningd/peer_control.c
  42. 138
      lightningd/peer_htlcs.c
  43. 3
      lightningd/peer_htlcs.h
  44. 1
      lightningd/test/Makefile
  45. 43
      lightningd/test/run-invoice-select-inchan.c
  46. 4
      lightningd/test/run-jsonrpc.c
  47. 6
      onchaind/onchain_wire.csv
  48. 186
      onchaind/onchaind.c
  49. 1
      onchaind/test/Makefile
  50. 19
      onchaind/test/run-grind_feerate.c
  51. 16
      openingd/opening_wire.csv
  52. 20
      openingd/openingd.c
  53. 1
      wallet/test/Makefile
  54. 19
      wallet/test/run-wallet.c
  55. 62
      wallet/wallet.c
  56. 14
      wallet/wallet.h
  57. 9
      wallet/walletrpc.c

6
channeld/channel_wire.csv

@ -7,7 +7,7 @@ channel_init,1000
channel_init,,chain_hash,struct bitcoin_blkid
channel_init,,funding_txid,struct bitcoin_txid
channel_init,,funding_txout,u16
channel_init,,funding_satoshi,u64
channel_init,,funding_satoshi,struct amount_sat
channel_init,,our_config,struct channel_config
channel_init,,their_config,struct channel_config
# FIXME: Fix generate-wire.py to allow NUM_SIDES*u32 here.
@ -23,7 +23,7 @@ channel_init,,old_remote_per_commit,struct pubkey
channel_init,,funder,enum side
channel_init,,fee_base,u32
channel_init,,fee_proportional,u32
channel_init,,local_msatoshi,u64
channel_init,,local_msatoshi,struct amount_msat
channel_init,,our_basepoints,struct basepoints
channel_init,,our_funding_pubkey,struct pubkey
channel_init,,local_node_id,struct pubkey
@ -69,7 +69,7 @@ channel_funding_locked,,depth,u32
# Tell channel to offer this htlc
channel_offer_htlc,1004
channel_offer_htlc,,amount_msat,u64
channel_offer_htlc,,amount_msat,struct amount_msat
channel_offer_htlc,,cltv_expiry,u32
channel_offer_htlc,,payment_hash,struct sha256
channel_offer_htlc,,onion_routing_packet,1366*u8

Can't render this file because it has a wrong number of fields in line 6.

19
channeld/channeld.c

@ -291,10 +291,10 @@ static void send_channel_update(struct peer *peer, int disable_flag)
disable_flag
== ROUTING_FLAGS_DISABLED,
peer->cltv_delta,
peer->channel->config[REMOTE].htlc_minimum.millisatoshis,
peer->channel->config[REMOTE].htlc_minimum,
peer->fee_base,
peer->fee_per_satoshi,
advertised_htlc_max(peer->channel).millisatoshis);
advertised_htlc_max(peer->channel));
wire_sync_write(GOSSIP_FD, take(msg));
}
@ -316,7 +316,7 @@ static void make_channel_local_active(struct peer *peer)
msg = towire_gossipd_local_add_channel(NULL,
&peer->short_channel_ids[LOCAL],
&peer->node_ids[REMOTE],
peer->channel->funding.satoshis);
peer->channel->funding);
wire_sync_write(GOSSIP_FD, take(msg));
/* Tell gossipd and the other side what parameters we expect should
@ -942,7 +942,7 @@ static secp256k1_ecdsa_signature *calc_commitsigs(const tal_t *ctx,
msg = towire_hsm_sign_remote_commitment_tx(NULL, txs[0],
&peer->channel->funding_pubkey[REMOTE],
*txs[0]->input[0].amount);
(struct amount_sat){*txs[0]->input[0].amount});
msg = hsm_req(tmpctx, take(msg));
if (!fromwire_hsm_sign_tx_reply(msg, commit_sig))
@ -980,7 +980,8 @@ static secp256k1_ecdsa_signature *calc_commitsigs(const tal_t *ctx,
struct bitcoin_signature sig;
msg = towire_hsm_sign_remote_htlc_tx(NULL, txs[i + 1],
wscripts[i + 1],
*txs[i+1]->input[0].amount,
(struct amount_sat)
{ *txs[i+1]->input[0].amount },
&peer->remote_per_commit);
msg = hsm_req(tmpctx, take(msg));
@ -1251,7 +1252,7 @@ static u8 *got_commitsig_msg(const tal_t *ctx,
struct secret s;
a.id = htlc->id;
a.amount_msat = htlc->amount.millisatoshis;
a.amount = htlc->amount;
a.payment_hash = htlc->rhash;
a.cltv_expiry = abs_locktime_to_blocks(&htlc->expiry);
memcpy(a.onion_routing_packet,
@ -2431,7 +2432,7 @@ static void handle_offer_htlc(struct peer *peer, const u8 *inmsg)
status_failed(STATUS_FAIL_MASTER_IO,
"funding not locked for offer_htlc");
if (!fromwire_channel_offer_htlc(inmsg, &amount.millisatoshis,
if (!fromwire_channel_offer_htlc(inmsg, &amount,
&cltv_expiry, &payment_hash,
onion_routing_packet))
master_badmsg(WIRE_CHANNEL_OFFER_HTLC, inmsg);
@ -2730,7 +2731,7 @@ static void init_channel(struct peer *peer)
if (!fromwire_channel_init(peer, msg,
&peer->chain_hash,
&funding_txid, &funding_txout,
&funding.satoshis,
&funding,
&conf[LOCAL], &conf[REMOTE],
feerate_per_kw,
&peer->feerate_min, &peer->feerate_max,
@ -2743,7 +2744,7 @@ static void init_channel(struct peer *peer)
&funder,
&peer->fee_base,
&peer->fee_per_satoshi,
&local_msat.millisatoshis,
&local_msat,
&points[LOCAL],
&funding_pubkey[LOCAL],
&peer->node_ids[LOCAL],

10
channeld/full_channel.c

@ -1066,20 +1066,20 @@ bool channel_force_htlcs(struct channel *channel,
for (i = 0; i < tal_count(htlcs); i++) {
enum channel_add_err e;
struct htlc *htlc;
struct amount_msat amount;
status_trace("Restoring HTLC %zu/%zu:"
" id=%"PRIu64" msat=%"PRIu64" cltv=%u"
" id=%"PRIu64" amount=%s cltv=%u"
" payment_hash=%s",
i, tal_count(htlcs),
htlcs[i].id, htlcs[i].amount_msat,
htlcs[i].id,
type_to_string(tmpctx, struct amount_msat,
&htlcs[i].amount),
htlcs[i].cltv_expiry,
type_to_string(tmpctx, struct sha256,
&htlcs[i].payment_hash));
amount.millisatoshis = htlcs[i].amount_msat;
e = add_htlc(channel, hstates[i],
htlcs[i].id, amount,
htlcs[i].id, htlcs[i].amount,
htlcs[i].cltv_expiry,
&htlcs[i].payment_hash,
htlcs[i].onion_routing_packet, &htlc, false);

14
closingd/closing_wire.csv

@ -5,16 +5,16 @@ closing_init,2001
closing_init,,crypto_state,struct crypto_state
closing_init,,funding_txid,struct bitcoin_txid
closing_init,,funding_txout,u16
closing_init,,funding_satoshi,u64
closing_init,,funding_satoshi,struct amount_sat
closing_init,,local_fundingkey,struct pubkey
closing_init,,remote_fundingkey,struct pubkey
closing_init,,funder,enum side
closing_init,,local_msatoshi,u64
closing_init,,remote_msatoshi,u64
closing_init,,our_dust_limit,u64
closing_init,,min_fee_satoshi,u64
closing_init,,fee_limit_satoshi,u64
closing_init,,initial_fee_satoshi,u64
closing_init,,local_sat,struct amount_sat
closing_init,,remote_sat,struct amount_sat
closing_init,,our_dust_limit,struct amount_sat
closing_init,,min_fee_satoshi,struct amount_sat
closing_init,,fee_limit_satoshi,struct amount_sat
closing_init,,initial_fee_satoshi,struct amount_sat
closing_init,,local_scriptpubkey_len,u16
closing_init,,local_scriptpubkey,local_scriptpubkey_len*u8
closing_init,,remote_scriptpubkey_len,u16

Can't render this file because it has a wrong number of fields in line 3.

257
closingd/closingd.c

@ -35,46 +35,53 @@ static struct bitcoin_tx *close_tx(const tal_t *ctx,
u8 *scriptpubkey[NUM_SIDES],
const struct bitcoin_txid *funding_txid,
unsigned int funding_txout,
u64 funding_satoshi,
const u64 satoshi_out[NUM_SIDES],
struct amount_sat funding,
const struct amount_sat out[NUM_SIDES],
enum side funder,
uint64_t fee,
uint64_t dust_limit)
struct amount_sat fee,
struct amount_sat dust_limit)
{
struct bitcoin_tx *tx;
struct amount_sat out_minus_fee[NUM_SIDES];
if (satoshi_out[funder] < fee)
out_minus_fee[LOCAL] = out[LOCAL];
out_minus_fee[REMOTE] = out[REMOTE];
if (!amount_sat_sub(&out_minus_fee[funder], out[funder], fee))
peer_failed(cs, channel_id,
"Funder cannot afford fee %"PRIu64
" (%"PRIu64" and %"PRIu64")",
fee, satoshi_out[LOCAL],
satoshi_out[REMOTE]);
status_trace("Making close tx at = %"PRIu64"/%"PRIu64" fee %"PRIu64,
satoshi_out[LOCAL], satoshi_out[REMOTE], fee);
"Funder cannot afford fee %s (%s and %s)",
type_to_string(tmpctx, struct amount_sat, &fee),
type_to_string(tmpctx, struct amount_sat,
&out[LOCAL]),
type_to_string(tmpctx, struct amount_sat,
&out[REMOTE]));
status_trace("Making close tx at = %s/%s fee %s",
type_to_string(tmpctx, struct amount_sat, &out[LOCAL]),
type_to_string(tmpctx, struct amount_sat, &out[REMOTE]),
type_to_string(tmpctx, struct amount_sat, &fee));
/* FIXME: We need to allow this! */
tx = create_close_tx(ctx,
scriptpubkey[LOCAL], scriptpubkey[REMOTE],
funding_txid,
funding_txout,
funding_satoshi,
satoshi_out[LOCAL] - (funder == LOCAL ? fee : 0),
satoshi_out[REMOTE] - (funder == REMOTE ? fee : 0),
funding,
out_minus_fee[LOCAL],
out_minus_fee[REMOTE],
dust_limit);
if (!tx)
peer_failed(cs, channel_id,
"Both outputs below dust limit:"
" funding = %"PRIu64
" fee = %"PRIu64
" dust_limit = %"PRIu64
" LOCAL = %"PRIu64
" REMOTE = %"PRIu64,
funding_satoshi,
fee,
dust_limit,
satoshi_out[LOCAL],
satoshi_out[REMOTE]);
" funding = %s"
" fee = %s"
" dust_limit = %s"
" LOCAL = %s"
" REMOTE = %s",
type_to_string(tmpctx, struct amount_sat, &funding),
type_to_string(tmpctx, struct amount_sat, &fee),
type_to_string(tmpctx, struct amount_sat, &dust_limit),
type_to_string(tmpctx, struct amount_sat, &out[LOCAL]),
type_to_string(tmpctx, struct amount_sat, &out[REMOTE]));
return tx;
}
@ -170,11 +177,11 @@ static void send_offer(struct crypto_state *cs,
u8 *scriptpubkey[NUM_SIDES],
const struct bitcoin_txid *funding_txid,
unsigned int funding_txout,
u64 funding_satoshi,
const u64 satoshi_out[NUM_SIDES],
struct amount_sat funding,
const struct amount_sat out[NUM_SIDES],
enum side funder,
uint64_t our_dust_limit,
uint64_t fee_to_offer)
struct amount_sat our_dust_limit,
struct amount_sat fee_to_offer)
{
struct bitcoin_tx *tx;
struct bitcoin_signature our_sig;
@ -190,8 +197,8 @@ static void send_offer(struct crypto_state *cs,
scriptpubkey,
funding_txid,
funding_txout,
funding_satoshi,
satoshi_out,
funding,
out,
funder, fee_to_offer, our_dust_limit);
/* BOLT #3:
@ -206,17 +213,18 @@ static void send_offer(struct crypto_state *cs,
take(towire_hsm_sign_mutual_close_tx(NULL,
tx,
&funding_pubkey[REMOTE],
funding_satoshi)));
funding)));
msg = wire_sync_read(tmpctx, HSM_FD);
if (!fromwire_hsm_sign_tx_reply(msg, &our_sig))
status_failed(STATUS_FAIL_HSM_IO,
"Bad hsm_sign_mutual_close_tx reply %s",
tal_hex(tmpctx, msg));
status_trace("sending fee offer %"PRIu64, fee_to_offer);
status_trace("sending fee offer %s",
type_to_string(tmpctx, struct amount_sat, &fee_to_offer));
assert(our_sig.sighash_type == SIGHASH_ALL);
msg = towire_closing_signed(NULL, channel_id, fee_to_offer, &our_sig.s);
msg = towire_closing_signed(NULL, channel_id, fee_to_offer.satoshis, &our_sig.s);
sync_crypto_write(cs, PEER_FD, take(msg));
}
@ -237,22 +245,23 @@ static void tell_master_their_offer(const struct bitcoin_signature *their_sig,
}
/* Returns fee they offered. */
static uint64_t receive_offer(struct crypto_state *cs,
const struct channel_id *channel_id,
const struct pubkey funding_pubkey[NUM_SIDES],
const u8 *funding_wscript,
u8 *scriptpubkey[NUM_SIDES],
const struct bitcoin_txid *funding_txid,
unsigned int funding_txout,
u64 funding_satoshi,
const u64 satoshi_out[NUM_SIDES],
enum side funder,
uint64_t our_dust_limit,
u64 min_fee_to_accept)
static struct amount_sat
receive_offer(struct crypto_state *cs,
const struct channel_id *channel_id,
const struct pubkey funding_pubkey[NUM_SIDES],
const u8 *funding_wscript,
u8 *scriptpubkey[NUM_SIDES],
const struct bitcoin_txid *funding_txid,
unsigned int funding_txout,
struct amount_sat funding,
const struct amount_sat out[NUM_SIDES],
enum side funder,
struct amount_sat our_dust_limit,
struct amount_sat min_fee_to_accept)
{
u8 *msg;
struct channel_id their_channel_id;
u64 received_fee;
struct amount_sat received_fee;
struct bitcoin_signature their_sig;
struct bitcoin_tx *tx;
@ -279,7 +288,7 @@ static uint64_t receive_offer(struct crypto_state *cs,
their_sig.sighash_type = SIGHASH_ALL;
if (!fromwire_closing_signed(msg, &their_channel_id,
&received_fee, &their_sig.s))
&received_fee.satoshis, &their_sig.s))
peer_failed(cs, channel_id,
"Expected closing_signed: %s",
tal_hex(tmpctx, msg));
@ -295,20 +304,20 @@ static uint64_t receive_offer(struct crypto_state *cs,
scriptpubkey,
funding_txid,
funding_txout,
funding_satoshi,
satoshi_out, funder, received_fee, our_dust_limit);
funding,
out, funder, received_fee, our_dust_limit);
if (!check_tx_sig(tx, 0, NULL, funding_wscript,
&funding_pubkey[REMOTE], &their_sig)) {
/* Trim it by reducing their output to minimum */
struct bitcoin_tx *trimmed;
u64 trimming_satoshi_out[NUM_SIDES];
struct amount_sat trimming_out[NUM_SIDES];
if (funder == REMOTE)
trimming_satoshi_out[REMOTE] = received_fee;
trimming_out[REMOTE] = received_fee;
else
trimming_satoshi_out[REMOTE] = 0;
trimming_satoshi_out[LOCAL] = satoshi_out[LOCAL];
trimming_out[REMOTE] = AMOUNT_SAT(0);
trimming_out[LOCAL] = out[LOCAL];
/* BOLT #3:
*
@ -324,8 +333,8 @@ static uint64_t receive_offer(struct crypto_state *cs,
scriptpubkey,
funding_txid,
funding_txout,
funding_satoshi,
trimming_satoshi_out,
funding,
trimming_out,
funder, received_fee, our_dust_limit);
if (!trimmed
|| !check_tx_sig(trimmed, 0, NULL, funding_wscript,
@ -345,10 +354,11 @@ static uint64_t receive_offer(struct crypto_state *cs,
tx = trimmed;
}
status_trace("Received fee offer %"PRIu64, received_fee);
status_trace("Received fee offer %s",
type_to_string(tmpctx, struct amount_sat, &received_fee));
/* Master sorts out what is best offer, we just tell it any above min */
if (received_fee >= min_fee_to_accept) {
if (amount_sat_greater_eq(received_fee, min_fee_to_accept)) {
status_trace("...offer is reasonable");
tell_master_their_offer(&their_sig, tx);
}
@ -358,14 +368,14 @@ static uint64_t receive_offer(struct crypto_state *cs,
struct feerange {
enum side higher_side;
u64 min, max;
struct amount_sat min, max;
};
static void init_feerange(struct feerange *feerange,
u64 commitment_fee,
const u64 offer[NUM_SIDES])
struct amount_sat commitment_fee,
const struct amount_sat offer[NUM_SIDES])
{
feerange->min = 0;
feerange->min = AMOUNT_SAT(0);
/* BOLT #2:
*
@ -375,58 +385,86 @@ static void init_feerange(struct feerange *feerange,
*/
feerange->max = commitment_fee;
if (offer[LOCAL] > offer[REMOTE])
if (amount_sat_greater(offer[LOCAL], offer[REMOTE]))
feerange->higher_side = LOCAL;
else
feerange->higher_side = REMOTE;
status_trace("Feerange init %"PRIu64"-%"PRIu64", %s higher",
feerange->min, feerange->max,
status_trace("Feerange init %s-%s, %s higher",
type_to_string(tmpctx, struct amount_sat, &feerange->min),
type_to_string(tmpctx, struct amount_sat, &feerange->max),
feerange->higher_side == LOCAL ? "local" : "remote");
}
static void adjust_feerange(struct feerange *feerange,
u64 offer, enum side side)
struct amount_sat offer, enum side side)
{
bool ok;
/* BOLT #2:
*
* - MUST propose a value "strictly between" the received
* `fee_satoshis` and its previously-sent `fee_satoshis`.
*/
if (side == feerange->higher_side)
feerange->max = offer - 1;
ok = amount_sat_sub(&feerange->max, offer, AMOUNT_SAT(1));
else
feerange->min = offer + 1;
ok = amount_sat_add(&feerange->min, offer, AMOUNT_SAT(1));
status_trace("Feerange %s update %"PRIu64": now %"PRIu64"-%"PRIu64,
status_trace("Feerange %s update %s: now %s-%s",
side == LOCAL ? "local" : "remote",
offer, feerange->min, feerange->max);
type_to_string(tmpctx, struct amount_sat, &offer),
type_to_string(tmpctx, struct amount_sat, &feerange->min),
type_to_string(tmpctx, struct amount_sat, &feerange->max));
if (!ok)
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Overflow in updating fee range");
}
/* Figure out what we should offer now. */
static u64 adjust_offer(struct crypto_state *cs,
const struct channel_id *channel_id,
const struct feerange *feerange,
u64 remote_offer,
u64 min_fee_to_accept)
static struct amount_sat adjust_offer(struct crypto_state *cs,
const struct channel_id *channel_id,
const struct feerange *feerange,
struct amount_sat remote_offer,
struct amount_sat min_fee_to_accept)
{
struct amount_sat min_plus_one, avg;
/* Within 1 satoshi? Agree. */
if (feerange->min + 1 >= feerange->max)
if (!amount_sat_add(&min_plus_one, feerange->min, AMOUNT_SAT(1)))
peer_failed(cs, channel_id,
"Fee offer %s min too large",
type_to_string(tmpctx, struct amount_sat,
&feerange->min));
if (amount_sat_greater_eq(min_plus_one, feerange->max))
return remote_offer;
/* Max is below our minimum acceptable? */
if (feerange->max < min_fee_to_accept)
if (amount_sat_less(feerange->max, min_fee_to_accept))
peer_failed(cs, channel_id,
"Feerange %"PRIu64"-%"PRIu64
" below minimum acceptable %"PRIu64,
feerange->min, feerange->max,
min_fee_to_accept);
"Feerange %s-%s"
" below minimum acceptable %s",
type_to_string(tmpctx, struct amount_sat,
&feerange->min),
type_to_string(tmpctx, struct amount_sat,
&feerange->max),
type_to_string(tmpctx, struct amount_sat,
&min_fee_to_accept));
/* Bisect between our minimum and max. */
if (feerange->min > min_fee_to_accept)
if (amount_sat_greater(feerange->min, min_fee_to_accept))
min_fee_to_accept = feerange->min;
return (feerange->max + min_fee_to_accept)/2;
if (!amount_sat_add(&avg, feerange->max, min_fee_to_accept))
peer_failed(cs, channel_id,
"Fee offer %s max too large",
type_to_string(tmpctx, struct amount_sat,
&feerange->max));
avg.satoshis /= 2;
return avg;
}
#if DEVELOPER
@ -460,9 +498,9 @@ int main(int argc, char *argv[])
struct pubkey funding_pubkey[NUM_SIDES];
struct bitcoin_txid funding_txid;
u16 funding_txout;
u64 funding_satoshi, satoshi_out[NUM_SIDES];
u64 our_dust_limit;
u64 min_fee_to_accept, commitment_fee, offer[NUM_SIDES];
struct amount_sat funding, out[NUM_SIDES];
struct amount_sat our_dust_limit;
struct amount_sat min_fee_to_accept, commitment_fee, offer[NUM_SIDES];
struct feerange feerange;
enum side funder;
u8 *scriptpubkey[NUM_SIDES], *funding_wscript, *final_scriptpubkey;
@ -480,12 +518,12 @@ int main(int argc, char *argv[])
if (!fromwire_closing_init(ctx, msg,
&cs,
&funding_txid, &funding_txout,
&funding_satoshi,
&funding,
&funding_pubkey[LOCAL],
&funding_pubkey[REMOTE],
&funder,
&satoshi_out[LOCAL],
&satoshi_out[REMOTE],
&out[LOCAL],
&out[REMOTE],
&our_dust_limit,
&min_fee_to_accept, &commitment_fee,
&offer[LOCAL],
@ -499,10 +537,13 @@ int main(int argc, char *argv[])
&final_scriptpubkey))
master_badmsg(WIRE_CLOSING_INIT, msg);
status_trace("satoshi_out = %"PRIu64"/%"PRIu64,
satoshi_out[LOCAL], satoshi_out[REMOTE]);
status_trace("dustlimit = %"PRIu64, our_dust_limit);
status_trace("fee = %"PRIu64, offer[LOCAL]);
status_trace("out = %s/%s",
type_to_string(tmpctx, struct amount_sat, &out[LOCAL]),
type_to_string(tmpctx, struct amount_sat, &out[REMOTE]));
status_trace("dustlimit = %s",
type_to_string(tmpctx, struct amount_sat, &our_dust_limit));
status_trace("fee = %s",
type_to_string(tmpctx, struct amount_sat, &offer[LOCAL]));
derive_channel_id(&channel_id, &funding_txid, funding_txout);
funding_wscript = bitcoin_redeem_2of2(ctx,
@ -517,9 +558,13 @@ int main(int argc, char *argv[])
/* We don't need this any more */
tal_free(final_scriptpubkey);
peer_billboard(true, "Negotiating closing fee between %"PRIu64
" and %"PRIu64" satoshi (ideal %"PRIu64")",
min_fee_to_accept, commitment_fee, offer[LOCAL]);
peer_billboard(true, "Negotiating closing fee between %s"
" and %s satoshi (ideal %s)",
type_to_string(tmpctx, struct amount_sat,
&min_fee_to_accept),
type_to_string(tmpctx, struct amount_sat,
&commitment_fee),
type_to_string(tmpctx, struct amount_sat, &offer[LOCAL]));
/* BOLT #2:
*
@ -534,7 +579,7 @@ int main(int argc, char *argv[])
send_offer(&cs,
&channel_id, funding_pubkey,
scriptpubkey, &funding_txid, funding_txout,
funding_satoshi, satoshi_out, funder,
funding, out, funder,
our_dust_limit,
offer[LOCAL]);
} else {
@ -544,15 +589,17 @@ int main(int argc, char *argv[])
else
peer_billboard(false, "Waiting for their initial"
" closing fee offer:"
" ours was %"PRIu64" satoshi",
offer[LOCAL]);
" ours was %s",
type_to_string(tmpctx,
struct amount_sat,
&offer[LOCAL]));
offer[REMOTE]
= receive_offer(&cs,
&channel_id, funding_pubkey,
funding_wscript,
scriptpubkey, &funding_txid,
funding_txout, funding_satoshi,
satoshi_out, funder,
funding_txout, funding,
out, funder,
our_dust_limit,
min_fee_to_accept);
}
@ -565,7 +612,7 @@ int main(int argc, char *argv[])
adjust_feerange(&feerange, offer[funder], funder);
/* Now any extra rounds required. */
while (offer[LOCAL] != offer[REMOTE]) {
while (!amount_sat_eq(offer[LOCAL], offer[REMOTE])) {
/* Still don't agree: adjust feerange based on previous offer */
adjust_feerange(&feerange,
offer[!whose_turn], !whose_turn);
@ -578,7 +625,7 @@ int main(int argc, char *argv[])
send_offer(&cs, &channel_id,
funding_pubkey,
scriptpubkey, &funding_txid, funding_txout,
funding_satoshi, satoshi_out, funder,
funding, out, funder,
our_dust_limit,
offer[LOCAL]);
} else {
@ -592,8 +639,8 @@ int main(int argc, char *argv[])
funding_pubkey,
funding_wscript,
scriptpubkey, &funding_txid,
funding_txout, funding_satoshi,
satoshi_out, funder,
funding_txout, funding,
out, funder,
our_dust_limit,
min_fee_to_accept);
}

21
common/close_tx.c

@ -9,14 +9,17 @@ struct bitcoin_tx *create_close_tx(const tal_t *ctx,
const u8 *their_script,
const struct bitcoin_txid *anchor_txid,
unsigned int anchor_index,
u64 anchor_satoshis,
uint64_t to_us, uint64_t to_them,
uint64_t dust_limit)
struct amount_sat funding,
struct amount_sat to_us,
struct amount_sat to_them,
struct amount_sat dust_limit)
{
struct bitcoin_tx *tx;
size_t num_outputs = 0;
struct amount_sat total_out;
assert(to_us + to_them <= anchor_satoshis);
assert(amount_sat_add(&total_out, to_us, to_them));
assert(amount_sat_less_eq(total_out, funding));
/* BOLT #3:
*
@ -34,19 +37,19 @@ struct bitcoin_tx *create_close_tx(const tal_t *ctx,
/* Our input spends the anchor tx output. */
tx->input[0].txid = *anchor_txid;
tx->input[0].index = anchor_index;
tx->input[0].amount = tal_dup(tx->input, u64, &anchor_satoshis);
tx->input[0].amount = tal_dup(tx->input, u64, &funding.satoshis);
if (to_us >= dust_limit) {
if (amount_sat_greater_eq(to_us, dust_limit)) {
/* One output is to us. */
tx->output[num_outputs].amount = to_us;
tx->output[num_outputs].amount = to_us.satoshis;
tx->output[num_outputs].script = tal_dup_arr(tx, u8,
our_script, tal_count(our_script), 0);
num_outputs++;
}
if (to_them >= dust_limit) {
if (amount_sat_greater_eq(to_them, dust_limit)) {
/* Other output is to them. */
tx->output[num_outputs].amount = to_them;
tx->output[num_outputs].amount = to_them.satoshis;
tx->output[num_outputs].script = tal_dup_arr(tx, u8,
their_script, tal_count(their_script),
0);

8
common/close_tx.h

@ -3,6 +3,7 @@
#include "config.h"
#include <ccan/short_types/short_types.h>
#include <ccan/tal/tal.h>
#include <common/amount.h>
struct pubkey;
@ -13,7 +14,8 @@ struct bitcoin_tx *create_close_tx(const tal_t *ctx,
const u8 *their_script,
const struct bitcoin_txid *anchor_txid,
unsigned int anchor_index,
u64 anchor_satoshis,
uint64_t to_us, uint64_t to_them,
uint64_t dust_limit);
struct amount_sat funding,
struct amount_sat to_us,
struct amount_sat to_them,
struct amount_sat dust_limit);
#endif /* LIGHTNING_COMMON_CLOSE_TX_H */

4
common/htlc_wire.c

@ -10,7 +10,7 @@
void towire_added_htlc(u8 **pptr, const struct added_htlc *added)
{
towire_u64(pptr, added->id);
towire_u64(pptr, added->amount_msat);
towire_amount_msat(pptr, added->amount);
towire_sha256(pptr, &added->payment_hash);
towire_u32(pptr, added->cltv_expiry);
towire(pptr, added->onion_routing_packet,
@ -77,7 +77,7 @@ void fromwire_added_htlc(const u8 **cursor, size_t *max,
struct added_htlc *added)
{
added->id = fromwire_u64(cursor, max);
added->amount_msat = fromwire_u64(cursor, max);
added->amount = fromwire_amount_msat(cursor, max);
fromwire_sha256(cursor, max, &added->payment_hash);
added->cltv_expiry = fromwire_u32(cursor, max);
fromwire(cursor, max, added->onion_routing_packet,

3
common/htlc_wire.h

@ -3,6 +3,7 @@
#include "config.h"
#include <bitcoin/preimage.h>
#include <ccan/short_types/short_types.h>
#include <common/amount.h>
#include <common/htlc.h>
#include <common/sphinx.h>
#include <wire/gen_onion_wire.h>
@ -13,7 +14,7 @@ struct shachain;
/* These are how we communicate about HTLC state to the master daemon */
struct added_htlc {
u64 id;
u64 amount_msat;
struct amount_msat amount;
struct sha256 payment_hash;
u32 cltv_expiry;
u8 onion_routing_packet[TOTAL_PACKET_SIZE];

4
common/sphinx.c

@ -307,7 +307,7 @@ static void serialize_hop_data(tal_t *ctx, u8 *dst, const struct hop_data *data)
u8 *buf = tal_arr(ctx, u8, 0);
towire_u8(&buf, data->realm);
towire_short_channel_id(&buf, &data->channel_id);
towire_u64(&buf, data->amt_forward);
towire_amount_msat(&buf, data->amt_forward);
towire_u32(&buf, data->outgoing_cltv);
towire_pad(&buf, 12);
towire(&buf, data->hmac, SECURITY_PARAMETER);
@ -321,7 +321,7 @@ static void deserialize_hop_data(struct hop_data *data, const u8 *src)
size_t max = HOP_DATA_SIZE;
data->realm = fromwire_u8(&cursor, &max);
fromwire_short_channel_id(&cursor, &max, &data->channel_id);
data->amt_forward = fromwire_u64(&cursor, &max);
data->amt_forward = fromwire_amount_msat(&cursor, &max);
data->outgoing_cltv = fromwire_u32(&cursor, &max);
fromwire_pad(&cursor, &max, 12);
fromwire(&cursor, &max, &data->hmac, SECURITY_PARAMETER);

2
common/sphinx.h

@ -67,7 +67,7 @@ enum route_next_case {
struct hop_data {
u8 realm;
struct short_channel_id channel_id;
u64 amt_forward;
struct amount_msat amt_forward;
u32 outgoing_cltv;
/* Padding omitted, will be zeroed */
u8 hmac[SECURITY_PARAMETER];

12
common/test/run-sphinx.c

@ -15,6 +15,9 @@
/* Generated stub for fromwire */
const u8 *fromwire(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, void *copy UNNEEDED, size_t n UNNEEDED)
{ fprintf(stderr, "fromwire called!\n"); abort(); }
/* Generated stub for fromwire_amount_msat */
struct amount_msat fromwire_amount_msat(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
{ fprintf(stderr, "fromwire_amount_msat called!\n"); abort(); }
/* Generated stub for fromwire_pad */
void fromwire_pad(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, size_t num UNNEEDED)
{ fprintf(stderr, "fromwire_pad called!\n"); abort(); }
@ -28,15 +31,15 @@ u16 fromwire_u16(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
/* Generated stub for fromwire_u32 */
u32 fromwire_u32(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
{ fprintf(stderr, "fromwire_u32 called!\n"); abort(); }
/* Generated stub for fromwire_u64 */
u64 fromwire_u64(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
{ fprintf(stderr, "fromwire_u64 called!\n"); abort(); }
/* Generated stub for fromwire_u8 */
u8 fromwire_u8(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
{ fprintf(stderr, "fromwire_u8 called!\n"); abort(); }
/* Generated stub for towire */
void towire(u8 **pptr UNNEEDED, const void *data UNNEEDED, size_t len UNNEEDED)
{ fprintf(stderr, "towire called!\n"); abort(); }
/* Generated stub for towire_amount_msat */
void towire_amount_msat(u8 **pptr UNNEEDED, const struct amount_msat msat UNNEEDED)
{ fprintf(stderr, "towire_amount_msat called!\n"); abort(); }
/* Generated stub for towire_pad */
void towire_pad(u8 **pptr UNNEEDED, size_t num UNNEEDED)
{ fprintf(stderr, "towire_pad called!\n"); abort(); }
@ -50,9 +53,6 @@ void towire_u16(u8 **pptr UNNEEDED, u16 v UNNEEDED)
/* Generated stub for towire_u32 */
void towire_u32(u8 **pptr UNNEEDED, u32 v UNNEEDED)
{ fprintf(stderr, "towire_u32 called!\n"); abort(); }
/* Generated stub for towire_u64 */
void towire_u64(u8 **pptr UNNEEDED, u64 v UNNEEDED)
{ fprintf(stderr, "towire_u64 called!\n"); abort(); }
/* Generated stub for towire_u8 */
void towire_u8(u8 **pptr UNNEEDED, u8 v UNNEEDED)
{ fprintf(stderr, "towire_u8 called!\n"); abort(); }

9
devtools/dump-gossipstore.c

@ -40,7 +40,7 @@ int main(int argc, char *argv[])
while (read(fd, &belen, sizeof(belen)) == sizeof(belen) &&
read(fd, &becsum, sizeof(becsum)) == sizeof(becsum)) {
u64 satoshis;
struct amount_sat sat;
struct short_channel_id scid;
u8 *gossip_msg;
u32 msglen = be32_to_cpu(belen);
@ -54,9 +54,10 @@ int main(int argc, char *argv[])
if (fromwire_gossip_store_channel_announcement(msg, msg,
&gossip_msg,
&satoshis)) {
printf("channel_announce for %"PRIu64" satoshis: %s\n",
satoshis, tal_hex(msg, gossip_msg));
&sat)) {
printf("channel_announce for %s: %s\n",
type_to_string(tmpctx, struct amount_sat, &sat),
tal_hex(msg, gossip_msg));
} else if (fromwire_gossip_store_channel_update(msg, msg,
&gossip_msg)) {
printf("channel_update: %s\n",

2
devtools/onion.c

@ -38,7 +38,7 @@ static void do_generate(int argc, char **argv)
hops_data[i].realm = i;
memset(&hops_data[i].channel_id, i,
sizeof(hops_data[i].channel_id));
hops_data[i].amt_forward = i;
hops_data[i].amt_forward.millisatoshis = i;
hops_data[i].outgoing_cltv = i;
fprintf(stderr, "Hopdata %d: %s\n", i, tal_hexstr(NULL, &hops_data[i], sizeof(hops_data[i])));
}

6
gossipd/gossip_peerd_wire.csv

@ -19,14 +19,14 @@ gossipd_send_gossip,,gossip,len*u8
gossipd_local_add_channel,3503
gossipd_local_add_channel,,short_channel_id,struct short_channel_id
gossipd_local_add_channel,,remote_node_id,struct pubkey
gossipd_local_add_channel,,satoshis,u64
gossipd_local_add_channel,,satoshis,struct amount_sat
# Send this channel_update.
gossipd_local_channel_update,3504
gossipd_local_channel_update,,short_channel_id,struct short_channel_id
gossipd_local_channel_update,,disable,bool
gossipd_local_channel_update,,cltv_expiry_delta,u16
gossipd_local_channel_update,,htlc_minimum_msat,u64
gossipd_local_channel_update,,htlc_minimum_msat,struct amount_msat
gossipd_local_channel_update,,fee_base_msat,u32
gossipd_local_channel_update,,fee_proportional_millionths,u32
gossipd_local_channel_update,,htlc_maximum_msat,u64
gossipd_local_channel_update,,htlc_maximum_msat,struct amount_msat

Can't render this file because it has a wrong number of fields in line 2.

6
gossipd/gossip_store.c

@ -104,10 +104,10 @@ static u8 *gossip_store_wrap_channel_announcement(const tal_t *ctx,
"Error parsing channel_announcement");
struct chan *chan = get_channel(rstate, &scid);
assert(chan && chan->satoshis > 0);
assert(chan && amount_sat_greater(chan->sat, AMOUNT_SAT(0)));
u8 *msg = towire_gossip_store_channel_announcement(ctx, gossip_msg,
chan->satoshis);
chan->sat);
return msg;
}
@ -247,7 +247,7 @@ void gossip_store_load(struct routing_state *rstate, struct gossip_store *gs)
beint32_t belen, becsum;
u32 msglen, checksum;
u8 *msg, *gossip_msg;
u64 satoshis;
struct amount_sat satoshis;
struct short_channel_id scid;
/* We set/check version byte on creation */
off_t known_good = 1;

4
gossipd/gossip_store.csv

@ -2,7 +2,7 @@
gossip_store_channel_announcement,4096
gossip_store_channel_announcement,,len,u16
gossip_store_channel_announcement,,announcement,len*u8
gossip_store_channel_announcement,,satoshis,u64
gossip_store_channel_announcement,,satoshis,struct amount_sat
gossip_store_channel_update,4097
gossip_store_channel_update,,len,u16
@ -17,4 +17,4 @@ gossip_store_channel_delete,,short_channel_id,struct short_channel_id
gossip_store_local_add_channel,4100
gossip_store_local_add_channel,,len,u16
gossip_store_local_add_channel,,local_add,len*u8
gossip_store_local_add_channel,,local_add,len*u8

Can't render this file because it has a wrong number of fields in line 2.

4
gossipd/gossip_wire.csv

@ -28,7 +28,7 @@ gossip_getnodes_reply,,nodes,num_nodes*struct gossip_getnodes_entry
gossip_getroute_request,3006
gossip_getroute_request,,source,struct pubkey
gossip_getroute_request,,destination,struct pubkey
gossip_getroute_request,,msatoshi,u64
gossip_getroute_request,,msatoshi,struct amount_msat
# We don't pass doubles, so pass riskfactor * 1000000.
gossip_getroute_request,,riskfactor_by_million,u64
gossip_getroute_request,,final_cltv,u32
@ -115,7 +115,7 @@ gossip_get_txout,,short_channel_id,struct short_channel_id
# master->gossipd here is the output, or empty if none.
gossip_get_txout_reply,3118
gossip_get_txout_reply,,short_channel_id,struct short_channel_id
gossip_get_txout_reply,,satoshis,u64
gossip_get_txout_reply,,satoshis,struct amount_sat
gossip_get_txout_reply,,len,u16
gossip_get_txout_reply,,outscript,len*u8

Can't render this file because it has a wrong number of fields in line 6.

58
gossipd/gossipd.c

@ -1180,10 +1180,10 @@ static void update_local_channel(struct daemon *daemon,
int direction,
bool disable,
u16 cltv_expiry_delta,
u64 htlc_minimum_msat,
struct amount_msat htlc_minimum,
u32 fee_base_msat,
u32 fee_proportional_millionths,
u64 htlc_maximum_msat,
struct amount_msat htlc_maximum,
const char *caller)
{
secp256k1_ecdsa_signature dummy_sig;
@ -1241,10 +1241,10 @@ static void update_local_channel(struct daemon *daemon,
timestamp,
message_flags, channel_flags,
cltv_expiry_delta,
htlc_minimum_msat,
htlc_minimum.millisatoshis,
fee_base_msat,
fee_proportional_millionths,
htlc_maximum_msat);
htlc_maximum.millisatoshis);
/* Note that we treat the hsmd as synchronous. This is simple (no
* callback hell)!, but may need to change to async if we ever want
@ -1316,10 +1316,10 @@ static void maybe_update_local_channel(struct daemon *daemon,
update_local_channel(daemon, chan, direction,
chan->local_disabled,
hc->delay,
hc->htlc_minimum_msat,
hc->htlc_minimum,
hc->base_fee,
hc->proportional_fee,
hc->htlc_maximum_msat,
hc->htlc_maximum,
/* Note this magic C macro which expands to the
* function name, for debug messages */
__func__);
@ -1402,18 +1402,18 @@ out:
* currently happen if the user restarts with different fee options, but we
* don't assume that. */
static bool halfchan_new_info(const struct half_chan *hc,
u16 cltv_delta, u64 htlc_minimum_msat,
u16 cltv_delta, struct amount_msat htlc_minimum,
u32 fee_base_msat, u32 fee_proportional_millionths,
u64 htlc_maximum_msat)
struct amount_msat htlc_maximum)
{
if (!is_halfchan_defined(hc))
return true;
return hc->delay != cltv_delta
|| hc->htlc_minimum_msat != htlc_minimum_msat
|| !amount_msat_eq(hc->htlc_minimum, htlc_minimum)
|| hc->base_fee != fee_base_msat
|| hc->proportional_fee != fee_proportional_millionths
|| hc->htlc_maximum_msat != htlc_maximum_msat;
|| !amount_msat_eq(hc->htlc_maximum, htlc_maximum);
}
/*~ channeld asks us to update the local channel. */
@ -1423,8 +1423,7 @@ static bool handle_local_channel_update(struct peer *peer, const u8 *msg)
struct short_channel_id scid;
bool disable;
u16 cltv_expiry_delta;
u64 htlc_minimum_msat;
u64 htlc_maximum_msat;
struct amount_msat htlc_minimum, htlc_maximum;
u32 fee_base_msat;
u32 fee_proportional_millionths;
int direction;
@ -1436,10 +1435,10 @@ static bool handle_local_channel_update(struct peer *peer, const u8 *msg)
&scid,
&disable,
&cltv_expiry_delta,
&htlc_minimum_msat,
&htlc_minimum,
&fee_base_msat,
&fee_proportional_millionths,
&htlc_maximum_msat)) {
&htlc_maximum)) {
status_broken("peer %s bad local_channel_update %s",
type_to_string(tmpctx, struct pubkey, &peer->id),
tal_hex(tmpctx, msg));
@ -1469,19 +1468,19 @@ static bool handle_local_channel_update(struct peer *peer, const u8 *msg)
* Or, if we're *enabling* an announced-disabled channel.
* Or, if it's an unannounced channel (only sending to peer). */
if (halfchan_new_info(&chan->half[direction],
cltv_expiry_delta, htlc_minimum_msat,
cltv_expiry_delta, htlc_minimum,
fee_base_msat, fee_proportional_millionths,
htlc_maximum_msat)
htlc_maximum)
|| ((chan->half[direction].channel_flags & ROUTING_FLAGS_DISABLED)
&& !disable)
|| !is_chan_public(chan)) {
update_local_channel(peer->daemon, chan, direction,
disable,
cltv_expiry_delta,
htlc_minimum_msat,
htlc_minimum,
fee_base_msat,
fee_proportional_millionths,
htlc_maximum_msat,
htlc_maximum,
__func__);
}
@ -1766,10 +1765,10 @@ static void gossip_send_keepalive_update(struct daemon *daemon,
hc->channel_flags & ROUTING_FLAGS_DIRECTION,
chan->local_disabled,
hc->delay,
hc->htlc_minimum_msat,
hc->htlc_minimum,
hc->base_fee,
hc->proportional_fee,
hc->htlc_maximum_msat,
hc->htlc_maximum,
__func__);
}
@ -1892,7 +1891,7 @@ static struct io_plan *getroute_req(struct io_conn *conn, struct daemon *daemon,
const u8 *msg)
{
struct pubkey source, destination;
u64 msatoshi;
struct amount_msat msat;
u32 final_cltv;
u64 riskfactor_by_million;
u32 max_hops;
@ -1909,19 +1908,20 @@ static struct io_plan *getroute_req(struct io_conn *conn, struct daemon *daemon,
* avoid being too predictable. */
if (!fromwire_gossip_getroute_request(msg, msg,
&source, &destination,
&msatoshi, &riskfactor_by_million,
&msat, &riskfactor_by_million,
&final_cltv, &fuzz,
&excluded,
&max_hops))
master_badmsg(WIRE_GOSSIP_GETROUTE_REQUEST, msg);
status_trace("Trying to find a route from %s to %s for %"PRIu64" msatoshi",
status_trace("Trying to find a route from %s to %s for %s",
pubkey_to_hexstr(tmpctx, &source),
pubkey_to_hexstr(tmpctx, &destination), msatoshi);
pubkey_to_hexstr(tmpctx, &destination),
type_to_string(tmpctx, struct amount_msat, &msat));
/* routing.c does all the hard work; can return NULL. */
hops = get_route(tmpctx, daemon->rstate, &source, &destination,
msatoshi, riskfactor_by_million / 1000000.0, final_cltv,
msat, riskfactor_by_million / 1000000.0, final_cltv,
fuzz, pseudorand_u64(), excluded, max_hops);
out = towire_gossip_getroute_reply(NULL, hops);
@ -1967,7 +1967,7 @@ static void append_half_channel(struct gossip_getchannels_entry **entries,
* raw in this case. */
raw_pubkey(e.source, &chan->nodes[idx]->id);
raw_pubkey(e.destination, &chan->nodes[!idx]->id);
e.satoshis = chan->satoshis;
e.sat = chan->sat;
e.channel_flags = c->channel_flags;
e.message_flags = c->message_flags;
e.local_disabled = chan->local_disabled;
@ -2496,13 +2496,13 @@ static struct io_plan *handle_txout_reply(struct io_conn *conn,
{
struct short_channel_id scid;
u8 *outscript;
u64 satoshis;
struct amount_sat sat;
if (!fromwire_gossip_get_txout_reply(msg, msg, &scid, &satoshis, &outscript))
if (!fromwire_gossip_get_txout_reply(msg, msg, &scid, &sat, &outscript))
master_badmsg(WIRE_GOSSIP_GET_TXOUT_REPLY, msg);
/* Outscript is NULL if it's not an unspent output */
handle_pending_cannouncement(daemon->rstate, &scid, satoshis, outscript);
handle_pending_cannouncement(daemon->rstate, &scid, sat, outscript);
/* Anywhere we might have announced a channel, we check if it's time to
* announce ourselves (ie. if we just announced our own first channel) */

252
gossipd/routing.c

@ -25,12 +25,6 @@
/* 365.25 * 24 * 60 / 10 */
#define BLOCKS_PER_YEAR 52596
/* For overflow avoidance, we never deal with msatoshi > 40 bits. */
#define MAX_MSATOSHI (1ULL << 40)
/* Proportional fee must be less than 24 bits, so never overflows. */
#define MAX_PROPORTIONAL_FEE (1 << 24)
/* We've unpacked and checked its signatures, now we wait for master to tell
* us the txout to check */
struct pending_cannouncement {
@ -287,7 +281,7 @@ struct chan *new_chan(struct routing_state *rstate,
const struct short_channel_id *scid,
const struct pubkey *id1,
const struct pubkey *id2,
u64 satoshis)
struct amount_sat satoshis)
{
struct chan *chan = tal(rstate, struct chan);
int n1idx = pubkey_idx(id1, id2);
@ -310,7 +304,7 @@ struct chan *new_chan(struct routing_state *rstate,
chan->txout_script = NULL;
chan->channel_announce = NULL;
chan->channel_announcement_index = 0;
chan->satoshis = satoshis;
chan->sat = satoshis;
chan->local_disabled = false;
tal_arr_expand(&n2->chans, chan);
@ -327,7 +321,7 @@ struct chan *new_chan(struct routing_state *rstate,
}
/* Too big to reach, but don't overflow if added. */
#define INFINITE 0x3FFFFFFFFFFFFFFFULL
#define INFINITE AMOUNT_MSAT(0x3FFFFFFFFFFFFFFFULL)
static void clear_bfg(struct node_map *nodes)
{
@ -338,37 +332,45 @@ static void clear_bfg(struct node_map *nodes)
size_t i;
for (i = 0; i < ARRAY_SIZE(n->bfg); i++) {
n->bfg[i].total = INFINITE;
n->bfg[i].risk = 0;
n->bfg[i].risk = AMOUNT_MSAT(0);
}
}
}
static u64 connection_fee(const struct half_chan *c, u64 msatoshi)
{
u64 fee;
assert(msatoshi < MAX_MSATOSHI);
assert(c->proportional_fee < MAX_PROPORTIONAL_FEE);
fee = (c->proportional_fee * msatoshi) / 1000000;
/* This can't overflow: c->base_fee is a u32 */
return c->base_fee + fee;
}
/* Risk of passing through this channel. We insert a tiny constant here
* in order to prefer shorter routes, all things equal. */
static u64 risk_fee(u64 amount, u32 delay, double riskfactor)
static WARN_UNUSED_RESULT bool risk_add_fee(struct amount_msat *risk,
struct amount_msat msat,
u32 delay, double riskfactor)
{
return 1 + amount * delay * riskfactor;
double r;
/* Won't overflow on add, just lose precision */
r = 1.0 + riskfactor * delay * msat.millisatoshis + risk->millisatoshis;
if (r > UINT64_MAX)
return false;
risk->millisatoshis = r;
return true;
}
/* Check that we can fit through this channel's indicated
* maximum_ and minimum_msat requirements.
*/
static bool hc_can_carry(const struct half_chan *hc, u64 requiredcap)
static bool hc_can_carry(const struct half_chan *hc,
struct amount_msat requiredcap)
{
return amount_msat_greater_eq(hc->htlc_maximum, requiredcap) &&
amount_msat_less_eq(hc->htlc_minimum, requiredcap);
}
/* Theoretically, this could overflow. */
static bool fuzz_fee(u64 *fee, double fee_scale)
{
return hc->htlc_maximum_msat >= requiredcap &&
hc->htlc_minimum_msat <= requiredcap;
u64 fuzzed_fee = *fee * fee_scale;
if (fee_scale > 1.0 && fuzzed_fee < *fee)
return false;
*fee = fuzzed_fee;
return true;
}
/* We track totals, rather than costs. That's because the fee depends
@ -397,38 +399,57 @@ static void bfg_one_edge(struct node *node,
for (h = 0; h < max_hops; h++) {
struct node *src;
/* FIXME: Bias against smaller channels. */
u64 fee;
u64 risk;
u64 requiredcap;
struct amount_msat fee, risk, requiredcap,
this_total, curr_total;
if (node->bfg[h].total == INFINITE)
if (!amount_msat_fee(&fee, node->bfg[h].total,
c->base_fee, c->proportional_fee))
continue;
fee = connection_fee(c, node->bfg[h].total) * fee_scale;
requiredcap = node->bfg[h].total + fee;
risk = node->bfg[h].risk +
risk_fee(requiredcap, c->delay, riskfactor);
if (!fuzz_fee(&fee.millisatoshis, fee_scale))
continue;
if (!amount_msat_add(&requiredcap, node->bfg[h].total, fee))
continue;
risk = node->bfg[h].risk;
if (!risk_add_fee(&risk, requiredcap, c->delay, riskfactor))
continue;
if (!hc_can_carry(c, requiredcap)) {
/* Skip a channel if it indicated that it won't route
* the requested amount. */
continue;
} else if (requiredcap >= MAX_MSATOSHI) {
SUPERVERBOSE("...extreme %"PRIu64
" + fee %"PRIu64
" + risk %"PRIu64" ignored",
node->bfg[h].total, fee, risk);
continue;
}
if (!amount_msat_add(&this_total, requiredcap, risk))
continue;
/* nodes[0] is src for connections[0] */
src = chan->nodes[idx];
if (requiredcap + risk <
src->bfg[h + 1].total + src->bfg[h + 1].risk) {
SUPERVERBOSE("...%s can reach here in hoplen %zu total %"PRIu64,
if (!amount_msat_add(&curr_total,
src->bfg[h + 1].total,
src->bfg[h + 1].risk)) {
/* We just calculated this: shouldn't happen! */
status_broken("Overflow: total %s + risk %s",
type_to_string(tmpctx, struct amount_msat,
&src->bfg[h + 1].total),
type_to_string(tmpctx, struct amount_msat,
&src->bfg[h + 1].risk));
continue;
}
if (amount_msat_less(this_total, curr_total)) {
SUPERVERBOSE("...%s can reach here hoplen %zu"
" total %s risk %s",
type_to_string(tmpctx, struct pubkey,
&src->id),
h, node->bfg[h].total + fee);
h,
type_to_string(tmpctx, struct amount_msat,
&requiredcap),
type_to_string(tmpctx, struct amount_msat,
&risk));
src->bfg[h+1].total = requiredcap;
src->bfg[h+1].risk = risk;
src->bfg[h+1].prev = chan;
@ -446,15 +467,17 @@ static bool hc_is_routable(const struct chan *chan, int idx)
/* riskfactor is already scaled to per-block amount */
static struct chan **
find_route(const tal_t *ctx, struct routing_state *rstate,
const struct pubkey *from, const struct pubkey *to, u64 msatoshi,
const struct pubkey *from, const struct pubkey *to,
struct amount_msat msat,
double riskfactor,
double fuzz, const struct siphash_seed *base_seed,
size_t max_hops,
u64 *fee)
struct amount_msat *fee)
{
struct chan **route;
struct node *n, *src, *dst;
struct node_map_iter it;
struct amount_msat best_total;
int runs, i, best;
/* Note: we map backwards, since we know the amount of satoshi we want
@ -476,12 +499,6 @@ find_route(const tal_t *ctx, struct routing_state *rstate,
return NULL;
}
if (msatoshi >= MAX_MSATOSHI) {
status_info("find_route: can't route huge amount %"PRIu64,
msatoshi);
return NULL;
}
if (max_hops > ROUTING_MAX_HOPS) {
status_info("find_route: max_hops huge amount %zu > %u",
max_hops, ROUTING_MAX_HOPS);
@ -493,8 +510,8 @@ find_route(const tal_t *ctx, struct routing_state *rstate,
/* Bellman-Ford-Gibson: like Bellman-Ford, but keep values for
* every path length. */
src->bfg[0].total = msatoshi;
src->bfg[0].risk = 0;
src->bfg[0].total = msat;
src->bfg[0].risk = AMOUNT_MSAT(0);
for (runs = 0; runs < max_hops; runs++) {
SUPERVERBOSE("Run %i", runs);
@ -528,17 +545,27 @@ find_route(const tal_t *ctx, struct routing_state *rstate,
}
best = 0;
for (i = 1; i <= max_hops; i++) {
status_trace("%i hop solution: %"PRIu64" + %"PRIu64,
i, dst->bfg[i].total, dst->bfg[i].risk);
if (dst->bfg[i].total + dst->bfg[i].risk
< dst->bfg[best].total + dst->bfg[best].risk)
best_total = INFINITE;
for (i = 0; i <= max_hops; i++) {
struct amount_msat total;
status_trace("%i hop solution: %s + %s",
i,
type_to_string(tmpctx, struct amount_msat,
&dst->bfg[i].total),
type_to_string(tmpctx, struct amount_msat,
&dst->bfg[i].risk));
if (!amount_msat_add(&total,
dst->bfg[i].total, dst->bfg[i].risk))
continue;
if (amount_msat_less(total, best_total)) {
best = i;
best_total = total;
}
}
status_trace("=> chose %i hop solution", best);
/* No route? */
if (dst->bfg[best].total >= INFINITE) {
if (amount_msat_greater_eq(best_total, INFINITE)) {
status_trace("find_route: No route to %s",
type_to_string(tmpctx, struct pubkey, to));
return NULL;
@ -546,7 +573,13 @@ find_route(const tal_t *ctx, struct routing_state *rstate,
/* We (dst) don't charge ourselves fees, so skip first hop */
n = other_node(dst, dst->bfg[best].prev);
*fee = n->bfg[best-1].total - msatoshi;
if (!amount_msat_sub(fee, n->bfg[best-1].total, msat)) {
status_broken("Could not subtract %s - %s for fee",
type_to_string(tmpctx, struct amount_msat,
&n->bfg[best-1].total),
type_to_string(tmpctx, struct amount_msat, &msat));
return NULL;
}
/* Lay out route */
route = tal_arr(ctx, struct chan *, best);
@ -732,7 +765,8 @@ static void add_channel_announce_to_broadcast(struct routing_state *rstate,
}
bool routing_add_channel_announcement(struct routing_state *rstate,
const u8 *msg TAKES, u64 satoshis)
const u8 *msg TAKES,
struct amount_sat sat)
{
struct chan *chan;
secp256k1_ecdsa_signature node_signature_1, node_signature_2;
@ -756,7 +790,7 @@ bool routing_add_channel_announcement(struct routing_state *rstate,
* channel_announcements. See handle_channel_announcement. */
chan = get_channel(rstate, &scid);
if (!chan)
chan = new_chan(rstate, &scid, &node_id_1, &node_id_2, satoshis);
chan = new_chan(rstate, &scid, &node_id_1, &node_id_2, sat);
/* Channel is now public. */
chan->channel_announce = tal_dup_arr(chan, u8, msg, tal_count(msg), 0);
@ -937,7 +971,7 @@ static void process_pending_channel_update(struct routing_state *rstate,
void handle_pending_cannouncement(struct routing_state *rstate,
const struct short_channel_id *scid,
const u64 satoshis,
struct amount_sat sat,
const u8 *outscript)
{
const u8 *s;
@ -985,7 +1019,7 @@ void handle_pending_cannouncement(struct routing_state *rstate,
return;
}
if (!routing_add_channel_announcement(rstate, pending->announce, satoshis))
if (!routing_add_channel_announcement(rstate, pending->announce, sat))
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Could not add channel_announcement");
@ -1025,14 +1059,14 @@ static void set_connection_values(struct chan *chan,
u8 message_flags,
u8 channel_flags,
u64 timestamp,
u64 htlc_minimum_msat,
u64 htlc_maximum_msat)
struct amount_msat htlc_minimum,
struct amount_msat htlc_maximum)
{
struct half_chan *c = &chan->half[idx];
c->delay = delay;
c->htlc_minimum_msat = htlc_minimum_msat;
c->htlc_maximum_msat = htlc_maximum_msat;
c->htlc_minimum = htlc_minimum;
c->htlc_maximum = htlc_maximum;
c->base_fee = base_fee;
c->proportional_fee = proportional_fee;
c->message_flags = message_flags;
@ -1043,16 +1077,6 @@ static void set_connection_values(struct chan *chan,
SUPERVERBOSE("Channel %s/%d was updated.",
type_to_string(tmpctx, struct short_channel_id, &chan->scid),
idx);
if (c->proportional_fee >= MAX_PROPORTIONAL_FEE) {
status_trace("Channel %s/%d massive proportional fee %u:"
" disabling.",
type_to_string(tmpctx, struct short_channel_id,
&chan->scid),
idx,
c->proportional_fee);
c->channel_flags |= ROUTING_FLAGS_DISABLED;
}
}
bool routing_add_channel_update(struct routing_state *rstate,
@ -1063,10 +1087,9 @@ bool routing_add_channel_update(struct routing_state *rstate,
u32 timestamp;
u8 message_flags, channel_flags;
u16 expiry;
u64 htlc_minimum_msat;
struct amount_msat htlc_minimum, htlc_maximum;
u32 fee_base_msat;
u32 fee_proportional_millionths;
u64 htlc_maximum_msat;
struct bitcoin_blkid chain_hash;
struct chan *chan;
u8 direction;
@ -1074,7 +1097,7 @@ bool routing_add_channel_update(struct routing_state *rstate,
if (!fromwire_channel_update(update, &signature, &chain_hash,
&short_channel_id, &timestamp,
&message_flags, &channel_flags,
&expiry, &htlc_minimum_msat, &fee_base_msat,
&expiry, &htlc_minimum.millisatoshis, &fee_base_msat,
&fee_proportional_millionths))
return false;
/* If it's flagged as containing the optional field, reparse for
@ -1084,9 +1107,9 @@ bool routing_add_channel_update(struct routing_state *rstate,
update, &signature, &chain_hash,
&short_channel_id, &timestamp,
&message_flags, &channel_flags,
&expiry, &htlc_minimum_msat, &fee_base_msat,
&expiry, &htlc_minimum.millisatoshis, &fee_base_msat,
&fee_proportional_millionths,
&htlc_maximum_msat))
&htlc_maximum.millisatoshis))
return false;
chan = get_channel(rstate, &short_channel_id);
if (!chan)
@ -1095,25 +1118,29 @@ bool routing_add_channel_update(struct routing_state *rstate,
if (message_flags & ROUTING_OPT_HTLC_MAX_MSAT) {
/* Reject update if the `htlc_maximum_msat` is greater
* than the total available channel satoshis */
if (htlc_maximum_msat > chan->satoshis * 1000)
if (amount_msat_greater_sat(htlc_maximum, chan->sat))
return false;
} else {
/* If not indicated, set htlc_max_msat to channel capacity */
htlc_maximum_msat = chan->satoshis * 1000;
if (!amount_sat_to_msat(&htlc_maximum, chan->sat)) {
status_broken("Channel capacity %s overflows!",
type_to_string(tmpctx, struct amount_sat,
&chan->sat));
return false;
}
}
/* FIXME: https://github.com/lightningnetwork/lightning-rfc/pull/512
* says we MUST NOT exceed 2^32-1, but c-lightning did, so just trim
* rather than rejecting. */
if (htlc_maximum_msat > rstate->chainparams->max_payment.millisatoshis)
htlc_maximum_msat = rstate->chainparams->max_payment.millisatoshis;
if (amount_msat_greater(htlc_maximum, rstate->chainparams->max_payment))
htlc_maximum = rstate->chainparams->max_payment;
direction = channel_flags & 0x1;
set_connection_values(chan, direction, fee_base_msat,
fee_proportional_millionths, expiry,
message_flags, channel_flags,
timestamp, htlc_minimum_msat,
htlc_maximum_msat);
timestamp, htlc_minimum, htlc_maximum);
/* Replace any old one. */
tal_free(chan->half[direction].channel_update);
@ -1500,22 +1527,22 @@ u8 *handle_node_announcement(struct routing_state *rstate, const u8 *node_ann)
struct route_hop *get_route(const tal_t *ctx, struct routing_state *rstate,
const struct pubkey *source,
const struct pubkey *destination,
const u64 msatoshi, double riskfactor,
struct amount_msat msat, double riskfactor,
u32 final_cltv,
double fuzz, u64 seed,
const struct short_channel_id_dir *excluded,
size_t max_hops)
{
struct chan **route;
u64 total_amount;
struct amount_msat total_amount;
unsigned int total_delay;
u64 fee;
struct amount_msat fee;
struct route_hop *hops;
struct node *n;
u64 *saved_capacity;
struct amount_msat *saved_capacity;
struct siphash_seed base_seed;
saved_capacity = tal_arr(tmpctx, u64, tal_count(excluded));
saved_capacity = tal_arr(tmpctx, struct amount_msat, tal_count(excluded));
base_seed.u.u64[0] = base_seed.u.u64[1] = seed;
@ -1524,12 +1551,11 @@ struct route_hop *get_route(const tal_t *ctx, struct routing_state *rstate,
struct chan *chan = get_channel(rstate, &excluded[i].scid);
if (!chan)
continue;
saved_capacity[i]
= chan->half[excluded[i].dir].htlc_maximum_msat;
chan->half[excluded[i].dir].htlc_maximum_msat = 0;
saved_capacity[i] = chan->half[excluded[i].dir].htlc_maximum;
chan->half[excluded[i].dir].htlc_maximum = AMOUNT_MSAT(0);
}
route = find_route(ctx, rstate, source, destination, msatoshi,
route = find_route(ctx, rstate, source, destination, msat,
riskfactor / BLOCKS_PER_YEAR / 100,
fuzz, &base_seed, max_hops, &fee);
@ -1538,8 +1564,7 @@ struct route_hop *get_route(const tal_t *ctx, struct routing_state *rstate,
struct chan *chan = get_channel(rstate, &excluded[i].scid);
if (!chan)
continue;
chan->half[excluded[i].dir].htlc_maximum_msat
= saved_capacity[i];
chan->half[excluded[i].dir].htlc_maximum = saved_capacity[i];
}
if (!route) {
@ -1548,27 +1573,36 @@ struct route_hop *get_route(const tal_t *ctx, struct routing_state *rstate,
/* Fees, delays need to be calculated backwards along route. */
hops = tal_arr(ctx, struct route_hop, tal_count(route));
total_amount = msatoshi;
total_amount = msat;
total_delay = final_cltv;
/* Start at destination node. */
n = get_node(rstate, destination);
for (int i = tal_count(route) - 1; i >= 0; i--) {
const struct half_chan *c;
int idx = half_chan_to(n, route[i]);
c = &route[i]->half[idx];
hops[i].channel_id = route[i]->scid;
hops[i].nodeid = n->id;
hops[i].amount.millisatoshis = total_amount;
hops[i].amount = total_amount;
hops[i].delay = total_delay;
hops[i].direction = idx;
total_amount += connection_fee(c, total_amount);
/* Since we calculated this route, it should not overflow! */
if (!amount_msat_add_fee(&total_amount,
c->base_fee, c->proportional_fee)) {
status_broken("Route overflow step %i: %s + %u/%u!?",
i, type_to_string(tmpctx, struct amount_msat,
&total_amount),
c->base_fee, c->proportional_fee);
return tal_free(hops);
}
total_delay += c->delay;
n = other_node(n, route[i]);
}
assert(pubkey_eq(&n->id, source));
/* FIXME: Shadow route! */
return hops;
}
@ -1701,10 +1735,10 @@ bool handle_local_add_channel(struct routing_state *rstate, const u8 *msg)
{
struct short_channel_id scid;
struct pubkey remote_node_id;
u64 satoshis;
struct amount_sat sat;
if (!fromwire_gossipd_local_add_channel(msg, &scid, &remote_node_id,
&satoshis)) {
&sat)) {
status_broken("Unable to parse local_add_channel message: %s",
tal_hex(msg, msg));
return false;
@ -1720,6 +1754,6 @@ bool handle_local_add_channel(struct routing_state *rstate, const u8 *msg)
type_to_string(tmpctx, struct short_channel_id, &scid));
/* Create new (unannounced) channel */
new_chan(rstate, &scid, &rstate->local_id, &remote_node_id, satoshis);
new_chan(rstate, &scid, &rstate->local_id, &remote_node_id, sat);
return true;
}

22
gossipd/routing.h

@ -27,11 +27,8 @@ struct half_chan {
/* -1 if channel_update is NULL */
s64 last_timestamp;
/* Minimum number of msatoshi in an HTLC */
u64 htlc_minimum_msat;
/* Maximum number of msatoshis in an HTLC */
u64 htlc_maximum_msat;
/* Minimum and maximum number of msatoshi in an HTLC */
struct amount_msat htlc_minimum, htlc_maximum;
/* Flags as specified by the `channel_update`s, among other
* things indicated direction wrt the `channel_id` */
@ -62,7 +59,7 @@ struct chan {
/* Disabled locally (due to peer disconnect) */
bool local_disabled;
u64 satoshis;
struct amount_sat sat;
};
/* A local channel can exist which isn't announcable. */
@ -103,9 +100,9 @@ struct node {
/* Temporary data for routefinding. */
struct {
/* Total to get to here from target. */
u64 total;
struct amount_msat total;
/* Total risk premium of this route. */
u64 risk;
struct amount_msat risk;
/* Where that came from. */
struct chan *prev;
} bfg[ROUTING_MAX_HOPS+1];
@ -225,7 +222,7 @@ struct chan *new_chan(struct routing_state *rstate,
const struct short_channel_id *scid,
const struct pubkey *id1,
const struct pubkey *id2,
u64 satoshis);
struct amount_sat sat);
/* Handlers for incoming messages */
@ -245,7 +242,7 @@ u8 *handle_channel_announcement(struct routing_state *rstate,
*/
void handle_pending_cannouncement(struct routing_state *rstate,
const struct short_channel_id *scid,
const u64 satoshis,
const struct amount_sat sat,
const u8 *txscript);
/* Returns NULL if all OK, otherwise an error for the peer which sent. */
@ -262,7 +259,7 @@ struct node *get_node(struct routing_state *rstate, const struct pubkey *id);
struct route_hop *get_route(const tal_t *ctx, struct routing_state *rstate,
const struct pubkey *source,
const struct pubkey *destination,
const u64 msatoshi, double riskfactor,
const struct amount_msat msat, double riskfactor,
u32 final_cltv,
double fuzz,
u64 seed,
@ -286,7 +283,8 @@ void route_prune(struct routing_state *rstate);
* @see{handle_channel_announcement} entrypoint to check before adding.
*/
bool routing_add_channel_announcement(struct routing_state *rstate,
const u8 *msg TAKES, u64 satoshis);
const u8 *msg TAKES,
struct amount_sat sat);
/**
* Add a channel_update without checking for errors

1
gossipd/test/Makefile

@ -7,6 +7,7 @@ GOSSIPD_TEST_OBJS := $(GOSSIPD_TEST_SRC:.c=.o)
GOSSIPD_TEST_PROGRAMS := $(GOSSIPD_TEST_OBJS:.o=)
GOSSIPD_TEST_COMMON_OBJS := \
common/amount.o \
common/features.o \
common/pseudorand.o \
common/type_to_string.o \

16
gossipd/test/run-bench-find_route.c

@ -44,10 +44,10 @@ bool fromwire_channel_update(const void *p UNNEEDED, secp256k1_ecdsa_signature *
bool fromwire_channel_update_option_channel_htlc_max(const void *p UNNEEDED, secp256k1_ecdsa_signature *signature UNNEEDED, struct bitcoin_blkid *chain_hash UNNEEDED, struct short_channel_id *short_channel_id UNNEEDED, u32 *timestamp UNNEEDED, u8 *message_flags UNNEEDED, u8 *channel_flags UNNEEDED, u16 *cltv_expiry_delta UNNEEDED, u64 *htlc_minimum_msat UNNEEDED, u32 *fee_base_msat UNNEEDED, u32 *fee_proportional_millionths UNNEEDED, u64 *htlc_maximum_msat UNNEEDED)
{ fprintf(stderr, "fromwire_channel_update_option_channel_htlc_max called!\n"); abort(); }
/* Generated stub for fromwire_gossipd_local_add_channel */
bool fromwire_gossipd_local_add_channel(const void *p UNNEEDED, struct short_channel_id *short_channel_id UNNEEDED, struct pubkey *remote_node_id UNNEEDED, u64 *satoshis UNNEEDED)
bool fromwire_gossipd_local_add_channel(const void *p UNNEEDED, struct short_channel_id *short_channel_id UNNEEDED, struct pubkey *remote_node_id UNNEEDED, struct amount_sat *satoshis UNNEEDED)
{ fprintf(stderr, "fromwire_gossipd_local_add_channel called!\n"); abort(); }
/* Generated stub for fromwire_gossip_store_channel_announcement */
bool fromwire_gossip_store_channel_announcement(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u8 **announcement UNNEEDED, u64 *satoshis UNNEEDED)
bool fromwire_gossip_store_channel_announcement(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u8 **announcement UNNEEDED, struct amount_sat *satoshis UNNEEDED)
{ fprintf(stderr, "fromwire_gossip_store_channel_announcement called!\n"); abort(); }
/* Generated stub for fromwire_gossip_store_channel_delete */
bool fromwire_gossip_store_channel_delete(const void *p UNNEEDED, struct short_channel_id *short_channel_id UNNEEDED)
@ -96,7 +96,7 @@ u8 *towire_errorfmt(const tal_t *ctx UNNEEDED,
const char *fmt UNNEEDED, ...)
{ fprintf(stderr, "towire_errorfmt called!\n"); abort(); }
/* Generated stub for towire_gossip_store_channel_announcement */
u8 *towire_gossip_store_channel_announcement(const tal_t *ctx UNNEEDED, const u8 *announcement UNNEEDED, u64 satoshis UNNEEDED)
u8 *towire_gossip_store_channel_announcement(const tal_t *ctx UNNEEDED, const u8 *announcement UNNEEDED, struct amount_sat satoshis UNNEEDED)
{ fprintf(stderr, "towire_gossip_store_channel_announcement called!\n"); abort(); }
/* Generated stub for towire_gossip_store_channel_delete */
u8 *towire_gossip_store_channel_delete(const tal_t *ctx UNNEEDED, const struct short_channel_id *short_channel_id UNNEEDED)
@ -143,7 +143,7 @@ static void add_connection(struct routing_state *rstate,
chan = get_channel(rstate, &scid);
if (!chan)
chan = new_chan(rstate, &scid, &nodes[from], &nodes[to],
1000000);
AMOUNT_SAT(1000000));
c = &chan->half[idx];
c->base_fee = base_fee;
@ -152,8 +152,8 @@ static void add_connection(struct routing_state *rstate,
c->channel_flags = get_channel_direction(&nodes[from], &nodes[to]);
/* This must be non-NULL, otherwise we consider it disabled! */
c->channel_update = tal(chan, u8);
c->htlc_maximum_msat = -1ULL;
c->htlc_minimum_msat = 0;
c->htlc_maximum = AMOUNT_MSAT(-1ULL);
c->htlc_minimum = AMOUNT_MSAT(0);
}
static struct pubkey nodeid(size_t n)
@ -254,11 +254,11 @@ int main(int argc, char *argv[])
for (size_t i = 0; i < num_runs; i++) {
const struct pubkey *from = &nodes[pseudorand(num_nodes)];
const struct pubkey *to = &nodes[pseudorand(num_nodes)];
u64 fee;
struct amount_msat fee;
struct chan **route;
route = find_route(tmpctx, rstate, from, to,
pseudorand(100000),
(struct amount_msat){pseudorand(100000)},
riskfactor,
0.75, &base_seed,
ROUTING_MAX_HOPS,

43
gossipd/test/run-find_route-specific.c

@ -33,10 +33,10 @@ bool fromwire_channel_update(const void *p UNNEEDED, secp256k1_ecdsa_signature *
bool fromwire_channel_update_option_channel_htlc_max(const void *p UNNEEDED, secp256k1_ecdsa_signature *signature UNNEEDED, struct bitcoin_blkid *chain_hash UNNEEDED, struct short_channel_id *short_channel_id UNNEEDED, u32 *timestamp UNNEEDED, u8 *message_flags UNNEEDED, u8 *channel_flags UNNEEDED, u16 *cltv_expiry_delta UNNEEDED, u64 *htlc_minimum_msat UNNEEDED, u32 *fee_base_msat UNNEEDED, u32 *fee_proportional_millionths UNNEEDED, u64 *htlc_maximum_msat UNNEEDED)
{ fprintf(stderr, "fromwire_channel_update_option_channel_htlc_max called!\n"); abort(); }
/* Generated stub for fromwire_gossipd_local_add_channel */
bool fromwire_gossipd_local_add_channel(const void *p UNNEEDED, struct short_channel_id *short_channel_id UNNEEDED, struct pubkey *remote_node_id UNNEEDED, u64 *satoshis UNNEEDED)
bool fromwire_gossipd_local_add_channel(const void *p UNNEEDED, struct short_channel_id *short_channel_id UNNEEDED, struct pubkey *remote_node_id UNNEEDED, struct amount_sat *satoshis UNNEEDED)
{ fprintf(stderr, "fromwire_gossipd_local_add_channel called!\n"); abort(); }
/* Generated stub for fromwire_gossip_store_channel_announcement */
bool fromwire_gossip_store_channel_announcement(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u8 **announcement UNNEEDED, u64 *satoshis UNNEEDED)
bool fromwire_gossip_store_channel_announcement(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u8 **announcement UNNEEDED, struct amount_sat *satoshis UNNEEDED)
{ fprintf(stderr, "fromwire_gossip_store_channel_announcement called!\n"); abort(); }
/* Generated stub for fromwire_gossip_store_channel_delete */
bool fromwire_gossip_store_channel_delete(const void *p UNNEEDED, struct short_channel_id *short_channel_id UNNEEDED)
@ -85,7 +85,7 @@ u8 *towire_errorfmt(const tal_t *ctx UNNEEDED,
const char *fmt UNNEEDED, ...)
{ fprintf(stderr, "towire_errorfmt called!\n"); abort(); }
/* Generated stub for towire_gossip_store_channel_announcement */
u8 *towire_gossip_store_channel_announcement(const tal_t *ctx UNNEEDED, const u8 *announcement UNNEEDED, u64 satoshis UNNEEDED)
u8 *towire_gossip_store_channel_announcement(const tal_t *ctx UNNEEDED, const u8 *announcement UNNEEDED, struct amount_sat satoshis UNNEEDED)
{ fprintf(stderr, "towire_gossip_store_channel_announcement called!\n"); abort(); }
/* Generated stub for towire_gossip_store_channel_delete */
u8 *towire_gossip_store_channel_delete(const tal_t *ctx UNNEEDED, const struct short_channel_id *short_channel_id UNNEEDED)
@ -120,7 +120,7 @@ get_or_make_connection(struct routing_state *rstate,
const struct pubkey *from_id,
const struct pubkey *to_id,
const char *shortid,
const u64 satoshis)
struct amount_sat satoshis)
{
struct short_channel_id scid;
struct chan *chan;
@ -135,8 +135,9 @@ get_or_make_connection(struct routing_state *rstate,
/* Make sure it's seen as initialized (update non-NULL). */
chan->half[idx].channel_update = (void *)chan;
chan->half[idx].htlc_minimum_msat = 0;
chan->half[idx].htlc_maximum_msat = satoshis * 1000;
chan->half[idx].htlc_minimum = AMOUNT_MSAT(0);
if (!amount_sat_to_msat(&chan->half[idx].htlc_maximum, satoshis))
abort();
return &chan->half[idx];
}
@ -162,7 +163,7 @@ int main(void)
struct half_chan *nc;
struct routing_state *rstate;
struct pubkey a, b, c, d;
u64 fee;
struct amount_msat fee;
struct chan **route;
const double riskfactor = 1.0 / BLOCKS_PER_YEAR / 10000;
@ -187,7 +188,7 @@ int main(void)
/* [{'active': True, 'short_id': '6990:2:1/1', 'fee_per_kw': 10, 'delay': 5, 'message_flags': 0, 'channel_flags': 1, 'destination': '0230ad0e74ea03976b28fda587bb75bdd357a1938af4424156a18265167f5e40ae', 'source': '02ea622d5c8d6143f15ed3ce1d501dd0d3d09d3b1c83a44d0034949f8a9ab60f06', 'last_update': 1504064344}, */
nc = get_or_make_connection(rstate, &c, &b, "6990x2x1", 1000);
nc = get_or_make_connection(rstate, &c, &b, "6990x2x1", AMOUNT_SAT(1000));
nc->base_fee = 0;
nc->proportional_fee = 10;
nc->delay = 5;
@ -196,7 +197,7 @@ int main(void)
nc->last_timestamp = 1504064344;
/* {'active': True, 'short_id': '6989:2:1/0', 'fee_per_kw': 10, 'delay': 5, 'message_flags': 0, 'channel_flags': 0, 'destination': '03c173897878996287a8100469f954dd820fcd8941daed91c327f168f3329be0bf', 'source': '0230ad0e74ea03976b28fda587bb75bdd357a1938af4424156a18265167f5e40ae', 'last_update': 1504064344}, */
nc = get_or_make_connection(rstate, &b, &a, "6989x2x1", 1000);
nc = get_or_make_connection(rstate, &b, &a, "6989x2x1", AMOUNT_SAT(1000));
nc->base_fee = 0;
nc->proportional_fee = 10;
nc->delay = 5;
@ -205,17 +206,17 @@ int main(void)
nc->last_timestamp = 1504064344;
/* {'active': True, 'short_id': '6990:2:1/0', 'fee_per_kw': 10, 'delay': 5, 'message_flags': 0, 'channel_flags': 0, 'destination': '02ea622d5c8d6143f15ed3ce1d501dd0d3d09d3b1c83a44d0034949f8a9ab60f06', 'source': '0230ad0e74ea03976b28fda587bb75bdd357a1938af4424156a18265167f5e40ae', 'last_update': 1504064344}, */
nc = get_or_make_connection(rstate, &b, &c, "6990x2x1", 1000);
nc = get_or_make_connection(rstate, &b, &c, "6990x2x1", AMOUNT_SAT(1000));
nc->base_fee = 0;
nc->proportional_fee = 10;
nc->delay = 5;
nc->channel_flags = 0;
nc->message_flags = 0;
nc->last_timestamp = 1504064344;
nc->htlc_minimum_msat = 100;
nc->htlc_minimum = AMOUNT_MSAT(100);
/* {'active': True, 'short_id': '6989:2:1/1', 'fee_per_kw': 10, 'delay': 5, 'message_flags': 0, 'channel_flags': 1, 'destination': '0230ad0e74ea03976b28fda587bb75bdd357a1938af4424156a18265167f5e40ae', 'source': '03c173897878996287a8100469f954dd820fcd8941daed91c327f168f3329be0bf', 'last_update': 1504064344}]} */
nc = get_or_make_connection(rstate, &a, &b, "6989x2x1", 1000);
nc = get_or_make_connection(rstate, &a, &b, "6989x2x1", AMOUNT_SAT(1000));
nc->base_fee = 0;
nc->proportional_fee = 10;
nc->delay = 5;
@ -223,7 +224,7 @@ int main(void)
nc->message_flags = 0;
nc->last_timestamp = 1504064344;
route = find_route(tmpctx, rstate, &a, &c, 100000, riskfactor, 0.0, NULL,
route = find_route(tmpctx, rstate, &a, &c, AMOUNT_MSAT(100000), riskfactor, 0.0, NULL,
ROUTING_MAX_HOPS, &fee);
assert(route);
assert(tal_count(route) == 2);
@ -232,41 +233,41 @@ int main(void)
/* We should not be able to find a route that exceeds our own capacity */
route = find_route(tmpctx, rstate, &a, &c, 1000001, riskfactor, 0.0, NULL,
route = find_route(tmpctx, rstate, &a, &c, AMOUNT_MSAT(1000001), riskfactor, 0.0, NULL,
ROUTING_MAX_HOPS, &fee);
assert(!route);
/* Now test with a query that exceeds the channel capacity after adding
* some fees */
route = find_route(tmpctx, rstate, &a, &c, 999999, riskfactor, 0.0, NULL,
route = find_route(tmpctx, rstate, &a, &c, AMOUNT_MSAT(999999), riskfactor, 0.0, NULL,
ROUTING_MAX_HOPS, &fee);
assert(!route);
/* This should fail to return a route because it is smaller than these
* htlc_minimum_msat on the last channel. */
route = find_route(tmpctx, rstate, &a, &c, 1, riskfactor, 0.0, NULL,
route = find_route(tmpctx, rstate, &a, &c, AMOUNT_MSAT(1), riskfactor, 0.0, NULL,
ROUTING_MAX_HOPS, &fee);
assert(!route);
/* {'active': True, 'short_id': '6990:2:1/0', 'fee_per_kw': 10, 'delay': 5, 'message_flags': 1, 'htlc_maximum_msat': 500000, 'htlc_minimum_msat': 100, 'channel_flags': 0, 'destination': '02cca6c5c966fcf61d121e3a70e03a1cd9eeeea024b26ea666ce974d43b242e636', 'source': '03c173897878996287a8100469f954dd820fcd8941daed91c327f168f3329be0bf', 'last_update': 1504064344}, */
nc = get_or_make_connection(rstate, &a, &d, "6991x2x1", 1000);
nc = get_or_make_connection(rstate, &a, &d, "6991x2x1", AMOUNT_SAT(1000));
nc->base_fee = 0;
nc->proportional_fee = 0;
nc->delay = 5;
nc->channel_flags = 0;
nc->message_flags = 1;
nc->last_timestamp = 1504064344;
nc->htlc_minimum_msat = 100;
nc->htlc_maximum_msat = 500000; /* half capacity */
nc->htlc_minimum = AMOUNT_MSAT(100);
nc->htlc_maximum = AMOUNT_MSAT(500000); /* half capacity */
/* This should route correctly at the max_msat level */
route = find_route(tmpctx, rstate, &a, &d, 500000, riskfactor, 0.0, NULL,
route = find_route(tmpctx, rstate, &a, &d, AMOUNT_MSAT(500000), riskfactor, 0.0, NULL,
ROUTING_MAX_HOPS, &fee);
assert(route);
/* This should fail to return a route because it's larger than the
* htlc_maximum_msat on the last channel. */
route = find_route(tmpctx, rstate, &a, &d, 500001, riskfactor, 0.0, NULL,
route = find_route(tmpctx, rstate, &a, &d, AMOUNT_MSAT(500001), riskfactor, 0.0, NULL,
ROUTING_MAX_HOPS, &fee);
assert(!route);

34
gossipd/test/run-find_route.c

@ -31,10 +31,10 @@ bool fromwire_channel_update(const void *p UNNEEDED, secp256k1_ecdsa_signature *
bool fromwire_channel_update_option_channel_htlc_max(const void *p UNNEEDED, secp256k1_ecdsa_signature *signature UNNEEDED, struct bitcoin_blkid *chain_hash UNNEEDED, struct short_channel_id *short_channel_id UNNEEDED, u32 *timestamp UNNEEDED, u8 *message_flags UNNEEDED, u8 *channel_flags UNNEEDED, u16 *cltv_expiry_delta UNNEEDED, u64 *htlc_minimum_msat UNNEEDED, u32 *fee_base_msat UNNEEDED, u32 *fee_proportional_millionths UNNEEDED, u64 *htlc_maximum_msat UNNEEDED)
{ fprintf(stderr, "fromwire_channel_update_option_channel_htlc_max called!\n"); abort(); }
/* Generated stub for fromwire_gossipd_local_add_channel */
bool fromwire_gossipd_local_add_channel(const void *p UNNEEDED, struct short_channel_id *short_channel_id UNNEEDED, struct pubkey *remote_node_id UNNEEDED, u64 *satoshis UNNEEDED)
bool fromwire_gossipd_local_add_channel(const void *p UNNEEDED, struct short_channel_id *short_channel_id UNNEEDED, struct pubkey *remote_node_id UNNEEDED, struct amount_sat *satoshis UNNEEDED)
{ fprintf(stderr, "fromwire_gossipd_local_add_channel called!\n"); abort(); }
/* Generated stub for fromwire_gossip_store_channel_announcement */
bool fromwire_gossip_store_channel_announcement(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u8 **announcement UNNEEDED, u64 *satoshis UNNEEDED)
bool fromwire_gossip_store_channel_announcement(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u8 **announcement UNNEEDED, struct amount_sat *satoshis UNNEEDED)
{ fprintf(stderr, "fromwire_gossip_store_channel_announcement called!\n"); abort(); }
/* Generated stub for fromwire_gossip_store_channel_delete */
bool fromwire_gossip_store_channel_delete(const void *p UNNEEDED, struct short_channel_id *short_channel_id UNNEEDED)
@ -83,7 +83,7 @@ u8 *towire_errorfmt(const tal_t *ctx UNNEEDED,
const char *fmt UNNEEDED, ...)
{ fprintf(stderr, "towire_errorfmt called!\n"); abort(); }
/* Generated stub for towire_gossip_store_channel_announcement */
u8 *towire_gossip_store_channel_announcement(const tal_t *ctx UNNEEDED, const u8 *announcement UNNEEDED, u64 satoshis UNNEEDED)
u8 *towire_gossip_store_channel_announcement(const tal_t *ctx UNNEEDED, const u8 *announcement UNNEEDED, struct amount_sat satoshis UNNEEDED)
{ fprintf(stderr, "towire_gossip_store_channel_announcement called!\n"); abort(); }
/* Generated stub for towire_gossip_store_channel_delete */
u8 *towire_gossip_store_channel_delete(const tal_t *ctx UNNEEDED, const struct short_channel_id *short_channel_id UNNEEDED)
@ -121,7 +121,7 @@ static void add_connection(struct routing_state *rstate,
struct short_channel_id scid;
struct half_chan *c;
struct chan *chan;
int satoshis = 100000;
struct amount_sat satoshis = AMOUNT_SAT(100000);
/* Make a unique scid. */
memcpy(&scid, from, sizeof(scid) / 2);
@ -138,8 +138,8 @@ static void add_connection(struct routing_state *rstate,
c->proportional_fee = proportional_fee;
c->delay = delay;
c->channel_flags = get_channel_direction(from, to);
c->htlc_minimum_msat = 0;
c->htlc_maximum_msat = satoshis * 1000;
c->htlc_minimum = AMOUNT_MSAT(0);
c->htlc_maximum = AMOUNT_MSAT(100000 * 1000);
}
/* Returns chan connecting from and to: *idx set to refer
@ -201,7 +201,7 @@ int main(void)
struct routing_state *rstate;
struct pubkey a, b, c, d;
struct privkey tmp;
u64 fee;
struct amount_msat fee;
struct chan **route;
const double riskfactor = 1.0 / BLOCKS_PER_YEAR / 10000;
@ -222,11 +222,11 @@ int main(void)
/* A<->B */
add_connection(rstate, &a, &b, 1, 1, 1);
route = find_route(tmpctx, rstate, &a, &b, 1000, riskfactor, 0.0, NULL,
route = find_route(tmpctx, rstate, &a, &b, AMOUNT_MSAT(1000), riskfactor, 0.0, NULL,
ROUTING_MAX_HOPS, &fee);
assert(route);
assert(tal_count(route) == 1);
assert(fee == 0);
assert(amount_msat_eq(fee, AMOUNT_MSAT(0)));
/* A<->B<->C */
memset(&tmp, 'c', sizeof(tmp));
@ -238,11 +238,11 @@ int main(void)
status_trace("C = %s", type_to_string(tmpctx, struct pubkey, &c));
add_connection(rstate, &b, &c, 1, 1, 1);
route = find_route(tmpctx, rstate, &a, &c, 1000, riskfactor, 0.0, NULL,
route = find_route(tmpctx, rstate, &a, &c, AMOUNT_MSAT(1000), riskfactor, 0.0, NULL,
ROUTING_MAX_HOPS, &fee);
assert(route);
assert(tal_count(route) == 2);
assert(fee == 1);
assert(amount_msat_eq(fee, AMOUNT_MSAT(1)));
/* A<->D<->C: Lower base, higher percentage. */
memset(&tmp, 'd', sizeof(tmp));
@ -254,32 +254,32 @@ int main(void)
add_connection(rstate, &d, &c, 0, 2, 1);
/* Will go via D for small amounts. */
route = find_route(tmpctx, rstate, &a, &c, 1000, riskfactor, 0.0, NULL,
route = find_route(tmpctx, rstate, &a, &c, AMOUNT_MSAT(1000), riskfactor, 0.0, NULL,
ROUTING_MAX_HOPS, &fee);
assert(route);
assert(tal_count(route) == 2);
assert(channel_is_between(route[0], &a, &d));
assert(channel_is_between(route[1], &d, &c));
assert(fee == 0);
assert(amount_msat_eq(fee, AMOUNT_MSAT(0)));
/* Will go via B for large amounts. */
route = find_route(tmpctx, rstate, &a, &c, 3000000, riskfactor, 0.0, NULL,
route = find_route(tmpctx, rstate, &a, &c, AMOUNT_MSAT(3000000), riskfactor, 0.0, NULL,
ROUTING_MAX_HOPS, &fee);
assert(route);
assert(tal_count(route) == 2);
assert(channel_is_between(route[0], &a, &b));
assert(channel_is_between(route[1], &b, &c));
assert(fee == 1 + 3);
assert(amount_msat_eq(fee, AMOUNT_MSAT(1 + 3)));
/* Make B->C inactive, force it back via D */
get_connection(rstate, &b, &c)->channel_flags |= ROUTING_FLAGS_DISABLED;
route = find_route(tmpctx, rstate, &a, &c, 3000000, riskfactor, 0.0, NULL,
route = find_route(tmpctx, rstate, &a, &c, AMOUNT_MSAT(3000000), riskfactor, 0.0, NULL,
ROUTING_MAX_HOPS, &fee);
assert(route);
assert(tal_count(route) == 2);
assert(channel_is_between(route[0], &a, &d));
assert(channel_is_between(route[1], &d, &c));
assert(fee == 0 + 6);
assert(amount_msat_eq(fee, AMOUNT_MSAT(0 + 6)));
tal_free(tmpctx);
secp256k1_context_destroy(secp256k1_ctx);

24
hsmd/hsm_wire.csv

@ -37,8 +37,8 @@ hsm_get_channel_basepoints_reply,,funding_pubkey,struct pubkey
#include <common/utxo.h>
# FIXME: This should also take their commit sig & details, to verify.
hsm_sign_funding,4
hsm_sign_funding,,satoshi_out,u64
hsm_sign_funding,,change_out,u64
hsm_sign_funding,,satoshi_out,struct amount_sat
hsm_sign_funding,,change_out,struct amount_sat
hsm_sign_funding,,change_keyindex,u32
hsm_sign_funding,,our_pubkey,struct pubkey
hsm_sign_funding,,their_pubkey,struct pubkey
@ -58,8 +58,8 @@ hsm_node_announcement_sig_reply,,signature,secp256k1_ecdsa_signature
# Sign a withdrawal request
hsm_sign_withdrawal,7
hsm_sign_withdrawal,,satoshi_out,u64
hsm_sign_withdrawal,,change_out,u64
hsm_sign_withdrawal,,satoshi_out,struct amount_sat
hsm_sign_withdrawal,,change_out,struct amount_sat
hsm_sign_withdrawal,,change_keyindex,u32
hsm_sign_withdrawal,,scriptpubkey_len,u16
hsm_sign_withdrawal,,scriptpubkey,scriptpubkey_len*u8
@ -107,7 +107,7 @@ hsm_sign_commitment_tx,,peer_id,struct pubkey
hsm_sign_commitment_tx,,channel_dbid,u64
hsm_sign_commitment_tx,,tx,struct bitcoin_tx
hsm_sign_commitment_tx,,remote_funding_key,struct pubkey
hsm_sign_commitment_tx,,funding_amount,u64
hsm_sign_commitment_tx,,funding_amount,struct amount_sat
hsm_sign_commitment_tx_reply,105
hsm_sign_commitment_tx_reply,,sig,struct bitcoin_signature
@ -120,21 +120,21 @@ hsm_sign_delayed_payment_to_us,,commit_num,u64
hsm_sign_delayed_payment_to_us,,tx,struct bitcoin_tx
hsm_sign_delayed_payment_to_us,,wscript_len,u16
hsm_sign_delayed_payment_to_us,,wscript,wscript_len*u8
hsm_sign_delayed_payment_to_us,,input_amount,u64
hsm_sign_delayed_payment_to_us,,input_amount,struct amount_sat
hsm_sign_remote_htlc_to_us,13
hsm_sign_remote_htlc_to_us,,remote_per_commitment_point,struct pubkey
hsm_sign_remote_htlc_to_us,,tx,struct bitcoin_tx
hsm_sign_remote_htlc_to_us,,wscript_len,u16
hsm_sign_remote_htlc_to_us,,wscript,wscript_len*u8
hsm_sign_remote_htlc_to_us,,input_amount,u64
hsm_sign_remote_htlc_to_us,,input_amount,struct amount_sat
hsm_sign_penalty_to_us,14
hsm_sign_penalty_to_us,,revocation_secret,struct secret
hsm_sign_penalty_to_us,,tx,struct bitcoin_tx
hsm_sign_penalty_to_us,,wscript_len,u16
hsm_sign_penalty_to_us,,wscript,wscript_len*u8
hsm_sign_penalty_to_us,,input_amount,u64
hsm_sign_penalty_to_us,,input_amount,struct amount_sat
# Onchaind asks HSM to sign a local HTLC success or HTLC timeout tx.
hsm_sign_local_htlc_tx,16
@ -142,27 +142,27 @@ hsm_sign_local_htlc_tx,,commit_num,u64
hsm_sign_local_htlc_tx,,tx,struct bitcoin_tx
hsm_sign_local_htlc_tx,,wscript_len,u16
hsm_sign_local_htlc_tx,,wscript,wscript_len*u8
hsm_sign_local_htlc_tx,,input_amount,u64
hsm_sign_local_htlc_tx,,input_amount,struct amount_sat
# Openingd/channeld asks HSM to sign the other sides' commitment tx.
hsm_sign_remote_commitment_tx,19
hsm_sign_remote_commitment_tx,,tx,struct bitcoin_tx
hsm_sign_remote_commitment_tx,,remote_funding_key,struct pubkey
hsm_sign_remote_commitment_tx,,funding_amount,u64
hsm_sign_remote_commitment_tx,,funding_amount,struct amount_sat
# channeld asks HSM to sign remote HTLC tx.
hsm_sign_remote_htlc_tx,20
hsm_sign_remote_htlc_tx,,tx,struct bitcoin_tx
hsm_sign_remote_htlc_tx,,len,u16
hsm_sign_remote_htlc_tx,,wscript,len*u8
hsm_sign_remote_htlc_tx,,amounts_satoshi,u64
hsm_sign_remote_htlc_tx,,amounts_satoshi,struct amount_sat
hsm_sign_remote_htlc_tx,,remote_per_commit_point,struct pubkey
# closingd asks HSM to sign mutual close tx.
hsm_sign_mutual_close_tx,21
hsm_sign_mutual_close_tx,,tx,struct bitcoin_tx
hsm_sign_mutual_close_tx,,remote_funding_key,struct pubkey
hsm_sign_mutual_close_tx,,funding_amount,u64
hsm_sign_mutual_close_tx,,funding,struct amount_sat
# Reply for all the above requests.
hsm_sign_tx_reply,112

Can't render this file because it has a wrong number of fields in line 2.

67
hsmd/hsmd.c

@ -728,7 +728,8 @@ static struct io_plan *handle_sign_commitment_tx(struct io_conn *conn,
const u8 *msg_in)
{
struct pubkey peer_id, remote_funding_pubkey, local_funding_pubkey;
u64 dbid, funding_amount;
u64 dbid;
struct amount_sat funding;
struct secret channel_seed;
struct bitcoin_tx *tx;
struct bitcoin_signature sig;
@ -739,7 +740,7 @@ static struct io_plan *handle_sign_commitment_tx(struct io_conn *conn,
&peer_id, &dbid,
&tx,
&remote_funding_pubkey,
&funding_amount))
&funding))
return bad_req(conn, c, msg_in);
get_channel_seed(&peer_id, dbid, &channel_seed);
@ -758,7 +759,7 @@ static struct io_plan *handle_sign_commitment_tx(struct io_conn *conn,
* pointer, as we don't always know it (and zero is a valid amount, so
* NULL is better to mean 'unknown' and has the nice property that
* you'll crash if you assume it's there and you're wrong. */
tx->input[0].amount = tal_dup(tx->input, u64, &funding_amount);
tx->input[0].amount = tal_dup(tx->input, u64, &funding.satoshis);
sign_tx_input(tx, 0, NULL, funding_wscript,
&secrets.funding_privkey,
&local_funding_pubkey,
@ -782,7 +783,7 @@ static struct io_plan *handle_sign_remote_commitment_tx(struct io_conn *conn,
const u8 *msg_in)
{
struct pubkey remote_funding_pubkey, local_funding_pubkey;
u64 funding_amount;
struct amount_sat funding;
struct secret channel_seed;
struct bitcoin_tx *tx;
struct bitcoin_signature sig;
@ -792,7 +793,7 @@ static struct io_plan *handle_sign_remote_commitment_tx(struct io_conn *conn,
if (!fromwire_hsm_sign_remote_commitment_tx(tmpctx, msg_in,
&tx,
&remote_funding_pubkey,
&funding_amount))
&funding))
bad_req(conn, c, msg_in);
get_channel_seed(&c->id, c->dbid, &channel_seed);
@ -803,7 +804,7 @@ static struct io_plan *handle_sign_remote_commitment_tx(struct io_conn *conn,
&local_funding_pubkey,
&remote_funding_pubkey);
/* Need input amount for signing */
tx->input[0].amount = tal_dup(tx->input, u64, &funding_amount);
tx->input[0].amount = tal_dup(tx->input, u64, &funding.satoshis);
sign_tx_input(tx, 0, NULL, funding_wscript,
&secrets.funding_privkey,
&local_funding_pubkey,
@ -825,7 +826,7 @@ static struct io_plan *handle_sign_remote_htlc_tx(struct io_conn *conn,
struct secrets secrets;
struct basepoints basepoints;
struct pubkey remote_per_commit_point;
u64 amount;
struct amount_sat amount;
u8 *wscript;
struct privkey htlc_privkey;
struct pubkey htlc_pubkey;
@ -852,7 +853,7 @@ static struct io_plan *handle_sign_remote_htlc_tx(struct io_conn *conn,
"Failed deriving htlc pubkey");
/* Need input amount for signing */
tx->input[0].amount = tal_dup(tx->input, u64, &amount);
tx->input[0].amount = tal_dup(tx->input, u64, &amount.satoshis);
sign_tx_input(tx, 0, NULL, wscript, &htlc_privkey, &htlc_pubkey,
SIGHASH_ALL, &sig);
@ -868,7 +869,7 @@ static struct io_plan *handle_sign_to_us_tx(struct io_conn *conn,
struct bitcoin_tx *tx,
const struct privkey *privkey,
const u8 *wscript,
u64 input_amount)
struct amount_sat input_sat)
{
struct bitcoin_signature sig;
struct pubkey pubkey;
@ -879,7 +880,7 @@ static struct io_plan *handle_sign_to_us_tx(struct io_conn *conn,
if (tal_count(tx->input) != 1)
return bad_req_fmt(conn, c, msg_in, "bad txinput count");
tx->input[0].amount = tal_dup(tx->input, u64, &input_amount);
tx->input[0].amount = tal_dup(tx->input, u64, &input_sat.satoshis);
sign_tx_input(tx, 0, NULL, wscript, privkey, &pubkey, SIGHASH_ALL, &sig);
return req_reply(conn, c, take(towire_hsm_sign_tx_reply(NULL, &sig)));
@ -893,7 +894,8 @@ static struct io_plan *handle_sign_delayed_payment_to_us(struct io_conn *conn,
struct client *c,
const u8 *msg_in)
{
u64 commit_num, input_amount;
u64 commit_num;
struct amount_sat input_sat;
struct secret channel_seed, basepoint_secret;
struct pubkey basepoint;
struct bitcoin_tx *tx;
@ -906,7 +908,7 @@ static struct io_plan *handle_sign_delayed_payment_to_us(struct io_conn *conn,
if (!fromwire_hsm_sign_delayed_payment_to_us(tmpctx, msg_in,
&commit_num,
&tx, &wscript,
&input_amount))
&input_sat))
return bad_req(conn, c, msg_in);
get_channel_seed(&c->id, c->dbid, &channel_seed);
@ -939,7 +941,7 @@ static struct io_plan *handle_sign_delayed_payment_to_us(struct io_conn *conn,
return bad_req_fmt(conn, c, msg_in, "failed deriving privkey");
return handle_sign_to_us_tx(conn, c, msg_in,
tx, &privkey, wscript, input_amount);
tx, &privkey, wscript, input_sat);
}
/*~ This is used when the a commitment transaction is onchain, and has an HTLC
@ -949,7 +951,7 @@ static struct io_plan *handle_sign_remote_htlc_to_us(struct io_conn *conn,
struct client *c,
const u8 *msg_in)
{
u64 input_amount;
struct amount_sat input_sat;
struct secret channel_seed, htlc_basepoint_secret;
struct pubkey htlc_basepoint;
struct bitcoin_tx *tx;
@ -960,7 +962,7 @@ static struct io_plan *handle_sign_remote_htlc_to_us(struct io_conn *conn,
if (!fromwire_hsm_sign_remote_htlc_to_us(tmpctx, msg_in,
&remote_per_commitment_point,
&tx, &wscript,
&input_amount))
&input_sat))
return bad_req(conn, c, msg_in);
get_channel_seed(&c->id, c->dbid, &channel_seed);
@ -978,7 +980,7 @@ static struct io_plan *handle_sign_remote_htlc_to_us(struct io_conn *conn,
"Failed deriving htlc privkey");
return handle_sign_to_us_tx(conn, c, msg_in,
tx, &privkey, wscript, input_amount);
tx, &privkey, wscript, input_sat);
}
/*~ This is used when the remote peer's commitment transaction is revoked;
@ -988,7 +990,7 @@ static struct io_plan *handle_sign_penalty_to_us(struct io_conn *conn,
struct client *c,
const u8 *msg_in)
{
u64 input_amount;
struct amount_sat input_sat;
struct secret channel_seed, revocation_secret, revocation_basepoint_secret;
struct pubkey revocation_basepoint;
struct bitcoin_tx *tx;
@ -999,7 +1001,7 @@ static struct io_plan *handle_sign_penalty_to_us(struct io_conn *conn,
if (!fromwire_hsm_sign_penalty_to_us(tmpctx, msg_in,
&revocation_secret,
&tx, &wscript,
&input_amount))
&input_sat))
return bad_req(conn, c, msg_in);
if (!pubkey_from_secret(&revocation_secret, &point))
@ -1021,7 +1023,7 @@ static struct io_plan *handle_sign_penalty_to_us(struct io_conn *conn,
"Failed deriving revocation privkey");
return handle_sign_to_us_tx(conn, c, msg_in,
tx, &privkey, wscript, input_amount);
tx, &privkey, wscript, input_sat);
}
/*~ This is used when the a commitment transaction is onchain, and has an HTLC
@ -1031,7 +1033,8 @@ static struct io_plan *handle_sign_local_htlc_tx(struct io_conn *conn,
struct client *c,
const u8 *msg_in)
{
u64 commit_num, input_amount;
u64 commit_num;
struct amount_sat input_sat;
struct secret channel_seed, htlc_basepoint_secret;
struct sha256 shaseed;
struct pubkey per_commitment_point, htlc_basepoint;
@ -1043,7 +1046,7 @@ static struct io_plan *handle_sign_local_htlc_tx(struct io_conn *conn,
if (!fromwire_hsm_sign_local_htlc_tx(tmpctx, msg_in,
&commit_num, &tx, &wscript,
&input_amount))
&input_sat))
return bad_req(conn, c, msg_in);
get_channel_seed(&c->id, c->dbid, &channel_seed);
@ -1076,7 +1079,7 @@ static struct io_plan *handle_sign_local_htlc_tx(struct io_conn *conn,
return bad_req_fmt(conn, c, msg_in, "bad txinput count");
/* FIXME: Check that output script is correct! */
tx->input[0].amount = tal_dup(tx->input, u64, &input_amount);
tx->input[0].amount = tal_dup(tx->input, u64, &input_sat.satoshis);
sign_tx_input(tx, 0, NULL, wscript, &htlc_privkey, &htlc_pubkey,
SIGHASH_ALL, &sig);
@ -1171,13 +1174,13 @@ static struct io_plan *handle_sign_mutual_close_tx(struct io_conn *conn,
struct pubkey remote_funding_pubkey, local_funding_pubkey;
struct bitcoin_signature sig;
struct secrets secrets;
u64 funding_amount;
struct amount_sat funding;
const u8 *funding_wscript;
if (!fromwire_hsm_sign_mutual_close_tx(tmpctx, msg_in,
&tx,
&remote_funding_pubkey,
&funding_amount))
&funding))
return bad_req(conn, c, msg_in);
/* FIXME: We should know dust level, decent fee range and
@ -1191,7 +1194,7 @@ static struct io_plan *handle_sign_mutual_close_tx(struct io_conn *conn,
&local_funding_pubkey,
&remote_funding_pubkey);
/* Need input amount for signing */
tx->input[0].amount = tal_dup(tx->input, u64, &funding_amount);
tx->input[0].amount = tal_dup(tx->input, u64, &funding.satoshis);
sign_tx_input(tx, 0, NULL, funding_wscript,
&secrets.funding_privkey,
&local_funding_pubkey,
@ -1363,7 +1366,7 @@ static struct io_plan *handle_sign_funding_tx(struct io_conn *conn,
struct client *c,
const u8 *msg_in)
{
u64 satoshi_out, change_out;
struct amount_sat satoshi_out, change_out;
u32 change_keyindex;
struct pubkey local_pubkey, remote_pubkey;
struct utxo **utxos;
@ -1378,7 +1381,7 @@ static struct io_plan *handle_sign_funding_tx(struct io_conn *conn,
&remote_pubkey, &utxos))
return bad_req(conn, c, msg_in);
if (change_out) {
if (amount_sat_greater(change_out, AMOUNT_SAT(0))) {
changekey = tal(tmpctx, struct pubkey);
bitcoin_key(NULL, changekey, change_keyindex);
} else
@ -1391,8 +1394,8 @@ static struct io_plan *handle_sign_funding_tx(struct io_conn *conn,
* ccan/cast which ensures the type is correct and
* we're not casting something random */
cast_const2(const struct utxo **, utxos),
satoshi_out, &local_pubkey, &remote_pubkey,
change_out, changekey,
satoshi_out.satoshis, &local_pubkey, &remote_pubkey,
change_out.satoshis, changekey,
NULL);
sign_all_inputs(tx, utxos);
@ -1405,7 +1408,7 @@ static struct io_plan *handle_sign_withdrawal_tx(struct io_conn *conn,
struct client *c,
const u8 *msg_in)
{
u64 satoshi_out, change_out;
struct amount_sat satoshi_out, change_out;
u32 change_keyindex;
struct utxo **utxos;
struct bitcoin_tx *tx;
@ -1425,8 +1428,8 @@ static struct io_plan *handle_sign_withdrawal_tx(struct io_conn *conn,
pubkey_from_der(ext.pub_key, sizeof(ext.pub_key), &changekey);
tx = withdraw_tx(tmpctx, cast_const2(const struct utxo **, utxos),
scriptpubkey, satoshi_out,
&changekey, change_out, NULL);
scriptpubkey, satoshi_out.satoshis,
&changekey, change_out.satoshis, NULL);
sign_all_inputs(tx, utxos);

20
lightningd/channel.c

@ -145,14 +145,14 @@ struct channel *new_channel(struct peer *peer, u64 dbid,
u64 next_htlc_id,
const struct bitcoin_txid *funding_txid,
u16 funding_outnum,
u64 funding_satoshi,
u64 push_msat,
struct amount_sat funding,
struct amount_msat push,
bool remote_funding_locked,
/* NULL or stolen */
struct short_channel_id *scid,
u64 our_msatoshi,
u64 msatoshi_to_us_min,
u64 msatoshi_to_us_max,
struct amount_msat our_msat,
struct amount_msat msat_to_us_min,
struct amount_msat msat_to_us_max,
/* Stolen */
struct bitcoin_tx *last_tx,
const struct bitcoin_signature *last_sig,
@ -210,13 +210,13 @@ struct channel *new_channel(struct peer *peer, u64 dbid,
channel->next_htlc_id = next_htlc_id;
channel->funding_txid = *funding_txid;
channel->funding_outnum = funding_outnum;
channel->funding_satoshi = funding_satoshi;
channel->push_msat = push_msat;
channel->funding = funding;
channel->push = push;
channel->remote_funding_locked = remote_funding_locked;
channel->scid = tal_steal(channel, scid);
channel->our_msatoshi = our_msatoshi;
channel->msatoshi_to_us_min = msatoshi_to_us_min;
channel->msatoshi_to_us_max = msatoshi_to_us_max;
channel->our_msat = our_msat;
channel->msat_to_us_min = msat_to_us_min;
channel->msat_to_us_max = msat_to_us_max;
channel->last_tx = tal_steal(channel, last_tx);
channel->last_sig = *last_sig;
channel->last_htlc_sigs = tal_steal(channel, last_htlc_sigs);

19
lightningd/channel.h

@ -59,16 +59,17 @@ struct channel {
/* Funding txid and amounts */
struct bitcoin_txid funding_txid;
u16 funding_outnum;
u64 funding_satoshi, push_msat;
struct amount_sat funding;
struct amount_msat push;
bool remote_funding_locked;
/* Channel if locked locally. */
struct short_channel_id *scid;
/* Amount going to us, not counting unfinished HTLCs; if we have one. */
u64 our_msatoshi;
struct amount_msat our_msat;
/* Statistics for min and max our_msatoshi. */
u64 msatoshi_to_us_min;
u64 msatoshi_to_us_max;
struct amount_msat msat_to_us_min;
struct amount_msat msat_to_us_max;
/* Timer we use in case they don't add an HTLC in a timely manner. */
struct oneshot *htlc_timeout;
@ -127,14 +128,14 @@ struct channel *new_channel(struct peer *peer, u64 dbid,
u64 next_htlc_id,
const struct bitcoin_txid *funding_txid,
u16 funding_outnum,
u64 funding_satoshi,
u64 push_msat,
struct amount_sat funding,
struct amount_msat push,
bool remote_funding_locked,
/* NULL or stolen */
struct short_channel_id *scid,
u64 our_msatoshi,
u64 msatoshi_to_us_min,
u64 msatoshi_to_us_max,
struct amount_msat our_msatoshi,
struct amount_msat msatoshi_to_us_min,
struct amount_msat msatoshi_to_us_max,
/* Stolen */
struct bitcoin_tx *last_tx,
const struct bitcoin_signature *last_sig,

4
lightningd/channel_control.c

@ -339,7 +339,7 @@ void peer_start_channeld(struct channel *channel,
&get_chainparams(ld)->genesis_blockhash,
&channel->funding_txid,
channel->funding_outnum,
channel->funding_satoshi,
channel->funding,
&channel->our_config,
&channel->channel_info.their_config,
channel->channel_info.feerate_per_kw,
@ -354,7 +354,7 @@ void peer_start_channeld(struct channel *channel,
channel->funder,
cfg->fee_base,
cfg->fee_per_satoshi,
channel->our_msatoshi,
channel->our_msat,
&channel->local_basepoints,
&channel->local_funding_pubkey,
&ld->id,

83
lightningd/closing_control.c

@ -17,6 +17,19 @@
#include <lightningd/peer_control.h>
#include <lightningd/subd.h>
static struct amount_sat calc_tx_fee(struct amount_sat sat_in,
const struct bitcoin_tx *tx)
{
struct amount_sat fee = sat_in;
for (size_t i = 0; i < tal_count(tx->output); i++) {
if (!amount_sat_sub(&fee, fee, (struct amount_sat){tx->output[i].amount}))
fatal("Tx spends more than input %s? %s",
type_to_string(tmpctx, struct amount_sat, &sat_in),
type_to_string(tmpctx, struct bitcoin_tx, tx));
}
return fee;
}
/* Is this better than the last tx we were holding? This can happen
* even without closingd misbehaving, if we have multiple,
* interrupted, rounds of negotiation. */
@ -24,22 +37,19 @@ static bool better_closing_fee(struct lightningd *ld,
struct channel *channel,
const struct bitcoin_tx *tx)
{
u64 weight, fee, last_fee, min_fee;
struct amount_sat fee, last_fee, min_fee;
u64 weight;
u32 min_feerate;
size_t i;
bool feerate_unknown;
/* Calculate actual fee (adds in eliminated outputs) */
fee = channel->funding_satoshi;
for (i = 0; i < tal_count(tx->output); i++)
fee -= tx->output[i].amount;
fee = calc_tx_fee(channel->funding, tx);
last_fee = calc_tx_fee(channel->funding, channel->last_tx);
last_fee = channel->funding_satoshi;
for (i = 0; i < tal_count(channel->last_tx->output); i++)
last_fee -= channel->last_tx->output[i].amount;
log_debug(channel->log, "Their actual closing tx fee is %"PRIu64
" vs previous %"PRIu64, fee, last_fee);
log_debug(channel->log, "Their actual closing tx fee is %s"
" vs previous %s",
type_to_string(tmpctx, struct amount_sat, &fee),
type_to_string(tmpctx, struct amount_sat, &last_fee));
/* Weight once we add in sigs. */
weight = measure_tx_weight(tx) + 74 * 2;
@ -47,11 +57,12 @@ static bool better_closing_fee(struct lightningd *ld,
/* If we don't have a feerate estimate, this gives feerate_floor */
min_feerate = feerate_min(ld, &feerate_unknown);
min_fee = min_feerate * weight / 1000;
if (fee < min_fee) {
log_debug(channel->log, "... That's below our min %"PRIu64
" for weight %"PRIu64" at feerate %u",
min_fee, weight, min_feerate);
min_fee = amount_tx_fee(min_feerate, weight);
if (amount_sat_less(fee, min_fee)) {
log_debug(channel->log, "... That's below our min %s"
" for weight %"PRIu64" at feerate %u",
type_to_string(tmpctx, struct amount_sat, &fee),
weight, min_feerate);
return false;
}
@ -60,10 +71,10 @@ static bool better_closing_fee(struct lightningd *ld,
/* If we don't know the feerate, prefer higher fee. */
if (feerate_unknown)
return fee >= last_fee;
return amount_sat_greater_eq(fee, last_fee);
/* Otherwise prefer lower fee. */
return fee <= last_fee;
return amount_sat_less_eq(fee, last_fee);
}
static void peer_received_closing_signature(struct channel *channel,
@ -143,9 +154,9 @@ void peer_start_closingd(struct channel *channel,
{
u8 *initmsg;
u32 feerate;
u64 minfee, startfee, feelimit;
struct amount_sat minfee, startfee, feelimit;
u64 num_revocations;
u64 funding_msatoshi, our_msatoshi, their_msatoshi;
struct amount_msat their_msat;
int hsmfd;
struct lightningd *ld = channel->peer->ld;
@ -185,10 +196,10 @@ void peer_start_closingd(struct channel *channel,
* [BOLT #3](03-transactions.md#fee-calculation).
*/
feelimit = commit_tx_base_fee(channel->channel_info.feerate_per_kw[LOCAL],
0).satoshis;
0);
/* Pick some value above slow feerate (or min possible if unknown) */
minfee = commit_tx_base_fee(feerate_min(ld, NULL), 0).satoshis;
minfee = commit_tx_base_fee(feerate_min(ld, NULL), 0);
/* If we can't determine feerate, start at half unilateral feerate. */
feerate = mutual_close_feerate(ld->topology);
@ -197,11 +208,11 @@ void peer_start_closingd(struct channel *channel,
if (feerate < feerate_floor())
feerate = feerate_floor();
}
startfee = commit_tx_base_fee(feerate, 0).satoshis;
startfee = commit_tx_base_fee(feerate, 0);
if (startfee > feelimit)
if (amount_sat_greater(startfee, feelimit))
startfee = feelimit;
if (minfee > feelimit)
if (amount_sat_greater(minfee, feelimit))
minfee = feelimit;
num_revocations
@ -212,22 +223,28 @@ void peer_start_closingd(struct channel *channel,
* Each node offering a signature:
* - MUST round each output down to whole satoshis.
*/
/* Convert unit */
funding_msatoshi = channel->funding_satoshi * 1000;
/* What is not ours is theirs */
our_msatoshi = channel->our_msatoshi;
their_msatoshi = funding_msatoshi - our_msatoshi;
if (!amount_sat_sub_msat(&their_msat,
channel->funding, channel->our_msat)) {
log_broken(channel->log, "our_msat overflow funding %s minus %s",
type_to_string(tmpctx, struct amount_sat,
&channel->funding),
type_to_string(tmpctx, struct amount_msat,
&channel->our_msat));
channel_fail_permanent(channel, "our_msat overflow on closing");
return;
}
initmsg = towire_closing_init(tmpctx,
cs,
&channel->funding_txid,
channel->funding_outnum,
channel->funding_satoshi,
channel->funding,
&channel->local_funding_pubkey,
&channel->channel_info.remote_fundingkey,
channel->funder,
our_msatoshi / 1000, /* Rounds down */
their_msatoshi / 1000, /* Rounds down */
channel->our_config.dust_limit.satoshis,
amount_msat_to_sat_round_down(channel->our_msat),
amount_msat_to_sat_round_down(their_msat),
channel->our_config.dust_limit,
minfee, feelimit, startfee,
p2wpkh_for_keyidx(tmpctx, ld,
channel->final_key_idx),

17
lightningd/gossip_control.c

@ -42,20 +42,20 @@ static void got_txout(struct bitcoind *bitcoind,
struct short_channel_id *scid)
{
const u8 *script;
u64 satoshis;
struct amount_sat sat;
/* output will be NULL if it wasn't found */
if (output) {
script = output->script;
satoshis = output->amount;
sat = (struct amount_sat){ output->amount};
} else {
script = NULL;
satoshis = 0;
sat = AMOUNT_SAT(0);
}
subd_send_msg(
bitcoind->ld->gossip,
towire_gossip_get_txout_reply(scid, scid, satoshis, script));
towire_gossip_get_txout_reply(scid, scid, sat, script));
tal_free(scid);
}
@ -78,7 +78,7 @@ static void get_txout(struct subd *gossip, const u8 *msg)
if (op) {
subd_send_msg(gossip,
towire_gossip_get_txout_reply(
scid, scid, op->satoshis, op->scriptpubkey));
scid, scid, op->sat, op->scriptpubkey));
tal_free(scid);
} else if (blockheight >= topo->min_blockheight &&
blockheight <= topo->max_blockheight) {
@ -87,7 +87,7 @@ static void get_txout(struct subd *gossip, const u8 *msg)
* this is either a spent outpoint or an invalid one. Return a
* failure. */
subd_send_msg(gossip, take(towire_gossip_get_txout_reply(
NULL, scid, 0, NULL)));
NULL, scid, AMOUNT_SAT(0), NULL)));
tal_free(scid);
} else {
bitcoind_getoutput(topo->bitcoind,
@ -354,7 +354,7 @@ static struct command_result *json_getroute(struct command *cmd,
}
u8 *req = towire_gossip_getroute_request(cmd, source, destination,
msat->millisatoshis,
*msat,
*riskfactor * 1000000.0,
*cltv, fuzz,
excluded,
@ -399,8 +399,7 @@ static void json_listchannels_reply(struct subd *gossip UNUSED, const u8 *reply,
type_to_string(reply, struct short_channel_id,
&entries[i].short_channel_id));
json_add_bool(response, "public", entries[i].public);
json_add_amount_sat(response,
(struct amount_sat){ entries[i].satoshis },
json_add_amount_sat(response, entries[i].sat,
"satoshis", "amount_msat");
json_add_num(response, "message_flags", entries[i].message_flags);
json_add_num(response, "channel_flags", entries[i].channel_flags);

4
lightningd/gossip_msg.c

@ -102,7 +102,7 @@ void fromwire_gossip_getchannels_entry(const u8 **pptr, size_t *max,
fromwire_short_channel_id(pptr, max, &entry->short_channel_id);
fromwire(pptr, max, entry->source, sizeof(entry->source));
fromwire(pptr, max, entry->destination, sizeof(entry->destination));
entry->satoshis = fromwire_u64(pptr, max);
entry->sat = fromwire_amount_sat(pptr, max);
entry->message_flags = fromwire_u8(pptr, max);
entry->channel_flags = fromwire_u8(pptr, max);
entry->public = fromwire_bool(pptr, max);
@ -119,7 +119,7 @@ void towire_gossip_getchannels_entry(u8 **pptr,
towire_short_channel_id(pptr, &entry->short_channel_id);
towire(pptr, entry->source, sizeof(entry->source));
towire(pptr, entry->destination, sizeof(entry->destination));
towire_u64(pptr, entry->satoshis);
towire_amount_sat(pptr, entry->sat);
towire_u8(pptr, entry->message_flags);
towire_u8(pptr, entry->channel_flags);
towire_bool(pptr, entry->public);

2
lightningd/gossip_msg.h

@ -24,7 +24,7 @@ struct gossip_getnodes_entry {
struct gossip_getchannels_entry {
/* These are raw to optimize marshaling: be careful! */
u8 source[sizeof(struct pubkey)], destination[sizeof(struct pubkey)];
u64 satoshis;
struct amount_sat sat;
struct short_channel_id short_channel_id;
u8 message_flags;
u8 channel_flags;

22
lightningd/htlc_end.c

@ -75,7 +75,7 @@ static void *PRINTF_FMT(2,3)
struct htlc_in *htlc_in_check(const struct htlc_in *hin, const char *abortstr)
{
if (hin->msatoshi == 0)
if (amount_msat_eq(hin->msat, AMOUNT_MSAT(0)))
return corrupt(abortstr, "zero msatoshi");
else if (htlc_state_owner(hin->hstate) != REMOTE)
return corrupt(abortstr, "invalid state %s",
@ -109,7 +109,7 @@ struct htlc_in *htlc_in_check(const struct htlc_in *hin, const char *abortstr)
struct htlc_in *new_htlc_in(const tal_t *ctx,
struct channel *channel, u64 id,
u64 msatoshi, u32 cltv_expiry,
struct amount_msat msat, u32 cltv_expiry,
const struct sha256 *payment_hash,
const struct secret *shared_secret TAKES,
const u8 *onion_routing_packet)
@ -119,7 +119,7 @@ struct htlc_in *new_htlc_in(const tal_t *ctx,
hin->dbid = 0;
hin->key.channel = channel;
hin->key.id = id;
hin->msatoshi = msatoshi;
hin->msat = msat;
hin->cltv_expiry = cltv_expiry;
hin->payment_hash = *payment_hash;
if (shared_secret)
@ -150,10 +150,13 @@ struct htlc_out *htlc_out_check(const struct htlc_out *hout,
return corrupt(abortstr, "Both origin and incoming");
if (hout->in) {
if (hout->in->msatoshi < hout->msatoshi)
return corrupt(abortstr, "Input msatoshi %"PRIu64
" less than %"PRIu64,
hout->in->msatoshi, hout->msatoshi);
if (amount_msat_less(hout->in->msat, hout->msat))
return corrupt(abortstr, "Input amount %s"
" less than %s",
type_to_string(tmpctx, struct amount_msat,
&hout->in->msat),
type_to_string(tmpctx, struct amount_msat,
&hout->msat));
if (hout->in->cltv_expiry <= hout->cltv_expiry)
return corrupt(abortstr, "Input cltv_expiry %u"
" less than %u",
@ -240,7 +243,8 @@ void htlc_out_connect_htlc_in(struct htlc_out *hout, struct htlc_in *hin)
/* You need to set the ID, then connect_htlc_out this! */
struct htlc_out *new_htlc_out(const tal_t *ctx,
struct channel *channel,
u64 msatoshi, u32 cltv_expiry,
struct amount_msat msat,
u32 cltv_expiry,
const struct sha256 *payment_hash,
const u8 *onion_routing_packet,
bool am_origin,
@ -253,7 +257,7 @@ struct htlc_out *new_htlc_out(const tal_t *ctx,
hout->key.channel = channel;
hout->key.id = HTLC_INVALID_ID;
hout->msatoshi = msatoshi;
hout->msat = msat;
hout->cltv_expiry = cltv_expiry;
hout->payment_hash = *payment_hash;
memcpy(hout->onion_routing_packet, onion_routing_packet,

10
lightningd/htlc_end.h

@ -3,6 +3,7 @@
#include "config.h"
#include <ccan/htable/htable_type.h>
#include <ccan/short_types/short_types.h>
#include <common/amount.h>
#include <common/htlc_state.h>
#include <common/sphinx.h>
#include <wire/gen_onion_wire.h>
@ -22,7 +23,7 @@ struct htlc_in {
* database. */
u64 dbid;
struct htlc_key key;
u64 msatoshi;
struct amount_msat msat;
u32 cltv_expiry;
struct sha256 payment_hash;
@ -55,7 +56,7 @@ struct htlc_out {
u64 dbid;
u64 origin_htlc_id;
struct htlc_key key;
u64 msatoshi;
struct amount_msat msat;
u32 cltv_expiry;
struct sha256 payment_hash;
@ -122,7 +123,7 @@ struct htlc_out *find_htlc_out(const struct htlc_out_map *map,
/* You still need to connect_htlc_in this! */
struct htlc_in *new_htlc_in(const tal_t *ctx,
struct channel *channel, u64 id,
u64 msatoshi, u32 cltv_expiry,
struct amount_msat msat, u32 cltv_expiry,
const struct sha256 *payment_hash,
const struct secret *shared_secret TAKES,
const u8 *onion_routing_packet);
@ -130,7 +131,8 @@ struct htlc_in *new_htlc_in(const tal_t *ctx,
/* You need to set the ID, then connect_htlc_out this! */
struct htlc_out *new_htlc_out(const tal_t *ctx,
struct channel *channel,
u64 msatoshi, u32 cltv_expiry,
struct amount_msat msat,
u32 cltv_expiry,
const struct sha256 *payment_hash,
const u8 *onion_routing_packet,
bool am_origin,

27
lightningd/invoice.c

@ -145,7 +145,7 @@ static struct command_result *parse_fallback(struct command *cmd,
/* BOLT11 struct wants an array of arrays (can provide multiple routes) */
static struct route_info **select_inchan(const tal_t *ctx,
struct lightningd *ld,
u64 capacity_needed,
struct amount_msat capacity_needed,
const struct route_info *inchans,
bool *any_offline)
{
@ -162,7 +162,7 @@ static struct route_info **select_inchan(const tal_t *ctx,
for (size_t i = 0; i < tal_count(inchans); i++) {
struct peer *peer;
struct channel *c;
u64 msatoshi_avail;
struct amount_msat avail, excess;
/* Do we know about this peer? */
peer = peer_by_id(ld, &inchans[i].pubkey);
@ -175,15 +175,22 @@ static struct route_info **select_inchan(const tal_t *ctx,
continue;
/* Does it have sufficient capacity. */
msatoshi_avail = c->funding_satoshi * 1000 - c->our_msatoshi;
if (!amount_sat_sub_msat(&avail, c->funding, c->our_msat)) {
log_broken(ld->log,
"underflow: funding %s - our_msat %s",
type_to_string(tmpctx, struct amount_sat,
&c->funding),
type_to_string(tmpctx, struct amount_msat,
&c->our_msat));
continue;
}
/* Even after reserve taken into account */
if (c->our_config.channel_reserve.satoshis * 1000
> msatoshi_avail)
if (!amount_msat_sub_sat(&avail,
avail, c->our_config.channel_reserve))
continue;
msatoshi_avail -= c->our_config.channel_reserve.satoshis * 1000;
if (msatoshi_avail < capacity_needed)
if (!amount_msat_sub(&excess, avail, capacity_needed))
continue;
/* Is it offline? */
@ -193,9 +200,9 @@ static struct route_info **select_inchan(const tal_t *ctx,
}
/* Avoid divide-by-zero corner case. */
wsum += (msatoshi_avail - capacity_needed + 1);
wsum += excess.millisatoshis + 1;
if (pseudorand(1ULL << 32)
<= ((msatoshi_avail - capacity_needed + 1) << 32) / wsum)
<= ((excess.millisatoshis + 1) << 32) / wsum)
r = &inchans[i];
}
@ -239,7 +246,7 @@ static void gossipd_incoming_channels_reply(struct subd *gossipd,
info->b11->routes
= select_inchan(info->b11,
info->cmd->ld,
info->b11->msat ? info->b11->msat->millisatoshis : 1,
info->b11->msat ? *info->b11->msat : AMOUNT_MSAT(1),
inchans,
&any_offline);

23
lightningd/onchain_control.c

@ -275,7 +275,7 @@ static void onchain_add_utxo(struct channel *channel, const u8 *msg)
if (!fromwire_onchain_add_utxo(msg, &u->txid, &u->outnum,
&u->close_info->commitment_point,
&u->amount.satoshis, &blockheight)) {
&u->amount, &blockheight)) {
fatal("onchaind gave invalid add_utxo message: %s", tal_hex(msg, msg));
}
u->blockheight = blockheight>0?&blockheight:NULL;
@ -449,18 +449,29 @@ enum watch_result onchaind_funding_spent(struct channel *channel,
feerate = try_get_feerate(ld->topology, FEERATE_NORMAL);
if (!feerate) {
/* We have at least one data point: the last tx's feerate. */
u64 fee = channel->funding_satoshi;
struct amount_sat fee = channel->funding;
for (size_t i = 0; i < tal_count(channel->last_tx->output); i++)
fee -= channel->last_tx->output[i].amount;
if (!amount_sat_sub(&fee, fee,
(struct amount_sat) {channel->last_tx->output[i].amount})) {
log_broken(channel->log, "Could not get fee"
" funding %s tx %s",
type_to_string(tmpctx,
struct amount_sat,
&channel->funding),
type_to_string(tmpctx,
struct bitcoin_tx,
channel->last_tx));
return KEEP_WATCHING;
}
feerate = fee / measure_tx_weight(tx);
feerate = fee.satoshis / measure_tx_weight(tx);
if (feerate < feerate_floor())
feerate = feerate_floor();
}
msg = towire_onchain_init(channel,
&channel->their_shachain.chain,
channel->funding_satoshi,
channel->funding,
&channel->channel_info.old_remote_per_commit,
&channel->channel_info.remote_per_commit,
/* BOLT #2:
@ -472,7 +483,7 @@ enum watch_result onchaind_funding_spent(struct channel *channel,
channel->channel_info.their_config.to_self_delay,
channel->our_config.to_self_delay,
feerate,
channel->our_config.dust_limit.satoshis,
channel->our_config.dust_limit,
&our_last_txid,
p2wpkh_for_keyidx(tmpctx, ld,
channel->final_key_idx),

80
lightningd/opening_control.c

@ -69,7 +69,7 @@ struct funding_channel {
struct command *cmd; /* Which initially owns us until openingd request */
struct wallet_tx wtx;
u64 push_msat;
struct amount_msat push;
u8 channel_flags;
/* Variables we need to compose fields in cmd's response */
@ -110,7 +110,7 @@ void kill_uncommitted_channel(struct uncommitted_channel *uc,
void json_add_uncommitted_channel(struct json_stream *response,
const struct uncommitted_channel *uc)
{
u64 msatoshi_total, our_msatoshi;
struct amount_msat total, ours;
if (!uc)
return;
@ -128,12 +128,14 @@ void json_add_uncommitted_channel(struct json_stream *response,
json_array_end(response);
}
msatoshi_total = uc->fc->wtx.amount.satoshis * 1000;
our_msatoshi = msatoshi_total - uc->fc->push_msat;
json_add_amount_msat(response, (struct amount_msat){our_msatoshi},
/* These should never fail. */
if (amount_sat_to_msat(&total, uc->fc->wtx.amount)
&& amount_msat_sub(&ours, total, uc->fc->push)) {
json_add_amount_msat(response, ours,
"msatoshi_to_us", "to_us_msat");
json_add_amount_msat(response, (struct amount_msat){msatoshi_total},
"msatoshi_total", "total_msat");
json_add_amount_msat(response, total,
"msatoshi_total", "total_msat");
}
json_object_end(response);
}
@ -146,14 +148,14 @@ wallet_commit_channel(struct lightningd *ld,
struct bitcoin_signature *remote_commit_sig,
const struct bitcoin_txid *funding_txid,
u16 funding_outnum,
u64 funding_satoshi,
u64 push_msat,
struct amount_sat funding,
struct amount_msat push,
u8 channel_flags,
struct channel_info *channel_info,
u32 feerate)
{
struct channel *channel;
u64 our_msatoshi;
struct amount_msat our_msat;
s64 final_key_idx;
/* Get a key to use for closing outputs from this tx */
@ -163,10 +165,17 @@ wallet_commit_channel(struct lightningd *ld,
return NULL;
}
if (uc->fc)
our_msatoshi = funding_satoshi * 1000 - push_msat;
else
our_msatoshi = push_msat;
if (uc->fc) {
if (!amount_sat_sub_msat(&our_msat, funding, push)) {
log_broken(uc->log, "push %s exceeds funding %s",
type_to_string(tmpctx, struct amount_msat,
&push),
type_to_string(tmpctx, struct amount_sat,
&funding));
return NULL;
}
} else
our_msat = push;
/* Feerates begin identical. */
channel_info->feerate_per_kw[LOCAL]
@ -188,17 +197,17 @@ wallet_commit_channel(struct lightningd *ld,
1, 1, 0,
funding_txid,
funding_outnum,
funding_satoshi,
push_msat,
funding,
push,
false, /* !remote_funding_locked */
NULL, /* no scid yet */
/* The three arguments below are msatoshi_to_us,
* msatoshi_to_us_min, and msatoshi_to_us_max.
* Because, this is a newly-funded channel,
* all three are same value. */
our_msatoshi,
our_msatoshi, /* msatoshi_to_us_min */
our_msatoshi, /* msatoshi_to_us_max */
our_msat,
our_msat, /* msat_to_us_min */
our_msat, /* msat_to_us_max */
remote_commit,
remote_commit_sig,
NULL, /* No HTLC sigs yet */
@ -305,7 +314,7 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp,
&channel_info.remote_fundingkey,
&expected_txid,
&feerate,
&fc->uc->our_config.channel_reserve.satoshis)) {
&fc->uc->our_config.channel_reserve)) {
log_broken(fc->uc->log,
"bad OPENING_FUNDER_REPLY %s",
tal_hex(resp, resp));
@ -387,8 +396,8 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp,
&remote_commit_sig,
&funding_txid,
funding_outnum,
fc->wtx.amount.satoshis,
fc->push_msat,
fc->wtx.amount,
fc->push,
fc->channel_flags,
&channel_info,
feerate);
@ -401,8 +410,8 @@ static void opening_funder_finished(struct subd *openingd, const u8 *resp,
/* Get HSM to sign the funding tx. */
log_debug(channel->log, "Getting HSM to sign funding tx");
msg = towire_hsm_sign_funding(tmpctx, channel->funding_satoshi,
fc->wtx.change.satoshis,
msg = towire_hsm_sign_funding(tmpctx, channel->funding,
fc->wtx.change,
fc->wtx.change_key_index,
&fc->uc->local_funding_pubkey,
&channel_info.remote_fundingkey,
@ -466,7 +475,8 @@ static void opening_fundee_finished(struct subd *openingd,
struct lightningd *ld = openingd->ld;
struct bitcoin_txid funding_txid;
u16 funding_outnum;
u64 funding_satoshi, push_msat;
struct amount_sat funding;
struct amount_msat push;
u32 feerate;
u8 channel_flags;
struct channel *channel;
@ -490,12 +500,12 @@ static void opening_fundee_finished(struct subd *openingd,
&channel_info.remote_fundingkey,
&funding_txid,
&funding_outnum,
&funding_satoshi,
&push_msat,
&funding,
&push,
&channel_flags,
&feerate,
&funding_signed,
&uc->our_config.channel_reserve.satoshis)) {
&uc->our_config.channel_reserve)) {
log_broken(uc->log, "bad OPENING_FUNDEE_REPLY %s",
tal_hex(reply, reply));
uncommitted_channel_disconnect(uc, "bad OPENING_FUNDEE_REPLY");
@ -515,8 +525,8 @@ static void opening_fundee_finished(struct subd *openingd,
&remote_commit_sig,
&funding_txid,
funding_outnum,
funding_satoshi,
push_msat,
funding,
push,
channel_flags,
&channel_info,
feerate);
@ -787,7 +797,7 @@ void peer_start_openingd(struct peer *peer,
&get_chainparams(peer->ld)->genesis_blockhash,
&uc->our_config,
max_to_self_delay,
min_effective_htlc_capacity.millisatoshis,
min_effective_htlc_capacity,
cs, &uc->local_basepoints,
&uc->local_funding_pubkey,
uc->minimum_depth,
@ -872,7 +882,7 @@ static struct command_result *json_fund_channel(struct command *cmd,
}
/* FIXME: Support push_msat? */
fc->push_msat = 0;
fc->push = AMOUNT_MSAT(0);
fc->channel_flags = OUR_CHANNEL_FLAGS;
if (!*announce_channel) {
fc->channel_flags &= ~CHANNEL_FLAGS_ANNOUNCE_CHANNEL;
@ -891,10 +901,10 @@ static struct command_result *json_fund_channel(struct command *cmd,
fc->uc = peer->uncommitted_channel;
msg = towire_opening_funder(NULL,
fc->wtx.amount.satoshis,
fc->push_msat,
fc->wtx.amount,
fc->push,
*feerate_per_kw,
fc->wtx.change.satoshis,
fc->wtx.change,
fc->wtx.change_key_index,
fc->channel_flags,
fc->wtx.utxos,

6
lightningd/pay.c

@ -610,7 +610,7 @@ send_payment(struct lightningd *ld,
for (i = 0; i < n_hops - 1; i++) {
hop_data[i].realm = 0;
hop_data[i].channel_id = route[i+1].channel_id;
hop_data[i].amt_forward = route[i+1].amount.millisatoshis;
hop_data[i].amt_forward = route[i+1].amount;
hop_data[i].outgoing_cltv = base_expiry + route[i+1].delay;
}
@ -619,7 +619,7 @@ send_payment(struct lightningd *ld,
hop_data[i].realm = 0;
hop_data[i].outgoing_cltv = base_expiry + route[i].delay;
memset(&hop_data[i].channel_id, 0, sizeof(struct short_channel_id));
hop_data[i].amt_forward = route[i].amount.millisatoshis;
hop_data[i].amt_forward = route[i].amount;
/* Now, do we already have a payment? */
payment = wallet_payment_by_hash(tmpctx, ld->wallet, rhash);
@ -675,7 +675,7 @@ send_payment(struct lightningd *ld,
type_to_string(tmpctx, struct amount_msat, &route[0].amount),
n_hops, msatoshi);
failcode = send_htlc_out(channel, route[0].amount.millisatoshis,
failcode = send_htlc_out(channel, route[0].amount,
base_expiry + route[0].delay,
rhash, onion, NULL, &hout);
if (failcode) {

47
lightningd/peer_control.c

@ -202,7 +202,7 @@ static void sign_last_tx(struct channel *channel)
channel->last_tx,
&channel->channel_info
.remote_fundingkey,
channel->funding_satoshi);
channel->funding);
if (!wire_sync_write(ld->hsm_fd, take(msg)))
fatal("Could not write to HSM: %s", strerror(errno));
@ -453,8 +453,7 @@ static void json_add_htlcs(struct lightningd *ld,
json_object_start(response, NULL);
json_add_string(response, "direction", "in");
json_add_u64(response, "id", hin->key.id);
json_add_amount_msat(response,
(struct amount_msat){ hin->msatoshi },
json_add_amount_msat(response, hin->msat,
"msatoshi", "amount_msat");
json_add_u64(response, "expiry", hin->cltv_expiry);
json_add_hex(response, "payment_hash",
@ -473,8 +472,7 @@ static void json_add_htlcs(struct lightningd *ld,
json_object_start(response, NULL);
json_add_string(response, "direction", "out");
json_add_u64(response, "id", hout->key.id);
json_add_amount_msat(response,
(struct amount_msat){ hout->msatoshi },
json_add_amount_msat(response, hout->msat,
"msatoshi", "amount_msat");
json_add_u64(response, "expiry", hout->cltv_expiry);
json_add_hex(response, "payment_hash",
@ -504,7 +502,7 @@ static void json_add_channel(struct lightningd *ld,
{
struct channel_id cid;
struct channel_stats channel_stats;
struct amount_msat spendable;
struct amount_msat spendable, funding_msat;
struct peer *p = channel->peer;
json_object_start(response, key);
@ -540,11 +538,11 @@ static void json_add_channel(struct lightningd *ld,
if (channel->funder == LOCAL) {
json_add_u64(response, pubkey_to_hexstr(tmpctx, &p->id), 0);
json_add_u64(response, pubkey_to_hexstr(tmpctx, &ld->id),
channel->funding_satoshi * 1000);
channel->funding.satoshis * 1000);
} else {
json_add_u64(response, pubkey_to_hexstr(tmpctx, &ld->id), 0);
json_add_u64(response, pubkey_to_hexstr(tmpctx, &p->id),
channel->funding_satoshi * 1000);
channel->funding.satoshis * 1000);
}
json_object_end(response);
@ -555,28 +553,31 @@ static void json_add_channel(struct lightningd *ld,
AMOUNT_SAT(0));
json_add_sat_only(response,
pubkey_to_hexstr(tmpctx, &ld->id),
(struct amount_sat){channel->funding_satoshi});
channel->funding);
} else {
json_add_sat_only(response,
pubkey_to_hexstr(tmpctx, &ld->id),
AMOUNT_SAT(0));
json_add_sat_only(response,
pubkey_to_hexstr(tmpctx, &p->id),
(struct amount_sat){channel->funding_satoshi});
channel->funding);
}
json_object_end(response);
json_add_amount_msat(response,
(struct amount_msat){channel->our_msatoshi},
if (!amount_sat_to_msat(&funding_msat, channel->funding)) {
log_broken(channel->log,
"Overflow converting funding %s",
type_to_string(tmpctx, struct amount_sat,
&channel->funding));
funding_msat = AMOUNT_MSAT(0);
}
json_add_amount_msat(response, channel->our_msat,
"msatoshi_to_us", "to_us_msat");
json_add_amount_msat(response,
(struct amount_msat){channel->msatoshi_to_us_min},
json_add_amount_msat(response, channel->msat_to_us_min,
"msatoshi_to_us_min", "min_to_us_msat");
json_add_amount_msat(response,
(struct amount_msat){channel->msatoshi_to_us_max},
json_add_amount_msat(response, channel->msat_to_us_max,
"msatoshi_to_us_max", "max_to_us_msat");
json_add_amount_msat(response,
(struct amount_msat){channel->funding_satoshi * 1000},
json_add_amount_msat(response, funding_msat,
"msatoshi_total", "total_msat");
/* channel config */
@ -605,7 +606,7 @@ static void json_add_channel(struct lightningd *ld,
"our_reserve_msat");
/* Compute how much we can send via this channel. */
if (!amount_msat_sub_sat(&spendable,
(struct amount_msat){channel->our_msatoshi},
channel->our_msat,
channel->channel_info.their_config.channel_reserve))
spendable = AMOUNT_MSAT(0);
@ -643,25 +644,25 @@ static void json_add_channel(struct lightningd *ld,
json_add_u64(response, "in_payments_offered",
channel_stats.in_payments_offered);
json_add_amount_msat(response,
(struct amount_msat){channel_stats.in_msatoshi_offered},
channel_stats.in_msatoshi_offered,
"in_msatoshi_offered",
"in_offered_msat");
json_add_u64(response, "in_payments_fulfilled",
channel_stats.in_payments_fulfilled);
json_add_amount_msat(response,
(struct amount_msat){channel_stats.in_msatoshi_fulfilled},
channel_stats.in_msatoshi_fulfilled,
"in_msatoshi_fulfilled",
"in_fulfilled_msat");
json_add_u64(response, "out_payments_offered",
channel_stats.out_payments_offered);
json_add_amount_msat(response,
(struct amount_msat){channel_stats.out_msatoshi_offered},
channel_stats.out_msatoshi_offered,
"out_msatoshi_offered",
"out_offered_msat");
json_add_u64(response, "out_payments_fulfilled",
channel_stats.out_payments_fulfilled);
json_add_amount_msat(response,
(struct amount_msat){channel_stats.out_msatoshi_fulfilled},
channel_stats.out_msatoshi_fulfilled,
"out_msatoshi_fulfilled",
"out_fulfilled_msat");

138
lightningd/peer_htlcs.c

@ -167,13 +167,22 @@ static void fail_out_htlc(struct htlc_out *hout, const char *localfail)
* the final node.
*/
static bool check_amount(struct htlc_in *hin,
u64 amt_to_forward, u64 amt_in_htlc, u64 fee)
struct amount_msat amt_to_forward,
struct amount_msat amt_in_htlc,
struct amount_msat fee)
{
if (amt_in_htlc - fee >= amt_to_forward)
struct amount_msat fwd;
if (amount_msat_sub(&fwd, amt_in_htlc, fee)
&& amount_msat_greater_eq(fwd, amt_to_forward))
return true;
log_debug(hin->key.channel->log, "HTLC %"PRIu64" incorrect amount:"
" %"PRIu64" in, %"PRIu64" out, fee reqd %"PRIu64,
hin->key.id, amt_in_htlc, amt_to_forward, fee);
" %s in, %s out, fee reqd %s",
hin->key.id,
type_to_string(tmpctx, struct amount_msat, &amt_in_htlc),
type_to_string(tmpctx, struct amount_msat, &amt_to_forward),
type_to_string(tmpctx, struct amount_msat, &fee));
return false;
}
@ -223,7 +232,7 @@ static void fulfill_htlc(struct htlc_in *hin, const struct preimage *preimage)
/* Update channel stats */
wallet_channel_stats_incr_in_fulfilled(wallet,
channel->dbid,
hin->msatoshi);
hin->msat);
/* No owner? We'll either send to channeld in peer_htlcs, or
* onchaind in onchaind_tell_fulfill. */
@ -246,7 +255,7 @@ static void fulfill_htlc(struct htlc_in *hin, const struct preimage *preimage)
static void handle_localpay(struct htlc_in *hin,
u32 cltv_expiry,
const struct sha256 *payment_hash,
u64 amt_to_forward,
struct amount_msat amt_to_forward,
u32 outgoing_cltv_value)
{
enum onion_type failcode;
@ -262,7 +271,7 @@ static void handle_localpay(struct htlc_in *hin,
*
* The amount in the HTLC doesn't match the value in the onion.
*/
if (!check_amount(hin, amt_to_forward, hin->msatoshi, 0)) {
if (!check_amount(hin, amt_to_forward, hin->msat, AMOUNT_MSAT(0))) {
failcode = WIRE_FINAL_INCORRECT_HTLC_AMOUNT;
goto fail;
}
@ -293,10 +302,10 @@ static void handle_localpay(struct htlc_in *hin,
* - if the amount paid is less than the amount expected:
* - MUST fail the HTLC.
*/
if (details->msatoshi != NULL && hin->msatoshi < *details->msatoshi) {
if (details->msatoshi != NULL && hin->msat.millisatoshis < *details->msatoshi) {
failcode = WIRE_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS;
goto fail;
} else if (details->msatoshi != NULL && hin->msatoshi > *details->msatoshi * 2) {
} else if (details->msatoshi != NULL && hin->msat.millisatoshis > *details->msatoshi * 2) {
/* FIXME: bolt update fixes this quote! */
/* BOLT #4:
*
@ -327,10 +336,12 @@ static void handle_localpay(struct htlc_in *hin,
log_info(ld->log, "Resolving invoice '%s' with HTLC %"PRIu64,
details->label->s, hin->key.id);
log_debug(ld->log, "%s: Actual amount %"PRIu64"msat, HTLC expiry %u",
details->label->s, hin->msatoshi, cltv_expiry);
log_debug(ld->log, "%s: Actual amount %s, HTLC expiry %u",
details->label->s,
type_to_string(tmpctx, struct amount_msat, &hin->msat),
cltv_expiry);
fulfill_htlc(hin, &details->r);
wallet_invoice_resolve(ld->wallet, invoice, hin->msatoshi);
wallet_invoice_resolve(ld->wallet, invoice, hin->msat.millisatoshis);
return;
@ -429,7 +440,8 @@ static void htlc_offer_timeout(struct channel *channel)
"Adding HTLC timed out: killed channel");
}
enum onion_type send_htlc_out(struct channel *out, u64 amount, u32 cltv,
enum onion_type send_htlc_out(struct channel *out,
struct amount_msat amount, u32 cltv,
const struct sha256 *payment_hash,
const u8 *onion_routing_packet,
struct htlc_in *in,
@ -472,13 +484,13 @@ enum onion_type send_htlc_out(struct channel *out, u64 amount, u32 cltv,
static void forward_htlc(struct htlc_in *hin,
u32 cltv_expiry,
u64 amt_to_forward,
struct amount_msat amt_to_forward,
u32 outgoing_cltv_value,
const struct pubkey *next_hop,
const u8 next_onion[TOTAL_PACKET_SIZE])
{
enum onion_type failcode;
u64 fee;
struct amount_msat fee;
struct lightningd *ld = hin->key.channel->peer->ld;
struct channel *next = active_channel_by_id(ld, next_hop, NULL);
@ -494,14 +506,16 @@ static void forward_htlc(struct htlc_in *hin,
* - SHOULD accept HTLCs that pay a fee equal to or greater than:
* - fee_base_msat + ( amount_to_forward * fee_proportional_millionths / 1000000 )
*/
if (mul_overflows_u64(amt_to_forward,
ld->config.fee_per_satoshi)) {
if (!amount_msat_fee(&fee, amt_to_forward,
ld->config.fee_base,
ld->config.fee_per_satoshi)) {
log_broken(ld->log, "Fee overflow forwarding %s!",
type_to_string(tmpctx, struct amount_msat,
&amt_to_forward));
failcode = WIRE_FEE_INSUFFICIENT;
goto fail;
}
fee = ld->config.fee_base
+ amt_to_forward * ld->config.fee_per_satoshi / 1000000;
if (!check_amount(hin, amt_to_forward, hin->msatoshi, fee)) {
if (!check_amount(hin, amt_to_forward, hin->msat, fee)) {
failcode = WIRE_FEE_INSUFFICIENT;
goto fail;
}
@ -559,7 +573,7 @@ fail:
/* Temporary information, while we resolve the next hop */
struct gossip_resolve {
struct short_channel_id next_channel;
u64 amt_to_forward;
struct amount_msat amt_to_forward;
u32 outgoing_cltv_value;
u8 *next_onion;
struct htlc_in *hin;
@ -721,7 +735,7 @@ static void fulfill_our_htlc_out(struct channel *channel, struct htlc_out *hout,
/* Update channel stats */
wallet_channel_stats_incr_out_fulfilled(ld->wallet,
channel->dbid,
hout->msatoshi);
hout->msat);
if (hout->am_origin)
payment_succeeded(ld, hout, preimage);
@ -874,12 +888,25 @@ static void remove_htlc_in(struct channel *channel, struct htlc_in *hin)
/* If we fulfilled their HTLC, credit us. */
if (hin->preimage) {
log_debug(channel->log, "Balance %"PRIu64" -> %"PRIu64,
channel->our_msatoshi,
channel->our_msatoshi + hin->msatoshi);
channel->our_msatoshi += hin->msatoshi;
if (channel->our_msatoshi > channel->msatoshi_to_us_max)
channel->msatoshi_to_us_max = channel->our_msatoshi;
struct amount_msat oldamt = channel->our_msat;
if (!amount_msat_add(&channel->our_msat, channel->our_msat,
hin->msat)) {
channel_internal_error(channel,
"Overflow our_msat %s + HTLC %s",
type_to_string(tmpctx,
struct amount_msat,
&channel->our_msat),
type_to_string(tmpctx,
struct amount_msat,
&hin->msat));
}
log_debug(channel->log, "Balance %s -> %s",
type_to_string(tmpctx, struct amount_msat, &oldamt),
type_to_string(tmpctx, struct amount_msat,
&channel->our_msat));
if (amount_msat_greater(channel->our_msat,
channel->msat_to_us_max))
channel->msat_to_us_max = channel->our_msat;
}
tal_free(hin);
@ -899,13 +926,26 @@ static void remove_htlc_out(struct channel *channel, struct htlc_out *hout)
if (!hout->preimage) {
fail_out_htlc(hout, NULL);
} else {
struct amount_msat oldamt = channel->our_msat;
/* We paid for this HTLC, so deduct balance. */
log_debug(channel->log, "Balance %"PRIu64" -> %"PRIu64,
channel->our_msatoshi,
channel->our_msatoshi - hout->msatoshi);
channel->our_msatoshi -= hout->msatoshi;
if (channel->our_msatoshi < channel->msatoshi_to_us_min)
channel->msatoshi_to_us_min = channel->our_msatoshi;
if (!amount_msat_sub(&channel->our_msat, channel->our_msat,
hout->msat)) {
channel_internal_error(channel,
"Underflow our_msat %s - HTLC %s",
type_to_string(tmpctx,
struct amount_msat,
&channel->our_msat),
type_to_string(tmpctx,
struct amount_msat,
&hout->msat));
}
log_debug(channel->log, "Balance %s -> %s",
type_to_string(tmpctx, struct amount_msat, &oldamt),
type_to_string(tmpctx, struct amount_msat,
&channel->our_msat));
if (amount_msat_less(channel->our_msat, channel->msat_to_us_min))
channel->msat_to_us_min = channel->our_msat;
}
tal_free(hout);
@ -950,7 +990,7 @@ static bool update_out_htlc(struct channel *channel,
/* Update channel stats */
wallet_channel_stats_incr_out_offered(ld->wallet,
channel->dbid,
hout->msatoshi);
hout->msat);
if (hout->in)
wallet_forwarded_payment_add(ld->wallet, hout->in, hout,
@ -1107,12 +1147,14 @@ static bool channel_added_their_htlc(struct channel *channel,
* - receiving an `amount_msat` equal to 0, OR less than its own `htlc_minimum_msat`:
* - SHOULD fail the channel.
*/
if (added->amount_msat == 0
|| added->amount_msat < channel->our_config.htlc_minimum.millisatoshis) {
if (amount_msat_eq(added->amount, AMOUNT_MSAT(0))
|| amount_msat_less(added->amount, channel->our_config.htlc_minimum)) {
channel_internal_error(channel,
"trying to add HTLC msat %"PRIu64
" but minimum is %s",
added->amount_msat,
"trying to add HTLC amount %s"
" but minimum is %s",
type_to_string(tmpctx,
struct amount_msat,
&added->amount),
type_to_string(tmpctx,
struct amount_msat,
&channel->our_config.htlc_minimum));
@ -1126,7 +1168,7 @@ static bool channel_added_their_htlc(struct channel *channel,
/* This stays around even if we fail it immediately: it *is*
* part of the current commitment. */
hin = new_htlc_in(channel, channel, added->id, added->amount_msat,
hin = new_htlc_in(channel, channel, added->id, added->amount,
added->cltv_expiry, &added->payment_hash,
shared_secret, added->onion_routing_packet);
@ -1134,7 +1176,7 @@ static bool channel_added_their_htlc(struct channel *channel,
wallet_htlc_save_in(ld->wallet, channel, hin);
/* Update channel stats */
wallet_channel_stats_incr_in_offered(ld->wallet, channel->dbid,
added->amount_msat);
added->amount);
log_debug(channel->log, "Adding their HTLC %"PRIu64, added->id);
connect_htlc_in(&channel->peer->ld->htlcs_in, hin);
@ -1386,7 +1428,7 @@ void peer_got_revoke(struct channel *channel, const u8 *msg)
static void add_htlc(struct added_htlc **htlcs,
enum htlc_state **htlc_states,
u64 id,
u64 amount_msat,
struct amount_msat amount,
const struct sha256 *payment_hash,
u32 cltv_expiry,
const u8 onion_routing_packet[TOTAL_PACKET_SIZE],
@ -1395,7 +1437,7 @@ static void add_htlc(struct added_htlc **htlcs,
struct added_htlc a;
a.id = id;
a.amount_msat = amount_msat;
a.amount = amount;
a.payment_hash = *payment_hash;
a.cltv_expiry = cltv_expiry;
memcpy(a.onion_routing_packet, onion_routing_packet,
@ -1478,7 +1520,7 @@ void peer_htlcs(const tal_t *ctx,
continue;
add_htlc(htlcs, htlc_states,
hin->key.id, hin->msatoshi, &hin->payment_hash,
hin->key.id, hin->msat, &hin->payment_hash,
hin->cltv_expiry, hin->onion_routing_packet,
hin->hstate);
@ -1498,7 +1540,7 @@ void peer_htlcs(const tal_t *ctx,
continue;
add_htlc(htlcs, htlc_states,
hout->key.id, hout->msatoshi, &hout->payment_hash,
hout->key.id, hout->msat, &hout->payment_hash,
hout->cltv_expiry, hout->onion_routing_packet,
hout->hstate);
@ -1701,11 +1743,11 @@ static void fixup_hout(struct lightningd *ld, struct htlc_out *hout)
}
log_broken(ld->log, "HTLC #%"PRIu64" (%s) "
" for amount %"PRIu64
" for amount %s"
" to %s"
" is missing a resolution: %s.",
hout->key.id, htlc_state_name(hout->hstate),
hout->msatoshi,
type_to_string(tmpctx, struct amount_msat, &hout->msat),
type_to_string(tmpctx, struct pubkey,
&hout->key.channel->peer->id),
fix);

3
lightningd/peer_htlcs.h

@ -44,7 +44,8 @@ void peer_got_revoke(struct channel *channel, const u8 *msg);
void update_per_commit_point(struct channel *channel,
const struct pubkey *per_commitment_point);
enum onion_type send_htlc_out(struct channel *out, u64 amount, u32 cltv,
enum onion_type send_htlc_out(struct channel *out,
struct amount_msat amount, u32 cltv,
const struct sha256 *payment_hash,
const u8 *onion_routing_packet,
struct htlc_in *in,

1
lightningd/test/Makefile

@ -8,6 +8,7 @@ ALL_TEST_PROGRAMS += $(LIGHTNINGD_TEST_PROGRAMS)
ALL_OBJS += $(LIGHTNINGD_TEST_OBJS)
LIGHTNINGD_TEST_COMMON_OBJS := \
common/amount.o \
common/bech32.o \
common/daemon_conn.o \
common/htlc_state.o \

43
lightningd/test/run-invoice-select-inchan.c

@ -6,18 +6,6 @@
bool deprecated_apis = false;
/* AUTOGENERATED MOCKS START */
/* Generated stub for amount_msat_greater */
bool amount_msat_greater(struct amount_msat a UNNEEDED, struct amount_msat b UNNEEDED)
{ fprintf(stderr, "amount_msat_greater called!\n"); abort(); }
/* Generated stub for amount_msat_sub_sat */
bool amount_msat_sub_sat(struct amount_msat *val UNNEEDED,
struct amount_msat a UNNEEDED,
struct amount_sat b UNNEEDED)
{ fprintf(stderr, "amount_msat_sub_sat called!\n"); abort(); }
/* Generated stub for amount_sat_to_msat */
bool amount_sat_to_msat(struct amount_msat *msat UNNEEDED,
struct amount_sat sat UNNEEDED)
{ fprintf(stderr, "amount_sat_to_msat called!\n"); abort(); }
/* Generated stub for bitcoind_gettxout */
void bitcoind_gettxout(struct bitcoind *bitcoind UNNEEDED,
const struct bitcoin_txid *txid UNNEEDED, const u32 outnum UNNEEDED,
@ -355,9 +343,6 @@ struct command_result *param_u64(struct command *cmd UNNEEDED, const char *name
const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
uint64_t **num UNNEEDED)
{ fprintf(stderr, "param_u64 called!\n"); abort(); }
/* Generated stub for parse_amount_msat */
bool parse_amount_msat(struct amount_msat *msat UNNEEDED, const char *s UNNEEDED, size_t slen UNNEEDED)
{ fprintf(stderr, "parse_amount_msat called!\n"); abort(); }
/* Generated stub for peer_memleak_done */
void peer_memleak_done(struct command *cmd UNNEEDED, struct subd *leaker UNNEEDED)
{ fprintf(stderr, "peer_memleak_done called!\n"); abort(); }
@ -437,7 +422,7 @@ u8 *towire_gossip_get_incoming_channels(const tal_t *ctx UNNEEDED, const bool *p
u8 *towire_hsm_get_channel_basepoints(const tal_t *ctx UNNEEDED, const struct pubkey *peerid UNNEEDED, u64 dbid UNNEEDED)
{ fprintf(stderr, "towire_hsm_get_channel_basepoints called!\n"); abort(); }
/* Generated stub for towire_hsm_sign_commitment_tx */
u8 *towire_hsm_sign_commitment_tx(const tal_t *ctx UNNEEDED, const struct pubkey *peer_id UNNEEDED, u64 channel_dbid UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const struct pubkey *remote_funding_key UNNEEDED, u64 funding_amount UNNEEDED)
u8 *towire_hsm_sign_commitment_tx(const tal_t *ctx UNNEEDED, const struct pubkey *peer_id UNNEEDED, u64 channel_dbid UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const struct pubkey *remote_funding_key UNNEEDED, struct amount_sat funding_amount UNNEEDED)
{ fprintf(stderr, "towire_hsm_sign_commitment_tx called!\n"); abort(); }
/* Generated stub for towire_hsm_sign_invoice */
u8 *towire_hsm_sign_invoice(const tal_t *ctx UNNEEDED, const u8 *u5bytes UNNEEDED, const u8 *hrp UNNEEDED)
@ -598,9 +583,9 @@ static void add_peer(struct lightningd *ld, int n, enum channel_state state,
c->state = state;
c->owner = connected ? (void *)peer : NULL;
/* Channel has incoming capacity n*1000 - 1 millisatoshi */
c->funding_satoshi = n+1;
c->our_msatoshi = 1;
c->our_config.channel_reserve.satoshis = 1;
c->funding.satoshis = n+1;
c->our_msat = AMOUNT_MSAT(1);
c->our_config.channel_reserve = AMOUNT_SAT(1);
list_add_tail(&peer->channels, &c->list);
}
@ -630,47 +615,47 @@ int main(void)
inchans = tal_arr(tmpctx, struct route_info, 0);
/* Nothing to choose from -> NULL result. */
assert(select_inchan(tmpctx, ld, 0, inchans, &any_offline) == NULL);
assert(select_inchan(tmpctx, ld, AMOUNT_MSAT(0), inchans, &any_offline) == NULL);
assert(any_offline == false);
/* inchan but no peer -> NULL result. */
add_inchan(&inchans, 0);
assert(select_inchan(tmpctx, ld, 0, inchans, &any_offline) == NULL);
assert(select_inchan(tmpctx, ld, AMOUNT_MSAT(0), inchans, &any_offline) == NULL);
assert(any_offline == false);
/* connected peer but no inchan -> NULL result. */
add_peer(ld, 1, CHANNELD_NORMAL, false);
assert(select_inchan(tmpctx, ld, 0, inchans, &any_offline) == NULL);
assert(select_inchan(tmpctx, ld, AMOUNT_MSAT(0), inchans, &any_offline) == NULL);
assert(any_offline == false);
/* inchan but peer awaiting lockin -> NULL result. */
add_peer(ld, 0, CHANNELD_AWAITING_LOCKIN, true);
assert(select_inchan(tmpctx, ld, 0, inchans, &any_offline) == NULL);
assert(select_inchan(tmpctx, ld, AMOUNT_MSAT(0), inchans, &any_offline) == NULL);
assert(any_offline == false);
/* inchan but peer not connected -> NULL result. */
add_inchan(&inchans, 1);
assert(select_inchan(tmpctx, ld, 0, inchans, &any_offline) == NULL);
assert(select_inchan(tmpctx, ld, AMOUNT_MSAT(0), inchans, &any_offline) == NULL);
assert(any_offline == true);
/* Finally, a correct peer! */
add_inchan(&inchans, 2);
add_peer(ld, 2, CHANNELD_NORMAL, true);
ret = select_inchan(tmpctx, ld, 0, inchans, &any_offline);
ret = select_inchan(tmpctx, ld, AMOUNT_MSAT(0), inchans, &any_offline);
assert(tal_count(ret) == 1);
assert(tal_count(ret[0]) == 1);
assert(any_offline == true);
assert(route_info_eq(ret[0], &inchans[2]));
/* Not if we ask for too much! Reserve is 1 satoshi */
ret = select_inchan(tmpctx, ld, 1999, inchans, &any_offline);
ret = select_inchan(tmpctx, ld, AMOUNT_MSAT(1999), inchans, &any_offline);
assert(tal_count(ret) == 1);
assert(tal_count(ret[0]) == 1);
assert(any_offline == false); /* Other candidate insufficient funds. */
assert(route_info_eq(ret[0], &inchans[2]));
ret = select_inchan(tmpctx, ld, 2000, inchans, &any_offline);
ret = select_inchan(tmpctx, ld, AMOUNT_MSAT(2000), inchans, &any_offline);
assert(ret == NULL);
assert(any_offline == false); /* Other candidate insufficient funds. */
@ -679,7 +664,7 @@ int main(void)
add_peer(ld, 3, CHANNELD_NORMAL, true);
for (size_t i = n = 0; i < 1000; i++) {
ret = select_inchan(tmpctx, ld, 1000, inchans, &any_offline);
ret = select_inchan(tmpctx, ld, AMOUNT_MSAT(1000), inchans, &any_offline);
assert(tal_count(ret) == 1);
assert(tal_count(ret[0]) == 1);
assert(any_offline == false); /* Other candidate insufficient funds. */
@ -695,7 +680,7 @@ int main(void)
n, 1000 - n);
for (size_t i = n = 0; i < 1000; i++) {
ret = select_inchan(tmpctx, ld, 1499, inchans, &any_offline);
ret = select_inchan(tmpctx, ld, AMOUNT_MSAT(1499), inchans, &any_offline);
assert(tal_count(ret) == 1);
assert(tal_count(ret[0]) == 1);
assert(any_offline == false); /* Other candidate insufficient funds. */

4
lightningd/test/run-jsonrpc.c

@ -3,10 +3,6 @@
#include "../json.c"
/* AUTOGENERATED MOCKS START */
/* Generated stub for amount_sat_to_msat */
bool amount_sat_to_msat(struct amount_msat *msat UNNEEDED,
struct amount_sat sat UNNEEDED)
{ fprintf(stderr, "amount_sat_to_msat called!\n"); abort(); }
/* Generated stub for db_begin_transaction_ */
void db_begin_transaction_(struct db *db UNNEEDED, const char *location UNNEEDED)
{ fprintf(stderr, "db_begin_transaction_ called!\n"); abort(); }

6
onchaind/onchain_wire.csv

@ -4,7 +4,7 @@
# Begin! Here's the onchain tx which spends funding tx, followed by all HTLCs.
onchain_init,5001
onchain_init,,shachain,struct shachain
onchain_init,,funding_amount_satoshi,u64
onchain_init,,funding_amount_satoshi,struct amount_sat
# Remote per commit point for committed tx.
onchain_init,,old_remote_per_commitment_point,struct pubkey
# Remote per commit point for current tx (needed if we haven't got revoke_and_ack yet).
@ -12,7 +12,7 @@ onchain_init,,remote_per_commitment_point,struct pubkey
onchain_init,,local_to_self_delay,u32
onchain_init,,remote_to_self_delay,u32
onchain_init,,feerate_per_kw,u32
onchain_init,,local_dust_limit_satoshi,u64
onchain_init,,local_dust_limit_satoshi,struct amount_sat
# Gives an easy way to tell if it's our unilateral close or theirs...
onchain_init,,our_broadcast_txid,struct bitcoin_txid
onchain_init,,local_scriptpubkey_len,u16
@ -88,7 +88,7 @@ onchain_add_utxo,5012
onchain_add_utxo,,prev_out_tx,struct bitcoin_txid
onchain_add_utxo,,prev_out_index,u32
onchain_add_utxo,,per_commit_point,struct pubkey
onchain_add_utxo,,value,u64
onchain_add_utxo,,value,struct amount_sat
onchain_add_utxo,,blockheight,u32
# master -> onchaind: do you have a memleak?

Can't render this file because it has a wrong number of fields in line 4.

186
onchaind/onchaind.c

@ -46,7 +46,7 @@ static u32 feerate_per_kw;
static u32 min_possible_feerate, max_possible_feerate;
/* The dust limit to use when we generate transactions. */
static u64 dust_limit_satoshis;
static struct amount_sat dust_limit;
/* The CSV delays for each side. */
static u32 to_self_delay[NUM_SIDES];
@ -89,7 +89,7 @@ struct tracked_output {
/* FIXME: Convert all depths to blocknums, then just get new blk msgs */
u32 depth;
u32 outnum;
u64 satoshi;
struct amount_sat sat;
enum output_type output_type;
/* If it is an HTLC, this is set, wscript is non-NULL. */
@ -107,13 +107,14 @@ struct tracked_output {
};
/* We vary feerate until signature they offered matches. */
static u64 grind_htlc_tx_fee(struct bitcoin_tx *tx,
const struct bitcoin_signature *remotesig,
const u8 *wscript,
u64 multiplier)
static bool grind_htlc_tx_fee(struct amount_sat *fee,
struct bitcoin_tx *tx,
const struct bitcoin_signature *remotesig,
const u8 *wscript,
u64 weight)
{
u64 prev_fee = UINT64_MAX;
u64 input_amount = *tx->input[0].amount;
struct amount_sat prev_fee = AMOUNT_SAT(UINT64_MAX);
struct amount_sat input_amount = (struct amount_sat){*tx->input[0].amount};
for (u64 i = min_possible_feerate; i <= max_possible_feerate; i++) {
/* BOLT #3:
@ -128,31 +129,36 @@ static u64 grind_htlc_tx_fee(struct bitcoin_tx *tx,
* 1. Multiply `feerate_per_kw` by 703 and divide by 1000
* (rounding down).
*/
u64 fee = i * multiplier / 1000;
struct amount_sat out;
if (fee > input_amount)
break;
*fee = amount_tx_fee(i, weight);
/* Minor optimization: don't check same fee twice */
if (fee == prev_fee)
if (amount_sat_eq(*fee, prev_fee))
continue;
prev_fee = fee;
tx->output[0].amount = input_amount - fee;
prev_fee = *fee;
if (!amount_sat_sub(&out, input_amount, *fee))
break;
tx->output[0].amount = out.satoshis;
if (!check_tx_sig(tx, 0, NULL, wscript,
&keyset->other_htlc_key, remotesig))
continue;
return fee;
status_trace("grind feerate_per_kw for %"PRIu64" = %"PRIu64,
weight, i);
return true;
}
return UINT64_MAX;
return false;
}
static bool set_htlc_timeout_fee(struct bitcoin_tx *tx,
const struct bitcoin_signature *remotesig,
const u8 *wscript)
{
static u64 fee = UINT64_MAX;
static struct amount_sat fee = AMOUNT_SAT(UINT64_MAX);
struct amount_sat out;
/* BOLT #3:
*
@ -161,12 +167,16 @@ static bool set_htlc_timeout_fee(struct bitcoin_tx *tx,
* 1. Multiply `feerate_per_kw` by 663 and divide by 1000 (rounding
* down).
*/
if (fee == UINT64_MAX) {
fee = grind_htlc_tx_fee(tx, remotesig, wscript, 663);
return fee != UINT64_MAX;
}
if (amount_sat_eq(fee, AMOUNT_SAT(UINT64_MAX)))
return grind_htlc_tx_fee(&fee, tx, remotesig, wscript, 663);
tx->output[0].amount = *tx->input[0].amount - fee;
out.satoshis = tx->output[0].amount;
if (!amount_sat_sub(&out, out, fee))
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Cannot deduct htlc-timeout fee %s from tx %s",
type_to_string(tmpctx, struct amount_sat, &fee),
type_to_string(tmpctx, struct bitcoin_tx, tx));
tx->output[0].amount = out.satoshis;
return check_tx_sig(tx, 0, NULL, wscript,
&keyset->other_htlc_key, remotesig);
}
@ -175,7 +185,8 @@ static void set_htlc_success_fee(struct bitcoin_tx *tx,
const struct bitcoin_signature *remotesig,
const u8 *wscript)
{
static u64 fee = UINT64_MAX;
static struct amount_sat fee = AMOUNT_SAT(UINT64_MAX);
struct amount_sat out;
/* BOLT #3:
*
@ -184,20 +195,36 @@ static void set_htlc_success_fee(struct bitcoin_tx *tx,
* 1. Multiply `feerate_per_kw` by 703 and divide by 1000
* (rounding down).
*/
if (fee == UINT64_MAX) {
fee = grind_htlc_tx_fee(tx, remotesig, wscript, 703);
if (amount_sat_eq(fee, AMOUNT_SAT(UINT64_MAX))) {
if (!grind_htlc_tx_fee(&fee, tx, remotesig, wscript, 703))
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"htlc_success_fee can't be found "
" for tx %s, signature %s, wscript %s",
type_to_string(tmpctx, struct bitcoin_tx,
tx),
type_to_string(tmpctx,
struct bitcoin_signature,
remotesig),
tal_hex(tmpctx, wscript));
return;
}
tx->output[0].amount = *tx->input[0].amount - fee;
out.satoshis = tx->output[0].amount;
if (!amount_sat_sub(&out, out, fee))
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Cannot deduct htlc-success fee %s from tx %s",
type_to_string(tmpctx, struct amount_sat, &fee),
type_to_string(tmpctx, struct bitcoin_tx, tx));
tx->output[0].amount = out.satoshis;
if (check_tx_sig(tx, 0, NULL, wscript,
&keyset->other_htlc_key, remotesig))
return;
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"htlc_success_fee %"PRIu64" failed sigcheck "
"htlc_success_fee %s failed sigcheck "
" for tx %s, signature %s, wscript %s",
fee,
type_to_string(tmpctx, struct amount_sat, &fee),
type_to_string(tmpctx, struct bitcoin_tx, tx),
type_to_string(tmpctx, struct bitcoin_signature, remotesig),
tal_hex(tmpctx, wscript));
@ -229,7 +256,7 @@ static u8 *delayed_payment_to_us(const tal_t *ctx,
{
return towire_hsm_sign_delayed_payment_to_us(ctx, commit_num,
tx, wscript,
*tx->input[0].amount);
(struct amount_sat){*tx->input[0].amount});
}
static u8 *remote_htlc_to_us(const tal_t *ctx,
@ -239,7 +266,7 @@ static u8 *remote_htlc_to_us(const tal_t *ctx,
return towire_hsm_sign_remote_htlc_to_us(ctx,
remote_per_commitment_point,
tx, wscript,
*tx->input[0].amount);
(struct amount_sat){*tx->input[0].amount});
}
static u8 *penalty_to_us(const tal_t *ctx,
@ -247,7 +274,7 @@ static u8 *penalty_to_us(const tal_t *ctx,
const u8 *wscript)
{
return towire_hsm_sign_penalty_to_us(ctx, remote_per_commitment_secret,
tx, wscript, *tx->input[0].amount);
tx, wscript, (struct amount_sat){*tx->input[0].amount});
}
/*
@ -272,8 +299,9 @@ static struct bitcoin_tx *tx_to_us(const tal_t *ctx,
enum tx_type *tx_type)
{
struct bitcoin_tx *tx;
u64 fee;
struct amount_sat fee, min_out, outsat;
struct bitcoin_signature sig;
size_t weight;
u8 *msg;
tx = bitcoin_tx(ctx, 1, 1);
@ -281,42 +309,45 @@ static struct bitcoin_tx *tx_to_us(const tal_t *ctx,
tx->input[0].sequence_number = to_self_delay;
tx->input[0].txid = out->txid;
tx->input[0].index = out->outnum;
tx->input[0].amount = tal_dup(tx->input, u64, &out->satoshi);
tx->input[0].amount = tal_dup(tx->input, u64, &out->sat.satoshis);
tx->output[0].amount = out->satoshi;
tx->output[0].amount = out->sat.satoshis;
tx->output[0].script = scriptpubkey_p2wpkh(tx->output,
&our_wallet_pubkey);
/* Worst-case sig is 73 bytes */
fee = feerate_per_kw * (measure_tx_weight(tx)
+ 1 + 3 + 73 + 0 + tal_count(wscript))
/ 1000;
weight = measure_tx_weight(tx) + 1 + 3 + 73 + 0 + tal_count(wscript);
fee = amount_tx_fee(feerate_per_kw, weight);
/* Result is trivial? Spend with small feerate, but don't wait
* around for it as it might not confirm. */
if (tx->output[0].amount < dust_limit_satoshis + fee) {
/* FIXME: We should use SIGHASH_NONE so others can take it */
fee = feerate_floor() * (measure_tx_weight(tx)
+ 1 + 3 + 73 + 0 + tal_count(wscript))
/ 1000;
/* This shouldn't happen (we don't set feerate below floor!),
* but just in case. */
if (tx->output[0].amount < dust_limit_satoshis + fee) {
fee = tx->output[0].amount - dust_limit_satoshis;
status_broken("TX %s can't afford minimal feerate"
"; setting fee to %"PRIu64,
tx_type_name(*tx_type),
fee);
} else
status_unusual("TX %s amount %"PRIu64" too small to"
" pay reasonable fee, using minimal fee"
" and ignoring",
tx_type_name(*tx_type),
out->satoshi);
if (!amount_sat_add(&min_out, dust_limit, fee))
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Cannot add dust_limit %s and fee %s",
type_to_string(tmpctx, struct amount_sat, &dust_limit),
type_to_string(tmpctx, struct amount_sat, &fee));
if (amount_sat_less(out->sat, min_out)) {
/* FIXME: We should use SIGHASH_NONE so others can take it */
fee = amount_tx_fee(feerate_floor(), weight);
status_unusual("TX %s amount %s too small to"
" pay reasonable fee, using minimal fee"
" and ignoring",
tx_type_name(*tx_type),
type_to_string(tmpctx, struct amount_sat, &out->sat));
*tx_type = IGNORING_TINY_PAYMENT;
}
tx->output[0].amount -= fee;
/* This can only happen if feerate_floor() is still too high; shouldn't
* happen! */
if (!amount_sat_sub(&outsat, out->sat, fee)) {
outsat = dust_limit;
status_broken("TX %s can't afford minimal feerate"
"; setting output to %s",
tx_type_name(*tx_type),
type_to_string(tmpctx, struct amount_sat, &outsat));
}
tx->output[0].amount = outsat.satoshis;
if (!wire_sync_write(HSM_FD, take(hsm_sign_msg(NULL, tx, wscript))))
status_failed(STATUS_FAIL_HSM_IO, "Writing sign request to hsm");
@ -340,7 +371,7 @@ static void hsm_sign_local_htlc_tx(struct bitcoin_tx *tx,
{
u8 *msg = towire_hsm_sign_local_htlc_tx(NULL, commit_num,
tx, wscript,
*tx->input[0].amount);
(struct amount_sat){*tx->input[0].amount});
if (!wire_sync_write(HSM_FD, take(msg)))
status_failed(STATUS_FAIL_HSM_IO,
@ -382,7 +413,9 @@ static struct tracked_output *
const secp256k1_ecdsa_signature *remote_htlc_sig)
{
struct tracked_output *out = tal(*outs, struct tracked_output);
struct amount_sat sat;
sat.satoshis = satoshi;
status_trace("Tracking output %u of %s: %s/%s",
outnum,
type_to_string(tmpctx, struct bitcoin_txid, txid),
@ -394,7 +427,7 @@ static struct tracked_output *
out->tx_blockheight = tx_blockheight;
out->depth = 0;
out->outnum = outnum;
out->satoshi = satoshi;
out->sat = sat;
out->output_type = output_type;
out->proposal = NULL;
out->resolved = NULL;
@ -1151,7 +1184,13 @@ static void handle_preimage(struct tracked_output **outs,
*/
if (outs[i]->remote_htlc_sig) {
struct amount_msat htlc_amount;
htlc_amount.millisatoshis = outs[i]->satoshi * 1000;
if (!amount_sat_to_msat(&htlc_amount, outs[i]->sat))
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Overflow in output %zu %s",
i,
type_to_string(tmpctx,
struct amount_sat,
&outs[i]->sat));
tx = htlc_success_tx(outs[i], &outs[i]->txid,
outs[i]->outnum,
htlc_amount,
@ -1346,7 +1385,11 @@ static size_t resolve_our_htlc_ourcommit(struct tracked_output *out,
size_t i;
struct amount_msat htlc_amount;
htlc_amount.millisatoshis = out->satoshi * 1000;
if (!amount_sat_to_msat(&htlc_amount, out->sat))
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Overflow in our_htlc output %s",
type_to_string(tmpctx, struct amount_sat,
&out->sat));
assert(tal_count(matches));
@ -1390,12 +1433,13 @@ static size_t resolve_our_htlc_ourcommit(struct tracked_output *out,
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"No valid signature found for %zu htlc_timeout_txs"
" feerate %u-%u,"
" last tx %s, inputamount %"PRIu64", signature %s,"
" last tx %s, input %s, signature %s,"
" cltvs %s wscripts %s",
tal_count(matches),
min_possible_feerate, max_possible_feerate,
type_to_string(tmpctx, struct bitcoin_tx, tx),
out->satoshi,
type_to_string(tmpctx, struct amount_sat,
&out->sat),
type_to_string(tmpctx, struct bitcoin_signature,
out->remote_htlc_sig),
cltvs, wscripts);
@ -1986,7 +2030,7 @@ static void handle_their_cheat(const struct bitcoin_tx *tx,
wire_sync_write(REQ_FD, towire_onchain_add_utxo(
tmpctx, txid, i,
remote_per_commitment_point,
tx->output[i].amount,
(struct amount_sat){tx->output[i].amount},
tx_blockheight));
continue;
}
@ -2198,7 +2242,7 @@ static void handle_their_unilateral(const struct bitcoin_tx *tx,
wire_sync_write(REQ_FD, towire_onchain_add_utxo(
tmpctx, txid, i,
remote_per_commitment_point,
tx->output[i].amount,
(struct amount_sat){tx->output[i].amount},
tx_blockheight));
continue;
}
@ -2327,7 +2371,7 @@ static void handle_unknown_commitment(const struct bitcoin_tx *tx,
wire_sync_write(REQ_FD, towire_onchain_add_utxo(
tmpctx, txid, i,
possible_remote_per_commitment_point,
tx->output[i].amount,
(struct amount_sat){tx->output[i].amount},
tx_blockheight));
to_us_output = i;
}
@ -2373,7 +2417,8 @@ int main(int argc, char *argv[])
struct tracked_output **outs;
struct bitcoin_txid our_broadcast_txid, txid;
secp256k1_ecdsa_signature *remote_htlc_sigs;
u64 funding_amount_satoshi, num_htlcs;
struct amount_sat funding;
u64 num_htlcs;
u8 *scriptpubkey[NUM_SIDES];
struct htlc_stub *htlcs;
bool *tell_if_missing, *tell_immediately;
@ -2389,13 +2434,13 @@ int main(int argc, char *argv[])
msg = wire_sync_read(tmpctx, REQ_FD);
if (!fromwire_onchain_init(tmpctx, msg,
&shachain,
&funding_amount_satoshi,
&funding,
&old_remote_per_commit_point,
&remote_per_commit_point,
&to_self_delay[LOCAL],
&to_self_delay[REMOTE],
&feerate_per_kw,
&dust_limit_satoshis,
&dust_limit,
&our_broadcast_txid,
&scriptpubkey[LOCAL],
&scriptpubkey[REMOTE],
@ -2414,6 +2459,7 @@ int main(int argc, char *argv[])
master_badmsg(WIRE_ONCHAIN_INIT, msg);
}
status_trace("feerate_per_kw = %u", feerate_per_kw);
bitcoin_txid(tx, &txid);
/* We need to keep tx around, but there's only one: not really a leak */
tal_steal(ctx, notleak(tx));
@ -2439,7 +2485,7 @@ int main(int argc, char *argv[])
0, /* We don't care about funding blockheight */
FUNDING_TRANSACTION,
tx->input[0].index,
funding_amount_satoshi,
funding.satoshis,
FUNDING_OUTPUT, NULL, NULL, NULL);
status_trace("Remote per-commit point: %s",

1
onchaind/test/Makefile

@ -7,6 +7,7 @@ ONCHAIND_TEST_OBJS := $(ONCHAIND_TEST_SRC:.c=.o)
ONCHAIND_TEST_PROGRAMS := $(ONCHAIND_TEST_OBJS:.o=)
ONCHAIND_TEST_COMMON_OBJS := \
common/amount.o \
common/features.o \
common/pseudorand.o \
common/type_to_string.o \

19
onchaind/test/run-grind_feerate.c

@ -40,7 +40,7 @@ bool fromwire_onchain_dev_memleak(const void *p UNNEEDED)
bool fromwire_onchain_htlc(const void *p UNNEEDED, struct htlc_stub *htlc UNNEEDED, bool *tell_if_missing UNNEEDED, bool *tell_immediately UNNEEDED)
{ fprintf(stderr, "fromwire_onchain_htlc called!\n"); abort(); }
/* Generated stub for fromwire_onchain_init */
bool fromwire_onchain_init(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct shachain *shachain UNNEEDED, u64 *funding_amount_satoshi UNNEEDED, struct pubkey *old_remote_per_commitment_point UNNEEDED, struct pubkey *remote_per_commitment_point UNNEEDED, u32 *local_to_self_delay UNNEEDED, u32 *remote_to_self_delay UNNEEDED, u32 *feerate_per_kw UNNEEDED, u64 *local_dust_limit_satoshi UNNEEDED, struct bitcoin_txid *our_broadcast_txid UNNEEDED, u8 **local_scriptpubkey UNNEEDED, u8 **remote_scriptpubkey UNNEEDED, struct pubkey *ourwallet_pubkey UNNEEDED, enum side *funder UNNEEDED, struct basepoints *local_basepoints UNNEEDED, struct basepoints *remote_basepoints UNNEEDED, struct bitcoin_tx **tx UNNEEDED, u32 *tx_blockheight UNNEEDED, u32 *reasonable_depth UNNEEDED, secp256k1_ecdsa_signature **htlc_signature UNNEEDED, u64 *num_htlcs UNNEEDED, u32 *min_possible_feerate UNNEEDED, u32 *max_possible_feerate UNNEEDED, struct pubkey **possible_remote_per_commit_point UNNEEDED)
bool fromwire_onchain_init(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct shachain *shachain UNNEEDED, struct amount_sat *funding_amount_satoshi UNNEEDED, struct pubkey *old_remote_per_commitment_point UNNEEDED, struct pubkey *remote_per_commitment_point UNNEEDED, u32 *local_to_self_delay UNNEEDED, u32 *remote_to_self_delay UNNEEDED, u32 *feerate_per_kw UNNEEDED, struct amount_sat *local_dust_limit_satoshi UNNEEDED, struct bitcoin_txid *our_broadcast_txid UNNEEDED, u8 **local_scriptpubkey UNNEEDED, u8 **remote_scriptpubkey UNNEEDED, struct pubkey *ourwallet_pubkey UNNEEDED, enum side *funder UNNEEDED, struct basepoints *local_basepoints UNNEEDED, struct basepoints *remote_basepoints UNNEEDED, struct bitcoin_tx **tx UNNEEDED, u32 *tx_blockheight UNNEEDED, u32 *reasonable_depth UNNEEDED, secp256k1_ecdsa_signature **htlc_signature UNNEEDED, u64 *num_htlcs UNNEEDED, u32 *min_possible_feerate UNNEEDED, u32 *max_possible_feerate UNNEEDED, struct pubkey **possible_remote_per_commit_point UNNEEDED)
{ fprintf(stderr, "fromwire_onchain_init called!\n"); abort(); }
/* Generated stub for fromwire_onchain_known_preimage */
bool fromwire_onchain_known_preimage(const void *p UNNEEDED, struct preimage *preimage UNNEEDED)
@ -112,19 +112,19 @@ u8 *to_self_wscript(const tal_t *ctx UNNEEDED,
u8 *towire_hsm_get_per_commitment_point(const tal_t *ctx UNNEEDED, u64 n UNNEEDED)
{ fprintf(stderr, "towire_hsm_get_per_commitment_point called!\n"); abort(); }
/* Generated stub for towire_hsm_sign_delayed_payment_to_us */
u8 *towire_hsm_sign_delayed_payment_to_us(const tal_t *ctx UNNEEDED, u64 commit_num UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const u8 *wscript UNNEEDED, u64 input_amount UNNEEDED)
u8 *towire_hsm_sign_delayed_payment_to_us(const tal_t *ctx UNNEEDED, u64 commit_num UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const u8 *wscript UNNEEDED, struct amount_sat input_amount UNNEEDED)
{ fprintf(stderr, "towire_hsm_sign_delayed_payment_to_us called!\n"); abort(); }
/* Generated stub for towire_hsm_sign_local_htlc_tx */
u8 *towire_hsm_sign_local_htlc_tx(const tal_t *ctx UNNEEDED, u64 commit_num UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const u8 *wscript UNNEEDED, u64 input_amount UNNEEDED)
u8 *towire_hsm_sign_local_htlc_tx(const tal_t *ctx UNNEEDED, u64 commit_num UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const u8 *wscript UNNEEDED, struct amount_sat input_amount UNNEEDED)
{ fprintf(stderr, "towire_hsm_sign_local_htlc_tx called!\n"); abort(); }
/* Generated stub for towire_hsm_sign_penalty_to_us */
u8 *towire_hsm_sign_penalty_to_us(const tal_t *ctx UNNEEDED, const struct secret *revocation_secret UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const u8 *wscript UNNEEDED, u64 input_amount UNNEEDED)
u8 *towire_hsm_sign_penalty_to_us(const tal_t *ctx UNNEEDED, const struct secret *revocation_secret UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const u8 *wscript UNNEEDED, struct amount_sat input_amount UNNEEDED)
{ fprintf(stderr, "towire_hsm_sign_penalty_to_us called!\n"); abort(); }
/* Generated stub for towire_hsm_sign_remote_htlc_to_us */
u8 *towire_hsm_sign_remote_htlc_to_us(const tal_t *ctx UNNEEDED, const struct pubkey *remote_per_commitment_point UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const u8 *wscript UNNEEDED, u64 input_amount UNNEEDED)
u8 *towire_hsm_sign_remote_htlc_to_us(const tal_t *ctx UNNEEDED, const struct pubkey *remote_per_commitment_point UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const u8 *wscript UNNEEDED, struct amount_sat input_amount UNNEEDED)
{ fprintf(stderr, "towire_hsm_sign_remote_htlc_to_us called!\n"); abort(); }
/* Generated stub for towire_onchain_add_utxo */
u8 *towire_onchain_add_utxo(const tal_t *ctx UNNEEDED, const struct bitcoin_txid *prev_out_tx UNNEEDED, u32 prev_out_index UNNEEDED, const struct pubkey *per_commit_point UNNEEDED, u64 value UNNEEDED, u32 blockheight UNNEEDED)
u8 *towire_onchain_add_utxo(const tal_t *ctx UNNEEDED, const struct bitcoin_txid *prev_out_tx UNNEEDED, u32 prev_out_index UNNEEDED, const struct pubkey *per_commit_point UNNEEDED, struct amount_sat value UNNEEDED, u32 blockheight UNNEEDED)
{ fprintf(stderr, "towire_onchain_add_utxo called!\n"); abort(); }
/* Generated stub for towire_onchain_all_irrevocably_resolved */
u8 *towire_onchain_all_irrevocably_resolved(const tal_t *ctx UNNEEDED)
@ -186,7 +186,7 @@ int main(int argc, char *argv[])
struct bitcoin_tx *tx;
struct bitcoin_signature sig;
u8 *der, *wscript;
u64 fee;
struct amount_sat fee;
struct pubkey htlc_key;
struct keyset *keys;
struct timeabs start, end;
@ -221,9 +221,10 @@ int main(int argc, char *argv[])
min_possible_feerate = max_possible_feerate + 1 - iterations;
start = time_now();
fee = grind_htlc_tx_fee(tx, &sig, wscript, 663);
if (!grind_htlc_tx_fee(&fee, tx, &sig, wscript, 663))
abort();
end = time_now();
assert(fee == 165750);
assert(amount_sat_eq(fee, AMOUNT_SAT(165750)));
printf("%u iterations in %"PRIu64" msec = %"PRIu64" nsec each\n",
iterations,
time_to_msec(time_between(end, start)),

16
openingd/opening_wire.csv

@ -9,7 +9,7 @@ opening_init,,chain_hash,struct bitcoin_blkid
opening_init,,our_config,struct channel_config
# Minimum/maximum configuration values we'll accept
opening_init,,max_to_self_delay,u32
opening_init,,min_effective_htlc_capacity_msat,u64
opening_init,,min_effective_htlc_capacity_msat,struct amount_msat
opening_init,,crypto_state,struct crypto_state
opening_init,,our_basepoints,struct basepoints
opening_init,,our_funding_pubkey,struct pubkey
@ -29,10 +29,10 @@ opening_can_accept_channel,6002
#include <common/htlc_wire.h>
# Master->openingd: please fund a channel.
opening_funder,6001
opening_funder,,funding_satoshis,u64
opening_funder,,push_msat,u64
opening_funder,,funding_satoshis,struct amount_sat
opening_funder,,push_msat,struct amount_msat
opening_funder,,feerate_per_kw,u32
opening_funder,,change_satoshis,u64
opening_funder,,change_satoshis,struct amount_sat
opening_funder,,change_keyindex,u32
opening_funder,,channel_flags,u8
#include <common/utxo.h>
@ -56,7 +56,7 @@ opening_funder_reply,,minimum_depth,u32
opening_funder_reply,,remote_fundingkey,struct pubkey
opening_funder_reply,,funding_txid,struct bitcoin_txid
opening_funder_reply,,feerate_per_kw,u32
opening_funder_reply,,our_channel_reserve_satoshis,u64
opening_funder_reply,,our_channel_reserve_satoshis,struct amount_sat
# Openingd->master: we failed to negotiation channel
opening_funder_failed,6004
@ -77,14 +77,14 @@ opening_fundee,,their_per_commit_point,struct pubkey
opening_fundee,,remote_fundingkey,struct pubkey
opening_fundee,,funding_txid,struct bitcoin_txid
opening_fundee,,funding_txout,u16
opening_fundee,,funding_satoshis,u64
opening_fundee,,push_msat,u64
opening_fundee,,funding_satoshis,struct amount_sat
opening_fundee,,push_msat,struct amount_msat
opening_fundee,,channel_flags,u8
opening_fundee,,feerate_per_kw,u32
# The funding signed message: send this and we're committed.
opening_fundee,,msglen,u16
opening_fundee,,funding_signed_msg,msglen*u8
opening_fundee,,our_channel_reserve_satoshis,u64
opening_fundee,,our_channel_reserve_satoshis,struct amount_sat
# master -> openingd: do you have a memleak?
opening_dev_memleak,6033

Can't render this file because it has a wrong number of fields in line 5.

20
openingd/openingd.c

@ -686,7 +686,7 @@ static u8 *funder_channel(struct state *state,
msg = towire_hsm_sign_remote_commitment_tx(NULL,
tx,
&state->channel->funding_pubkey[REMOTE],
state->channel->funding.satoshis);
state->channel->funding);
wire_sync_write(HSM_FD, take(msg));
msg = wire_sync_read(tmpctx, HSM_FD);
@ -822,7 +822,7 @@ static u8 *funder_channel(struct state *state,
&their_funding_pubkey,
&state->funding_txid,
state->feerate_per_kw,
state->localconf.channel_reserve.satoshis);
state->localconf.channel_reserve);
fail:
if (taken(utxos))
@ -1139,7 +1139,7 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg)
msg = towire_hsm_sign_remote_commitment_tx(NULL,
remote_commit,
&state->channel->funding_pubkey[REMOTE],
state->channel->funding.satoshis);
state->channel->funding);
wire_sync_write(HSM_FD, take(msg));
msg = wire_sync_read(tmpctx, HSM_FD);
@ -1165,12 +1165,12 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg)
&their_funding_pubkey,
&state->funding_txid,
state->funding_txout,
state->funding.satoshis,
state->push_msat.millisatoshis,
state->funding,
state->push_msat,
channel_flags,
state->feerate_per_kw,
msg,
state->localconf.channel_reserve.satoshis);
state->localconf.channel_reserve);
}
/*~ Standard "peer sent a message, handle it" demuxer. Though it really only
@ -1307,10 +1307,10 @@ static u8 *handle_master_in(struct state *state)
switch (t) {
case WIRE_OPENING_FUNDER:
if (!fromwire_opening_funder(state, msg,
&state->funding.satoshis,
&state->push_msat.millisatoshis,
&state->funding,
&state->push_msat,
&state->feerate_per_kw,
&change.satoshis,
&change,
&change_keyindex,
&channel_flags, &utxos,
&bip32_base))
@ -1367,7 +1367,7 @@ int main(int argc, char *argv[])
&chain_hash,
&state->localconf,
&state->max_to_self_delay,
&state->min_effective_htlc_capacity.millisatoshis,
&state->min_effective_htlc_capacity,
&state->cs,
&state->our_points,
&state->our_funding_pubkey,

1
wallet/test/Makefile

@ -3,6 +3,7 @@ WALLET_TEST_OBJS := $(WALLET_TEST_SRC:.c=.o)
WALLET_TEST_PROGRAMS := $(WALLET_TEST_OBJS:.o=)
WALLET_TEST_COMMON_OBJS := \
common/amount.o \
common/base32.o \
common/derive_basepoints.o \
common/htlc_state.o \

19
wallet/test/run-wallet.c

@ -30,15 +30,6 @@ static void db_log_(struct log *log UNUSED, enum log_level level UNUSED, const c
bool deprecated_apis = true;
/* AUTOGENERATED MOCKS START */
/* Generated stub for amount_msat_sub_sat */
bool amount_msat_sub_sat(struct amount_msat *val UNNEEDED,
struct amount_msat a UNNEEDED,
struct amount_sat b UNNEEDED)
{ fprintf(stderr, "amount_msat_sub_sat called!\n"); abort(); }
/* Generated stub for amount_sat_to_msat */
bool amount_sat_to_msat(struct amount_msat *msat UNNEEDED,
struct amount_sat sat UNNEEDED)
{ fprintf(stderr, "amount_sat_to_msat called!\n"); abort(); }
/* Generated stub for bitcoind_gettxout */
void bitcoind_gettxout(struct bitcoind *bitcoind UNNEEDED,
const struct bitcoin_txid *txid UNNEEDED, const u32 outnum UNNEEDED,
@ -493,7 +484,7 @@ u8 *towire_channel_got_commitsig_reply(const tal_t *ctx UNNEEDED)
u8 *towire_channel_got_revoke_reply(const tal_t *ctx UNNEEDED)
{ fprintf(stderr, "towire_channel_got_revoke_reply called!\n"); abort(); }
/* Generated stub for towire_channel_offer_htlc */
u8 *towire_channel_offer_htlc(const tal_t *ctx UNNEEDED, u64 amount_msat UNNEEDED, u32 cltv_expiry UNNEEDED, const struct sha256 *payment_hash UNNEEDED, const u8 onion_routing_packet[1366])
u8 *towire_channel_offer_htlc(const tal_t *ctx UNNEEDED, struct amount_msat amount_msat UNNEEDED, u32 cltv_expiry UNNEEDED, const struct sha256 *payment_hash UNNEEDED, const u8 onion_routing_packet[1366])
{ fprintf(stderr, "towire_channel_offer_htlc called!\n"); abort(); }
/* Generated stub for towire_channel_sending_commitsig_reply */
u8 *towire_channel_sending_commitsig_reply(const tal_t *ctx UNNEEDED)
@ -516,7 +507,7 @@ u8 *towire_errorfmt(const tal_t *ctx UNNEEDED,
u8 *towire_gossip_get_channel_peer(const tal_t *ctx UNNEEDED, const struct short_channel_id *channel_id UNNEEDED)
{ fprintf(stderr, "towire_gossip_get_channel_peer called!\n"); abort(); }
/* Generated stub for towire_hsm_sign_commitment_tx */
u8 *towire_hsm_sign_commitment_tx(const tal_t *ctx UNNEEDED, const struct pubkey *peer_id UNNEEDED, u64 channel_dbid UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const struct pubkey *remote_funding_key UNNEEDED, u64 funding_amount UNNEEDED)
u8 *towire_hsm_sign_commitment_tx(const tal_t *ctx UNNEEDED, const struct pubkey *peer_id UNNEEDED, u64 channel_dbid UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const struct pubkey *remote_funding_key UNNEEDED, struct amount_sat funding_amount UNNEEDED)
{ fprintf(stderr, "towire_hsm_sign_commitment_tx called!\n"); abort(); }
/* Generated stub for towire_onchain_dev_memleak */
u8 *towire_onchain_dev_memleak(const tal_t *ctx UNNEEDED)
@ -821,7 +812,7 @@ static bool channelseq(struct channel *c1, struct channel *c2)
CHECK_MSG(pubkey_eq(&p1->id, &p2->id), "NodeIDs do not match");
CHECK((c1->scid == NULL && c2->scid == NULL)
|| short_channel_id_eq(c1->scid, c2->scid));
CHECK(c1->our_msatoshi == c2->our_msatoshi);
CHECK(amount_msat_eq(c1->our_msat, c2->our_msat));
CHECK((c1->remote_shutdown_scriptpubkey == NULL && c2->remote_shutdown_scriptpubkey == NULL) || memeq(
c1->remote_shutdown_scriptpubkey,
tal_count(c1->remote_shutdown_scriptpubkey),
@ -1040,12 +1031,12 @@ static bool test_htlc_crud(struct lightningd *ld, const tal_t *ctx)
memset(&payment_key, 'B', sizeof(payment_key));
in.key.id = 42;
in.key.channel = chan;
in.msatoshi = 42;
in.msat = AMOUNT_MSAT(42);
out.in = &in;
out.key.id = 1337;
out.key.channel = chan;
out.msatoshi = 41;
out.msat = AMOUNT_MSAT(41);
/* Store the htlc_in */
CHECK_MSG(transaction_wrap(w->db, wallet_htlc_save_in(w, chan, &in)),

62
wallet/wallet.c

@ -680,13 +680,13 @@ static struct channel *wallet_stmt2channel(const tal_t *ctx, struct wallet *w, s
sqlite3_column_int64(stmt, 11),
&funding_txid,
sqlite3_column_int(stmt, 13),
sqlite3_column_int64(stmt, 14),
sqlite3_column_int64(stmt, 16),
sqlite3_column_amount_sat(stmt, 14),
sqlite3_column_amount_msat(stmt, 16),
sqlite3_column_int(stmt, 15) != 0,
scid,
sqlite3_column_int64(stmt, 17),
sqlite3_column_int64(stmt, 38), /* msatoshi_to_us_min */
sqlite3_column_int64(stmt, 39), /* msatoshi_to_us_max */
sqlite3_column_amount_msat(stmt, 17),
sqlite3_column_amount_msat(stmt, 38), /* msatoshi_to_us_min */
sqlite3_column_amount_msat(stmt, 39), /* msatoshi_to_us_max */
sqlite3_column_tx(tmpctx, stmt, 32),
&last_sig,
wallet_htlc_sigs_load(tmpctx, w,
@ -761,7 +761,7 @@ void wallet_channel_stats_incr_x(struct wallet *w,
char const *dir,
char const *typ,
u64 cdbid,
u64 msatoshi)
struct amount_msat msat)
{
char const *payments_stat = tal_fmt(tmpctx, "%s_payments_%s",
dir, typ);
@ -773,24 +773,28 @@ void wallet_channel_stats_incr_x(struct wallet *w,
" , %s = COALESCE(%s, 0) + %"PRIu64""
" WHERE id = %"PRIu64";",
payments_stat, payments_stat,
msatoshi_stat, msatoshi_stat, msatoshi,
msatoshi_stat, msatoshi_stat, msat.millisatoshis,
cdbid);
sqlite3_stmt *stmt = db_prepare(w->db, qry);
db_exec_prepared(w->db, stmt);
}
void wallet_channel_stats_incr_in_offered(struct wallet *w, u64 id, u64 m)
void wallet_channel_stats_incr_in_offered(struct wallet *w, u64 id,
struct amount_msat m)
{
wallet_channel_stats_incr_x(w, "in", "offered", id, m);
}
void wallet_channel_stats_incr_in_fulfilled(struct wallet *w, u64 id, u64 m)
void wallet_channel_stats_incr_in_fulfilled(struct wallet *w, u64 id,
struct amount_msat m)
{
wallet_channel_stats_incr_x(w, "in", "fulfilled", id, m);
}
void wallet_channel_stats_incr_out_offered(struct wallet *w, u64 id, u64 m)
void wallet_channel_stats_incr_out_offered(struct wallet *w, u64 id,
struct amount_msat m)
{
wallet_channel_stats_incr_x(w, "out", "offered", id, m);
}
void wallet_channel_stats_incr_out_fulfilled(struct wallet *w, u64 id, u64 m)
void wallet_channel_stats_incr_out_fulfilled(struct wallet *w, u64 id,
struct amount_msat m)
{
wallet_channel_stats_incr_x(w, "out", "fulfilled", id, m);
}
@ -817,12 +821,12 @@ void wallet_channel_stats_load(struct wallet *w,
stats->in_payments_offered = sqlite3_column_int64(stmt, 0);
stats->in_payments_fulfilled = sqlite3_column_int64(stmt, 1);
stats->in_msatoshi_offered = sqlite3_column_int64(stmt, 2);
stats->in_msatoshi_fulfilled = sqlite3_column_int64(stmt, 3);
stats->in_msatoshi_offered = sqlite3_column_amount_msat(stmt, 2);
stats->in_msatoshi_fulfilled = sqlite3_column_amount_msat(stmt, 3);
stats->out_payments_offered = sqlite3_column_int64(stmt, 4);
stats->out_payments_fulfilled = sqlite3_column_int64(stmt, 5);
stats->out_msatoshi_offered = sqlite3_column_int64(stmt, 6);
stats->out_msatoshi_fulfilled = sqlite3_column_int64(stmt, 7);
stats->out_msatoshi_offered = sqlite3_column_amount_msat(stmt, 6);
stats->out_msatoshi_fulfilled = sqlite3_column_amount_msat(stmt, 7);
db_stmt_done(stmt);
}
@ -960,10 +964,10 @@ void wallet_channel_save(struct wallet *w, struct channel *chan)
sqlite3_bind_sha256_double(stmt, 10, &chan->funding_txid.shad);
sqlite3_bind_int(stmt, 11, chan->funding_outnum);
sqlite3_bind_int64(stmt, 12, chan->funding_satoshi);
sqlite3_bind_amount_sat(stmt, 12, chan->funding);
sqlite3_bind_int(stmt, 13, chan->remote_funding_locked);
sqlite3_bind_int64(stmt, 14, chan->push_msat);
sqlite3_bind_int64(stmt, 15, chan->our_msatoshi);
sqlite3_bind_amount_msat(stmt, 14, chan->push);
sqlite3_bind_amount_msat(stmt, 15, chan->our_msat);
if (chan->remote_shutdown_scriptpubkey)
sqlite3_bind_blob(stmt, 16, chan->remote_shutdown_scriptpubkey,
@ -979,8 +983,8 @@ void wallet_channel_save(struct wallet *w, struct channel *chan)
sqlite3_bind_int(stmt, 21, chan->last_was_revoke);
sqlite3_bind_int(stmt, 22, chan->min_possible_feerate);
sqlite3_bind_int(stmt, 23, chan->max_possible_feerate);
sqlite3_bind_int64(stmt, 24, chan->msatoshi_to_us_min);
sqlite3_bind_int64(stmt, 25, chan->msatoshi_to_us_max);
sqlite3_bind_amount_msat(stmt, 24, chan->msat_to_us_min);
sqlite3_bind_amount_msat(stmt, 25, chan->msat_to_us_max);
sqlite3_bind_int64(stmt, 26, chan->dbid);
db_exec_prepared(w->db, stmt);
@ -1181,7 +1185,7 @@ void wallet_htlc_save_in(struct wallet *wallet,
sqlite3_bind_int64(stmt, 1, chan->dbid);
sqlite3_bind_int64(stmt, 2, in->key.id);
sqlite3_bind_int(stmt, 3, DIRECTION_INCOMING);
sqlite3_bind_int64(stmt, 4, in->msatoshi);
sqlite3_bind_amount_msat(stmt, 4, in->msat);
sqlite3_bind_int(stmt, 5, in->cltv_expiry);
sqlite3_bind_sha256(stmt, 6, &in->payment_hash);
@ -1236,7 +1240,7 @@ void wallet_htlc_save_out(struct wallet *wallet,
sqlite3_bind_int64(stmt, 4, out->in->dbid);
else
sqlite3_bind_null(stmt, 4);
sqlite3_bind_int64(stmt, 5, out->msatoshi);
sqlite3_bind_amount_msat(stmt, 5, out->msat);
sqlite3_bind_int(stmt, 6, out->cltv_expiry);
sqlite3_bind_sha256(stmt, 7, &out->payment_hash);
@ -1302,7 +1306,7 @@ static bool wallet_stmt2htlc_in(struct channel *channel,
in->dbid = sqlite3_column_int64(stmt, 0);
in->key.id = sqlite3_column_int64(stmt, 1);
in->key.channel = channel;
in->msatoshi = sqlite3_column_int64(stmt, 2);
in->msat = sqlite3_column_amount_msat(stmt, 2);
in->cltv_expiry = sqlite3_column_int(stmt, 3);
in->hstate = sqlite3_column_int(stmt, 4);
@ -1345,7 +1349,7 @@ static bool wallet_stmt2htlc_out(struct channel *channel,
out->dbid = sqlite3_column_int64(stmt, 0);
out->key.id = sqlite3_column_int64(stmt, 1);
out->key.channel = channel;
out->msatoshi = sqlite3_column_int64(stmt, 2);
out->msat = sqlite3_column_amount_msat(stmt, 2);
out->cltv_expiry = sqlite3_column_int(stmt, 3);
out->hstate = sqlite3_column_int(stmt, 4);
sqlite3_column_sha256(stmt, 5, &out->payment_hash);
@ -1405,12 +1409,12 @@ static void fixup_hin(struct wallet *wallet, struct htlc_in *hin)
hin->failcode = WIRE_TEMPORARY_NODE_FAILURE;
log_broken(wallet->log, "HTLC #%"PRIu64" (%s) "
" for amount %"PRIu64
" for amount %s"
" from %s"
" is missing a resolution:"
" subsituting temporary node failure",
hin->key.id, htlc_state_name(hin->hstate),
hin->msatoshi,
type_to_string(tmpctx, struct amount_msat, &hin->msat),
type_to_string(tmpctx, struct pubkey,
&hin->key.channel->peer->id));
#endif
@ -2240,7 +2244,7 @@ struct outpoint *wallet_outpoint_for_scid(struct wallet *w, tal_t *ctx,
op->spendheight = sqlite3_column_int(stmt, 1);
op->scriptpubkey = tal_arr(op, u8, sqlite3_column_bytes(stmt, 2));
memcpy(op->scriptpubkey, sqlite3_column_blob(stmt, 2), sqlite3_column_bytes(stmt, 2));
op->satoshis = sqlite3_column_int64(stmt, 3);
op->sat = sqlite3_column_amount_sat(stmt, 3);
db_stmt_done(stmt);
return op;
@ -2450,8 +2454,8 @@ void wallet_forwarded_payment_add(struct wallet *w, const struct htlc_in *in,
sqlite3_bind_int64(stmt, 2, out->dbid);
sqlite3_bind_int64(stmt, 3, in->key.channel->scid->u64);
sqlite3_bind_int64(stmt, 4, out->key.channel->scid->u64);
sqlite3_bind_int64(stmt, 5, in->msatoshi);
sqlite3_bind_int64(stmt, 6, out->msatoshi);
sqlite3_bind_amount_msat(stmt, 5, in->msat);
sqlite3_bind_amount_msat(stmt, 6, out->msat);
sqlite3_bind_int(stmt, 7, wallet_forward_status_in_db(state));
db_exec_prepared(w->db, stmt);
}

14
wallet/wallet.h

@ -234,7 +234,7 @@ struct outpoint {
u32 blockheight;
u32 txindex;
u32 outnum;
u64 satoshis;
struct amount_sat sat;
u8 *scriptpubkey;
u32 spendheight;
};
@ -242,9 +242,9 @@ struct outpoint {
/* Statistics for a channel */
struct channel_stats {
u64 in_payments_offered, in_payments_fulfilled;
u64 in_msatoshi_offered, in_msatoshi_fulfilled;
struct amount_msat in_msatoshi_offered, in_msatoshi_fulfilled;
u64 out_payments_offered, out_payments_fulfilled;
u64 out_msatoshi_offered, out_msatoshi_fulfilled;
struct amount_msat out_msatoshi_offered, out_msatoshi_fulfilled;
};
struct channeltx {
@ -435,10 +435,10 @@ bool wallet_channels_load_active(const tal_t *ctx, struct wallet *w);
* @cdbid: channel database id
* @msatoshi: amount in msatoshi being transferred
*/
void wallet_channel_stats_incr_in_offered(struct wallet *w, u64 cdbid, u64 msatoshi);
void wallet_channel_stats_incr_in_fulfilled(struct wallet *w, u64 cdbid, u64 msatoshi);
void wallet_channel_stats_incr_out_offered(struct wallet *w, u64 cdbid, u64 msatoshi);
void wallet_channel_stats_incr_out_fulfilled(struct wallet *w, u64 cdbid, u64 msatoshi);
void wallet_channel_stats_incr_in_offered(struct wallet *w, u64 cdbid, struct amount_msat msatoshi);
void wallet_channel_stats_incr_in_fulfilled(struct wallet *w, u64 cdbid, struct amount_msat msatoshi);
void wallet_channel_stats_incr_out_offered(struct wallet *w, u64 cdbid, struct amount_msat msatoshi);
void wallet_channel_stats_incr_out_fulfilled(struct wallet *w, u64 cdbid, struct amount_msat msatoshi);
/**
* wallet_channel_stats_load - Load channel statistics

9
wallet/walletrpc.c

@ -156,8 +156,8 @@ static struct command_result *json_withdraw(struct command *cmd,
txfilter_add_derkey(cmd->ld->owned_txfilter, ext.pub_key);
u8 *msg = towire_hsm_sign_withdrawal(cmd,
withdraw->wtx.amount.satoshis,
withdraw->wtx.change.satoshis,
withdraw->wtx.amount,
withdraw->wtx.change,
withdraw->wtx.change_key_index,
withdraw->destination,
withdraw->wtx.utxos);
@ -463,10 +463,9 @@ static struct command_result *json_listfunds(struct command *cmd,
c->scid);
json_add_amount_sat(response,
amount_msat_to_sat_round_down((struct amount_msat){c->our_msatoshi}),
amount_msat_to_sat_round_down(c->our_msat),
"channel_sat", "our_amount_msat");
json_add_amount_sat(response,
(struct amount_sat){c->funding_satoshi},
json_add_amount_sat(response, c->funding,
"channel_total_sat", "amount_msat");
json_add_txid(response, "funding_txid",
&c->funding_txid);

Loading…
Cancel
Save