Return-Path: <gsanders87@gmail.com>
Received: from smtp2.osuosl.org (smtp2.osuosl.org [140.211.166.133])
 by lists.linuxfoundation.org (Postfix) with ESMTP id 2C216C002D
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Tue, 17 May 2022 17:56:56 +0000 (UTC)
Received: from localhost (localhost [127.0.0.1])
 by smtp2.osuosl.org (Postfix) with ESMTP id 01C6B40102
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Tue, 17 May 2022 17:56:56 +0000 (UTC)
X-Virus-Scanned: amavisd-new at osuosl.org
X-Spam-Flag: NO
X-Spam-Score: -1.848
X-Spam-Level: 
X-Spam-Status: No, score=-1.848 tagged_above=-999 required=5
 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1,
 DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,
 FREEMAIL_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001,
 HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001,
 SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Authentication-Results: smtp2.osuosl.org (amavisd-new);
 dkim=pass (2048-bit key) header.d=gmail.com
Received: from smtp2.osuosl.org ([127.0.0.1])
 by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)
 with ESMTP id MozlUKW9vbOF
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Tue, 17 May 2022 17:56:52 +0000 (UTC)
X-Greylist: whitelisted by SQLgrey-1.8.0
Received: from mail-yw1-x112c.google.com (mail-yw1-x112c.google.com
 [IPv6:2607:f8b0:4864:20::112c])
 by smtp2.osuosl.org (Postfix) with ESMTPS id 85D86400E7
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Tue, 17 May 2022 17:56:52 +0000 (UTC)
Received: by mail-yw1-x112c.google.com with SMTP id
 00721157ae682-2ebf4b91212so195810527b3.8
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Tue, 17 May 2022 10:56:52 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112;
 h=mime-version:references:in-reply-to:from:date:message-id:subject:to;
 bh=IPSmmfu8DGHH6ekbR4ZmCoQpMjkx2Vwj2zvFBUooybs=;
 b=ayMTg4ooKfc8qdOAt1V+6TitFNsDBJYwsj3SXrRM1TzR+G1IeNI4zB95sj0fwSZc/U
 dwgda9zEvyT1QWGijnjZGfGF+FIQsCdiWFhV8lPDzU54QGncdDtrNxtQkMn5REe9bRBq
 50TkwSOen1+YM1v4lRWPXz71LubMW9GhQD6r8NQiroxXUc4ZRo0FWy8wQ3ZXKqmmWJlm
 bGXYJsATcAaUHXTxUPECwkWKjH+JQuYFQTIeHWjtSvC6/10JFgOHjf0Km0vmFvfk2MuJ
 IQrVBM4JbDUGzOq7oGFRc4Pz/QpUILfkoraSQqNkWEsk5tjpR4wqBoE6KqGp2H7SAJMP
 SF6g==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20210112;
 h=x-gm-message-state:mime-version:references:in-reply-to:from:date
 :message-id:subject:to;
 bh=IPSmmfu8DGHH6ekbR4ZmCoQpMjkx2Vwj2zvFBUooybs=;
 b=hMRQdQMHldowrzGHlsgwg3VLbfmMBadHPocGzz86O2Av86t6DQnWTImbuH1SY1+swP
 QdFIaowrWx7wo0bwMUc7ZnajQ+BM1w9j8opc+VfwwScMQL/1jxb3svf8C8MRsD/HEpft
 wymCQAmzecRx1EC/Ejzd5lCaWEAv2d8/YiWF9s/7E2chazDzPmSvmvAkV0GyP3Xb+zXd
 w8idxuthP5rE7ggZTh0gHCszROF5f7WKmLRMkx3Fasz6FM63Ze6wxTjjgFbHCjyt03oD
 F7lGk272XILuA/ipua6X9fFiRCAjHf1uSQF7k3EvRkYdn2/dv+8/hAG/xhp+zrJkod/i
 FkcA==
X-Gm-Message-State: AOAM531eD0wv6dWOAyKnvw73JmpRG3tpzPKfDQds9oD9Jvq7hB9qr6uN
 dMtkT+FBw3zHmUNDLql7BIVWsnnK9qxG9XjCn8mq4TtVt9Q=
X-Google-Smtp-Source: ABdhPJzb4gbVHbMFKB2q4RAljOel9oZBt2yZIsWS3JptHmlxKKBkeC32/IceB6+SNwxPus2g/wLd4epOQ0PZXjq5Ttw=
X-Received: by 2002:a81:1f02:0:b0:2f8:5866:9431 with SMTP id
 f2-20020a811f02000000b002f858669431mr28274733ywf.403.1652810211127; Tue, 17
 May 2022 10:56:51 -0700 (PDT)
MIME-Version: 1.0
References: <CAFXO6=JROe_9ih2h+_CCH-UbxehsM5RQ6YyNnPesEpveBEtdow@mail.gmail.com>
In-Reply-To: <CAFXO6=JROe_9ih2h+_CCH-UbxehsM5RQ6YyNnPesEpveBEtdow@mail.gmail.com>
From: Greg Sanders <gsanders87@gmail.com>
Date: Tue, 17 May 2022 13:56:40 -0400
Message-ID: <CAB3F3DsJPHQJiyRfBTAFfP2SSjOJbGREbGO0N5rXmxwkHLeHeg@mail.gmail.com>
To: Gloria Zhao <gloriajzhao@gmail.com>, 
 Bitcoin Protocol Discussion <bitcoin-dev@lists.linuxfoundation.org>
Content-Type: multipart/alternative; boundary="00000000000083f72c05df38dd1b"
X-Mailman-Approved-At: Tue, 17 May 2022 18:09:25 +0000
Subject: Re: [bitcoin-dev] Package Relay Proposal
X-BeenThere: bitcoin-dev@lists.linuxfoundation.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: Bitcoin Protocol Discussion <bitcoin-dev.lists.linuxfoundation.org>
List-Unsubscribe: <https://lists.linuxfoundation.org/mailman/options/bitcoin-dev>, 
 <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=unsubscribe>
List-Archive: <http://lists.linuxfoundation.org/pipermail/bitcoin-dev/>
List-Post: <mailto:bitcoin-dev@lists.linuxfoundation.org>
List-Help: <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=help>
List-Subscribe: <https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev>, 
 <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=subscribe>
X-List-Received-Date: Tue, 17 May 2022 17:56:56 -0000

--00000000000083f72c05df38dd1b
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Hi Gloria,

Thanks for working on this important proposal!

Still a lot to digest, but I just had on area of comment/question:

> A child-with-unconfirmed-parents package sent between nodes must abide by
the rules below, otherwise the package is malformed and the sender should
be disconnected.

> However, if the child has confirmed parents, they must not be in the
package.

If my naive understanding is correct, this means things like otherwise
common situations such as a new block will result in disconnects, say when
the sender doesn't hear about a new block which makes the relay package
superfluous/irrelevant. Similar would be disconnection
when confirmed gets turned into unconfirmed, but those situations are
extremely uncommon. The other rules are entirely under the control
of the sender, which leads me to wonder if it's appropriate.

Cheers,
Greg

On Tue, May 17, 2022 at 12:09 PM Gloria Zhao via bitcoin-dev <
bitcoin-dev@lists.linuxfoundation.org> wrote:

