mirror of
https://github.com/ElementsProject/lightning.git
synced 2026-08-13 12:32:55 +02:00
global: more missing BOLT quotes.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
a7abb0a2e1
commit
c6f18ff705
21 changed files with 227 additions and 13 deletions
|
|
@ -658,9 +658,21 @@ static void handle_peer_add_htlc(struct peer *peer, const u8 *msg)
|
|||
"Bad peer_add_htlc %s", tal_hex(msg, msg));
|
||||
}
|
||||
|
||||
/* BOLT #2:
|
||||
* - if the sender did not previously acknowledge the commitment of that HTLC:
|
||||
* - MUST ignore a repeated `id` value after a reconnection.
|
||||
*/
|
||||
/* We do this is a subtle way: we only save the HTLC to the db once we
|
||||
* have received commitment_signed, which is when we send the
|
||||
* acknowledgement. So if we disconnect, we restart channeld which
|
||||
* doesn't know about the HTLC, thus rexmits are fine.
|
||||
*
|
||||
* If we got the commitment_signed, we increment the reestablish fields
|
||||
* so they know not to send it again. */
|
||||
/* BOLT #2:
|
||||
* - MUST allow multiple HTLCs with the same `payment_hash`.
|
||||
*/
|
||||
/* We do: the key is the id, not the payment_hash */
|
||||
add_err = channel_add_htlc(peer->channel, REMOTE, id, amount,
|
||||
cltv_expiry, &payment_hash,
|
||||
onion_routing_packet,
|
||||
|
|
|
|||
|
|
@ -59,6 +59,15 @@ static struct bitcoin_tx *close_tx(const tal_t *ctx,
|
|||
struct bitcoin_tx *tx;
|
||||
struct amount_sat out_minus_fee[NUM_SIDES];
|
||||
|
||||
/* BOLT #3:
|
||||
* ## Legacy Closing Transaction
|
||||
*...
|
||||
* ### Requirements
|
||||
*
|
||||
* Each node offering a signature:
|
||||
*...
|
||||
* - MUST subtract the fee given by `fee_satoshis` from the output to the funder.
|
||||
*/
|
||||
out_minus_fee[LOCAL] = out[LOCAL];
|
||||
out_minus_fee[REMOTE] = out[REMOTE];
|
||||
if (!amount_sat_sub(&out_minus_fee[opener], out[opener], fee))
|
||||
|
|
|
|||
|
|
@ -105,6 +105,17 @@ fail:
|
|||
return false;
|
||||
}
|
||||
|
||||
/* BOLT #12:
|
||||
* # Encoding
|
||||
*...
|
||||
* ## Requirements
|
||||
* Writers of a bolt12 string:
|
||||
* - MUST either use all lowercase or all UPPERCASE.
|
||||
* - SHOULD use uppercase for QR codes.
|
||||
* - SHOULD use lower case otherwise.
|
||||
* - MAY use `+`, optionally followed by whitespace, to separate large bolt12 strings.
|
||||
*/
|
||||
/* We use lower case, and we leave it to the caller to upcase (and +-break) if it wants */
|
||||
char *to_bech32_charset(const tal_t *ctx,
|
||||
const char *hrp, const u8 *data)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1407,6 +1407,13 @@ char *bolt11_encode_(const tal_t *ctx,
|
|||
|
||||
bech32_push_bits(&data, sig_and_recid, sizeof(sig_and_recid) * CHAR_BIT);
|
||||
|
||||
/* BOLT #11:
|
||||
* A writer:
|
||||
* - MUST encode the payment request in Bech32 (see BIP-0173)
|
||||
* - SHOULD use upper case for QR codes (see BIP-0173)
|
||||
* - MAY exceed the 90-character limit specified in BIP-0173.
|
||||
*/
|
||||
/* We let the user upcase if they want */
|
||||
output = tal_arr(ctx, char, strlen(hrp) + tal_count(data) + 8);
|
||||
if (!bech32_encode(output, hrp, data, tal_count(data), (size_t)-1,
|
||||
BECH32_ENCODING_BECH32))
|
||||
|
|
|
|||
|
|
@ -6,6 +6,15 @@
|
|||
#include <common/utils.h>
|
||||
#include <wire/wire.h>
|
||||
|
||||
/* BOLT #2:
|
||||
* ### The `funding_signed` Message
|
||||
*...
|
||||
* #### Requirements
|
||||
*...
|
||||
* The sender MUST set:
|
||||
* - `channel_id` by exclusive-OR of the `funding_txid` and the
|
||||
* `funding_output_index` from the `funding_created` message.
|
||||
*/
|
||||
void derive_channel_id(struct channel_id *channel_id,
|
||||
const struct bitcoin_outpoint *outpoint)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -23,6 +23,17 @@ struct bitcoin_tx *create_close_tx(const tal_t *ctx,
|
|||
struct amount_sat total_out;
|
||||
u8 *script;
|
||||
|
||||
/* BOLT #3:
|
||||
* ## Legacy Closing Transaction
|
||||
*...
|
||||
* ### Requirements
|
||||
*
|
||||
* Each node offering a signature:
|
||||
* - MUST round each output down to whole satoshis.
|
||||
* - MUST subtract the fee given by `fee_satoshis` from the output to the funder.
|
||||
* - MUST remove any output below its own `dust_limit_satoshis`.
|
||||
* - MAY eliminate its own output.
|
||||
*/
|
||||
assert(amount_sat_add(&total_out, to_us, to_them));
|
||||
assert(amount_sat_less_eq(total_out, funding_sats));
|
||||
|
||||
|
|
|
|||
|
|
@ -495,6 +495,15 @@ static void inject_gossip(struct daemon *daemon, const u8 *msg)
|
|||
|
||||
/*~ This is where lightningd tells us that a channel's funding transaction has
|
||||
* been spent. */
|
||||
/* BOLT #7:
|
||||
* ## Pruning the Network View
|
||||
*...
|
||||
* ### Requirements
|
||||
*
|
||||
* A node:
|
||||
* - SHOULD monitor the funding transactions in the blockchain, to identify
|
||||
* channels that are being closed.
|
||||
*/
|
||||
static void handle_outpoints_spent(struct daemon *daemon, const u8 *msg)
|
||||
{
|
||||
struct short_channel_id *scids;
|
||||
|
|
|
|||
|
|
@ -1088,6 +1088,14 @@ static void channel_fail_perm(struct channel *channel,
|
|||
why);
|
||||
}
|
||||
|
||||
/* BOLT #5:
|
||||
* A node:
|
||||
* - if a *local commitment transaction* has NOT ever contained a `to_local`
|
||||
* or HTLC output:
|
||||
* - MAY simply forget the channel.
|
||||
*/
|
||||
/* FIXME: We only implement a subset of this; we keep waiting
|
||||
* as long as it was finished opening. */
|
||||
if (channel_state_open_uncommitted(channel->state)) {
|
||||
delete_channel(channel, false);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -433,6 +433,9 @@ void peer_start_closingd(struct channel *channel, struct peer_fd *peer_fd)
|
|||
}
|
||||
|
||||
/* BOLT #3:
|
||||
* ## Legacy Closing Transaction
|
||||
*...
|
||||
* ### Requirements
|
||||
*
|
||||
* Each node offering a signature:
|
||||
* - MUST round each output down to whole satoshis.
|
||||
|
|
|
|||
|
|
@ -1235,6 +1235,12 @@ static struct command_result *json_invoice(struct command *cmd,
|
|||
info->b11->description_hash = NULL;
|
||||
info->b11->payment_secret = tal_dup(info->b11, struct secret,
|
||||
&payment_secret);
|
||||
/* BOLT #11:
|
||||
*
|
||||
* A writer:
|
||||
* - MUST set the `9` field to a feature vector compliant with the
|
||||
* [BOLT 9 origin node requirements](09-features.md#requirements).
|
||||
*/
|
||||
info->b11->features = tal_dup_talarr(info->b11, u8,
|
||||
cmd->ld->our_features
|
||||
->bits[BOLT11_FEATURE]);
|
||||
|
|
|
|||
|
|
@ -890,6 +890,21 @@ static struct feature_set *default_features(const tal_t *ctx)
|
|||
* option_data_loss_protect (all but 11 nodes)
|
||||
* option_static_remotekey (all but 16 nodes)
|
||||
*/
|
||||
/* BOLT #9:
|
||||
* The origin node:
|
||||
* * If it supports a feature above, SHOULD set the corresponding odd
|
||||
* bit in all feature fields indicated by the Context column unless
|
||||
* indicated that it must set the even feature bit instead.
|
||||
* * If it requires a feature above, MUST set the corresponding even
|
||||
* feature bit in all feature fields indicated by the Context column,
|
||||
* unless indicated that it must set the odd feature bit instead.
|
||||
* * MUST NOT set feature bits it does not support.
|
||||
* * MUST NOT set feature bits in fields not specified by the table above.
|
||||
* * MUST NOT set both the optional and mandatory bits.
|
||||
* * MUST set all transitive feature dependencies.
|
||||
* * MUST support:
|
||||
* * `var_onion_optin`
|
||||
*/
|
||||
struct feature_set *ret = NULL;
|
||||
static const u32 features[] = {
|
||||
COMPULSORY_FEATURE(OPT_DATA_LOSS_PROTECT),
|
||||
|
|
|
|||
|
|
@ -932,6 +932,15 @@ static struct bitcoin_tx *onchaind_tx_unsigned(const tal_t *ctx,
|
|||
weight = bitcoin_tx_weight(tx) + 1 + 3 + 73 + 0 + tal_count(info->wscript);
|
||||
weight += elements_tx_overhead(chainparams, 1, 1);
|
||||
|
||||
/* BOLT #5:
|
||||
* A node which broadcasts an HTLC-success or HTLC-timeout transaction for a
|
||||
* commitment transaction:
|
||||
* - if `option_anchors` applies:
|
||||
* - MUST combine it with inputs contributing sufficient fee to ensure timely
|
||||
* inclusion in a block.
|
||||
* - MAY combine it with other transactions.
|
||||
*/
|
||||
/* FIXME: We don't combine! */
|
||||
block_target = info->deadline_block;
|
||||
for (;;) {
|
||||
u32 feerate;
|
||||
|
|
@ -1305,6 +1314,21 @@ static void create_onchain_tx(struct channel *channel,
|
|||
welements)));
|
||||
}
|
||||
|
||||
/* BOLT #5:
|
||||
*
|
||||
* - if `option_anchors` applies:
|
||||
* - MAY use a single transaction to *resolve* all the outputs.
|
||||
* - if confirmation doesn't happen before reaching `security_delay` blocks from
|
||||
* expiry:
|
||||
* - SHOULD *resolve* revoked outputs in their own, separate penalty transactions. A previous
|
||||
* penalty transaction claiming multiple revoked outputs at once may be blocked from confirming
|
||||
* because of a transaction pinning attack.
|
||||
* - otherwise:
|
||||
* - MAY use a single transaction to *resolve* all the outputs.
|
||||
* - MUST handle its transactions being invalidated by HTLC transactions.
|
||||
*/
|
||||
/* FIXME: we always use one transaction per HTLC, even when we have
|
||||
* plenty of time and could combine them. */
|
||||
static void handle_onchaind_spend_to_us(struct channel *channel,
|
||||
const u8 *msg)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -228,6 +228,14 @@ u8 *p2tr_for_keyidx(const tal_t *ctx, struct lightningd *ld, u64 keyidx)
|
|||
return scriptpubkey_p2tr(ctx, &shutdownkey);
|
||||
}
|
||||
|
||||
/* BOLT #2:
|
||||
* A node:
|
||||
* - MUST NOT broadcast old (revoked) commitment transactions,
|
||||
* - Note: doing so will allow the other node to seize all channel funds.
|
||||
* - SHOULD NOT sign commitment transactions, unless it's about to broadcast
|
||||
* them (due to a failed connection),
|
||||
* - Note: this is to reduce the above risk.
|
||||
*/
|
||||
static struct bitcoin_tx *sign_last_tx(const tal_t *ctx,
|
||||
const struct channel *channel,
|
||||
const struct bitcoin_tx *last_tx,
|
||||
|
|
|
|||
|
|
@ -2625,6 +2625,12 @@ void peer_got_revoke(struct channel *channel, const u8 *msg)
|
|||
badonions = tal_arrz(msg, enum onion_wire, tal_count(changed));
|
||||
failmsgs = tal_arrz(msg, u8 *, tal_count(changed));
|
||||
for (i = 0; i < tal_count(changed); i++) {
|
||||
/* BOLT #2:
|
||||
* A node:
|
||||
* - until an incoming HTLC has been irrevocably committed:
|
||||
* - MUST NOT offer the corresponding outgoing HTLC
|
||||
* (`update_add_htlc`) in response to that incoming HTLC.
|
||||
*/
|
||||
/* If we're doing final accept, we need to forward */
|
||||
if (changed[i].newstate == RCVD_ADD_ACK_REVOCATION) {
|
||||
peer_accepted_htlc(failmsgs,
|
||||
|
|
|
|||
|
|
@ -961,6 +961,10 @@ static void billboard_update(struct tracked_output **outs)
|
|||
output_type_name(best->output_type), best->depth);
|
||||
}
|
||||
|
||||
/* BOLT #5:
|
||||
* - SHOULD extract the payment preimage from the transaction input witness, if
|
||||
* it's not already known.
|
||||
*/
|
||||
static void handle_htlc_onchain_fulfill(struct tracked_output *out,
|
||||
const struct tx_parts *tx_parts,
|
||||
const struct bitcoin_outpoint *htlc_outpoint)
|
||||
|
|
@ -1376,7 +1380,14 @@ static void tx_new_depth(struct tracked_output **outs,
|
|||
{
|
||||
size_t i;
|
||||
|
||||
/* Special handling for commitment tx reaching depth */
|
||||
/* BOLT #5:
|
||||
* - for any committed HTLC that does NOT have an output in this
|
||||
* commitment transaction:
|
||||
*...
|
||||
* - otherwise:
|
||||
* - once the commitment transaction has reached reasonable depth:
|
||||
* - MUST fail the corresponding incoming HTLC (if any).
|
||||
*/
|
||||
if (bitcoin_txid_eq(&outs[0]->resolved->txid, txid)
|
||||
&& depth >= reasonable_depth
|
||||
&& missing_htlc_msgs) {
|
||||
|
|
@ -2036,6 +2047,11 @@ static enum side matches_direction(const size_t *matches,
|
|||
static void note_missing_htlcs(u8 **htlc_scripts,
|
||||
const struct htlcs_info *htlcs_info)
|
||||
{
|
||||
/* BOLT #5:
|
||||
* - for any committed HTLC that does NOT have an output in this
|
||||
* commitment transaction:
|
||||
*/
|
||||
/* See onchain_control.c for the rest of the quote! */
|
||||
for (size_t i = 0; i < tal_count(htlcs_info->htlcs); i++) {
|
||||
u8 *msg;
|
||||
|
||||
|
|
@ -2161,9 +2177,18 @@ static void handle_our_unilateral(const struct tx_parts *tx,
|
|||
|
||||
/* BOLT #5:
|
||||
*
|
||||
* In this case, a node discovers its *local commitment transaction*,
|
||||
* which *resolves* the funding transaction output.
|
||||
* A node:
|
||||
* - upon discovering its *local commitment transaction*:
|
||||
* - SHOULD spend the `to_local` output to a convenient address.
|
||||
* - MUST wait until the `OP_CHECKSEQUENCEVERIFY` delay has passed (as
|
||||
* specified by the remote node's `to_self_delay` field) before spending the
|
||||
* output.
|
||||
* - Note: if the output is spent (as recommended), the output is *resolved*
|
||||
* by the spending transaction, otherwise it is considered *resolved* by the
|
||||
* commitment transaction itself.
|
||||
*/
|
||||
/* We do NOT spend our unilateral, we remember how to spend it
|
||||
* in the wallet, thus it's immediately resolved. */
|
||||
resolved_by_other(outs[0], &tx->txid, OUR_UNILATERAL);
|
||||
|
||||
/* Figure out what delayed to-us output looks like */
|
||||
|
|
@ -2267,7 +2292,7 @@ static void handle_our_unilateral(const struct tx_parts *tx,
|
|||
&& wally_tx_output_scripteq(tx->outputs[i],
|
||||
script[REMOTE])) {
|
||||
/* BOLT #5:
|
||||
*
|
||||
*...
|
||||
* - MAY ignore the `to_remote` output.
|
||||
* - Note: No action is required by the local
|
||||
* node, as `to_remote` is considered *resolved*
|
||||
|
|
@ -2409,7 +2434,7 @@ static void handle_our_unilateral(const struct tx_parts *tx,
|
|||
*
|
||||
* - MUST handle HTLCs offered by itself as specified
|
||||
* in [HTLC Output Handling: Local Commitment,
|
||||
* Local Offers]
|
||||
* Local Offers](#htlc-output-handling-local-commitment-local-offers).
|
||||
*/
|
||||
out = new_tracked_output(&outs, &outpoint,
|
||||
tx_blockheight,
|
||||
|
|
@ -2431,10 +2456,9 @@ static void handle_our_unilateral(const struct tx_parts *tx,
|
|||
NULL, NULL,
|
||||
remote_htlc_sigs);
|
||||
/* BOLT #5:
|
||||
*
|
||||
* - MUST handle HTLCs offered by the remote node
|
||||
* as specified in [HTLC Output Handling: Local
|
||||
* Commitment, Remote Offers]
|
||||
* - MUST handle HTLCs offered by the remote node
|
||||
* as specified in [HTLC Output Handling: Local
|
||||
* Commitment, Remote Offers](#htlc-output-handling-local-commitment-remote-offers).
|
||||
*/
|
||||
/* Tells us which htlc to use */
|
||||
which_htlc = resolve_their_htlc(out, matches,
|
||||
|
|
|
|||
|
|
@ -410,15 +410,20 @@ static u8 *funder_channel_start(struct state *state, u8 channel_flags,
|
|||
their_mindepth);
|
||||
|
||||
/* BOLT #2:
|
||||
* - if `channel_type` is set, and `channel_type` was set in
|
||||
* `open_channel`, and they are not equal types:
|
||||
* - MUST fail the channel.
|
||||
* - if `option_channel_type` was negotiated but the message doesn't
|
||||
* include a `channel_type`:
|
||||
* - MAY fail the channel.
|
||||
*/
|
||||
if (!accept_tlvs->channel_type) {
|
||||
negotiation_failed(state,
|
||||
"accept_channel without a channel_type");
|
||||
}
|
||||
|
||||
/* BOLT #2:
|
||||
* - if `channel_type` is set, and `channel_type` was set in
|
||||
* `open_channel`, and they are not equal types:
|
||||
* - MUST fail the channel.
|
||||
*/
|
||||
/* Simple case: caller specified, don't allow any variants */
|
||||
if (!featurebits_eq(accept_tlvs->channel_type, state->channel_type->features)) {
|
||||
negotiation_failed(state,
|
||||
|
|
|
|||
|
|
@ -368,6 +368,16 @@ struct command_result *handle_invoice_onion_message(struct command *cmd,
|
|||
struct sent *sent;
|
||||
struct command_result *err;
|
||||
|
||||
/* BOLT #4:
|
||||
* - otherwise (it is the final node):
|
||||
* - if `path_id` is set and corresponds to a path the reader has previously published in a `reply_path`:
|
||||
* - if the onion message is not a reply to that previous onion:
|
||||
* - MUST ignore the onion message
|
||||
* - otherwise (unknown or unset `path_id`):
|
||||
* - if the onion message is a reply to an onion message which contained a `path_id`:
|
||||
* - MUST respond (or not respond) exactly as if it did not send the initial onion message.
|
||||
*/
|
||||
/* We unmarshal the path_id into our secret: if it is NULL or wrong, we exit here */
|
||||
sent = find_sent_by_secret(pathsecret);
|
||||
if (!sent)
|
||||
return NULL;
|
||||
|
|
@ -771,6 +781,14 @@ static struct command_result *invreq_done(struct command *cmd,
|
|||
payload->invoice_request = tal_arr(payload, u8, 0);
|
||||
towire_tlv_invoice_request(&payload->invoice_request, sent->invreq);
|
||||
|
||||
/* BOLT #12:
|
||||
* - if it chooses to send an invoice request, it sends an onion message:
|
||||
* - if `offer_paths` is set:
|
||||
* - MUST send the onion message via any path in `offer_paths` to the final
|
||||
* `onion_msg_hop`.`blinded_node_id` in that path
|
||||
* - otherwise:
|
||||
* - MUST send the onion message to `offer_issuer_id`
|
||||
*/
|
||||
/* Don't expect a reply message for cancel */
|
||||
return send_message(cmd, sent,
|
||||
sent->invreq->invreq_recurrence_cancel ? false : true,
|
||||
|
|
|
|||
|
|
@ -288,6 +288,19 @@ static struct command_result *onion_message_recv(struct command *cmd,
|
|||
return res;
|
||||
}
|
||||
|
||||
/* BOLT #4:
|
||||
* - otherwise (it is the final node):
|
||||
* - if `path_id` is set and corresponds to a path the reader has previously published in a `reply_path`:
|
||||
* - if the onion message is not a reply to that previous onion:
|
||||
* - MUST ignore the onion message
|
||||
* - otherwise (unknown or unset `path_id`):
|
||||
* - if the onion message is a reply to an onion message which contained a `path_id`:
|
||||
* - MUST respond (or not respond) exactly as if it did not send the initial onion message.
|
||||
*/
|
||||
/* FIXME: Technically, we don't meet the first half of this: we
|
||||
* always do parsing and sanity checking before checking the
|
||||
* secret (thus the path_id). But we ignore it *after* that.
|
||||
*/
|
||||
replytok = json_get_member(buf, om, "reply_blindedpath");
|
||||
if (replytok) {
|
||||
reply_path = json_to_blinded_path(cmd, buf, replytok);
|
||||
|
|
|
|||
|
|
@ -257,6 +257,10 @@ struct command_result *handle_invoice(struct command *cmd,
|
|||
fmt_sha256(tmpctx, &inv->invreq_id));
|
||||
}
|
||||
} else {
|
||||
/* BOLT #12:
|
||||
* - if `invreq_paths` is present:
|
||||
* - MUST reject the invoice if it did not arrive via one of those paths.
|
||||
*/
|
||||
/* Didn't use path. Was it supposed to? */
|
||||
if (inv->inv->invreq_paths) {
|
||||
if (command_dev_apis(cmd))
|
||||
|
|
|
|||
|
|
@ -459,7 +459,12 @@ static struct command_result *json_listfunds(struct command *cmd,
|
|||
p = peer_node_id_map_next(cmd->ld->peers, &it)) {
|
||||
struct channel *c;
|
||||
list_for_each(&p->channels, c, list) {
|
||||
/* We don't print out uncommitted channels */
|
||||
/* We don't print out uncommitted channels, which makes us meet this: */
|
||||
/* BOLT #2:
|
||||
* The receiving node MUST NOT:
|
||||
* - consider funds received, using `push_msat`, to be received
|
||||
* until the funding transaction has reached sufficient depth.
|
||||
*/
|
||||
if (channel_state_uncommitted(c->state))
|
||||
continue;
|
||||
json_object_start(response, NULL);
|
||||
|
|
|
|||
|
|
@ -203,6 +203,13 @@ bool fromwire_tlv(const u8 **cursor, size_t *max,
|
|||
}
|
||||
}
|
||||
|
||||
/* BOLT #1:
|
||||
* - otherwise, if `type` is unknown:
|
||||
* - if `type` is even:
|
||||
* - MUST fail to parse the `tlv_stream`.
|
||||
* - otherwise, if `type` is odd:
|
||||
* - MUST discard the next `length` bytes.
|
||||
*/
|
||||
if (!field.meta && !tlv_type_is_allowed(&field, extra_types)) {
|
||||
SUPERVERBOSE("unknown even");
|
||||
if (err_type != NULL)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue