diff --git a/channeld/channel_wire.csv b/channeld/channel_wire.csv index 8c0fdb80b142..2cc52657502f 100644 --- a/channeld/channel_wire.csv +++ b/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 diff --git a/channeld/channeld.c b/channeld/channeld.c index 0291f979243f..9d429e4b4906 100644 --- a/channeld/channeld.c +++ b/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], diff --git a/channeld/full_channel.c b/channeld/full_channel.c index 94eb10eda0c9..50333aebcb4c 100644 --- a/channeld/full_channel.c +++ b/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); diff --git a/closingd/closing_wire.csv b/closingd/closing_wire.csv index 43abd60810a5..623476d52daf 100644 --- a/closingd/closing_wire.csv +++ b/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 diff --git a/closingd/closingd.c b/closingd/closingd.c index c4761821d3bb..e3d9417aede6 100644 --- a/closingd/closingd.c +++ b/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); } diff --git a/common/close_tx.c b/common/close_tx.c index 6525c9b88ef4..56e3e081c322 100644 --- a/common/close_tx.c +++ b/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); diff --git a/common/close_tx.h b/common/close_tx.h index 078fe4e4dc9a..9db1eed19bc6 100644 --- a/common/close_tx.h +++ b/common/close_tx.h @@ -3,6 +3,7 @@ #include "config.h" #include #include +#include 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 */ diff --git a/common/htlc_wire.c b/common/htlc_wire.c index 529baf8490f3..58d0922c289a 100644 --- a/common/htlc_wire.c +++ b/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, diff --git a/common/htlc_wire.h b/common/htlc_wire.h index f0c5a0cce709..5841ea61b95a 100644 --- a/common/htlc_wire.h +++ b/common/htlc_wire.h @@ -3,6 +3,7 @@ #include "config.h" #include #include +#include #include #include #include @@ -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]; diff --git a/common/sphinx.c b/common/sphinx.c index 62043902a6a1..61288809d832 100644 --- a/common/sphinx.c +++ b/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); diff --git a/common/sphinx.h b/common/sphinx.h index 8bca1dff4220..e1f6fb5a5178 100644 --- a/common/sphinx.h +++ b/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]; diff --git a/common/test/run-sphinx.c b/common/test/run-sphinx.c index 72a9d7b566fb..c4d6c2cd5cf4 100644 --- a/common/test/run-sphinx.c +++ b/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(); } diff --git a/devtools/dump-gossipstore.c b/devtools/dump-gossipstore.c index 7604ce17fce3..4e86a866f6d0 100644 --- a/devtools/dump-gossipstore.c +++ b/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", diff --git a/devtools/onion.c b/devtools/onion.c index 33f9e0ed0e86..2707b015fef2 100644 --- a/devtools/onion.c +++ b/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]))); } diff --git a/gossipd/gossip_peerd_wire.csv b/gossipd/gossip_peerd_wire.csv index d4460be7b2f3..ec3844e37989 100644 --- a/gossipd/gossip_peerd_wire.csv +++ b/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 diff --git a/gossipd/gossip_store.c b/gossipd/gossip_store.c index eba7fbcc3dfa..b791a0828e7c 100644 --- a/gossipd/gossip_store.c +++ b/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; diff --git a/gossipd/gossip_store.csv b/gossipd/gossip_store.csv index f10fb09a6a97..6b8a260f4d3f 100644 --- a/gossipd/gossip_store.csv +++ b/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 \ No newline at end of file +gossip_store_local_add_channel,,local_add,len*u8 diff --git a/gossipd/gossip_wire.csv b/gossipd/gossip_wire.csv index e86f1260ec83..a9b86522562f 100644 --- a/gossipd/gossip_wire.csv +++ b/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 diff --git a/gossipd/gossipd.c b/gossipd/gossipd.c index 556e12aedd3f..cbd028d6ffc9 100644 --- a/gossipd/gossipd.c +++ b/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 @@ static bool handle_get_update(struct peer *peer, const u8 *msg) * 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) */ diff --git a/gossipd/routing.c b/gossipd/routing.c index 26516b8aaa7e..446a6aea35fe 100644 --- a/gossipd/routing.c +++ b/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, ×tamp, &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, ×tamp, &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; } diff --git a/gossipd/routing.h b/gossipd/routing.h index 05744d702921..2fb5d73aee30 100644 --- a/gossipd/routing.h +++ b/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 diff --git a/gossipd/test/Makefile b/gossipd/test/Makefile index 04b14dad07c2..a3d76a9512f9 100644 --- a/gossipd/test/Makefile +++ b/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 \ diff --git a/gossipd/test/run-bench-find_route.c b/gossipd/test/run-bench-find_route.c index 418d45a657a6..db18e01f2103 100644 --- a/gossipd/test/run-bench-find_route.c +++ b/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, diff --git a/gossipd/test/run-find_route-specific.c b/gossipd/test/run-find_route-specific.c index c27cc769e144..a972af193fc3 100644 --- a/gossipd/test/run-find_route-specific.c +++ b/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); diff --git a/gossipd/test/run-find_route.c b/gossipd/test/run-find_route.c index ea8becbee060..f91b419f2d79 100644 --- a/gossipd/test/run-find_route.c +++ b/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); diff --git a/hsmd/hsm_wire.csv b/hsmd/hsm_wire.csv index 357f2ba5e692..88f523d910a2 100644 --- a/hsmd/hsm_wire.csv +++ b/hsmd/hsm_wire.csv @@ -37,8 +37,8 @@ hsm_get_channel_basepoints_reply,,funding_pubkey,struct pubkey #include # 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 diff --git a/hsmd/hsmd.c b/hsmd/hsmd.c index b39f9de91e6c..e08a8411bc12 100644 --- a/hsmd/hsmd.c +++ b/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); diff --git a/lightningd/channel.c b/lightningd/channel.c index 3d85c527bb0e..d429fb1685bb 100644 --- a/lightningd/channel.c +++ b/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); diff --git a/lightningd/channel.h b/lightningd/channel.h index 09759c9dfae1..fb5b6176dc39 100644 --- a/lightningd/channel.h +++ b/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, diff --git a/lightningd/channel_control.c b/lightningd/channel_control.c index 8e3e0b932635..98dcba45be14 100644 --- a/lightningd/channel_control.c +++ b/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, diff --git a/lightningd/closing_control.c b/lightningd/closing_control.c index a0a0e07c225e..2504d46b0598 100644 --- a/lightningd/closing_control.c +++ b/lightningd/closing_control.c @@ -17,6 +17,19 @@ #include #include +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), diff --git a/lightningd/gossip_control.c b/lightningd/gossip_control.c index 657627891063..19cd9dab885d 100644 --- a/lightningd/gossip_control.c +++ b/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); diff --git a/lightningd/gossip_msg.c b/lightningd/gossip_msg.c index 2d5ab6dec961..e9c6935cc416 100644 --- a/lightningd/gossip_msg.c +++ b/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); diff --git a/lightningd/gossip_msg.h b/lightningd/gossip_msg.h index a9de59961c5a..35c197ecc5be 100644 --- a/lightningd/gossip_msg.h +++ b/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; diff --git a/lightningd/htlc_end.c b/lightningd/htlc_end.c index 25499ad9625e..9bd5949146a9 100644 --- a/lightningd/htlc_end.c +++ b/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, diff --git a/lightningd/htlc_end.h b/lightningd/htlc_end.h index 128493632a8c..558924f28304 100644 --- a/lightningd/htlc_end.h +++ b/lightningd/htlc_end.h @@ -3,6 +3,7 @@ #include "config.h" #include #include +#include #include #include #include @@ -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, diff --git a/lightningd/invoice.c b/lightningd/invoice.c index d67ffc4cd6fe..63f066431c7d 100644 --- a/lightningd/invoice.c +++ b/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); diff --git a/lightningd/onchain_control.c b/lightningd/onchain_control.c index c0a2f9e4a1e9..e3f6522972f7 100644 --- a/lightningd/onchain_control.c +++ b/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), diff --git a/lightningd/opening_control.c b/lightningd/opening_control.c index abfb3de14277..647fe102f0b2 100644 --- a/lightningd/opening_control.c +++ b/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, diff --git a/lightningd/pay.c b/lightningd/pay.c index c1b4b98f83d5..4ffcdddc6327 100644 --- a/lightningd/pay.c +++ b/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) { diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 437a340cbcfa..2ddc78843dec 100644 --- a/lightningd/peer_control.c +++ b/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"); diff --git a/lightningd/peer_htlcs.c b/lightningd/peer_htlcs.c index 019a4bcc3e02..b0d00a1017a8 100644 --- a/lightningd/peer_htlcs.c +++ b/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 @@ static void forward_htlc(struct htlc_in *hin, /* 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); diff --git a/lightningd/peer_htlcs.h b/lightningd/peer_htlcs.h index 6f3ad3646e2b..27f601b864ac 100644 --- a/lightningd/peer_htlcs.h +++ b/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, diff --git a/lightningd/test/Makefile b/lightningd/test/Makefile index f0b7c3504d84..17e2fc5392b6 100644 --- a/lightningd/test/Makefile +++ b/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 \ diff --git a/lightningd/test/run-invoice-select-inchan.c b/lightningd/test/run-invoice-select-inchan.c index 5dfce1f308c4..02d16450f5b7 100644 --- a/lightningd/test/run-invoice-select-inchan.c +++ b/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. */ diff --git a/lightningd/test/run-jsonrpc.c b/lightningd/test/run-jsonrpc.c index e68d1aa87473..6ebe3e8e4951 100644 --- a/lightningd/test/run-jsonrpc.c +++ b/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(); } diff --git a/onchaind/onchain_wire.csv b/onchaind/onchain_wire.csv index ac97561cd9d7..acb46047042b 100644 --- a/onchaind/onchain_wire.csv +++ b/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? diff --git a/onchaind/onchaind.c b/onchaind/onchaind.c index 8879d28d1eb0..eb071120a988 100644 --- a/onchaind/onchaind.c +++ b/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", diff --git a/onchaind/test/Makefile b/onchaind/test/Makefile index 86b4e71d9d39..c487946df1cc 100644 --- a/onchaind/test/Makefile +++ b/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 \ diff --git a/onchaind/test/run-grind_feerate.c b/onchaind/test/run-grind_feerate.c index 8b97bbaad165..5d28ac6edc14 100644 --- a/onchaind/test/run-grind_feerate.c +++ b/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)), diff --git a/openingd/opening_wire.csv b/openingd/opening_wire.csv index c9e05d74749b..6e8a30fb3218 100644 --- a/openingd/opening_wire.csv +++ b/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 # 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 @@ -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 diff --git a/openingd/openingd.c b/openingd/openingd.c index 9a58975877e1..e50251b5b12f 100644 --- a/openingd/openingd.c +++ b/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, diff --git a/wallet/test/Makefile b/wallet/test/Makefile index e33af34824bd..ba17897ec2cb 100644 --- a/wallet/test/Makefile +++ b/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 \ diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index 6175c8fcac95..9f63f7887151 100644 --- a/wallet/test/run-wallet.c +++ b/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 = ∈ 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)), diff --git a/wallet/wallet.c b/wallet/wallet.c index 54650ede00b8..2a91abd624a4 100644 --- a/wallet/wallet.c +++ b/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); } diff --git a/wallet/wallet.h b/wallet/wallet.h index 2ee03a23a727..b6bb0dbf7fe6 100644 --- a/wallet/wallet.h +++ b/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 diff --git a/wallet/walletrpc.c b/wallet/walletrpc.c index be1b91efe449..7b9b85255994 100644 --- a/wallet/walletrpc.c +++ b/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);