From rusty at rustcorp.com.au Thu Feb 24 04:37:46 2022 From: rusty at rustcorp.com.au (Rusty Russell) Date: Thu, 24 Feb 2022 15:07:46 +1030 Subject: [Lightning-dev] A Proposal for Adding Bandwidth Metered Payment to Onion Messages In-Reply-To: <CAO3Pvs-L0AK+f1y=4ESKEjUpTDyPOWno9wynBMGGAt_MNo0n7Q@mail.gmail.com> References: <CAO3Pvs-L0AK+f1y=4ESKEjUpTDyPOWno9wynBMGGAt_MNo0n7Q@mail.gmail.com> Message-ID: <87k0dkop5x.fsf@rustcorp.com.au> Olaoluwa Osuntokun <laolu32 at gmail.com> writes: > Hi y'all, > > (TL;DR: a way to nodes to get paid to forward onion messages by adding an > upfront session creation phase that uses AMP tender a messaging session to a > receiver, with nodes being paid upfront for purchase of forwarding > bandwidth, and a session identifier being transmitted alongside onion > messages to identify paid sessions) AMP seems to be a Lightning Labs proprietary extension. You mean keysend, which at least has a draft spec? > Onion messaging has been proposed as a way to do things like fetch invoices > directly from a potential receiver _directly_ over the existing LN. The > current proposal (packaged under the BOLT 12 umbrella) uses a new message > (`onion_message`) that inherits the design of the existing Sphinx-based > onion blob included in htlc_add messages as a way to propagate arbitrary > messages across the network. Blinded paths which are effectively an unrolled > Sphinx SURB (single use reply block), are used to support reply messages in > a more private manner. Compared to SURBs, blinded paths are more flexible as > they don't lock in things like fees or CLTV values. > > A direct outcome of widespread adoption of the proposal is that the scope of > LN is expanded beyond "just" a decentralized p2p payment system, with the Sure, let's keep encouraging people to use HTLCs for free to send data? I can certainly implement that if you prefer! > 1. As there's no explicit session creation/acceptance, a node can be > spammed with unsolicited messages with no way to deny unwanted messages nor > explicitly allow messages from certain senders. > > 2. Nodes that forward these messages (up to 32 KB per message) receive no > compensation for the network bandwidth their expend, effectively shuffling > around messages for free. > > 3. Rate limiting isn't concretely addressed, which may result in > heterogeneous rate limiting policies enforced around the network, which can > degrade the developer/user experience (why are my packets being randomly > dropped?). Sure, this is a fun one! I can post separately on ratelimiting; I suggest naively limiting to 10/sec for peers with channels, and 1/sec for peers without for now. (In practice, spamming with HTLCs is infinitely more satisfying...) > In this email I propose a way to address the issues mentioned above by > adding explicit onion messaging session creation as well as a way for nodes > to be (optionally) paid for any onion messages they forward. In short, an > explicit session creation phase is introduced, with the receiver being able > to accept/deny the session. If the session is accepted, then all nodes that > comprise the session route are compensated for allotting a certain amount of > bandwidth to the session (which is ephemeral by nature). It's an interesting layer on top (esp if you want to stream movies), but I never proposed this because it seems to add a source-identifying session id, which is a huge privacy step backwards. You really *do not want* to use this for independent transmissions. I flirted with using blinded tokens, but it gets complex fast; ideas welcome! > ## Node Announcement TLV Extension > > In order to allow nodes to signal that they want to be paid to forward onion > messages and also specify their pricing, we add two new TLV to the node_ann > message: > > * type: 1 (`sats_per_byte`) > * data: > * [`uint64`:`forwarding_rate`] > * type: 2 (`sats_per_block`) > * data: > * [`uint64`:`per_block_rate`] You mean: * type: 1 (`sats_per_byte`) * data: * [`tu64`:`forwarding_rate`] * type: 3 (`sats_per_block`) * data: * [`tu64`:`per_block_rate`] 1. Don't use an even TLV field. 2. Might as well use truncated u64. > The `sats_per_byte` field allows nodes to price their bandwidth, ensuring > that they get paid for each chunk of allocated bandwidth. As sessions have a > fixed time frame and nodes need to store additional data within that time > frame, the `sats_per_block` allows nodes to price this cost, as they'll hold > onto the session identifier information until the specified block height > (detailed below). > > As onion messages will _typically_ be fixed sized we may want to use > coursers > metering here instead of bytes, possibly paying for 1.3KB or 32 KB chunks > instead. I think it's a premature optimization? Make standard duration 2016 blocks; then they can request multiples if they want? Reduces node_announcement size. > With the above nodes are able to express that they're willing to forward > messages for sats, and how much they charge per byte as well as per block. > Next we add a new TLV in the _existing_ HTLC onion blob that allows a > sending node to tender paid onion message session creation. A sketch of this > type would look something like: > > * type: 14 (`onion_session_id`) > * data: > * [`32*byte`:`session_id`] I'd be tempted to use 16 bytes? Collisions here are not really a thing since you'd need a network packet per probe, and you're time limited. > After session creation succeeds, nodes will forward onion messages that > include that `onion_session_id`. The set of `encrypted_data_tlv` for onion > messages is extended to also specify a new type that stores the session ID: > > * type: 10 (`onion_session_id`) > * data: > * [`32*byte`:`session_id`] > > When forwarding an onion message that includes an `onion_session_id` (a node > may only forward messages that contain such an ID), nodes do the necessary > bookkeeping to tally how much bandwidth if left in this session, and also > check that the session hasn't expired before forwarding. This is good because it doesn't require a db write (if you crash and forget to charge, it's OK). AFAICT this is easy to implement on top of onion_messages as they stand today (if you don't want to fwd free onion messages at all, don't set that bit?). Cheers, Rusty.