> Hi everybody,
>
> I=E2=80=99m writing to propose a set of p2p protocol changes to enable pa=
ckage
> relay, soliciting feedback on the design and approach. Here is a link
> to the most up-to-date proposal:
>
> https://github.com/bitcoin/bips/pull/1324
>
> If you have concept or approach feedback, *please respond on the
> mailing list* to allow everybody to view and participate in the
> discussion. If you find a typo or inaccurate wording, please feel free
> to leave suggestions on the PR.
>
> I=E2=80=99m also working on an implementation for Bitcoin Core.
>
>
> The rest of this post will include the same contents as the proposal,
> with a bit of reordering and additional context. If you are not 100%
> up-to-date on package relay and find the proposal hard to follow, I
> hope you find this format more informative and persuasive.
>
>
> =3D=3DBackground and Motivation=3D=3D
>
> Users may create and broadcast transactions that depend upon, i.e.
> spend outputs of, unconfirmed transactions. A =E2=80=9Cpackage=E2=80=9D i=
s the
> widely-used term for a group of transactions representable by a
> connected Directed Acyclic Graph (where a directed edge exists between
> a transaction that spends the output of another transaction).
>
> Incentive-compatible mempool and miner policies help create a fair,
> fee-based market for block space. While miners maximize transaction
> fees in order to earn higher block rewards, non-mining users
> participating in transaction relay reap many benefits from employing
> policies that result in a mempool with the same contents, including
> faster compact block relay and more accurate fee estimation.
> Additionally, users may take advantage of mempool and miner policy to
> bump the priority of their transactions by attaching high-fee
> descendants (Child Pays for Parent or CPFP).  Only considering
> transactions one at a time for submission to the mempool creates a
> limitation in the node's ability to determine which transactions have
> the highest feerates, since it cannot take into account descendants
> until all the transactions are in the mempool. Similarly, it cannot
> use a transaction's descendants when considering which of two
> conflicting transactions to keep (Replace by Fee or RBF).
>
> When a user's transaction does not meet a mempool's minimum feerate
> and they cannot create a replacement transaction directly, their
> transaction will simply be rejected by this mempool. They also cannot
> attach a descendant to pay for replacing a conflicting transaction.
> This limitation harms users' ability to fee-bump their transactions.
> Further, it presents a security issue in contracting protocols which
> rely on **presigned**, time-sensitive transactions to prevent cheating
> (HTLC-Timeout in LN Penalty [1] [2] [3], Unvault Cancel in Revault
> [4], Refund Transaction in Discreet Log Contracts [5], Updates in
> eltoo [6]). In other words, a key security assumption of many
> contracting protocols is that all parties can propagate and confirm
> transactions in a timely manner.
>
> In the past few years, increasing attention [0][1][2][3][6] has been
> brought to **pinning attacks**, a type of censorship in which the
> attacker uses mempool policy restrictions to prevent a transaction
> from being relayed or getting mined.  TLDR: revocation transactions
> must meet a certain confirmation target to be effective, but their
> feerates are negotiated well ahead of broadcast time. If the
> forecasted feerate was too low and no fee-bumping options are
> available, attackers can steal money from their counterparties. I walk
> through a concrete example for stealing Lightning HTLC outputs at
> ~23:58 in this talk [7][8].  Note that most attacks are only possible
> when the market for blockspace at broadcast time  demands much higher
> feerates than originally anticipated at signing time. Always
> overestimating fees may sidestep this issue temporarily (while mempool
> traffic is low and predictable), but this solution is not foolproof
> and wastes users' money. The feerate market can change due to sudden
> spikes in traffic (e.g. huge 12sat/vB dump a few days ago [9]) or
> sustained, high volume of Bitcoin payments (e.g.  April 2021 and
> December 2017).
>
> The best solution is to enable nodes to consider packages of
> transactions as a unit, e.g. one or more low-fee parent transactions
> with a high-fee child, instead of separately. A package-aware mempool
> policy can help determine if it would actually be economically
> rational to accept a transaction to the mempool if it doesn't meet fee
> requirements individually. Network-wide adoption of these policies
> would create a more purely-feerate-based market for block space and
> allow contracting protocols to adjust fees (and therefore mining
> priority) at broadcast time.  Some support for packages has existed in
> Bitcoin Core for years. Since v0.13, Bitcoin Core has used ancestor
> packages instead of individual transactions to evaluate the incentive
> compatibility of transactions in the mempool [10] and select them for
> inclusion in blocks [11].
>
> Package Relay, the concept of {announcing, requesting, downloading}
> packages between nodes on the p2p network, has also been discussed for
> many years. The earliest public mention I can find is from 2015 [12].
> The two most common use cases for package relay are fee-bumping
> otherwise-too-low-fee transactions and reducing the amount of orphans.
> It seems uncontroversial to say that everybody desires package relay
> conceptually, with varying degrees of urgency. Lots of work has been
> done by others over the past few years, from which I've taken
> inspiration from [13][14][15][16].
>
> My approach has been to split the project into two components: (1) Packag=
e
> Mempool Accept, which includes validation logic and mempool policy.
> (3) Package Relay, which includes the p2p protocol changes.
>
> Progress so far:
> After discussions with various developers of contracting protocols
> (with heavier emphasis towards LN), it was determined that a
> package containing a child with all of its unconfirmed parents
> (child-with-unconfirmed-parents or 1-child-multi-parent package) would
> be sufficient for their use case, i.e. fee-bumping presigned
> transactions. A child-with-unconfirmed-parents package has several
> properties that make many things easier to reason about.
>
> A few months ago, I proposed a set of policies for safe package
> validation and fee assessment for packages of this restricted
> topology [17]. A series of PRs implementing this proposal have
> been merged into Bitcoin Core [18].
>
> Theoretically, developing a safe and incentive-compatible package
> mempool acceptance policy is sufficient to solve this issue. Nodes
> could opportunistically accept packages (e.g. by trying combinations
> of transactions rejected from their mempools), but this practice would
> likely be inefficient at best and open new Denial of Service attacks
> at worst. Additional p2p messages may enable nodes to request and
> share package validation-related information with one another in a
> more communication-efficient way.
>
> Given that only package RBF remains for package mempool accept, and we
> can make progress on p2p and mempool in parallel, I think it=E2=80=99s
> appropriate to put forward a package relay proposal.
>
> =3D=3DProposal=3D=3D
>
> This proposal contains 2 components: a =E2=80=9Cgeneric=E2=80=9D package =
relay
> protocol and an extension of it, child-with-unconfirmed-parents
> packages, as version 1 package relay. Another version of packages,
> =E2=80=9Ctx-with-unconfirmed-ancestors=E2=80=9D can be created to extend =
package relay
> for eliminating orphans.
>
> =3D=3D=3DGeneric Package Relay=3D=3D=3D
>
> Two main ideas are introduced:
>
> Download and validate packages of transactions together.
>
> Provide information to help peers decide whether to request and/or how
> to validate transactions which are part of a package.
>
> =3D=3D=3D=3DIntended Protocol Flow=3D=3D=3D=3D
>
> Due to the asynchronous nature of a distributed transaction relay
> network, nodes may not receive all of the information needed to
> validate a transaction at once. For example, after a node completes
> Initial Block Download (IBD) and first starts participating in
> transaction relay with an empty mempool, it is common to receive
> orphans. In such scenarios where a node is aware that it is missing
> information, a ''receiver-initiated'' dialogue is appropriate:
>
> 1. Receiver requests package information.
>
> 2. The sender provides package information, including the wtxids of
>    the transactions in the package and anything else that might be
> relevant (e.g. total fees and size).
>
> 3. The reciever uses the package information to decide how to request
>    and validate the transactions.
>
> Sometimes, no matter what order transactions are received by a node,
> validating them individually is insufficient. When the sender is aware
> of additional information that the receiver needs to accept a package,
> a proactive ''sender-initiated'' dialogue should be enabled:
>
> 1. Sender announces they have package information pertaining to a
>    transaction that might otherwise be undesired on its own.
>
> 2. The receiver requests package information.
>
> 3. The sender provides package information, including the wtxids of
>    the transactions in the package and anything else that might be
> relevant (e.g. total fees and size).
>
> 4. The reciever uses the package information to decide how to request
>    and validate the transactions.
>
> Package relay is negotiated between two peers during the version
> handshake. Package relay requires both peers to support wtxid-based
> relay because package transactions are referenced by their wtxid.
>
> =3D=3D=3D=3DNew Messages=3D=3D=3D=3D
>
> Three new protocol messages are added for use in any version of
> package relay. Additionally, each version of package relay must define
> its own inv type and "pckginfo" message version, referred to in this
> document as "MSG_PCKG" and "pckginfo" respectively. See
> BIP-v1-packages for a concrete example.
>
> =3D=3D=3D=3D=3Dsendpackages=3D=3D=3D=3D=3D
>
> {|
> |  Field Name  ||  Type  ||  Size  ||  Purpose
> |-
> |version || uint32_t || 4 || Denotes a package version supported by the
> node.
> |-
> |max_count || uint32_t || 4 ||Specifies the maximum number of transaction=
s
> per package this node is
> willing to accept.
> |-
> |max_weight || uint32_t || 4 ||Specifies the maximum total weight per
> package this node is willing
> to accept.
> |-
> |}
>
> 1. The "sendpackages" message has the structure defined above, with
>    pchCommand =3D=3D "sendpackages".
>
> 2. During version handshake, nodes should send a "sendpackages"
>    message indicate they support package relay and may request
> packages.
>
> 3. The message should contain a version supported by the node. Nodes
>    should send a "sendpackages" message for each version they support.
>
> 4. The "sendpackages" message MUST be sent before sending a "verack"
>    message. If a "sendpackages" message is received afer "verack", the
> sender should be disconnected.
>
> 5. If 'fRelay=3D=3Dfalse' in a peer's version message, the node must not
>    send "sendpackages" to them. If a "sendpackages" message is
> received by a peer after sending `fRelay=3D=3Dfalse` in their version
> message, the sender should be disconnected.
>
> 6.. Upon receipt of a "sendpackages" message with a version that is
> not supported, a node must treat the peer as if it never received the
> message.
>
> 7. If both peers send "wtxidrelay" and "sendpackages" with the same
>    version, the peers should announce, request, and send package
> information to each other.
>
> =3D=3D=3D=3D=3Dgetpckgtxns=3D=3D=3D=3D=3D
>
> {|
> |  Field Name  ||  Type  ||  Size  ||   Purpose
> |-
> |txns_length||CompactSize||1 or 3 bytes|| The number of transactions
> requested.
> |-
> |txns||List of wtxids||txns_length * 32|| The wtxids of each transaction
> in the package.
> |}
>
> 1. The "getpckgtxns" message has the structure defined above, with
>    pchCommand =3D=3D "getpckgtxns".
>
> 2. A "getpckgtxns" message should be used to request all or some of
>    the transactions previously announced in a "pckginfo" message,
> specified by witness transactiosome id.
>
> 3. Upon receipt of a "getpckgtxns" message, a node must respond with
>    either a "pckgtxns" containing the requested transactions or a
> "notfound" message indicating one or more of the transactions is
> unavailable. This allows the receiver to avoid downloading and storing
> transactions that cannot be validated immediately.
>
> 4. A "getpckgtxns" message should only be sent if both peers agreed to
>    send packages in the version handshake. If a "getpckgtxns" message
> is received from a peer with which package relay was not negotiated,
> the sender should be disconnected.
>
> =3D=3D=3D=3D=3Dpckgtxns=3D=3D=3D=3D=3D
>
> {|
> |  Field Name  ||  Type  ||  Size  ||   Purpose
> |-
> |txns_length||CompactSize||1 or 3 bytes|| The number of transactions
> provided.
> |-
> |txns||List of transactions||variable|| The transactions in the package.
> |}
>
> 1. The "pckgtxns" message has the structure defined above, with
>    pchCommand =3D=3D "pckgtxns".
>
> 2. A "pckgtxns" message should contain the transaction data requested
>    using "getpckgtxns".
>
> 3. A "pckgtxns" message should only be sent to a peer that requested
>    the package using "getpckgtxns". If a node receives an unsolicited
> package, the sender should be disconnected.
>
> 4. A "pckgtxns" message should only be sent if both peers agreed to
>    send packages in the version handshake. If a "pckgtxns" message is
> received from a peer with which package relay was not negotiated, the
> sender should be disconnected.
>
> =3D=3D=3DVersion 1 Packages: child-with-unconfirmed-parents=3D=3D=3D
>
> This extends package relay for packages consisting of one transaction
> and all of its unconfirmed parents,by defining version 1 packages, a
> pckginfo1 message, and a MSG_PCKG1 inv type. It enables the use case
> in which a child pays for its otherwise-too-low-fee parents and their
> mempool conflict(s).
>
> =3D=3D=3D=3DIntended Protocol Flow=3D=3D=3D=3D
>
> When relaying a package of low-fee parent(s) and high-fee child, the
> sender and receiver do the following:
>
> 1. Sender announces they have a child-with-unconfirmed-parents package
>    for a child that pays for otherwise-too-low-fee parent(s) using
> "inv(MSG_PCKG1)".
>
> 2. The receiver requests package information using
>    "getdata(MSG_PCKG1)".
>
> 3. The sender provides package information using "pckginfo1",
>    including the blockhash of the sender's best block, the wtxids of
> the transactions in the package, their total fees and total weight.
>
> 4. The reciever uses the package information to decide how to request
>    the transactions. For example, if the receiver already has some of
> the transactions in their mempool, they only request the missing ones.
> They could also decide not to request the package at all based on the
> fee information provided.
>
> 5. Upon receiving a "pckgtxns", the receiver submits the transactions
>    together as a package.
>
> =3D=3D=3D=3DNew Messages=3D=3D=3D=3D
>
> A new inv type, "MSG_PCKG1", and new protocol message, "PCKGINFO1",
> are added.
>
> =3D=3D=3D=3D=3Dpckginfo1=3D=3D=3D=3D=3D
>
> {|
> |  Field Name  ||  Type  ||  Size  ||   Purpose
> |-
> |blockhash || uint256 || 32 || The chain tip at which this package is
> defined.
> |-
> |pckg_fee||CAmount||4|| The sum total fees paid by all transactions in th=
e
> package.
> |-
> |pckg_weight||int64_t||8|| The sum total weight of all transactions in th=
e
> package.
> |-
> |txns_length||CompactSize||1 or 3 bytes|| The number of transactions
> provided.
> |-
> |txns||List of wtxids||txns_length * 32|| The wtxids of each transaction
> in the package.
> |}
>
>
> 1. The "pckginfo1" message has the structure defined above, with
>    pchCommand =3D=3D "pckginfo1".
>
> 2. A "pckginfo1" message contains information about a version 1
>    package (defined below), referenced by the wtxid of the transaction
> it pertains to and the current blockhash.
>
> 3. Upon receipt of a "pckginfo1" message, the node should decide if it
>    wants to validate the package, request transaction data if
> necessary, etc.
>
> 4. Upon receipt of a malformed "pckginfo1" message or package that
>    does not abide by the max_count, max_weight, or other rules
> specified by the version agreed upon in the initial negotiation, the
> sender should be disconnected.  If a node receives a "pckginfo1"
> message for which the "pckg_fee" or "pckg_weight" do not reflect the
> true total fees and weight, respectively, or the transactions in the
> package, the message is malformed.
>
> 5. A node MUST NOT send a "pckginfo1" message that has not been
>    requested by the recipient. Upon receipt of an unsolicited
> "pckginfo1", a node should disconnect the sender.
>
> 6. A "pckginfo1" message should only be sent if both peers agreed to
>    send version 1 packages in the version handshake. If a "pckginfo1"
> message is received from a peer with which package relay was not
> negotiated, the sender should be disconnected.
>
> =3D=3D=3D=3D=3DMSG_PCKG1=3D=3D=3D=3D=3D
>
> 1. A new inv type (MSG_PCKG1 =3D=3D 0x6) is added, for use in inv message=
s
>    and getdata requests pertaining to version 1 packages.
>
> 2. As an inv type, it indicates that both transaction data and version
>    1 package information are available for the transaction. The
> transaction is referenced by its wtxid. As a getdata request type, it
> indicates that the sender wants package information for the
> transaction.
>
> 3. Upon receipt of a "getdata" request for "MSG_PCKG1", the node
>    should respond with the version 1 package corresponding to the
> requested transaction and its current chain tip, or with NOTFOUND.
> The node should not assume that the sender is requesting the
> transaction data as well.
>
> =3D=3D=3D=3DChild With Parent Packages Rules=3D=3D=3D=3D
>
> A child-with-unconfirmed-parents package sent between nodes must abide
> by the rules below, otherwise the package is malformed and the sender
> should be disconnected.
>
> A version 1 or ''child-with-unconfirmed-parents'' package can be
> defined for any transaction that spends unconfirmed inputs. The child
> can be thought of as the "representative" of the package. This package
> can be uniquely identified by the transaction's wtxid and the current
> chain tip block hash.
>
> A ''child-with-unconfirmed-parents'' package MUST be:
>
> 1. ''Sorted topologically.'' For every transaction t in the package,
>    if any of t's parents are present in the package, the parent must
> appear somewhere in the list before t. In other words, the
> transactions must be sorted in ascending order of the number of
> ancestors present in the package.
>
> 2. ''Only 1 child with unconfirmed parents.'' The package must consist
>    of one transaction and its unconfirmed parents. There must not be
> any other transactions in the package. Other dependency relationships
> may exist within the package (e.g. one parent may spend the output of
> another parent) provided that topological order is respected.
>
> 3. ''All unconfirmed parents.'' All of the child's unconfirmed parents
>    must be present.
>
> 4. ''No conflicts.'' None of the transactions in the package may
>    conflict with each other (i.e.  spend the same prevout).
>
> 5. ''Total fees and weight.'' The 'total_fee' and 'total_weight'
>    fields must accurately represent the sum total of all transactions'
> fees and weights as defined in BIP141, respectively.
>
> Not all of the child's parents must be present; the child transaction
> may also spend confirmed inputs. However, if the child has confirmed
> parents, they must not be in the package.
>
> While a child-with-unconfirmed-parents package is perhaps most
> relevant when the child has a higher feerate than its parents, this
> property is not required to construct a valid package.
>
> =3D=3D=3D=3DClarifications=3D=3D=3D=3D
>
> ''Q: Under what circumstances should a sender announce a
> child-with-unconfirmed-parents package?''
>
> A child-with-unconfirmed-parents package for a transaction should be
> announced when it meets the peer's fee filter but one or more of its
> parents don't; a "inv(MSG_PCKG1)" instead of "inv(WTX)" should be sent
> for the child. Each of the parents which meet the peer's fee filter
> should still be announced normally.
>
> ''Q: What if a new block arrives in between messages?''
>
> A child-with-unconfirmed-parents package is defined for a transaction
> based on the current chain state. As such, a new block extending the
> tip may decrease the number of transactions in the package (i.e. if
> any of the transaction's parents were included in the block). In a
> reorg, the number of transactions in the package may decrease or
> increase (i.e. if any of the transaction's parents were included in a
> block in the previous chain but not the new one).
>
> If the new block arrives before the "getdata" or "pckginfo1", nothing
> needs to change.
>
> If the new block arrives before "getpckgtxns" or before "pckgtxns",
> the receiver may need to re-request package information if the block
> contained a transaction in the package. If the block doesn't contain
> any transactions in the package, whether it extends the previous tip
> or causes a reorg, nothing needs to change.
>
> ''Q: Can "getpckgtxns" and "pckgtxns" messages contain only one
> transaction?''
>
> Yes.
>
> =3D=3D=3DFurther Protocol Extensions=3D=3D=3D
>
> When introducing a new type of package, assign it a version number "n"
> and use an additional "sendpackages" message during version handshake
> to negotiate support for it. An additional package information message
> "pckginfon" and inv type "MSG_PCKGn" should be defined for the type of
> package.  However, "getpckgtxns" and "pckgtxns" do not need to be
> changed.
>
> Example proposal for tx-with-unconfirmed-ancestors package relay: [19]
>
> =3D=3D=3DCompatibility=3D=3D=3D
>
> Older clients remain fully compatible and interoperable after this
> change. Clients implementing this protocol will only attempt to send
> and request packages if agreed upon during the version handshake.
>
> =3D=3D=3DPackage Erlay=3D=3D=3D
>
> Clients using BIP330 reconciliation-based transaction relay (Erlay)
> are able to use package relay without interference. In fact, a package
> of transactions may be announced using both Erlay and package relay.
> After reconciliation, if the initiator would have announced a
> transaction by wtxid but also has package information for it, they may
> send "inv(MSG_PCKG)" instead of "inv(WTX)".
>
> =3D=3D=3DRationale=3D=3D=3D
>
> =3D=3D=3D=3DP2P Message Design=3D=3D=3D=3D
>
> These p2p messages are added for communication efficiency and, as
> such, one should measure alternative solutions based on the resources
> used to communicate (not necessarily trustworthy) information: We
> would like to minimize network bandwidth, avoid downloading a
> transaction more than once, avoid downloading transactions that are
> eventually rejected, and minimize storage allocated for
> not-yet-validated transactions.
>
> Consider these (plausible) scenarios in transaction relay:
>
> Alice (the "sender") is relaying transactions to Bob (the "receiver").
> Alice's mempool has a minimum feerate of 1sat/vB and Bob's has a
> minimum feerate of 3sat/vB. For simplicity, all transactions are
> 1600Wu in virtual size and 500 bytes in serialized size. Apart from
> the spending relationships specified, all other inputs are from
> confirmed UTXOs.
>
> 1. Package {A, B} where A pays 0 satoshis and B pays 8000 satoshis in
>    fees.
>
> 2. Package {C, D} where C pays 0 satoshis and D pays 1200 satoshis in
>    fees.
>
> 3. Package {E, F, G, H, J} that pays 4000, 8000, 0, 2000, and 4000
>    satoshis in fees, respectively.
>
> =3D=3D=3D=3DAlternative Designs Considered=3D=3D=3D=3D
>
> ''Package Information Only:'' Just having "pckginfo" gives enough
> information for the receiver to accept the package. Omit the
> "getpckgtxns" and "pckgtxns" messages. While this option is a good
> fallback if batched transaction download fails for some reason, it
> shouldn't be used as the default because it 'always' requires storage
> of unvalidated transactions.
>
> ''No Package Information Round:'' Instead of having a package
> information round, just use the child's wtxid to refer to the package
> and always send the entire package together. This would cause nodes to
> redownload duplicate transactions.
>
> I have also created a slidedeck exploring various alternative designs
> and some examples in which they fall flat [20]. Please feel free to
> suggest other alternatives.
>
> =3D=3D=3D=3DVersioning System=3D=3D=3D=3D
>
> This protocol should be extensible to support multiple types of
> packages based on future desired use cases. Two "flavors" of
> versioning were considered:
>
> 1. When package mempool acceptance is upgraded to support more types
>    of packages, increment the version number (similar to Erlay).
> During version handshake, peers negotiate which version of package
> relay they will use by each sending one "sendpackages" message.
>
> 2. When introducing another type of package, assign a version number
>    to it and announce it as an additional supported version (similar
> to Compact Block Relay). During version handshake, peers send one
> "sendpackages" message for each version supported.
>
> The second option was favored because it allows different parameters
> for different versions.  For example, it should be possible to support
> both "arbitrary topology but maximum 3-transaction" package as well as
> "child-with-unconfirmed-parents with default mempool ancestor limits"
> packages simultaneously.
>
> =3D=3DAcknowledgements=3D=3D
>
> I hope to have made it abundantly clear that this proposal isn=E2=80=99t
> inventing the concept of package relay, and in fact builds upon years
> of work by many others, including Suhas Daftuar and Antoine Riard.
>
> Thank you to John Newbery and Martin Zumsande for input on the design.
>
> Thank you to Matt Corallo, Christian Decker, David Harding, Antoine
> Poinsot, Antoine Riard, Gregory Sanders, Chris Stewart, Bastien
> Teinturier, and others for input on the desired interface for
> contracting protocols.
>
> Looking forward to hearing your thoughts!
>
> Best,
> Gloria
>
> [0]:
> https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-January/0198=
17.html
> [1]:
> https://lists.linuxfoundation.org/pipermail/lightning-dev/2020-April/0026=
39.html
> [2]:
> https://lists.linuxfoundation.org/pipermail/lightning-dev/2020-June/00275=
8.html
> [3]:
> https://github.com/t-bast/lightning-docs/blob/master/pinning-attacks.md
> [4]:
> https://github.com/revault/practical-revault/blob/master/transactions.md#=
cancel_tx
> [5]:
> https://github.com/discreetlogcontracts/dlcspecs/blob/master/Transactions=
.md#refund-transaction
> [6]: https://gist.github.com/instagibbs/60264606e181451e977e439a49f69fe1
> [7]:
> https://btctranscripts.com/adopting-bitcoin/2021/2021-11-16-gloria-zhao-t=
ransaction-relay-policy/#lightning-attacks
> [8]: https://youtu.be/fbWSQvJjKFs?t=3D1438
> [9]:
> https://www.reddit.com/r/Bitcoin/comments/unew4e/looks_like_70_mvb_of_tra=
nsactions_just_got_dumped/
> [10]: https://github.com/bitcoin/bitcoin/pull/7594
> [11]: https://github.com/bitcoin/bitcoin/pull/7600
> [12]: https://github.com/bitcoin/bitcoin/pull/6455#issuecomment-122716820
> [13]: https://gist.github.com/sdaftuar/8756699bfcad4d3806ba9f3396d4e66a
> [14]: https://github.com/bitcoin/bitcoin/issues/14895
> [15]: https://github.com/bitcoin/bitcoin/pull/16401
> [16]: https://github.com/bitcoin/bitcoin/pull/19621
> [17]:
> https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-September/01=
9464.html
> [18]: https://github.com/users/glozow/projects/5/views/4?layout=3Dboard
> [19]: https://gist.github.com/glozow/9b321cd3ef6505135c763112033ff2a7
> [20]:
> https://docs.google.com/presentation/d/1B__KlZO1VzxJGx-0DYChlWawaEmGJ9EGA=
pEzrHqZpQc/edit?usp=3Dsharing
> _______________________________________________
> bitcoin-dev mailing list
> bitcoin-dev@lists.linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>

--00000000000083f72c05df38dd1b
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hi Gloria,<div><br></div><div>Thanks for working on this i=
mportant proposal!</div><div><br></div><div>Still a lot to digest, but I ju=
st had on area of comment/question:</div><div><br></div><div>&gt;=C2=A0<spa=
n style=3D"color:rgb(0,0,0);white-space:pre-wrap">A child-with-unconfirmed-=
parents package sent between nodes must abide </span><span style=3D"color:r=
gb(0,0,0);white-space:pre-wrap">by the rules below, otherwise the package i=
s malformed and the sender </span><span style=3D"color:rgb(0,0,0);white-spa=
ce:pre-wrap">should be disconnected.</span></div><div><span style=3D"color:=
rgb(0,0,0);white-space:pre-wrap"><br></span></div><div><span style=3D"color=
:rgb(0,0,0);white-space:pre-wrap">&gt; </span>However, if the child has con=
firmed parents, they must not be in the package.</div><div><br></div><div><=
span style=3D"color:rgb(0,0,0);white-space:pre-wrap">If my naive understand=
ing is correct, this means things like otherwise common situations such as =
a new block will result in disconnects, say when</span></div><div><span sty=
le=3D"color:rgb(0,0,0);white-space:pre-wrap">the sender doesn&#39;t hear ab=
out a new block which makes the relay package superfluous/irrelevant. Simil=
ar would be disconnection</span></div><div><span style=3D"color:rgb(0,0,0);=
white-space:pre-wrap">when confirmed gets turned into unconfirmed, but thos=
e situations are extremely uncommon. The other rules are entirely under the=
 control</span></div><div><span style=3D"color:rgb(0,0,0);white-space:pre-w=
rap">of the sender, which leads me to wonder if it&#39;s appropriate.</span=
></div><div><span style=3D"color:rgb(0,0,0);white-space:pre-wrap"><br></spa=
n></div><div><span style=3D"white-space:pre-wrap;color:rgb(0,0,0)">Cheers,<=
/span><br></div><div><font color=3D"#000000"><span style=3D"white-space:pre=
-wrap">Greg</span></font></div></div><br><div class=3D"gmail_quote"><div di=
r=3D"ltr" class=3D"gmail_attr">On Tue, May 17, 2022 at 12:09 PM Gloria Zhao=
 via bitcoin-dev &lt;<a href=3D"mailto:bitcoin-dev@lists.linuxfoundation.or=
g">bitcoin-dev@lists.linuxfoundation.org</a>&gt; wrote:<br></div><blockquot=
e class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px s=
olid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr">Hi everybody,<br><=
br>I=E2=80=99m writing to propose a set of p2p protocol changes to enable p=
ackage<br>relay, soliciting feedback on the design and approach. Here is a =
link<br>to the most up-to-date proposal:<br><br><a href=3D"https://github.c=
om/bitcoin/bips/pull/1324" target=3D"_blank">https://github.com/bitcoin/bip=
s/pull/1324</a><br><br>If you have concept or approach feedback, *please re=
spond on the<br>mailing list* to allow everybody to view and participate in=
 the<br>discussion. If you find a typo or inaccurate wording, please feel f=
ree<br>to leave suggestions on the PR.<br><br>I=E2=80=99m also working on a=
n implementation for Bitcoin Core.<br><div><br></div><div><br></div>The res=
t of this post will include the same contents as the proposal,<br>with a bi=
t of reordering and additional context. If you are not 100%<br>up-to-date o=
n package relay and find the proposal hard to follow, I<br><div>hope you fi=
nd this format more informative and persuasive.</div><div><br></div><br>=3D=
=3DBackground and Motivation=3D=3D<br><br>Users may create and broadcast tr=
ansactions that depend upon, i.e.<br>spend outputs of, unconfirmed transact=
ions. A =E2=80=9Cpackage=E2=80=9D is the<br>widely-used term for a group of=
 transactions representable by a<br>connected Directed Acyclic Graph (where=
 a directed edge exists between<br>a transaction that spends the output of =
another transaction).<br><br>Incentive-compatible mempool and miner policie=
s help create a fair,<br>fee-based market for block space. While miners max=
imize transaction<br>fees in order to earn higher block rewards, non-mining=
 users<br>participating in transaction relay reap many benefits from employ=
ing<br>policies that result in a mempool with the same contents, including<=
br>faster compact block relay and more accurate fee estimation.<br>Addition=
ally, users may take advantage of mempool and miner policy to<br>bump the p=
riority of their transactions by attaching high-fee<br>descendants (Child P=
ays for Parent or CPFP).=C2=A0 Only considering<br>transactions one at a ti=
me for submission to the mempool creates a<br>limitation in the node&#39;s =
ability to determine which transactions have<br>the highest feerates, since=
 it cannot take into account descendants<br>until all the transactions are =
in the mempool. Similarly, it cannot<br>use a transaction&#39;s descendants=
 when considering which of two<br>conflicting transactions to keep (Replace=
 by Fee or RBF).<br><br>When a user&#39;s transaction does not meet a mempo=
ol&#39;s minimum feerate<br>and they cannot create a replacement transactio=
n directly, their<br>transaction will simply be rejected by this mempool. T=
hey also cannot<br>attach a descendant to pay for replacing a conflicting t=
ransaction.<br>This limitation harms users&#39; ability to fee-bump their t=
ransactions.<br>Further, it presents a security issue in contracting protoc=
ols which<br>rely on **presigned**, time-sensitive transactions to prevent =
cheating<br>(HTLC-Timeout in LN Penalty [1] [2] [3], Unvault Cancel in Reva=
ult<br>[4], Refund Transaction in Discreet Log Contracts [5], Updates in<br=
>eltoo [6]). In other words, a key security assumption of many<br>contracti=
ng protocols is that all parties can propagate and confirm<br>transactions =
in a timely manner.<br><br>In the past few years, increasing attention [0][=
1][2][3][6] has been<br>brought to **pinning attacks**, a type of censorshi=
p in which the<br>attacker uses mempool policy restrictions to prevent a tr=
ansaction<br>from being relayed or getting mined.=C2=A0 TLDR: revocation tr=
ansactions<br>must meet a certain confirmation target to be effective, but =
their<br>feerates are negotiated well ahead of broadcast time. If the<br>fo=
recasted feerate was too low and no fee-bumping options are<br>available, a=
ttackers can steal money from their counterparties. I walk<br>through a con=
crete example for stealing Lightning HTLC outputs at<br>~23:58 in this talk=
 [7][8].=C2=A0 Note that most attacks are only possible<br>when the market =
for blockspace at broadcast time =C2=A0demands much higher<br>feerates than=
 originally anticipated at signing time. Always<br>overestimating fees may =
sidestep this issue temporarily (while mempool<br>traffic is low and predic=
table), but this solution is not foolproof<br>and wastes users&#39; money. =
The feerate market can change due to sudden<br>spikes in traffic (e.g. huge=
 12sat/vB dump a few days ago [9]) or<br>sustained, high volume of Bitcoin =
payments (e.g.=C2=A0 April 2021 and<br>December 2017).<br><br>The best solu=
tion is to enable nodes to consider packages of<br>transactions as a unit, =
e.g. one or more low-fee parent transactions<br>with a high-fee child, inst=
ead of separately. A package-aware mempool<br>policy can help determine if =
it would actually be economically<br>rational to accept a transaction to th=
e mempool if it doesn&#39;t meet fee<br>requirements individually. Network-=
wide adoption of these policies<br>would create a more purely-feerate-based=
 market for block space and<br>allow contracting protocols to adjust fees (=
and therefore mining<br>priority) at broadcast time.=C2=A0 Some support for=
 packages has existed in<br>Bitcoin Core for years. Since v0.13, Bitcoin Co=
re has used ancestor<br>packages instead of individual transactions to eval=
uate the incentive<br>compatibility of transactions in the mempool [10] and=
 select them for<br>inclusion in blocks [11].<br><br>Package Relay, the con=
cept of {announcing, requesting, downloading}<br>packages between nodes on =
the p2p network, has also been discussed for<br>many years. The earliest pu=
blic mention I can find is from 2015 [12].<br>The two most common use cases=
 for package relay are fee-bumping<br>otherwise-too-low-fee transactions an=
d reducing the amount of orphans.<br>It seems uncontroversial to say that e=
verybody desires package relay<br>conceptually, with varying degrees of urg=
ency. Lots of work has been<br>done by others over the past few years, from=
 which I&#39;ve taken<br>inspiration from [13][14][15][16].<br><br>My appro=
ach has been to split the project into two components: (1) Package<br>Mempo=
ol Accept, which includes validation logic and mempool policy.<br>(3) Packa=
ge Relay, which includes the p2p protocol changes.<br><br>Progress so far:<=
br>After discussions with various developers of contracting protocols<br>(w=
ith heavier emphasis towards LN), it was determined that a<br>package conta=
ining a child with all of its unconfirmed parents<br>(child-with-unconfirme=
d-parents or 1-child-multi-parent package) would<br>be sufficient for their=
 use case, i.e. fee-bumping presigned<br>transactions. A child-with-unconfi=
rmed-parents package has several<br>properties that make many things easier=
 to reason about.<br><br>A few months ago, I proposed a set of policies for=
 safe package<br>validation and fee assessment for packages of this restric=
ted<br><div>topology [17]. A series of PRs implementing this proposal have<=
/div><div>been merged into Bitcoin Core [18].<br></div><br>Theoretically, d=
eveloping a safe and incentive-compatible package<br>mempool acceptance pol=
icy is sufficient to solve this issue. Nodes<br>could opportunistically acc=
ept packages (e.g. by trying combinations<br>of transactions rejected from =
their mempools), but this practice would<br>likely be inefficient at best a=
nd open new Denial of Service attacks<br>at worst. Additional p2p messages =
may enable nodes to request and<br>share package validation-related informa=
tion with one another in a<br>more communication-efficient way.<br><br>Give=
n that only package RBF remains for package mempool accept, and we<br>can m=
ake progress on p2p and mempool in parallel, I think it=E2=80=99s<br>approp=
riate to put forward a package relay proposal.<br><br>=3D=3DProposal=3D=3D<=
br><br>This proposal contains 2 components: a =E2=80=9Cgeneric=E2=80=9D pac=
kage relay<br>protocol and an extension of it, child-with-unconfirmed-paren=
ts<br>packages, as version 1 package relay. Another version of packages,<br=
>=E2=80=9Ctx-with-unconfirmed-ancestors=E2=80=9D can be created to extend p=
ackage relay<br>for eliminating orphans.<br><br>=3D=3D=3DGeneric Package Re=
lay=3D=3D=3D<br><br>Two main ideas are introduced:<br><br>Download and vali=
date packages of transactions together.<br><br>Provide information to help =
peers decide whether to request and/or how<br>to validate transactions whic=
h are part of a package.<br><br>=3D=3D=3D=3DIntended Protocol Flow=3D=3D=3D=
=3D<br><br>Due to the asynchronous nature of a distributed transaction rela=
y<br>network, nodes may not receive all of the information needed to<br>val=
idate a transaction at once. For example, after a node completes<br>Initial=
 Block Download (IBD) and first starts participating in<br>transaction rela=
y with an empty mempool, it is common to receive<br>orphans. In such scenar=
ios where a node is aware that it is missing<br>information, a &#39;&#39;re=
ceiver-initiated&#39;&#39; dialogue is appropriate:<br><br>1. Receiver requ=
ests package information.<br><br>2. The sender provides package information=
, including the wtxids of<br>=C2=A0 =C2=A0the transactions in the package a=
nd anything else that might be<br>relevant (e.g. total fees and size).<br><=
br>3. The reciever uses the package information to decide how to request<br=
>=C2=A0 =C2=A0and validate the transactions.<br><br>Sometimes, no matter wh=
at order transactions are received by a node,<br>validating them individual=
ly is insufficient. When the sender is aware<br>of additional information t=
hat the receiver needs to accept a package,<br>a proactive &#39;&#39;sender=
-initiated&#39;&#39; dialogue should be enabled:<br><br>1. Sender announces=
 they have package information pertaining to a<br>=C2=A0 =C2=A0transaction =
that might otherwise be undesired on its own.<br><br>2. The receiver reques=
ts package information.<br><br>3. The sender provides package information, =
including the wtxids of<br>=C2=A0 =C2=A0the transactions in the package and=
 anything else that might be<br>relevant (e.g. total fees and size).<br><br=
>4. The reciever uses the package information to decide how to request<br>=
=C2=A0 =C2=A0and validate the transactions.<br><br>Package relay is negotia=
ted between two peers during the version<br>handshake. Package relay requir=
es both peers to support wtxid-based<br>relay because package transactions =
are referenced by their wtxid.<br><br>=3D=3D=3D=3DNew Messages=3D=3D=3D=3D<=
br><br>Three new protocol messages are added for use in any version of<br>p=
ackage relay. Additionally, each version of package relay must define<br>it=
s own inv type and &quot;pckginfo&quot; message version, referred to in thi=
s<br>document as &quot;MSG_PCKG&quot; and &quot;pckginfo&quot; respectively=
. See<br>BIP-v1-packages for a concrete example.<br><br>=3D=3D=3D=3D=3Dsend=
packages=3D=3D=3D=3D=3D<br><br>{|<br>| =C2=A0Field Name =C2=A0|| =C2=A0Type=
 =C2=A0|| =C2=A0Size =C2=A0|| =C2=A0Purpose<br>|-<br>|version || uint32_t |=
| 4 || Denotes a package version supported by the node.<br>|-<br>|max_count=
 || uint32_t || 4 ||Specifies the maximum number of transactions per packag=
e this node is<br>willing to accept.<br>|-<br>|max_weight || uint32_t || 4 =
||Specifies the maximum total weight per package this node is willing<br>to=
 accept.<br>|-<br>|}<br><br>1. The &quot;sendpackages&quot; message has the=
 structure defined above, with<br>=C2=A0 =C2=A0pchCommand =3D=3D &quot;send=
packages&quot;.<br><br>2. During version handshake, nodes should send a &qu=
ot;sendpackages&quot;<br>=C2=A0 =C2=A0message indicate they support package=
 relay and may request<br>packages.<br><br>3. The message should contain a =
version supported by the node. Nodes<br>=C2=A0 =C2=A0should send a &quot;se=
ndpackages&quot; message for each version they support.<br><br>4. The &quot=
;sendpackages&quot; message MUST be sent before sending a &quot;verack&quot=
;<br>=C2=A0 =C2=A0message. If a &quot;sendpackages&quot; message is receive=
d afer &quot;verack&quot;, the<br>sender should be disconnected.<br><br>5. =
If &#39;fRelay=3D=3Dfalse&#39; in a peer&#39;s version message, the node mu=
st not<br>=C2=A0 =C2=A0send &quot;sendpackages&quot; to them. If a &quot;se=
ndpackages&quot; message is<br>received by a peer after sending `fRelay=3D=
=3Dfalse` in their version<br>message, the sender should be disconnected.<b=
r><br>6.. Upon receipt of a &quot;sendpackages&quot; message with a version=
 that is<br>not supported, a node must treat the peer as if it never receiv=
ed the<br>message.<br><br>7. If both peers send &quot;wtxidrelay&quot; and =
&quot;sendpackages&quot; with the same<br>=C2=A0 =C2=A0version, the peers s=
hould announce, request, and send package<br>information to each other.<br>=
<br>=3D=3D=3D=3D=3Dgetpckgtxns=3D=3D=3D=3D=3D<br><br>{|<br>| =C2=A0Field Na=
me =C2=A0|| =C2=A0Type =C2=A0|| =C2=A0Size =C2=A0|| =C2=A0 Purpose<br>|-<br=
>|txns_length||CompactSize||1 or 3 bytes|| The number of transactions reque=
sted.<br>|-<br>|txns||List of wtxids||txns_length * 32|| The wtxids of each=
 transaction in the package.<br>|}<br><br>1. The &quot;getpckgtxns&quot; me=
ssage has the structure defined above, with<br>=C2=A0 =C2=A0pchCommand =3D=
=3D &quot;getpckgtxns&quot;.<br><br>2. A &quot;getpckgtxns&quot; message sh=
ould be used to request all or some of<br>=C2=A0 =C2=A0the transactions pre=
viously announced in a &quot;pckginfo&quot; message,<br>specified by witnes=
s transactiosome id.<br><br>3. Upon receipt of a &quot;getpckgtxns&quot; me=
ssage, a node must respond with<br>=C2=A0 =C2=A0either a &quot;pckgtxns&quo=
t; containing the requested transactions or a<br>&quot;notfound&quot; messa=
ge indicating one or more of the transactions is<br>unavailable. This allow=
s the receiver to avoid downloading and storing<br>transactions that cannot=
 be validated immediately.<br><br>4. A &quot;getpckgtxns&quot; message shou=
ld only be sent if both peers agreed to<br>=C2=A0 =C2=A0send packages in th=
e version handshake. If a &quot;getpckgtxns&quot; message<br>is received fr=
om a peer with which package relay was not negotiated,<br>the sender should=
 be disconnected.<br><br>=3D=3D=3D=3D=3Dpckgtxns=3D=3D=3D=3D=3D<br><br>{|<b=
r>| =C2=A0Field Name =C2=A0|| =C2=A0Type =C2=A0|| =C2=A0Size =C2=A0|| =C2=
=A0 Purpose<br>|-<br>|txns_length||CompactSize||1 or 3 bytes|| The number o=
f transactions provided.<br>|-<br>|txns||List of transactions||variable|| T=
he transactions in the package.<br>|}<br><br>1. The &quot;pckgtxns&quot; me=
ssage has the structure defined above, with<br>=C2=A0 =C2=A0pchCommand =3D=
=3D &quot;pckgtxns&quot;.<br><br>2. A &quot;pckgtxns&quot; message should c=
ontain the transaction data requested<br>=C2=A0 =C2=A0using &quot;getpckgtx=
ns&quot;.<br><br>3. A &quot;pckgtxns&quot; message should only be sent to a=
 peer that requested<br>=C2=A0 =C2=A0the package using &quot;getpckgtxns&qu=
ot;. If a node receives an unsolicited<br>package, the sender should be dis=
connected.<br><br>4. A &quot;pckgtxns&quot; message should only be sent if =
both peers agreed to<br>=C2=A0 =C2=A0send packages in the version handshake=
. If a &quot;pckgtxns&quot; message is<br>received from a peer with which p=
ackage relay was not negotiated, the<br>sender should be disconnected.<br><=
br>=3D=3D=3DVersion 1 Packages: child-with-unconfirmed-parents=3D=3D=3D =C2=
=A0<br><br>This extends package relay for packages consisting of one transa=
ction<br>and all of its unconfirmed parents,by defining version 1 packages,=
 a<br>pckginfo1 message, and a MSG_PCKG1 inv type. It enables the use case<=
br>in which a child pays for its otherwise-too-low-fee parents and their<br=
>mempool conflict(s).<br><br>=3D=3D=3D=3DIntended Protocol Flow=3D=3D=3D=3D=
<br><br>When relaying a package of low-fee parent(s) and high-fee child, th=
e<br>sender and receiver do the following:<br><br>1. Sender announces they =
have a child-with-unconfirmed-parents package<br>=C2=A0 =C2=A0for a child t=
hat pays for otherwise-too-low-fee parent(s) using<br>&quot;inv(MSG_PCKG1)&=
quot;.<br><br>2. The receiver requests package information using<br>=C2=A0 =
=C2=A0&quot;getdata(MSG_PCKG1)&quot;.<br><br>3. The sender provides package=
 information using &quot;pckginfo1&quot;,<br>=C2=A0 =C2=A0including the blo=
ckhash of the sender&#39;s best block, the wtxids of<br>the transactions in=
 the package, their total fees and total weight.<br><br>4. The reciever use=
s the package information to decide how to request<br>=C2=A0 =C2=A0the tran=
sactions. For example, if the receiver already has some of<br>the transacti=
ons in their mempool, they only request the missing ones.<br>They could als=
o decide not to request the package at all based on the<br>fee information =
provided.<br><br>5. Upon receiving a &quot;pckgtxns&quot;, the receiver sub=
mits the transactions<br>=C2=A0 =C2=A0together as a package.<br><br>=3D=3D=
=3D=3DNew Messages=3D=3D=3D=3D<br><br>A new inv type, &quot;MSG_PCKG1&quot;=
, and new protocol message, &quot;PCKGINFO1&quot;,<br>are added.<br><br>=3D=
=3D=3D=3D=3Dpckginfo1=3D=3D=3D=3D=3D<br><br>{|<br>| =C2=A0Field Name =C2=A0=
|| =C2=A0Type =C2=A0|| =C2=A0Size =C2=A0|| =C2=A0 Purpose<br>|-<br>|blockha=
sh || uint256 || 32 || The chain tip at which this package is defined.<br>|=
-<br>|pckg_fee||CAmount||4|| The sum total fees paid by all transactions in=
 the package.<br>|-<br>|pckg_weight||int64_t||8|| The sum total weight of a=
ll transactions in the package.<br>|-<br>|txns_length||CompactSize||1 or 3 =
bytes|| The number of transactions provided.<br>|-<br>|txns||List of wtxids=
||txns_length * 32|| The wtxids of each transaction in the package.<br>|}<b=
r><br><br>1. The &quot;pckginfo1&quot; message has the structure defined ab=
ove, with<br>=C2=A0 =C2=A0pchCommand =3D=3D &quot;pckginfo1&quot;.<br><br>2=
. A &quot;pckginfo1&quot; message contains information about a version 1<br=
>=C2=A0 =C2=A0package (defined below), referenced by the wtxid of the trans=
action<br>it pertains to and the current blockhash.<br><br>3. Upon receipt =
of a &quot;pckginfo1&quot; message, the node should decide if it<br>=C2=A0 =
=C2=A0wants to validate the package, request transaction data if<br>necessa=
ry, etc.<br><br>4. Upon receipt of a malformed &quot;pckginfo1&quot; messag=
e or package that<br>=C2=A0 =C2=A0does not abide by the max_count, max_weig=
ht, or other rules<br>specified by the version agreed upon in the initial n=
egotiation, the<br>sender should be disconnected.=C2=A0 If a node receives =
a &quot;pckginfo1&quot;<br>message for which the &quot;pckg_fee&quot; or &q=
uot;pckg_weight&quot; do not reflect the<br>true total fees and weight, res=
pectively, or the transactions in the<br>package, the message is malformed.=
<br><br>5. A node MUST NOT send a &quot;pckginfo1&quot; message that has no=
t been<br>=C2=A0 =C2=A0requested by the recipient. Upon receipt of an unsol=
icited<br>&quot;pckginfo1&quot;, a node should disconnect the sender.<br><b=
r>6. A &quot;pckginfo1&quot; message should only be sent if both peers agre=
ed to<br>=C2=A0 =C2=A0send version 1 packages in the version handshake. If =
a &quot;pckginfo1&quot;<br>message is received from a peer with which packa=
ge relay was not<br>negotiated, the sender should be disconnected.<br><br>=
=3D=3D=3D=3D=3DMSG_PCKG1=3D=3D=3D=3D=3D<br><br>1. A new inv type (MSG_PCKG1=
 =3D=3D 0x6) is added, for use in inv messages<br>=C2=A0 =C2=A0and getdata =
requests pertaining to version 1 packages.<br><br>2. As an inv type, it ind=
icates that both transaction data and version<br>=C2=A0 =C2=A01 package inf=
ormation are available for the transaction. The<br>transaction is reference=
d by its wtxid. As a getdata request type, it<br>indicates that the sender =
wants package information for the<br>transaction.<br><br>3. Upon receipt of=
 a &quot;getdata&quot; request for &quot;MSG_PCKG1&quot;, the node<br>=C2=
=A0 =C2=A0should respond with the version 1 package corresponding to the<br=
>requested transaction and its current chain tip, or with NOTFOUND.<br>The =
node should not assume that the sender is requesting the<br>transaction dat=
a as well.<br><br>=3D=3D=3D=3DChild With Parent Packages Rules=3D=3D=3D=3D<=
br><br>A child-with-unconfirmed-parents package sent between nodes must abi=
de<br>by the rules below, otherwise the package is malformed and the sender=
<br>should be disconnected.<br><br>A version 1 or &#39;&#39;child-with-unco=
nfirmed-parents&#39;&#39; package can be<br>defined for any transaction tha=
t spends unconfirmed inputs. The child<br>can be thought of as the &quot;re=
presentative&quot; of the package. This package<br>can be uniquely identifi=
ed by the transaction&#39;s wtxid and the current<br>chain tip block hash.<=
br><br>A &#39;&#39;child-with-unconfirmed-parents&#39;&#39; package MUST be=
:<br><br>1. &#39;&#39;Sorted topologically.&#39;&#39; For every transaction=
 t in the package,<br>=C2=A0 =C2=A0if any of t&#39;s parents are present in=
 the package, the parent must<br>appear somewhere in the list before t. In =
other words, the<br>transactions must be sorted in ascending order of the n=
umber of<br>ancestors present in the package.<br><br>2. &#39;&#39;Only 1 ch=
ild with unconfirmed parents.&#39;&#39; The package must consist<br>=C2=A0 =
=C2=A0of one transaction and its unconfirmed parents. There must not be<br>=
any other transactions in the package. Other dependency relationships<br>ma=
y exist within the package (e.g. one parent may spend the output of<br>anot=
her parent) provided that topological order is respected.<br><br>3. &#39;&#=
39;All unconfirmed parents.&#39;&#39; All of the child&#39;s unconfirmed pa=
rents<br>=C2=A0 =C2=A0must be present.<br><br>4. &#39;&#39;No conflicts.&#3=
9;&#39; None of the transactions in the package may<br>=C2=A0 =C2=A0conflic=
t with each other (i.e. =C2=A0spend the same prevout).<br><br>5. &#39;&#39;=
Total fees and weight.&#39;&#39; The &#39;total_fee&#39; and &#39;total_wei=
ght&#39;<br>=C2=A0 =C2=A0fields must accurately represent the sum total of =
all transactions&#39;<br>fees and weights as defined in BIP141, respectivel=
y.<br><br>Not all of the child&#39;s parents must be present; the child tra=
nsaction<br>may also spend confirmed inputs. However, if the child has conf=
irmed<br>parents, they must not be in the package.<br><br>While a child-wit=
h-unconfirmed-parents package is perhaps most<br>relevant when the child ha=
s a higher feerate than its parents, this<br>property is not required to co=
nstruct a valid package.<br><br>=3D=3D=3D=3DClarifications=3D=3D=3D=3D<br><=
br>&#39;&#39;Q: Under what circumstances should a sender announce a<br>chil=
d-with-unconfirmed-parents package?&#39;&#39;<br><br>A child-with-unconfirm=
ed-parents package for a transaction should be<br>announced when it meets t=
he peer&#39;s fee filter but one or more of its<br>parents don&#39;t; a &qu=
ot;inv(MSG_PCKG1)&quot; instead of &quot;inv(WTX)&quot; should be sent<br>f=
or the child. Each of the parents which meet the peer&#39;s fee filter<br>s=
hould still be announced normally.<br><br>&#39;&#39;Q: What if a new block =
arrives in between messages?&#39;&#39;<br><br>A child-with-unconfirmed-pare=
nts package is defined for a transaction<br>based on the current chain stat=
e. As such, a new block extending the<br>tip may decrease the number of tra=
nsactions in the package (i.e. if<br>any of the transaction&#39;s parents w=
ere included in the block). In a<br>reorg, the number of transactions in th=
e package may decrease or<br>increase (i.e. if any of the transaction&#39;s=
 parents were included in a<br>block in the previous chain but not the new =
one).<br><br>If the new block arrives before the &quot;getdata&quot; or &qu=
ot;pckginfo1&quot;, nothing<br>needs to change.<br><br>If the new block arr=
ives before &quot;getpckgtxns&quot; or before &quot;pckgtxns&quot;,<br>the =
receiver may need to re-request package information if the block<br>contain=
ed a transaction in the package. If the block doesn&#39;t contain<br>any tr=
ansactions in the package, whether it extends the previous tip<br>or causes=
 a reorg, nothing needs to change.<br><br>&#39;&#39;Q: Can &quot;getpckgtxn=
s&quot; and &quot;pckgtxns&quot; messages contain only one<br>transaction?&=
#39;&#39;<br><br>Yes.<br><br>=3D=3D=3DFurther Protocol Extensions=3D=3D=3D<=
br><br>When introducing a new type of package, assign it a version number &=
quot;n&quot;<br>and use an additional &quot;sendpackages&quot; message duri=
ng version handshake<br>to negotiate support for it. An additional package =
information message<br>&quot;pckginfon&quot; and inv type &quot;MSG_PCKGn&q=
uot; should be defined for the type of<br>package.=C2=A0 However, &quot;get=
pckgtxns&quot; and &quot;pckgtxns&quot; do not need to be<br>changed.<br><b=
r>Example proposal for tx-with-unconfirmed-ancestors package relay: [19] <b=
r><br>=3D=3D=3DCompatibility=3D=3D=3D<br><br>Older clients remain fully com=
patible and interoperable after this<br>change. Clients implementing this p=
rotocol will only attempt to send<br>and request packages if agreed upon du=
ring the version handshake.<br><br>=3D=3D=3DPackage Erlay=3D=3D=3D<br><br>C=
lients using BIP330 reconciliation-based transaction relay (Erlay)<br>are a=
ble to use package relay without interference. In fact, a package<br>of tra=
nsactions may be announced using both Erlay and package relay.<br>After rec=
onciliation, if the initiator would have announced a<br>transaction by wtxi=
d but also has package information for it, they may<br>send &quot;inv(MSG_P=
CKG)&quot; instead of &quot;inv(WTX)&quot;.<br><br>=3D=3D=3DRationale=3D=3D=
=3D<br><br>=3D=3D=3D=3DP2P Message Design=3D=3D=3D=3D<br><br>These p2p mess=
ages are added for communication efficiency and, as<br>such, one should mea=
sure alternative solutions based on the resources<br>used to communicate (n=
ot necessarily trustworthy) information: We<br>would like to minimize netwo=
rk bandwidth, avoid downloading a<br>transaction more than once, avoid down=
loading transactions that are<br>eventually rejected, and minimize storage =
allocated for<br>not-yet-validated transactions.<br><br>Consider these (pla=
usible) scenarios in transaction relay:<br><br>Alice (the &quot;sender&quot=
;) is relaying transactions to Bob (the &quot;receiver&quot;).<br>Alice&#39=
;s mempool has a minimum feerate of 1sat/vB and Bob&#39;s has a<br>minimum =
feerate of 3sat/vB. For simplicity, all transactions are<br>1600Wu in virtu=
al size and 500 bytes in serialized size. Apart from<br>the spending relati=
onships specified, all other inputs are from<br>confirmed UTXOs.<br><br>1. =
Package {A, B} where A pays 0 satoshis and B pays 8000 satoshis in<br>=C2=
=A0 =C2=A0fees.<br><br>2. Package {C, D} where C pays 0 satoshis and D pays=
 1200 satoshis in<br>=C2=A0 =C2=A0fees.<br><br>3. Package {E, F, G, H, J} t=
hat pays 4000, 8000, 0, 2000, and 4000<br>=C2=A0 =C2=A0satoshis in fees, re=
spectively.<br><br>=3D=3D=3D=3DAlternative Designs Considered=3D=3D=3D=3D<b=
r><br>&#39;&#39;Package Information Only:&#39;&#39; Just having &quot;pckgi=
nfo&quot; gives enough<br>information for the receiver to accept the packag=
e. Omit the<br>&quot;getpckgtxns&quot; and &quot;pckgtxns&quot; messages. W=
hile this option is a good<br>fallback if batched transaction download fail=
s for some reason, it<br>shouldn&#39;t be used as the default because it &#=
39;always&#39; requires storage<br>of unvalidated transactions.<br><br>&#39=
;&#39;No Package Information Round:&#39;&#39; Instead of having a package<b=
r>information round, just use the child&#39;s wtxid to refer to the package=
<br>and always send the entire package together. This would cause nodes to<=
br>redownload duplicate transactions.<br><br>I have also created a slidedec=
k exploring various alternative designs<br>and some examples in which they =
fall flat [20]. Please feel free to<br>suggest other alternatives.<br><br>=
=3D=3D=3D=3DVersioning System=3D=3D=3D=3D<br><br>This protocol should be ex=
tensible to support multiple types of<br>packages based on future desired u=
se cases. Two &quot;flavors&quot; of<br>versioning were considered:<br><br>=
1. When package mempool acceptance is upgraded to support more types<br>=C2=
=A0 =C2=A0of packages, increment the version number (similar to Erlay).<br>=
During version handshake, peers negotiate which version of package<br>relay=
 they will use by each sending one &quot;sendpackages&quot; message.<br><br=
>2. When introducing another type of package, assign a version number<br>=
=C2=A0 =C2=A0to it and announce it as an additional supported version (simi=
lar<br>to Compact Block Relay). During version handshake, peers send one<br=
>&quot;sendpackages&quot; message for each version supported.<br><br>The se=
cond option was favored because it allows different parameters<br>for diffe=
rent versions.=C2=A0 For example, it should be possible to support<br>both =
&quot;arbitrary topology but maximum 3-transaction&quot; package as well as=
<br>&quot;child-with-unconfirmed-parents with default mempool ancestor limi=
ts&quot;<br>packages simultaneously.<br><br>=3D=3DAcknowledgements=3D=3D<br=
><br>I hope to have made it abundantly clear that this proposal isn=E2=80=
=99t<br>inventing the concept of package relay, and in fact builds upon yea=
rs<br>of work by many others, including Suhas Daftuar and Antoine Riard.<br=
><br>Thank you to John Newbery and Martin Zumsande for input on the design.=
<br><br>Thank you to Matt Corallo, Christian Decker, David Harding, Antoine=
<br>Poinsot, Antoine Riard, Gregory Sanders, Chris Stewart, Bastien<br>Tein=
turier, and others for input on the desired interface for<br>contracting pr=
otocols.<br><br><div>Looking forward to hearing your thoughts!</div><div><b=
r></div><div>Best,</div><div>Gloria<br></div><div><br></div>[0]: <a href=3D=
"https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-January/01981=
7.html" target=3D"_blank">https://lists.linuxfoundation.org/pipermail/bitco=
in-dev/2022-January/019817.html</a><br>[1]: <a href=3D"https://lists.linuxf=
oundation.org/pipermail/lightning-dev/2020-April/002639.html" target=3D"_bl=
ank">https://lists.linuxfoundation.org/pipermail/lightning-dev/2020-April/0=
02639.html</a><br>[2]: <a href=3D"https://lists.linuxfoundation.org/piperma=
il/lightning-dev/2020-June/002758.html" target=3D"_blank">https://lists.lin=
uxfoundation.org/pipermail/lightning-dev/2020-June/002758.html</a><br>[3]: =
<a href=3D"https://github.com/t-bast/lightning-docs/blob/master/pinning-att=
acks.md" target=3D"_blank">https://github.com/t-bast/lightning-docs/blob/ma=
ster/pinning-attacks.md</a><br>[4]: <a href=3D"https://github.com/revault/p=
ractical-revault/blob/master/transactions.md#cancel_tx" target=3D"_blank">h=
ttps://github.com/revault/practical-revault/blob/master/transactions.md#can=
cel_tx</a><br>[5]: <a href=3D"https://github.com/discreetlogcontracts/dlcsp=
ecs/blob/master/Transactions.md#refund-transaction" target=3D"_blank">https=
://github.com/discreetlogcontracts/dlcspecs/blob/master/Transactions.md#ref=
und-transaction</a><br>[6]: <a href=3D"https://gist.github.com/instagibbs/6=
0264606e181451e977e439a49f69fe1" target=3D"_blank">https://gist.github.com/=
instagibbs/60264606e181451e977e439a49f69fe1</a><br>[7]: <a href=3D"https://=
btctranscripts.com/adopting-bitcoin/2021/2021-11-16-gloria-zhao-transaction=
-relay-policy/#lightning-attacks" target=3D"_blank">https://btctranscripts.=
com/adopting-bitcoin/2021/2021-11-16-gloria-zhao-transaction-relay-policy/#=
lightning-attacks</a><br>[8]: <a href=3D"https://youtu.be/fbWSQvJjKFs?t=3D1=
438" target=3D"_blank">https://youtu.be/fbWSQvJjKFs?t=3D1438</a><br>[9]: <a=
 href=3D"https://www.reddit.com/r/Bitcoin/comments/unew4e/looks_like_70_mvb=
_of_transactions_just_got_dumped/" target=3D"_blank">https://www.reddit.com=
/r/Bitcoin/comments/unew4e/looks_like_70_mvb_of_transactions_just_got_dumpe=
d/</a><br>[10]: <a href=3D"https://github.com/bitcoin/bitcoin/pull/7594" ta=
rget=3D"_blank">https://github.com/bitcoin/bitcoin/pull/7594</a><br>[11]: <=
a href=3D"https://github.com/bitcoin/bitcoin/pull/7600" target=3D"_blank">h=
ttps://github.com/bitcoin/bitcoin/pull/7600</a><br>[12]: <a href=3D"https:/=
/github.com/bitcoin/bitcoin/pull/6455#issuecomment-122716820" target=3D"_bl=
ank">https://github.com/bitcoin/bitcoin/pull/6455#issuecomment-122716820</a=
><br>[13]: <a href=3D"https://gist.github.com/sdaftuar/8756699bfcad4d3806ba=
9f3396d4e66a" target=3D"_blank">https://gist.github.com/sdaftuar/8756699bfc=
ad4d3806ba9f3396d4e66a</a><br>[14]: <a href=3D"https://github.com/bitcoin/b=
itcoin/issues/14895" target=3D"_blank">https://github.com/bitcoin/bitcoin/i=
ssues/14895</a><br>[15]: <a href=3D"https://github.com/bitcoin/bitcoin/pull=
/16401" target=3D"_blank">https://github.com/bitcoin/bitcoin/pull/16401</a>=
<br>[16]: <a href=3D"https://github.com/bitcoin/bitcoin/pull/19621" target=
=3D"_blank">https://github.com/bitcoin/bitcoin/pull/19621</a><br>[17]: <a h=
ref=3D"https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-Septemb=
er/019464.html" target=3D"_blank">https://lists.linuxfoundation.org/piperma=
il/bitcoin-dev/2021-September/019464.html</a><br>[18]: <a href=3D"https://g=
ithub.com/users/glozow/projects/5/views/4?layout=3Dboard" target=3D"_blank"=
>https://github.com/users/glozow/projects/5/views/4?layout=3Dboard</a><br>[=
19]: <a href=3D"https://gist.github.com/glozow/9b321cd3ef6505135c763112033f=
f2a7" target=3D"_blank">https://gist.github.com/glozow/9b321cd3ef6505135c76=
3112033ff2a7</a><br>[20]: <a href=3D"https://docs.google.com/presentation/d=
/1B__KlZO1VzxJGx-0DYChlWawaEmGJ9EGApEzrHqZpQc/edit?usp=3Dsharing" target=3D=
"_blank">https://docs.google.com/presentation/d/1B__KlZO1VzxJGx-0DYChlWawaE=
mGJ9EGApEzrHqZpQc/edit?usp=3Dsharing</a></div>
_______________________________________________<br>
bitcoin-dev mailing list<br>
<a href=3D"mailto:bitcoin-dev@lists.linuxfoundation.org" target=3D"_blank">=
bitcoin-dev@lists.linuxfoundation.org</a><br>
<a href=3D"https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev" =
rel=3D"noreferrer" target=3D"_blank">https://lists.linuxfoundation.org/mail=
man/listinfo/bitcoin-dev</a><br>
</blockquote></div>

--00000000000083f72c05df38dd1b--