Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Non-interactive channels without commiting to value in script pubkey #19

Open
LLFourn opened this issue Dec 12, 2022 · 10 comments
Open

Comments

@LLFourn
Copy link

LLFourn commented Dec 12, 2022

It would be convenient to be able to construct a p2tr address that was actually a payment channel with some 3rd party. This is the perfect bridging mechanism between layer-1 and layer-2. The key issue with constructing this with existing covenant proposals (iiuc) is that the value that will be sent to the address cannot be known when constructing the script pubkey.

The main use case here is obvious. Anytime anyone is paying to your address it can go into a channel without any kind of cooperation from the sender. Coins can be withdrawn straight from exchanges into layer-2 without exchanges having to support anything more than p2tr.

Less obvious use cases include batch lightning channel opening which requires lightning specific protocols right now [1]. It Would be great if we could just have a batch transaction protocols which were able to open lightning channels without this extra complexity and interaction. -- this could already be achieved by the simpler non-interactive-channels idea with OP_CTV.

To do this the covenant proposal needs to be able to constrain spends out of the address to the first commitment transaction (or however your channel works) whose output value must be proportional to the value at the output being spent.

cc @DanGould @nickfarrow

[1] https://nolooking.chaincase.app/

PS I'm unable to attend the meetings at that time so I'll bring up this for discussion here. Thanks a lot for starting this initiative @ariard.

@ajtowns
Copy link
Contributor

ajtowns commented Dec 13, 2022

I guess the difference between this and https://utxos.org/uses/non-interactive-channels/ is that here the receiver is attempting to non-interactively create a channel, whereas the CTV use case imagines the sender being the one that wants to create the channel.

I don't think this works in concept though: if the recipient is Bob and the sender is Alice, the scriptPubKey needs to be constrained to being spent by either "B at state 0 after delay" (fine if given the ability to inspect the utxo's amount, to be able to automatically refund Alice) but also "A and B" (in order to generate new states and to do a cooperative close), but recovering an address "A" for Alice from a static scriptPubKey generated prior to knowing who Alice was seems impossible. (You could look at the sender address, but then Alice needs to do two transactions to send to Bob, and it's no longer something the sender can be ignorant of)

@LLFourn
Copy link
Author

LLFourn commented Dec 13, 2022

Hey @ajtowns. Let me clarify what I am imagining. There are three parties Alice (sender), Bob (receiver) and Larry (Bob's LSP). Bob gives Alice an address that is a function of his public key and Larry's but not necessarily a function of the value that Alice intends to send to him.

I think this is just a more powerful version of non-interactive-channels where the amount of the channel is not committed to and is set once the output is created. This allows you to safely have the Alice != Larry. For example if I am withdrawing from an exchange I can give them a withdrawal address and an amount. With OP_CTV I will have to precisely calculate the amount I am receiving or risk the possibility of the coins being stuck forever if I mess it up (e.g. overestimate by not taking into account the withdrawal fees taken by the exchange).

@ajtowns
Copy link
Contributor

ajtowns commented Dec 13, 2022

Ah, in that case sending to (L and B1) or (B2 and sPK=X) where X is (B3 and CSV) or (L and B4) is all you need, I think? If Larry doesn't participate, then Bob gets all the funds via the B2/B3 path; and Bob can invalidate that path by giving Larry a signature with B4 (either to a penalty tx or to a an eltoo-ish update).

I don't think either APO or CTV let you specify "sPK=X" without also committing to the output amount, of course.

@LLFourn LLFourn changed the title Add layer-2 channel address use case Non-interactive channels without commiting to value in script pubkey Dec 13, 2022
@LLFourn
Copy link
Author

LLFourn commented Dec 13, 2022

Yes. I've changed the title the to reflect that this is about extending the existing non-interactive channels idea to be able to avoid committing to the amount the channel output spk. Instead, being able to restrict it to be some function of the output being spent.

@ariard
Copy link
Owner

ariard commented Dec 13, 2022

Hey @LLFourn

So from my understanding, you have Alice receiving a p2tr paying to C_tx0, where there are 2 initial balances, one for Bob and one for Larry. The p2tr should also commit to the amount of the balances, as instructed by Alice. She should include Bob's p2tr in a funding transaction, the parent of C_tx0.

To the best of my knowledge, I don't think OP_CTV let's you do this today, neither APO with the "script-in-the-sig" trick. I think what could work is template malleability or signature malleability not committing to the commitment transaction balance outputs amounts. However, you might still would like some constraints to avoid Larry finalizing C_tx0 and siphoning the whole funds destined to Bob. Maybe they could be "hardcoded" in the taproot annex, though if you would like fine granularity (as Bob don't know Alice amount, only the distribution between him and Larry), you could have a "payout curve" encoded in the tree of tapscripts.

No worries for the timezones, I'll keep archiving logs of the meetings for everyone.

@ajtowns
Copy link
Contributor

ajtowns commented Dec 14, 2022

Oh, SIGHASH_ANYAMOUNT is a good idea, and suggests that you could kind-of do this with ANYPREVOUTANYSCRIPT via a CTV-ish approach.

First, generate the taproot address for X, which has two paths, either (B3 and CSV) or (B4 and L).

Then, generate the taproot address for Y, which also has two paths, (B2 and L) and sig G CHECKSIGVERIFY B1 CHECKSIG where G is the generator point, and sig is an ANYPREVOUTANYSCRIPT signature spending to X [[edit: that signature doesn't commit to the output amount due to APOAS, so Bob can update to whatever the correct amount was when constructing the spend of Y]].

I think this doesn't actually work though, as B can use that second path in Y to spend the entire value to fees, which provides a way to collude with a miner to steal funds from Larry. So you'd still need an OP_PUSH_IN_OUT_AMOUNTS operation of some sort, at which point you might as well have OP_PUSH_OUT_SCRIPTPUBKEY as well.

@LLFourn
Copy link
Author

LLFourn commented Dec 16, 2022

So from my understanding, you have Alice receiving a p2tr paying to C_tx0, where there are 2 initial balances, one for Bob and one for Larry. The p2tr should also commit to the amount of the balances, as instructed by Alice. She should include Bob's p2tr in a funding transaction, the parent of C_tx0.

Hah. No. Perhaps this idea is not as obvious as I first thought! All the balance goes to Bob's side of the channel and Alice isn't even aware it is a channel. e.g. Bob puts a donation address at the bottom of his youtube video. Every donation he receives turns into a channel via magic so Bob never has to touch on-chain transactions (optimistically) but his fans can donate him to a simple on-chain address.

Maybe they could be "hardcoded" in the taproot annex, though if you would like fine granularity (as Bob don't know Alice amount, only the distribution between him and Larry), you could have a "payout curve" encoded in the tree of tapscripts.

Payout for different amounts is an interesting idea -- might be worth implementing if we cannot have a more elegant solution. The thing is Bob will have a 2-of-2 with Larry if nothing works so assuming Larry is a reliable and honest LSP he should be willing to fork over the correct commitment tx. Bob can use one of his 10 thousand CTV value commitment leaves otherwise. Seems awkward though.

@naumenkogs
Copy link

I think this is a great idea and worth consideration in the discussion of the covenants. It would be great to see which covenants enable this and at what cost/risks.

Correct me if I'm wrong, but I'm thinking about two directions to achieve this:

  1. enforcing the limitations on spending from the beginning of the channel lifetime, and pouring new value in the same address (yeah address reuse);
  2. sending to a different address linked to the initially communciated public keys and so on, but otherwise separate.

Does any of this make sense?

@ariard
Copy link
Owner

ariard commented Jan 3, 2023

I think this doesn't actually work though, as B can use that second path in Y to spend the entire value to fees, which provides > a way to collude with a miner to steal funds from Larry. So you'd still need an OP_PUSH_IN_OUT_AMOUNTS operation of
some sort, at which point you might as well have OP_PUSH_OUT_SCRIPTPUBKEY as well.

So I don't know the purpose of the second path (B2 and L), if this would be a ptr2 MuSig2 2-of-2 to redeem the funds from the pre-committed channel without the CSV delay encumbrance on the commitment transaction balance outputs. However, yes as I noted there is a risk of either Bob or Larry finalizing the commitment transaction in their favor to siphon the value. For this reason, the old branch I have about SIGHASH_GROUP+SIGHASH_ANYAMOUNT had some "transitivity value" enforcing the spent input amount should be equal to the output amount in the bundle. OP_PUSH_IN_OUT_AMOUNTS operation could work as the trade-off of more witness space, I guess.

Hah. No. Perhaps this idea is not as obvious as I first thought! All the balance goes to Bob's side of the channel and Alice isn't > even aware it is a channel. e.g. Bob puts a donation address at the bottom of his youtube video. Every donation he receives > turns into a channel via magic so Bob never has to touch on-chain transactions (optimistically) but his fans can donate him to > a simple on-chain address.

I think I see better. It's either "Bob gets all Alice funds OR Larry and Bob gets a funding 2-of-2 output with initial commitment transactions". From then they can choose to engage in the channel and revoke the first initial commitment transaction to a second state where Larry balance is non-null.

  1. sending to a different address linked to the initially communciated public keys and so on, but otherwise separate.

So I understand the first option as SIGHASH_ANYMOUNT+"transivity_value" locked-in or OP_PUSH_IN_OUT_AMOUNTS approaches. However it's unclear how non-interactive amount-wildcard channels would work with a scheme in the family of 2 ? If you can give a more precise example with scripts and counterparties ?

@LLFourn
Copy link
Author

LLFourn commented Jan 4, 2023

I think this is a great idea and worth consideration in the discussion of the covenants. It would be great to see which covenants enable this and at what cost/risks.

Correct me if I'm wrong, but I'm thinking about two directions to achieve this:

1. enforcing the limitations on spending from the beginning of the channel lifetime, and pouring new value in the same address (yeah address reuse);

2. sending to a different address linked to the initially communciated public keys and so on, but otherwise separate.

Does any of this make sense?

I'd hope that user address is non-interactively derived from the LSP's public key and address re-use isn't any more of a thing than it is already (the scheme should support address re-use of course).

I think I see better. It's either "Bob gets all Alice funds OR Larry and Bob gets a funding 2-of-2 output with initial commitment transactions". From then they can choose to engage in the channel and revoke the first initial commitment transaction to a second state where Larry balance is non-null.

I think there is no OR here. Bob always gets a 2-of-2 funding for every output with that script pubkey. Larry will always be needed to move the funds instantly (either on-chain or off). Bob will have to force close channel and wait CSV to spend if Larry disappears after the address is created.

Important note is that Zman and @jesseposner have come up with a scheme that does this today but with the limitation that the channel has a fixed CSV expiry date: https://lists.linuxfoundation.org/pipermail/lightning-dev/2023-January/003810.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants