Thanks for sharing your thoughts on packaged transaction relay.
"Propagate transactions that are incentive-compatible to mine, even if they don't meet minimum feerate alone."
I actually do think there are additional goals we should include in any protocol change involving transaction relay, such as ensuring that we minimize bandwidth waste as much as possible (as I mentioned in a previous message in this thread).
While I understand your proposal seeks to improve on an idea of static packages in favor of dynamic package construction based on knowledge a node should have of its peers, I think the main drawback of your proposal is that it doesn't take into account the complexities of what a peer's "minimum feerate" might mean. The consequence of this is that it's not generally possible for a node to accurately guess whether a given transaction should be sent in a package to a given peer, or not, and so in addition to any "packaged transaction relay" mechanism that is implemented by a transaction announcer, we'd still need to add protocol support for a receiving peer to retrieve a package as well.
First of all, a node's feerate is a dynamic value. BIP 133 allows for nodes to send feefilter messages at any time during the lifetime of a peer connection. If we were to compare the feerate of ancestors of a relayed transaction to the feerate in place at a peer as indicated by feefilter messages, and use that determine whether those ancestors would have been successfully relayed or not, then doing so accurately would seem to require caching relay success for each transaction, for each peer, at the time such transaction is relayed (or perhaps caching feefilter values that are received from a peer?). This seems likely to be undesirable, and, at any rate, is more complex than merely comparing a pair of feerates.
But even more fundamental than feerates being dynamic is that feerate itself is not a well-defined concept when applied to arbitrary transaction (sub-)graphs, and this is at the crux of the difficulty in coming up with proposals that would meet the objective of ensuring that transactions which are incentive-compatible to mine all get relayed successfully across the network. Here are a couple examples that illustrate this:
- Let A be a low feerate transaction (below any peer's minimum feerate). Let B and C be descendants of A (but are otherwise unrelated). Suppose these transactions are relayed to a node in the order A, B, C. In the algorithm you proposed, I believe the determination for whether C should be announced to a given peer as a package (A, C) or as a singleton would either (1) depend on whether the package (A, B) was sufficient to meet the peer's feerate, or (2) waste bandwidth by engaging in packaged relay whenever A was already successfully relayed as part of a package. Both of these approaches seem undesirable.
- Let A be a high fee, but low feerate transaction. Suppose B is a transaction that conflicts with A, has a high feerate, but lower total fee. In this situation, two different nodes that learned of these two transactions in opposite order [(A, B) vs (B, A)] might be expected to have differing mempools -- this at least would be the case in the BIP 125 algorithm (which requires that both feerate and total fee must increase when replacing an existing transaction), and at any rate it's not obvious from the information given which would be more optimal to include in a block, as that depends on factors that go beyond just these two transactions. Suppose further that a new transaction C is relayed on the network, which is a child of B and very high feerate, such that B + C have higher fee and higher feerate than A, when taken together. In this case we'd want our relay protocol to ensure that even nodes which saw A first should still have a chance to consider transaction C, but the packaging design you propose (which would compare transaction B's feerate to the peer's, and conclude packaging is unnecessary because B's feerate might already exceed the peer's feerate) would not facilitate this.
To summarize, the point I'd make from these examples is that we should not expect that "feerate" (whatever that means) alone will be a sufficient predictor of what is in our peer's mempools. So while there may be some situations where a transaction relayer might be able to usefully package up a transaction with its dependencies (perhaps in narrowly defined situations), there will also always be situations where this isn't possible, and what I conclude from that is that it should be helpful to add to the protocol some way for the recipient of a transaction to request the dependencies directly.
Taken together, I roughly understand Gloria's efforts here to be a combination of these two approaches: add some amount of packaged transaction relay for simple cases (ie where the transaction graph has been sufficiently narrowed, to minimize bandwidth waste while reducing latency), and also allow for a fallback mechanism where the recipient of a transaction can efficiently retrieve dependencies. There seems to be a tradeoff involving latency, bandwidth, and robustness of these two approaches (and maybe also implementation complexity), so I think it's natural to expect that it will take some discussion and understanding of what practices are common on the network and what behaviors wallet or other software might adopt, given potential protocol changes, to figure out how best to balance these ideas.