From 2ae73b42b0424a13955790c6cab8150b748764db Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 22 Sep 2022 13:02:16 +0930 Subject: [PATCH 1/2] pyln-spec: update Makefile to use poetry for release, generate versions 1. Update default specdir to the new modern name. 2. Don't use python to extract version, use sed. 3. Use poetry publish. Signed-off-by: Rusty Russell --- contrib/pyln-spec/Makefile | 45 ++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/contrib/pyln-spec/Makefile b/contrib/pyln-spec/Makefile index 5ed10647ca2e..14ad23aa7f0b 100755 --- a/contrib/pyln-spec/Makefile +++ b/contrib/pyln-spec/Makefile @@ -1,6 +1,6 @@ #! /usr/bin/make -SPECDIR := ../../../lightning-rfc +SPECDIR := ../../../bolts # This gives us something like 'v1.0-137-gae2d248b7ad8b0965f224c303019ba04c661008f' GITDESCRIBE := $(shell git -C $(SPECDIR) describe --abbrev=40) # -> 1.0 @@ -31,12 +31,14 @@ check-source-mypy-%: cd $* && mypy --ignore-missing-imports `find * -name '*.py'` # Given a bolt number and a variable, get the value from inside the package. -extract = $(shell python3 -c 'from pyln.spec import bolt$1 as bolt;print(bolt.$2)') -# Get the version for this bolt -version = $(call extract,$1,__version__) +extract = $(shell cat bolt$1/pyln/spec/bolt$1/gen_*version.py | sed -n 's/^$2 = \"\(.*\)\"/\1/p') -# Given a direc the csv version for this bolt. +# Get the version for this bolt +base_version = $(call extract,$1,__base_version__) csv_version = $(call extract,$1,__csv_version__) +post_version = $(call extract,$1,__post_version__) + +version = $(call base_version,$1).$(call csv_version,$1).$(call post_version,$1) # Given a bolt number, get the current version. sdistfiles = $(foreach b,$(BOLTS),bolt$b/dist/pyln-bolt$b-$(call version,$b).tar.gz) @@ -50,26 +52,27 @@ bdistfiles = $(foreach b,$(BOLTS),bolt$b/dist/pyln_bolt$b-$(call version,$b)-py3 ARTEFACTS := $(foreach b,$(BOLTS),$(call bdistfiles,$b) $(call sdistfiles,$b)) -test-release-bolt%: $(ARTEFACTS) - python3 -m twine upload --repository testpypi --skip-existing $(call bdistfiles,$*) $(call sdistfiles,$*) +test-release-%: + cd bolt$b && poetry publish --repository testpypi + +test-release: $(BOLTS:%=prod-release-%) - # Create a test virtualenv, install from the testpypi and run the - # tests against it (make sure not to use any virtualenv that may have - # pyln-proto already installed). - virtualenv testpypi-$* --python=/usr/bin/python3 --download --always-copy --clear - # Install the requirements from the prod repo, they are not being kept up to date on the test repo - testpypi-$*/bin/python3 -m pip install -r requirements.txt pytest pytest-timeout - testpypi-$*/bin/python3 -m pip install -I --index-url https://test.pypi.org/simple/ --no-deps pyln-bolt$* - testpypi-$*/bin/python3 -c "from pyln.spec import bolt$* as bolt;assert(bolt.__version__ == '$(call version,$*)')" - testpypi-$*/bin/pytest bolt$*/tests - rm -rf testpypi-$* +prod-release-%: + cd bolt$b && poetry publish -test-release: check $(foreach b,$(BOLTS),test-release-bolt$b) +prod-release: $(BOLTS:%=prod-release-%) -prod-release: test-release $(ARTEFACTS) - python3 -m twine upload $(ARTEFACTS) +# Pattern rules don't work reliably with multiple % in prereqs! +refresh-1: bolt1/pyln/spec/bolt1/gen_csv_version.py bolt1/pyln/spec/bolt1/gen_version.py + cd bolt1 && poetry version $(call version,1) +refresh-2: bolt2/pyln/spec/bolt2/gen_csv_version.py bolt2/pyln/spec/bolt2/gen_version.py + cd bolt2 && poetry version $(call version,2) +refresh-4: bolt4/pyln/spec/bolt4/gen_csv_version.py bolt4/pyln/spec/bolt4/gen_version.py + cd bolt4 && poetry version $(call version,4) +refresh-7: bolt7/pyln/spec/bolt7/gen_csv_version.py bolt7/pyln/spec/bolt7/gen_version.py + cd bolt7 && poetry version $(call version,7) -refresh: $(CODE_DIRS:%=%/gen_csv_version.py) $(CODE_DIRS:%=%/gen_version.py) +refresh: $(BOLTS:%=refresh-%) bolt1/pyln/spec/bolt1/csv.py bolt1/pyln/spec/bolt1/text.py: $(SPECDIR)/01-messaging.md Makefile bolt2/pyln/spec/bolt2/csv.py bolt2/pyln/spec/bolt2/text.py: $(SPECDIR)/02-peer-protocol.md Makefile From 22906c55e59a656763841ce35dfde7ae572f653b Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 22 Sep 2022 13:07:11 +0930 Subject: [PATCH 2/2] pyln-spec: update to latest spec. In particular, some field names have changed. lnprototest in master has already upgraded names, so this brings us into compatibility again. Signed-off-by: Rusty Russell Changelog-Changed: pyln-spec: package updated to latest spec version. --- .../bolt1/pyln/spec/bolt1/gen_version.py | 4 +- .../pyln-spec/bolt1/pyln/spec/bolt1/text.py | 8 +- contrib/pyln-spec/bolt1/pyproject.toml | 2 +- .../pyln-spec/bolt2/pyln/spec/bolt2/csv.py | 9 +- .../bolt2/pyln/spec/bolt2/gen_csv_version.py | 2 +- .../bolt2/pyln/spec/bolt2/gen_version.py | 4 +- .../pyln-spec/bolt2/pyln/spec/bolt2/text.py | 138 +++++++++++++----- contrib/pyln-spec/bolt2/pyproject.toml | 2 +- .../pyln-spec/bolt4/pyln/spec/bolt4/csv.py | 2 +- .../bolt4/pyln/spec/bolt4/gen_csv_version.py | 2 +- .../bolt4/pyln/spec/bolt4/gen_version.py | 4 +- .../pyln-spec/bolt4/pyln/spec/bolt4/text.py | 17 ++- contrib/pyln-spec/bolt4/pyproject.toml | 2 +- .../pyln-spec/bolt7/pyln/spec/bolt7/csv.py | 2 +- .../bolt7/pyln/spec/bolt7/gen_csv_version.py | 2 +- .../bolt7/pyln/spec/bolt7/gen_version.py | 4 +- .../pyln-spec/bolt7/pyln/spec/bolt7/text.py | 110 +++++++------- contrib/pyln-spec/bolt7/pyproject.toml | 2 +- 18 files changed, 203 insertions(+), 113 deletions(-) diff --git a/contrib/pyln-spec/bolt1/pyln/spec/bolt1/gen_version.py b/contrib/pyln-spec/bolt1/pyln/spec/bolt1/gen_version.py index 3377756caf44..fe86b5a5abaf 100644 --- a/contrib/pyln-spec/bolt1/pyln/spec/bolt1/gen_version.py +++ b/contrib/pyln-spec/bolt1/pyln/spec/bolt1/gen_version.py @@ -1,3 +1,3 @@ __base_version__ = "1.0" -__post_version__ = "222" -__gitversion__ = "f1c797df2966237244527c1c6343dbe9bc765342" +__post_version__ = "246" +__gitversion__ = "f32c6ddb5f11b431c9bb4f501cdec604172a90de" diff --git a/contrib/pyln-spec/bolt1/pyln/spec/bolt1/text.py b/contrib/pyln-spec/bolt1/pyln/spec/bolt1/text.py index 721c6ac76a35..96c27eabf2e7 100644 --- a/contrib/pyln-spec/bolt1/pyln/spec/bolt1/text.py +++ b/contrib/pyln-spec/bolt1/pyln/spec/bolt1/text.py @@ -6,7 +6,13 @@ This protocol assumes an underlying authenticated and ordered transport mechanism that takes care of framing individual messages. [BOLT #8](08-transport.md) specifies the canonical transport layer used in Lightning, though it can be replaced by any transport that fulfills the above guarantees. -The default TCP port is 9735. This corresponds to hexadecimal `0x2607`: the Unicode code point for LIGHTNING.[1](#reference-1) +The default TCP port depends on the network used. The most common networks are: + +- Bitcoin mainet with port number 9735 or the corresponding hexadecimal `0x2607`; +- Bitcoin testnet with port number 19735 (`0x4D17`); +- Bitcoin signet with port number 39735 (`0xF87`). + +The Unicode code point for LIGHTNING [1](#reference-1), and the port convention try to follow the Bitcoin Core convention. All data fields are unsigned big-endian unless otherwise specified. diff --git a/contrib/pyln-spec/bolt1/pyproject.toml b/contrib/pyln-spec/bolt1/pyproject.toml index c6ee8219eb12..743fa0a5d64b 100644 --- a/contrib/pyln-spec/bolt1/pyproject.toml +++ b/contrib/pyln-spec/bolt1/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "pyln-bolt1" -version = "1.0.1.187.post0" +version = "1.0.2.246" description = "" authors = ["Rusty Russell "] license = "MIT" diff --git a/contrib/pyln-spec/bolt2/pyln/spec/bolt2/csv.py b/contrib/pyln-spec/bolt2/pyln/spec/bolt2/csv.py index b24b32454e4e..78233b9641bb 100644 --- a/contrib/pyln-spec/bolt2/pyln/spec/bolt2/csv.py +++ b/contrib/pyln-spec/bolt2/pyln/spec/bolt2/csv.py @@ -51,9 +51,12 @@ "msgtype,funding_signed,35", "msgdata,funding_signed,channel_id,channel_id,", "msgdata,funding_signed,signature,signature,", - "msgtype,funding_locked,36", - "msgdata,funding_locked,channel_id,channel_id,", - "msgdata,funding_locked,next_per_commitment_point,point,", + "msgtype,channel_ready,36", + "msgdata,channel_ready,channel_id,channel_id,", + "msgdata,channel_ready,second_per_commitment_point,point,", + "msgdata,channel_ready,tlvs,channel_ready_tlvs,", + "tlvtype,channel_ready_tlvs,short_channel_id,1", + "tlvdata,channel_ready_tlvs,short_channel_id,alias,short_channel_id,", "msgtype,shutdown,38", "msgdata,shutdown,channel_id,channel_id,", "msgdata,shutdown,len,u16,", diff --git a/contrib/pyln-spec/bolt2/pyln/spec/bolt2/gen_csv_version.py b/contrib/pyln-spec/bolt2/pyln/spec/bolt2/gen_csv_version.py index 2140fc8212ff..fec7e9616295 100644 --- a/contrib/pyln-spec/bolt2/pyln/spec/bolt2/gen_csv_version.py +++ b/contrib/pyln-spec/bolt2/pyln/spec/bolt2/gen_csv_version.py @@ -1 +1 @@ -__csv_version__ = "2" +__csv_version__ = "3" diff --git a/contrib/pyln-spec/bolt2/pyln/spec/bolt2/gen_version.py b/contrib/pyln-spec/bolt2/pyln/spec/bolt2/gen_version.py index 3377756caf44..fe86b5a5abaf 100644 --- a/contrib/pyln-spec/bolt2/pyln/spec/bolt2/gen_version.py +++ b/contrib/pyln-spec/bolt2/pyln/spec/bolt2/gen_version.py @@ -1,3 +1,3 @@ __base_version__ = "1.0" -__post_version__ = "222" -__gitversion__ = "f1c797df2966237244527c1c6343dbe9bc765342" +__post_version__ = "246" +__gitversion__ = "f32c6ddb5f11b431c9bb4f501cdec604172a90de" diff --git a/contrib/pyln-spec/bolt2/pyln/spec/bolt2/text.py b/contrib/pyln-spec/bolt2/pyln/spec/bolt2/text.py index 66ba1fbb4e22..3c63f4c4f9d4 100644 --- a/contrib/pyln-spec/bolt2/pyln/spec/bolt2/text.py +++ b/contrib/pyln-spec/bolt2/pyln/spec/bolt2/text.py @@ -13,7 +13,7 @@ * [The `accept_channel` Message](#the-accept_channel-message) * [The `funding_created` Message](#the-funding_created-message) * [The `funding_signed` Message](#the-funding_signed-message) - * [The `funding_locked` Message](#the-funding_locked-message) + * [The `channel_ready` Message](#the-channel_ready-message) * [Channel Close](#channel-close) * [Closing Initiation: `shutdown`](#closing-initiation-shutdown) * [Closing Negotiation: `closing_signed`](#closing-negotiation-closing_signed) @@ -71,8 +71,8 @@ the `funding_signed` message is sent/received, both sides should wait for the funding transaction to enter the blockchain and reach the specified depth (number of confirmations). After both sides have sent -the `funding_locked` message, the channel is established and can begin -normal operation. The `funding_locked` message includes information +the `channel_ready` message, the channel is established and can begin +normal operation. The `channel_ready` message includes information that will be used to construct channel authentication proofs. @@ -83,8 +83,8 @@ | A |--(3)-- funding_created --->| B | | |<-(4)-- funding_signed -----| | | | | | - | |--(5)--- funding_locked ---->| | - | |<-(6)--- funding_locked -----| | + | |--(5)--- channel_ready ---->| | + | |<-(6)--- channel_ready -----| | +-------+ +-------+ - where node A is 'funder' and node B is 'fundee' @@ -208,12 +208,16 @@ arbitrary combination (they represent the persistent features which affect the channel operation). -The currently defined types are: +The currently defined basic types are: - no features (no bits set) - `option_static_remotekey` (bit 12) - `option_anchor_outputs` and `option_static_remotekey` (bits 20 and 12) - `option_anchors_zero_fee_htlc_tx` and `option_static_remotekey` (bits 22 and 12) +Each basic type has the following variations allowed: + - `option_scid_alias` (bit 46) + - `option_zeroconf` (bit 50) + #### Requirements The sending node: @@ -240,6 +244,8 @@ - MUST set it to a defined type representing the type it wants. - MUST use the smallest bitmap possible to represent the channel type. - SHOULD NOT set it to a type containing a feature which was not negotiated. + - if `announce_channel` is `true` (not `0`): + - MUST NOT send `channel_type` with the `option_scid_alias` bit set. The sending node SHOULD: - set `to_self_delay` sufficient to ensure the sender can irreversibly spend a commitment transaction output, in case of misbehavior by the receiver. @@ -277,7 +283,9 @@ - the funder's amount for the initial commitment transaction is not sufficient for full [fee payment](03-transactions.md#fee-payment). - both `to_local` and `to_remote` amounts for the initial commitment transaction are less than or equal to `channel_reserve_satoshis` (see [BOLT 3](03-transactions.md#commitment-transaction-outputs)). - `funding_satoshis` is greater than or equal to 2^24 and the receiver does not support `option_support_large_channel`. - - It supports `channel_type`, `channel_type` was set, and the `type` is not suitable. + - It supports `channel_type` and `channel_type` was set: + - if `type` is not suitable. + - if `type` includes `option_zeroconf` and it does not trust the sender to open an unconfirmed channel. The receiving node MUST NOT: - consider funds received, using `push_msat`, to be received until the funding transaction has reached sufficient depth. @@ -345,8 +353,10 @@ the `open_channel` message. The sender: - - SHOULD set `minimum_depth` to a number of blocks it considers reasonable to -avoid double-spending of the funding transaction. + - if `channel_type` includes `option_zeroconf`: + - MUST set `minimum_depth` to zero. + - otherwise: + - SHOULD set `minimum_depth` to a number of blocks it considers reasonable to avoid double-spending of the funding transaction. - MUST set `channel_reserve_satoshis` greater than or equal to `dust_limit_satoshis` from the `open_channel` message. - MUST set `dust_limit_satoshis` less than or equal to `channel_reserve_satoshis` from the `open_channel` message. - if `option_channel_type` was negotiated: @@ -464,31 +474,67 @@ `option_static_remotekey`, and the superior one is favored if more than one is negotiated. -### The `funding_locked` Message +### The `channel_ready` Message + +This message (which used to be called `funding_locked`) indicates that the funding transaction has sufficient confirms for channel use. Once both nodes have sent this, the channel enters normal operating mode. -This message indicates that the funding transaction has reached the `minimum_depth` asked for in `accept_channel`. Once both nodes have sent this, the channel enters normal operating mode. +Note that the opener is free to send this message at any time (since it presumably trusts itself), but the +accepter would usually wait until the funding has reached the `minimum_depth` asked for in `accept_channel`. -1. type: 36 (`funding_locked`) +1. type: 36 (`channel_ready`) 2. data: * [`channel_id`:`channel_id`] - * [`point`:`next_per_commitment_point`] + * [`point`:`second_per_commitment_point`] + * [`channel_ready_tlvs`:`tlvs`] + +1. `tlv_stream`: `channel_ready_tlvs` +2. types: + 1. type: 1 (`short_channel_id`) + 2. data: + * [`short_channel_id`:`alias`] #### Requirements -The sender MUST: - - NOT send `funding_locked` unless outpoint of given by `funding_txid` and +The sender: + - MUST NOT send `channel_ready` unless outpoint of given by `funding_txid` and `funding_output_index` in the `funding_created` message pays exactly `funding_satoshis` to the scriptpubkey specified in [BOLT #3](03-transactions.md#funding-transaction-output). - - wait until the funding transaction has reached `minimum_depth` before - sending this message. - - set `next_per_commitment_point` to the per-commitment point to be used - for the following commitment transaction, derived as specified in + - if it is not the node opening the channel: + - SHOULD wait until the funding transaction has reached `minimum_depth` before + sending this message. + - MUST set `second_per_commitment_point` to the per-commitment point to be used + for commitment transaction #1, derived as specified in [BOLT #3](03-transactions.md#per-commitment-secret-requirements). + - if `option_scid_alias` was negotiated: + - MUST set `short_channel_id` `alias`. + - otherwise: + - MAY set `short_channel_id` `alias`. + - if it sets `alias`: + - if the `announce_channel` bit was set in `open_channel`: + - SHOULD initially set `alias` to value not related to the real `short_channel_id`. + - otherwise: + - MUST set `alias` to a value not related to the real `short_channel_id`. + - MUST NOT send the same `alias` for multiple peers or use an alias which + collides with a `short_channel_id` of a channel on the same node. + - MUST always recognize the `alias` as a `short_channel_id` for incoming HTLCs to this channel. + - if `channel_type` has `option_scid_alias` set: + - MUST NOT allow incoming HTLCs to this channel using the real `short_channel_id` + - MAY send multiple `channel_ready` messages to the same peer with different `alias` values. + - otherwise: + - MUST wait until the funding transaction has reached `minimum_depth` before sending this message. + + +The sender: A non-funding node (fundee): - SHOULD forget the channel if it does not see the correct funding - transaction after a timeout of 2016 blocks. + transaction after a timeout of 2016 blocks. -From the point of waiting for `funding_locked` onward, either node MAY +The receiver: + - MAY use any of the `alias` it received, in BOLT 11 `r` fields. + - if `channel_type` has `option_scid_alias` set: + - MUST NOT use the real `short_channel_id` in BOLT 11 `r` fields. + +From the point of waiting for `channel_ready` onward, either node MAY send an `error` and fail the channel if it does not receive a required response from the other node after a reasonable timeout. @@ -504,6 +550,17 @@ channel. To avoid this, the funder should ensure the funding transaction confirms in the next 2016 blocks. +The `alias` here is required for two distinct use cases. The first one is +for routing payments through channels that are not confirmed yet (since +the real `short_channel_id` is unknown until confirmation). The second one +is to provide one or more aliases to use for private channels (even once +a real `short_channel_id` is available). + +While a node can send multiple `alias`, it must remember all of the +ones it has sent so it can use them should they be requested by +incoming HTLCs. The recipient only need remember one, for use in +`r` route hints in BOLT 11 invoices. + ## Channel Close Nodes can negotiate a mutual close of the connection, which unlike a @@ -544,12 +601,14 @@ A sending node: - if it hasn't sent a `funding_created` (if it is a funder) or a `funding_signed` (if it is a fundee): - MUST NOT send a `shutdown` - - MAY send a `shutdown` before a `funding_locked`, i.e. before the funding transaction has reached `minimum_depth`. + - MAY send a `shutdown` before a `channel_ready`, i.e. before the funding transaction has reached `minimum_depth`. - if there are updates pending on the receiving node's commitment transaction: - MUST NOT send a `shutdown`. + - MUST NOT send multiple `shutdown` messages. - MUST NOT send an `update_add_htlc` after a `shutdown`. - - if no HTLCs remain in either commitment transaction: - - MUST NOT send any `update` message after a `shutdown`. + - if no HTLCs remain in either commitment transaction (including dust HTLCs) + and neither side has a pending `revoke_and_ack` to send: + - MUST NOT send any `update` message after that point. - SHOULD fail to route any HTLC added after it has sent `shutdown`. - if it sent a non-zero-length `shutdown_scriptpubkey` in `open_channel` or `accept_channel`: - MUST send the same value in `scriptpubkey`. @@ -566,7 +625,7 @@ - SHOULD send an `error` and fail the channel. - if the `scriptpubkey` is not in one of the above forms: - SHOULD send a `warning`. - - if it hasn't sent a `funding_locked` yet: + - if it hasn't sent a `channel_ready` yet: - MAY reply to a `shutdown` message with a `shutdown` - once there are no outstanding updates on the peer, UNLESS it has already sent a `shutdown`: - MUST reply to a `shutdown` message with a `shutdown` @@ -581,10 +640,13 @@ the sender always sends a `commitment_signed` first. As shutdown implies a desire to terminate, it implies that no new -HTLCs will be added or accepted. Once any HTLCs are cleared, the peer -may immediately begin closing negotiation, so we ban further updates -to the commitment transaction (in particular, `update_fee` would be -possible otherwise). +HTLCs will be added or accepted. Once any HTLCs are cleared, there are no commitments +for which a revocation is owed, and all updates are included on both commitment +transactions, the peer may immediately begin closing negotiation, so we ban further +updates to the commitment transaction (in particular, `update_fee` would be +possible otherwise). However, while there are HTLCs on the commitment transaction, +the initiator may find it desirable to increase the feerate as there may be pending +HTLCs on the commitment which could timeout. The `scriptpubkey` forms include only standard segwit forms accepted by the Bitcoin network, which ensures the resulting transaction will @@ -603,8 +665,9 @@ ### Closing Negotiation: `closing_signed` -Once shutdown is complete and the channel is empty of HTLCs, the final -current commitment transactions will have no HTLCs, and closing fee +Once shutdown is complete, the channel is empty of HTLCs, there are no commitments +for which a revocation is owed, and all updates are included on both commitments, +the final current commitment transactions will have no HTLCs, and closing fee negotiation begins. The funder chooses a fee it thinks is fair, and signs the closing transaction with the `scriptpubkey` fields from the `shutdown` messages (along with its chosen fee) and sends the signature; @@ -716,7 +779,7 @@ ## Normal Operation -Once both nodes have exchanged `funding_locked` (and optionally [`announcement_signatures`](07-routing-gossip.md#the-announcement_signatures-message)), the channel can be used to make payments via Hashed Time Locked Contracts. +Once both nodes have exchanged `channel_ready` (and optionally [`announcement_signatures`](07-routing-gossip.md#the-announcement_signatures-message)), the channel can be used to make payments via Hashed Time Locked Contracts. Changes are sent in batches: one or more `update_` messages are sent before a `commitment_signed` message, as in the following diagram: @@ -1370,11 +1433,12 @@ A node: - if `next_commitment_number` is 1 in both the `channel_reestablish` it sent and received: - - MUST retransmit `funding_locked`. + - MUST retransmit `channel_ready`. - otherwise: - - MUST NOT retransmit `funding_locked`. + - MUST NOT retransmit `channel_ready`, but MAY send `channel_ready` with + a different `short_channel_id` `alias` field. - upon reconnection: - - MUST ignore any redundant `funding_locked` it receives. + - MUST ignore any redundant `channel_ready` it receives. - if `next_commitment_number` is equal to the commitment number of the last `commitment_signed` message the receiving node has sent: - MUST reuse the same commitment number for its next `commitment_signed`. @@ -1442,7 +1506,7 @@ is if the `funding_signed` message is sent but not received. In this case, the funder will forget the channel, and presumably open a new one upon reconnection; meanwhile, the other node will eventually forget -the original channel, due to never receiving `funding_locked` or seeing +the original channel, due to never receiving `channel_ready` or seeing the funding transaction on-chain. There's no acknowledgment for `error`, so if a reconnect occurs it's @@ -1478,7 +1542,7 @@ `commitment_signed` for commitment number 1 is send and then the revocation for commitment number 0 is received. -`funding_locked` is implicitly acknowledged by the start of normal +`channel_ready` is implicitly acknowledged by the start of normal operation, which is known to have begun after a `commitment_signed` has been received — hence, the test for a `next_commitment_number` greater than 1. diff --git a/contrib/pyln-spec/bolt2/pyproject.toml b/contrib/pyln-spec/bolt2/pyproject.toml index 10367daa99b8..bbb708866440 100644 --- a/contrib/pyln-spec/bolt2/pyproject.toml +++ b/contrib/pyln-spec/bolt2/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "pyln-bolt2" -version = "1.0.2.187.post0" +version = "1.0.3.246" description = "A pure python implementation of BOLT2" authors = ["Rusty Russell "] license = "MIT" diff --git a/contrib/pyln-spec/bolt4/pyln/spec/bolt4/csv.py b/contrib/pyln-spec/bolt4/pyln/spec/bolt4/csv.py index b6458142ab21..ca65ecd52202 100644 --- a/contrib/pyln-spec/bolt4/pyln/spec/bolt4/csv.py +++ b/contrib/pyln-spec/bolt4/pyln/spec/bolt4/csv.py @@ -49,7 +49,7 @@ "msgtype,final_incorrect_htlc_amount,19", "msgdata,final_incorrect_htlc_amount,incoming_htlc_amt,u64,", "msgtype,channel_disabled,UPDATE|20", - "msgdata,channel_disabled,flags,u16,", + "msgdata,channel_disabled,disabled_flags,u16,", "msgdata,channel_disabled,len,u16,", "msgdata,channel_disabled,channel_update,byte,len", "msgtype,expiry_too_far,21", diff --git a/contrib/pyln-spec/bolt4/pyln/spec/bolt4/gen_csv_version.py b/contrib/pyln-spec/bolt4/pyln/spec/bolt4/gen_csv_version.py index fec7e9616295..85d6a77f6912 100644 --- a/contrib/pyln-spec/bolt4/pyln/spec/bolt4/gen_csv_version.py +++ b/contrib/pyln-spec/bolt4/pyln/spec/bolt4/gen_csv_version.py @@ -1 +1 @@ -__csv_version__ = "3" +__csv_version__ = "4" diff --git a/contrib/pyln-spec/bolt4/pyln/spec/bolt4/gen_version.py b/contrib/pyln-spec/bolt4/pyln/spec/bolt4/gen_version.py index 3377756caf44..fe86b5a5abaf 100644 --- a/contrib/pyln-spec/bolt4/pyln/spec/bolt4/gen_version.py +++ b/contrib/pyln-spec/bolt4/pyln/spec/bolt4/gen_version.py @@ -1,3 +1,3 @@ __base_version__ = "1.0" -__post_version__ = "222" -__gitversion__ = "f1c797df2966237244527c1c6343dbe9bc765342" +__post_version__ = "246" +__gitversion__ = "f32c6ddb5f11b431c9bb4f501cdec604172a90de" diff --git a/contrib/pyln-spec/bolt4/pyln/spec/bolt4/text.py b/contrib/pyln-spec/bolt4/pyln/spec/bolt4/text.py index 398e908a8659..fe6454e2b7d0 100644 --- a/contrib/pyln-spec/bolt4/pyln/spec/bolt4/text.py +++ b/contrib/pyln-spec/bolt4/pyln/spec/bolt4/text.py @@ -854,7 +854,9 @@ * 0x1000 (UPDATE): new channel update enclosed Please note that the `channel_update` field is mandatory in messages whose -`failure_code` includes the `UPDATE` flag. +`failure_code` includes the `UPDATE` flag. It is encoded *with* the message +type prefix, i.e. it should always start with `0x0102`. Note that historical +lightning implementations serialized this without the `0x0102` message type. The following `failure_code`s are defined: @@ -999,11 +1001,13 @@ 1. type: UPDATE|20 (`channel_disabled`) 2. data: - * [`u16`:`flags`] + * [`u16`:`disabled_flags`] * [`u16`:`len`] * [`len*byte`:`channel_update`] The channel from the processing node has been disabled. +No flags for `disabled_flags` are currently defined, thus it is currently +always two zero bytes. 1. type: 21 (`expiry_too_far`) @@ -1115,6 +1119,15 @@ - if the `amt_to_forward` does NOT correspond with the `incoming_htlc_amt` from the final node's HTLC: - MUST return a `final_incorrect_htlc_amount` error. + - if it returns a `channel_update`: + - MUST set `short_channel_id` to the `short_channel_id` used by the incoming onion. + +### Rationale + +In the case of multiple short_channel_id aliases, the `channel_update` +`short_channel_id` should refer to the one the original sender is +expecting, to both avoid confusion and to avoid leaking information +about other aliases (or the real location of the channel UTXO). ## Receiving Failure Codes diff --git a/contrib/pyln-spec/bolt4/pyproject.toml b/contrib/pyln-spec/bolt4/pyproject.toml index 1d3361de1b91..eb261be16ae9 100644 --- a/contrib/pyln-spec/bolt4/pyproject.toml +++ b/contrib/pyln-spec/bolt4/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "pyln-bolt4" -version = "1.0.2.187.post0" +version = "1.0.4.246" description = "A pure python implementation of BOLT4" authors = ["Rusty Russell "] license = "MIT" diff --git a/contrib/pyln-spec/bolt7/pyln/spec/bolt7/csv.py b/contrib/pyln-spec/bolt7/pyln/spec/bolt7/csv.py index d94248c545a7..80d60c1a286b 100644 --- a/contrib/pyln-spec/bolt7/pyln/spec/bolt7/csv.py +++ b/contrib/pyln-spec/bolt7/pyln/spec/bolt7/csv.py @@ -38,7 +38,7 @@ "msgdata,channel_update,htlc_minimum_msat,u64,", "msgdata,channel_update,fee_base_msat,u32,", "msgdata,channel_update,fee_proportional_millionths,u32,", - "msgdata,channel_update,htlc_maximum_msat,u64,,option_channel_htlc_max", + "msgdata,channel_update,htlc_maximum_msat,u64,", "msgtype,query_short_channel_ids,261,gossip_queries", "msgdata,query_short_channel_ids,chain_hash,chain_hash,", "msgdata,query_short_channel_ids,len,u16,", diff --git a/contrib/pyln-spec/bolt7/pyln/spec/bolt7/gen_csv_version.py b/contrib/pyln-spec/bolt7/pyln/spec/bolt7/gen_csv_version.py index fec7e9616295..85d6a77f6912 100644 --- a/contrib/pyln-spec/bolt7/pyln/spec/bolt7/gen_csv_version.py +++ b/contrib/pyln-spec/bolt7/pyln/spec/bolt7/gen_csv_version.py @@ -1 +1 @@ -__csv_version__ = "3" +__csv_version__ = "4" diff --git a/contrib/pyln-spec/bolt7/pyln/spec/bolt7/gen_version.py b/contrib/pyln-spec/bolt7/pyln/spec/bolt7/gen_version.py index 3377756caf44..fe86b5a5abaf 100644 --- a/contrib/pyln-spec/bolt7/pyln/spec/bolt7/gen_version.py +++ b/contrib/pyln-spec/bolt7/pyln/spec/bolt7/gen_version.py @@ -1,3 +1,3 @@ __base_version__ = "1.0" -__post_version__ = "222" -__gitversion__ = "f1c797df2966237244527c1c6343dbe9bc765342" +__post_version__ = "246" +__gitversion__ = "f32c6ddb5f11b431c9bb4f501cdec604172a90de" diff --git a/contrib/pyln-spec/bolt7/pyln/spec/bolt7/text.py b/contrib/pyln-spec/bolt7/pyln/spec/bolt7/text.py index 84c430ec8a2b..404303a26ddd 100644 --- a/contrib/pyln-spec/bolt7/pyln/spec/bolt7/text.py +++ b/contrib/pyln-spec/bolt7/pyln/spec/bolt7/text.py @@ -86,7 +86,7 @@ A node: - if the `open_channel` message has the `announce_channel` bit set AND a `shutdown` message has not been sent: - MUST send the `announcement_signatures` message. - - MUST NOT send `announcement_signatures` messages until `funding_locked` + - MUST NOT send `announcement_signatures` messages until `channel_ready` has been sent and received AND the funding transaction has at least six confirmations. - otherwise: - MUST NOT send the `announcement_signatures` message. @@ -105,8 +105,8 @@ `error` and fail the channel. - if it has sent AND received a valid `announcement_signatures` message: - SHOULD queue the `channel_announcement` message for its peers. - - if it has not sent funding_locked: - - MAY defer handling the announcement_signatures until after it has sent funding_locked + - if it has not sent `channel_ready`: + - MAY defer handling the announcement_signatures until after it has sent `channel_ready` - otherwise: - MUST ignore it. @@ -168,7 +168,7 @@ - for the _Bitcoin blockchain_: - MUST set `chain_hash` value (encoded in hex) equal to `6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000`. - MUST set `short_channel_id` to refer to the confirmed funding transaction, - as specified in [BOLT #2](02-peer-protocol.md#the-funding_locked-message). + as specified in [BOLT #2](02-peer-protocol.md#the-channel_ready-message). - Note: the corresponding output MUST be a P2WSH, as described in [BOLT #3](03-transactions.md#funding-transaction-output). - MUST set `node_id_1` and `node_id_2` to the public keys of the two nodes operating the channel, such that `node_id_1` is the lexicographically-lesser of the @@ -225,7 +225,7 @@ - otherwise: - SHOULD store this `channel_announcement`. - once its funding output has been spent OR reorganized out: - - SHOULD forget a channel. + - SHOULD forget a channel after a 12-block delay. ### Rationale @@ -250,6 +250,10 @@ will have _even_ feature bits (["It's OK to be odd!"](00-introduction.md#glossary-and-terminology-guide)). +A delay of 12-blocks is used when forgetting a channel on funding output spend +as to permit a new `channel_announcement` to propagate which indicates this +channel was spliced. + ## The `node_announcement` Message This gossip message allows a node to indicate extra data associated with it, in @@ -287,6 +291,10 @@ onion service addresses; Encodes: `[32:32_byte_ed25519_pubkey] || [2:checksum] || [1:version]`, where `checksum = sha3(".onion checksum" | pubkey || version)[:2]`. + * `5`: DNS hostname; data = `[1:hostname_len][hostname_len:hostname][2:port]` (length up to 258) + * `hostname` bytes MUST be ASCII characters. + * Non-ASCII characters MUST be encoded using Punycode: + https://en.wikipedia.org/wiki/Punycode ### Requirements @@ -308,13 +316,14 @@ - MUST place address descriptors in ascending order. - SHOULD NOT place any zero-typed address descriptors anywhere. - SHOULD use placement only for aligning fields that follow `addresses`. - - MUST NOT create a `type 1` OR `type 2` address descriptor with `port` equal - to 0. + - MUST NOT create a `type 1`, `type 2` or `type 5` address descriptor with + `port` equal to 0. - SHOULD ensure `ipv4_addr` AND `ipv6_addr` are routable addresses. - MUST set `features` according to [BOLT #9](09-features.md#assigned-features-flags) - SHOULD set `flen` to the minimum length required to hold the `features` bits it sets. - SHOULD not announce a Tor v2 onion service. + - MUST NOT announce more than one `type 5` DNS hostname. The receiving node: - if `node_id` is NOT a valid compressed public key: @@ -339,7 +348,7 @@ - SHOULD send a `warning`. - MAY close the connection. - if `port` is equal to 0: - - SHOULD ignore `ipv6_addr` OR `ipv4_addr`. + - SHOULD ignore `ipv6_addr` OR `ipv4_addr` OR `hostname`. - if `node_id` is NOT previously known from a `channel_announcement` message, OR if `timestamp` is NOT greater than the last-received `node_announcement` from this `node_id`: @@ -352,6 +361,9 @@ - MAY use `rgb_color` AND `alias` to reference nodes in interfaces. - SHOULD insinuate their self-signed origins. - SHOULD ignore Tor v2 onion services. + - if more than one `type 5` address is announced: + - SHOULD ignore the additional data. + - MUST not forward the `node_announcement`. ### Rationale @@ -414,7 +426,7 @@ * [`u64`:`htlc_minimum_msat`] * [`u32`:`fee_base_msat`] * [`u32`:`fee_proportional_millionths`] - * [`u64`:`htlc_maximum_msat`] (option_channel_htlc_max) + * [`u64`:`htlc_maximum_msat`] The `channel_flags` bitfield is used to indicate the direction of the channel: it identifies the node that this update originated from and signals various options @@ -426,18 +438,12 @@ | 0 | `direction` | Direction this update refers to. | | 1 | `disable` | Disable the channel. | -The `message_flags` bitfield is used to indicate the presence of optional -fields in the `channel_update` message: - -| Bit Position | Name | Field | -| ------------- | ------------------------- | -------------------------------- | -| 0 | `option_channel_htlc_max` | `htlc_maximum_msat` | +The `message_flags` bitfield is used to provide additional details about the message: -Note that the `htlc_maximum_msat` field is static in the current -protocol over the life of the channel: it is *not* designed to be -indicative of real-time channel capacity in each direction, which -would be both a massive data leak and uselessly spam the network (it -takes an average of 30 seconds for gossip to propagate each hop). +| Bit Position | Name | +| ------------- | ---------------| +| 0 | `must_be_one` | +| 1 | `dont_forward` | The `node_id` for the signature verification is taken from the corresponding `channel_announcement`: `node_id_1` if the least-significant bit of flags is 0 @@ -446,10 +452,13 @@ ### Requirements The origin node: - - MUST NOT send a created `channel_update` before `funding_locked` has been received. + - MUST NOT send a created `channel_update` before `channel_ready` has been received. - MAY create a `channel_update` to communicate the channel parameters to the channel peer, even though the channel has not yet been announced (i.e. the `announce_channel` bit was not set). + - MUST set the `short_channel_id` to either an `alias` it has + received from the peer, or the real channel `short_channel_id`. + - MUST set `dont_forward` to 1 in `message_flags` - MUST NOT forward such a `channel_update` to other peers, for privacy reasons. - Note: such a `channel_update`, one not preceded by a @@ -463,15 +472,8 @@ - MUST set the `direction` bit of `channel_flags` to 0. - otherwise: - MUST set the `direction` bit of `channel_flags` to 1. - - if the `htlc_maximum_msat` field is present: - - MUST set the `option_channel_htlc_max` bit of `message_flags` to 1. - - MUST set `htlc_maximum_msat` to the maximum value it will send through this channel for a single HTLC. - - MUST set this to less than or equal to the channel capacity. - - MUST set this to less than or equal to `max_htlc_value_in_flight_msat` - it received from the peer. - - otherwise: - - MUST set the `option_channel_htlc_max` bit of `message_flags` to 0. - - MUST set bits in `channel_flags` and `message_flags `that are not assigned a meaning to 0. + - MUST set `must_be_one` in `message_flags` to 1. + - MUST set bits in `channel_flags` and `message_flags` that are not assigned a meaning to 0. - MAY create and send a `channel_update` with the `disable` bit set to 1, to signal a channel's temporary unavailability (e.g. due to a loss of connectivity) OR permanent unavailability (e.g. prior to an on-chain @@ -490,6 +492,8 @@ - MUST set `fee_proportional_millionths` to the amount (in millionths of a satoshi) it will charge per transferred satoshi. - SHOULD NOT create redundant `channel_update`s + - If it creates a new `channel_update` with updated channel parameters: + - SHOULD keep accepting the previous channel parameters for 10 minutes The receiving node: - if the `short_channel_id` does NOT match a previous `channel_announcement`, @@ -522,14 +526,11 @@ - otherwise: - SHOULD queue the message for rebroadcasting. - MAY choose NOT to for messages longer than the minimum expected length. - - if the `option_channel_htlc_max` bit of `message_flags` is 0: - - MUST consider `htlc_maximum_msat` not to be present. + - if `htlc_maximum_msat` is greater than channel capacity: + - MAY blacklist this `node_id` + - SHOULD ignore this channel during route considerations. - otherwise: - - if `htlc_maximum_msat` is not present or greater than channel capacity: - - MAY blacklist this `node_id` - - SHOULD ignore this channel during route considerations. - - otherwise: - - SHOULD consider the `htlc_maximum_msat` when routing. + - SHOULD consider the `htlc_maximum_msat` when routing. ### Rationale @@ -539,23 +540,17 @@ 1970-01-01). This cannot be a hard requirement, however, given the possible case of two `channel_update`s within a single second. -It is assumed that more than one `channel_update` message changing the channel -parameters in the same second may be a DoS attempt, and therefore, the node responsible -for signing such messages may be blacklisted. However, a node may send a same -`channel_update` message with a different signature (changing the nonce in signature -signing), and hence fields apart from signature are checked to see if the channel -parameters have changed for the same timestamp. It is also important to note that -ECDSA signatures are malleable. So, an intermediate node who received the `channel_update` -message can rebroadcast it just by changing the `s` component of signature with `-s`. +It is assumed that more than one `channel_update` message changing the channel +parameters in the same second may be a DoS attempt, and therefore, the node responsible +for signing such messages may be blacklisted. However, a node may send a same +`channel_update` message with a different signature (changing the nonce in signature +signing), and hence fields apart from signature are checked to see if the channel +parameters have changed for the same timestamp. It is also important to note that +ECDSA signatures are malleable. So, an intermediate node who received the `channel_update` +message can rebroadcast it just by changing the `s` component of signature with `-s`. This should however not result in the blacklist of the `node_id` from where the message originated. -The explicit `option_channel_htlc_max` flag to indicate the presence -of `htlc_maximum_msat` (rather than having `htlc_maximum_msat` implied -by the message length) allows us to extend the `channel_update` -with different fields in future. Since channels are limited to 2^32-1 -millisatoshis in Bitcoin, the `htlc_maximum_msat` has the same restriction. - The recommendation against redundant `channel_update`s minimizes spamming the network, however it is sometimes inevitable. For example, a channel with a peer which is unreachable will eventually cause a `channel_update` to @@ -564,6 +559,15 @@ messages are batched and replace previous ones, the result may be a single seemingly-redundant update. +When a node creates a new `channel_update` to change its channel parameters, +it will take some time to propagate through the network and payers may use +older parameters. It is recommended to keep accepting older parameters for +at least 10 minutes to improve payment latency and reliability. + +The `must_be_one` field in `message_flags` was previously used to indicate +the presence of the `htlc_maximum_msat` field. This field must now always +be present, so `must_be_one` is a constant value, and ignored by receivers. + ## Query Messages Negotiating the `gossip_queries` option via `init` enables a number @@ -986,8 +990,8 @@ #### Requirements A node: - - if a channel's oldest `channel_update`s `timestamp` is older than two weeks - (1209600 seconds): + - if the `timestamp` of the latest `channel_update` in either direction is + older than two weeks (1209600 seconds): - MAY prune the channel. - MAY ignore the channel. - Note: this is an individual node policy and MUST NOT be enforced by diff --git a/contrib/pyln-spec/bolt7/pyproject.toml b/contrib/pyln-spec/bolt7/pyproject.toml index bc6b128ea567..1048f43bd1e1 100644 --- a/contrib/pyln-spec/bolt7/pyproject.toml +++ b/contrib/pyln-spec/bolt7/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "pyln-bolt7" -version = "1.0.2.186.post0" +version = "1.0.4.246" description = "BOLT7" authors = ["Rusty Russell"] license = "BSD-MIT"