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

Channel refactor #24

Open
wants to merge 99 commits into
base: master
Choose a base branch
from
Open

Conversation

canndrew
Copy link
Member

Refactor DNL's Channel type in order to (a) separate state which is saved to the wallet from transient state which is discarded on disconnection, (b) simplify the API to make it less confusing, less bug-prone and require less duplicated effort between DNL and geewallet.

@canndrew
Copy link
Member Author

This is what was posted on the telegram channel w.r.t. getting these changes into a mergable state:

Andrés G. A., [11.02.21 15:39]
bb70f99 -> ok, but remove code (don't leave commented code)

Andrés G. A., [11.02.21 15:39]
6299085 -> you already did this one for coldstorage support right?

Andrés G. A., [11.02.21 15:40]
facad52 -> ok if it's commented code in DNL upstream (if it's commented code introduced by the previous commits, let's remove it in those commits)

Andrés G. A., [11.02.21 15:41]
74c33c9 -> ok, , but remove code (don't leave commented code)

Andrés G. A., [11.02.21 15:41]
c0820b8 -> ok, , but remove code (don't leave commented code)

Andrés G. A., [11.02.21 15:42]
1abfd71 -> ok

Andrés G. A., [11.02.21 15:42]
c41f7cb -> ok

Andrés G. A., [11.02.21 15:43]
520e385 -> ok

Andrés G. A., [11.02.21 15:43]
498786d -> ok

Andrés G. A., [11.02.21 15:44]
7f6723f -> only remove unused type, don't change "readability" aspects

Andrés G. A., [11.02.21 15:45]
[In reply to Andrés G. A.]
can do in a lower-priority PR later

Andrés G. A., [11.02.21 15:46]
000a3d8 -> ok

Andrés G. A., [11.02.21 15:46]
b8e8271 -> ok

Andrés G. A., [11.02.21 15:48]
78c166c , 54da375 , f5af1f8 , 4dc3c7f -> please squash these 4 commits into 1

Andrés G. A., [11.02.21 15:49]
a24f64b, f8f035e -> please squash these 2 commits into 1

Andrés G. A., [11.02.21 15:50]
375f9dc -> ok

Andrés G. A., [11.02.21 15:51]
5333bbe -> ok

Andrés G. A., [11.02.21 15:52]
b0778ca -> ok

Andrés G. A., [11.02.21 15:52]
e4d6816 -> ok

Andrés G. A., [11.02.21 15:55]
[In reply to Andrés G. A.]
0cb47ea -> squash with the 2 above

Andrés G. A., [11.02.21 15:57]
769318b, c02298b, 9a2cdb4 -> squash these 3 into 1

Andrés G. A., [11.02.21 15:59]
ea58de8 -> ok

Andrés G. A., [11.02.21 16:00]
680a20e -> ok

Andrés G. A., [11.02.21 16:00]
296e1f1 -> ok

Andrés G. A., [11.02.21 16:00]
1af4b74 -> ok

Andrés G. A., [11.02.21 16:01]
7dd1f00 -> ok

Andrés G. A., [11.02.21 16:01]
51bcf5c -> ok

Andrés G. A., [11.02.21 16:02]
561257e -> ok

Andrés G. A., [11.02.21 16:07]
661d674 -> ok

Andrés G. A., [11.02.21 16:07]
27d2d49 -> ok

Andrés G. A., [11.02.21 16:07]
130cfd6 -> ok

Andrés G. A., [11.02.21 16:08]
8ee9cdc -> ok

Andrés G. A., [11.02.21 16:10]
f5036a7 -> ok

Andrés G. A., [11.02.21 16:13]
8c490b8 -> ok

Andrés G. A., [11.02.21 16:13]
6e6daef -> ok

Andrés G. A., [11.02.21 16:15]
c449e7e -> ok but don't rename members to have Opt suffix

Andrés G. A., [11.02.21 16:17]
eecbba8 -> I don't think this is needed; I understand the need to use Opt suffix for variables (because you have fooOpt and inside the match pattern you then later have real foo) but there's no need to do it on members, otherwise whenever they change their type they need to be renamed

Andrés G. A., [11.02.21 16:24]
1fb3bf7 -> ok

Andrés G. A., [11.02.21 16:25]
c4bfaf5 -> ok

Andrés G. A., [11.02.21 16:26]
8d5107e -> ok

Andrés G. A., [11.02.21 16:26]
7a2571e -> ok

Andrés G. A., [11.02.21 16:27]
51e8c49 -> ok

Andrés G. A., [11.02.21 16:31]
aaa0aa1, ef8e51d, 136aa4e, e5b761f, 15bad14, 9d21775, 0434788, 5c5ef44, f4d283d -> squash all these removals into 1 pls, as they all seem related

Andrés G. A., [11.02.21 16:31]
7b08bd8 -> ok

Andrés G. A., [11.02.21 16:32]
51ba93f -> ok

Andrés G. A., [11.02.21 16:32]
355f863 -> ok

Andrés G. A., [11.02.21 16:34]
5354977 -> ok

Andrés G. A., [11.02.21 16:36]
7e9c362 -> ok, but don't add commented code (just remove the code), and remove the Opt suffix

Andrés G. A., [11.02.21 16:37]
4582279 -> ok, but remove the Opt suffix

Andrés G. A., [11.02.21 16:38]
70ac292 -> if it can be derived, then leave the TxId as a getter-only property?

Andrés G. A., [11.02.21 16:39]
3658a3b -> ok

Andrés G. A., [11.02.21 16:39]
2ef038b -> ok

Andrés G. A., [11.02.21 16:40]
f2d50e9 -> ok

Andrés G. A., [11.02.21 16:40]
2935f40 ->ok

@knocte
Copy link
Member

knocte commented Mar 2, 2021

Please don't forget that this needs to be rebased against Joe's master, not DNL.Kiss' master. But don't propose PR there until I have re-reviewed myself.

@canndrew
Copy link
Member Author

canndrew commented Mar 2, 2021

I've made the requested changes with a couple of exceptions:

  • 0cb47ea -> squash with the 2 above

This didn't make a lot of sense to me. I'm not sure why it should be squashed into the two before it.

  • 7f6723f -> only remove unused type, don't change "readability" aspects

Maybe I shouldn't have change the formatting of ChannelTypes.fs in the first place, but reverting the formatting would probably take a couple of hours since there's 50 or so commits after it which change that file. Just removing the Opt suffixes was a lot of work and that's a smaller change that had to be rebased through far fewer commits. Also, at the end of the rebase, that file will get stripped down to almost nothing anyway. Also the new formatting is lot more readable (for me at least). I'd prefer to just not do this unless you feel very strongly about it. Going forward I won't make these kinds of changes for no good reason.

I've also started rebasing on top of joe's commits. So this now almost up to date with joe's master, with the exception of the most recent commit (FundingTxProvider removal) since that'll be a bit of work to rebase on. I haven't rebased-away the DNL.Kiss changes yet either, except for the "Prevent possible F#4.0 issue" commit (ie. ResultUtils.Portability) since that's included in joe's master.

@knocte
Copy link
Member

knocte commented Mar 3, 2021

This didn't make a lot of sense to me. I'm not sure why it should be squashed into the two before it.

Fair enough, but you can merge the 2 above into 1? (merge 2 into 1 instead of 3 into 1).

but reverting the formatting would probably take a couple of hours since there's 50 or so commits after it which change that file

😬

Going forward I won't make these kinds of changes for no good reason.

But the real way to learn this properly is feeling the pain 😅 .
Well let's reach a compromise: you can leave the formatting changes there, so long as you split the commit into 2 (one that just does formatting changes, and the other that removes the unused type).

@knocte
Copy link
Member

knocte commented Mar 3, 2021

so long as you split the commit into 2

FYI this should only take 5 minutes if you use git rebase -i and the edit keyword.

Fix several build warnings.
@canndrew
Copy link
Member Author

canndrew commented Mar 4, 2021

Fair enough, but you can merge the 2 above into 1? (merge 2 into 1 instead of 3 into 1).

Done.

split the commit into 2 (one that just does formatting changes, and the other that removes the unused type).

Done. That sort of thing doesn't take long :)

@canndrew
Copy link
Member Author

canndrew commented Mar 4, 2021

I've rebased on top of the joe's master now. So we have the FundingTxProvider-removal commit.

I've also fixed the warnings on joe's master and I'll rebase on top of that next and make sure none of my commits introduce any new warnings and that tests still pass after each one (this can be automated with git rebase -i, assuming everything goes well).

knocte and others added 19 commits March 4, 2021 21:21
- LICENSE: change from MIT to AGPL (.Kiss fork)
- Change package name suffix from .Core to .Kiss
(skipping native build)
This commit adds the following:

* getFundsFromForceClosingTransaction

This function takes an on-chain transaction which spends the channel
funds and tries to extract spendable utxos out of it. If successful, it
returns a TransactionBuilder with txins added for each spendable output
of the closing transaction and with the necessary keys and
BuilderExtension added. To recover funds from a broadcast commitment
transaction you just need to call this function, add outputs to the
returned TransactionBuilder to send the money where you want it to go,
then broadcast the transaction.

* CommitmentToLocalBuilderExtension

This is an NBitcoin BuilderExtension that tells TransactionBuilder how
to recognise and sign lightning commitment transaction to_local outputs.
getFundsFromForceClosingTransaction adds this extension to the
TransactionBuilder it returns if it's needed to sign the transaction.

* SeqConsumer

A computation expression which makes it easy to write code that consumes
a sequence one element at a time.

* OptionCE

A computation expression for creation options. Similar to the result
computation expression.
This NBitcoin issue: MetacoSA/NBitcoin#931
somehow still hasn't been fixed properly (our geewallet CI still encounters it,
surprisingly).

So let's reapply the workaround[1] that we had removed[2].

[1] joemphilips@d813a97
[2] joemphilips@256893c
These tests are failing randomly and macaroons aren't used by geewallet
anyway. So exclude them from CI.
Move/rename ChannelError.feeRateMismatch to FeeRatePerKw.MismatchRatio.

This function is useful outside of DotNetLightning, so we now export it
so that library consumers can use it.
Prior to this commit, apply an update_fee message would cause DNL to
validate the message but not actually apply it to its commitments.

It now updates its commitments as it should.
These states don't have commitments, only exist before the existence of
a channel is confirmed, don't need to be saved in a wallet, and can only
handle one specific ChannelCommand each.

As such, it doesn't make much sense to have them be part of
ChannelState. They can instead be seperate types which exist prior to the
creation of a channel and which have specialized methods for performing
the single operation which they can handle.
They don't need to anymore since all channel states have a channel id
and commitments.
This field is unused.
These settings are only used for choosing whether to accept open/accept
channel messages. They don't need to be stored in the channel.
Previously the local shutdown script was stored in two places in the
channel and also provided as an argument when initiating a shutdown.
This made it possible to send invalid shutdown messages if the shutdown
scripts provided by the user at different times were different. Also,
shutdown scripts have to be in certain forms, but the only place that
they were validated was when initiating a shutdown.

There's now a ShutdownScriptPubKey type which wraps a Script and
enforces that the script is a valid shutdown script. This is used
throughout the code for all scripts which are shutdown scripts, which
forces us to check their validity at all required points.

The DefaultFinalScriptPubKey field has been removed from LocalParams so
that we only store the local shutdown script in (at most) one place in
the channel datastructure. This shutdown script is an Option, and can be
None in the case that we didn't specify a shutdown script to give to the
remote peer when creating the channel. As such as we still pass a
shutdown script as an argument when closing a channel but we also check
that it matches the recorded shutdown script that we previously gave the
remote peer in the case that it's Some.
The types WaitForOpenChannelData, WaitForFundingInternalData, and
WaitForRemotePublishFutureCommitmentData were defined but not used at
all. They have been removed.
Remove long lines and excessive rightward drift. Add types to function
parameters and return types. This makes the code more readable and
consistent.
Since all ChannelState variants have a Commitments field, this field can
be factored out into the Channel object.

Also, remove the ChannelId field from the ChannelState variants since it
is duplicated inside Commitments.
Commitments already stores the funding tx outpoint, which is what the
channel id is dervied from. So we can de-duplicate state by deriving the
channel id when needed.
The types WaitForFundingSignedData, WaitForFundingCreatedData,
ChannelWaitingForAcceptChannel and InputInit{Funder,Fundee} are only
used in a single place each as part of larger structures that they can
be inlined into. This will make it easy to refactor the channel types in
a subsequent commit.
This module defined the following interfaces:

    type IState = interface end
    type IStateData = interface end
    type ICommand = interface end
    type IEvent = interface end

These were not used in the code anywhere
This is needed in geewallet for getting the spendable balance of channel
when we only have the components of a Channel object but not the Channel
object itself.

This method can be moved onto SavedChannelState when the necessary
fields remaining in Channel/Commitments are moved there.
When SpendableBalance is called when the funding is not yet locked,
report the full channel balance rather than crashing.
Previously SignCommitment would return None instead of a
CommitmentSignedMsg if either:
  (a) There were not updates to sign or
  (b) A revoke-and-ack for a previous commitment was not yet received

Since these cases both indicate a misuse of the API they have been
changed to errors.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants