-
-
Notifications
You must be signed in to change notification settings - Fork 29
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
How to properly handle ephemeral state in state channels #238
Comments
Yes, you can't prepare a new state transition since transition builder uses stash, and you do not add ephemeral state on off chain transactions in the channel to the stash. The proper way is to add them to the stash via consuming fascia, since otherwise in cases of uncooperative channel closing you will lose funds and won't be able to create a penalty transaction. Yes, this means that stash (and also contract state cache and index) will accumulate growing ephemeral historical state - but that was the part of the design from the very begging, and the stash is made to be capable of doing that. In other words, the same way you keep and accumulate all signatures for the off chain channel transaction - the same way you have to accumulate fascia in the stash. |
Initially we were consuming the bundles (that are now inside the fascia) but then after some updates we encountered some problems and on telegram (https://t.me/c/1793511697/1041) you said:
Anyway, we added a test to the |
Both is true:
The problem is that (a) there is no API to do the (2), and (b) designing it represent an immense amount of work. The only downside of (1) is that it will grow the size of the stash over the time (with channel operations), which can be avoided in case of (2). However, I propose to postpone implementation of (2) for v0.12, since it may require a lot of refactoring and API breaks once again. |
If I understand this correctly, it means that consuming the fascia for ephemeral transfers is expected, but it still fails when trying to replace it with a new commitment transaction, as our |
Yes, I consider inability to consume following fascia is a bug. It is much easier to fix that comparing to creating builders operating on not just stash but also some additional ephemeral data |
Ok so you're going to provide a fix for this before releasing final 0.11, do I get it correctly? Thanks |
Yes, I will work on the fix. I might discover that it is impossible to have an easy fix and it is easier to refactor the builder. But let's see. |
The test fails with the error Basically this is not a bug and is a safeguard, which happens since existing HTLCs doesn't update their state transitions with new deterministically-generated salts, which results in the fact they have the same RGB state transition bundles and their id, now trying to bind them to a different witness. The proper way of fixing the problem is to re-generate a new bundle for each HTLCs upon the channel update. Is that possible? Since otherwise I need to remove this safety measure which may reduce off chain wallet security... |
The issue is not directly related to HTLCs, it happens with commitment transactions (with no HTLCs) as well. Anyway I don't understand what the check should prevent. I don't see any issue in generating a deterministic bundle ID. Could you please explain what issue you see in allowing this? |
Normally, if you have a state transition, it must be associated only with one witness bitcoin transaction committing to it. This checks prevents replacing one associations with other. If you replace it, you won't be able to "go back" and restore funds in case of uncooperative closing. |
This seems an implementation issue more than a protocol/security issue. Maybe we could store bundles together with the witnesses (e.g. the map key would be
By saving RGB amounts for each state update (and assuming a static blinding or deterministic one) I think we can recreate the RGB data that would be necessary on uncooperative closing. So IMO this should not be a concern. |
Yes, this is an implementation issue. I have stated above: while it is possibly to deterministically re-create all RGB-related channel information, it would require a significant work on the rgb-std side, which can/should be postponed to v0.12. In other words: even though this is an implementation issue, it requires a lot of re-implementation work. So instead we can utilize the ability of the stash to consume all the shit and save our time in v0.11:
Does anybody read what I write here? |
Anyway I have discovered that we need to allow multiple witness transactions for the same bundle, so I will work on that in v.0.11 and you will be able to consume all the fascia for a lightning channel updates: #247 Later I will work on new APIs able to "color" PSBTs from fascia without their consumption into a stash. Maybe I will get it into v0.11, but this will be a low priority and maybe it will get into v0.12 |
So, with #247 merged the proper way of handling ephemeral state in the state channels for v0.11 is the following:
2.1. Before calling 2.2. Consume fascias from all PSBTs for each channel transaction on each of the channel state updates. This will allow to keep the past state necessary for non-cooperative closes In v0.12 I will work on adding API for using information from fascia alongside stash to generate consignment, which will make steps 1 and 2.2 unnecessary and will save storage space. |
I'm not sure about the need of Anyway I confirm the It seems though there's still a similar issue:
this panic comes from https://github.com/RGB-WG/rgb-std/blob/master/src/contract/assignments.rs#L75. |
Hm, I believe you need it to report the new commitment transaction as
Yes, it was created to prevent from having multiple versions of the same state transition pointing to different witnesses and defining different seals, so now it is unnecessary. Removed in #255 |
It doesn't seem so, in my tests I'm able to construct the HTLC TXs without setting the commitment to With #255 the test succeeds. I've also added some logic to it to see what happens if a PSBT representing an old state gets broadacasted and by calling |
This is probably due to the fact that you build HTLC state transitions not from the state but directly from PSBTs. I had forgotten that when was writing my comment. Glad that everything works! |
I've added a test here https://github.com/zoedberg/rgb-integration-tests/tree/ln_transfers that reproduces an issue we encountered on our LN node (run
cargo test --test transfers ln_htlc_transfer
).In the test we try to simulate the creation of a commitment TX and of an HTLC TX spending a vout of the commitment. In this case RGB fails to find inputs when calling the
contract_assignments_for
method. I assume this is because we haven't consumed the fascia. But AFAIR it would be incorrect to consume the fascia of a commitment TX that hasn't been broadcast and might never be. Therefore I'm not sure how we should address this, I normally callcontract_assignments_for
to obtain theOpout
andPersistedState
needed to call theadd_input
method of theTransitionBuilder
.Just a note: to mimic the behavior of LN we had to add some custom methods to create and color a PSBT, this code is mostly copied from RGB repos so we expect it to be correct. We will extend these methods to make also some complex validation tests but for now it should be sufficient to demonstrate the problem.
The text was updated successfully, but these errors were encountered: