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

Refactor #28

Open
wants to merge 68 commits into
base: wip/upstream
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
f5c71a6
Remove ChannelAnnoucement field from NormalData
canndrew Dec 8, 2020
906743e
Remove NormalData.ChannelUpdate field
canndrew Dec 8, 2020
43819b0
Merge WaitForFunding{Locked,Confirmed} states into Normal
canndrew Dec 8, 2020
9152eab
Remove nextCommitments from AcceptedShutdownWhileWeHaveUnsignedOutgoi…
canndrew Dec 8, 2020
95ed42c
Remove ChannelState.Shutdown
canndrew Dec 8, 2020
4212a73
Record remote's ShutdownScriptPubKey from open/accept channel msgs
canndrew Dec 8, 2020
24e5dbd
Replace ShutdownMsg fields with ShutdownScriptPubKey in channel states
canndrew Dec 8, 2020
3eecdd8
De-duplicate shutdown scripts
canndrew Dec 10, 2020
9bbe3c3
Remove unused fields from ClosingData
canndrew Dec 10, 2020
6370c95
Change type of NegotiatingData.ClosingTxProposed
canndrew Dec 10, 2020
4acc391
Change type (again) of NegotiatingData.ClosingTxPerformed
canndrew Dec 10, 2020
c86289d
Remove MaybeBestUnpublishedTx from NegotiatingData
canndrew Dec 10, 2020
49aa083
Remove ClosingTxProposed type
canndrew Dec 18, 2020
ad97be6
Track previous fee proposed by remote peer during fee negotiation
canndrew Dec 18, 2020
ca0e59c
Move RemoteNextCommitInfoOpt into Channel
canndrew Dec 18, 2020
7ec37fa
Move ShortChannelIdOpt out of NormalData into Channel
canndrew Dec 18, 2020
cdf2a1c
Remove handleMutualClose function
canndrew Dec 18, 2020
3e0af18
Remove claimCurrentLocalCommitTxOutputs
canndrew Dec 18, 2020
6f130a3
Add ChannelFlags type
canndrew Jan 29, 2021
82e3061
Remove ChannelState
canndrew Jan 29, 2021
240b73c
Move some channel fields into new StaticChannelConfig type
canndrew Mar 1, 2021
4d0996e
Move FeeEstimator into ChannelOptions
canndrew Mar 5, 2021
b1233f3
Remove redundant arg from New{In,Out}Bound methods
canndrew Jun 14, 2021
25ab9d0
Factor reestablishment-creation into a method
canndrew Mar 5, 2021
363bb47
Turn ApplyFundingLocked into a method
canndrew Mar 8, 2021
03017da
Make ApplyFundingConfirmedOnBC into a method
canndrew Mar 8, 2021
4186854
Make RemoteNextCommitInfoIfFundingLocked{,Normal} helper...
canndrew Jun 14, 2021
f57e8b5
Make AddHTLC into a method
canndrew Mar 8, 2021
80d1d08
Make ApplyUpdateAddHTLC into a method
canndrew Mar 8, 2021
86a0f62
Make FulfillHTLC into a method
canndrew Mar 8, 2021
6c0c37b
Make ApplyUpdateFulfillHTLC into a method
canndrew Mar 8, 2021
9c0227e
Make FailHTLC into a method
canndrew Mar 8, 2021
2192fd1
Make FailMalformedHTLC into a method
canndrew Mar 8, 2021
89b9d98
Make ApplyUpdateFailHTLC into a method
canndrew Mar 8, 2021
8dac882
Make ApplyUpdateFailMalformedHTLC into a method
canndrew Mar 8, 2021
59a1790
Make UpdateFee into a method
canndrew Mar 8, 2021
47255db
Make ApplyUpdateFee into a method
canndrew Mar 8, 2021
91218a8
Make SignCommitment into a method:w
canndrew Mar 8, 2021
64a1a91
Make ApplyCommitmentSigned into a method
canndrew Mar 8, 2021
dc56f77
Make ApplyRevokeAndACK into a method
canndrew Mar 8, 2021
0cc1025
Make Close into a method
canndrew Mar 8, 2021
ed6dc9a
Make RemoteShutdown into a method
canndrew Mar 8, 2021
d49a6b5
Make ApplyClosingSigned into a method
canndrew Mar 8, 2021
03b0ad3
Remove Channel{Operation,Event}
canndrew Mar 8, 2021
38de92c
Remove ChannelWaitingForFundingSigned.LastSent field
canndrew Mar 10, 2021
1cc2eb8
Remove ChannelWaitingForFundingCreated.TemporaryFailure field
canndrew Mar 10, 2021
e4e7b00
Expand/Remove ChannelWaitingForFundingTx.LastReceived field
canndrew Mar 10, 2021
dfd281e
Remove WhichInput field from tx types
canndrew Mar 10, 2021
972dcc0
Seperate incoming and outgoing htlcs in CommitmentSpec
canndrew Mar 11, 2021
095e9f8
Move StaticChannelConfig into new SavedChannelState type
canndrew Mar 18, 2021
8ed3c86
Move RemotePerCommitmentSecrets into SavedChannelState
canndrew Mar 18, 2021
abc0476
Move ShortChannelId into SavedChannelState
canndrew Mar 18, 2021
ad47d28
Move {Local,Remote}Commit into SavedChannelState
canndrew Mar 18, 2021
b199658
Move proposed local changes out of LocalChanges
canndrew Mar 26, 2021
95c8a2a
Move proposed remote changes out of RemoteChanges
canndrew Mar 26, 2021
e38394f
Move Local,RemoteChanges into SavedChannelState
canndrew Mar 26, 2021
2a7aee5
Core: remove unneeded MSat/Satoshis suffixes to non-primitive vars
knocte Jun 15, 2021
2e30352
Core: better variable name than single letter (readability)
knocte Jun 15, 2021
9827c87
Remove DomainUtils/Type.fs and its interface definitions
canndrew Jun 16, 2021
37e12dd
Make SignCommitment not return an Option
canndrew Jun 17, 2021
c28cb68
ApplyFundingConfirmedOnBC: error if depth insufficient
canndrew Jun 17, 2021
29c3fa7
Fix ApplyFundingLocked
canndrew Jun 17, 2021
ad397c0
Fix ApplyFundingConfirmedOnBC
canndrew Jun 17, 2021
7b8daf2
RemoteShutdown: give user local shutdown msg when they need it
canndrew Jun 17, 2021
5ab1a1d
Typo: NowKnown -> NotKnown
aarani Jun 14, 2021
c4d0ebc
Cosmetic: normalize 'self.' and 'x.' to 'this.' or '__.' for consistency
knocte Jun 18, 2021
fa1fe14
Fix broken HTLC handling in Spec.Reduce function
aarani Jun 22, 2021
648c12c
Fix closing_signed fee check
canndrew Jun 18, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,030 changes: 1,088 additions & 942 deletions src/DotNetLightning.Core/Channel/Channel.fs

Large diffs are not rendered by default.

153 changes: 113 additions & 40 deletions src/DotNetLightning.Core/Channel/ChannelError.fs

Large diffs are not rendered by default.

82 changes: 37 additions & 45 deletions src/DotNetLightning.Core/Channel/ChannelOperations.fs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ open DotNetLightning.Transactions
open DotNetLightning.Serialization

open NBitcoin
open Aether

open ResultUtils
open ResultUtils.Portability
Expand Down Expand Up @@ -102,48 +103,39 @@ type RemoteParams = {
Features = remoteInit.Features
}

/// possible input to the channel. Command prefixed from `Apply` is passive. i.e.
/// it has caused by the outside world and not by the user. Mostly this is a message sent
/// from this channel's remote peer.
/// others are active commands which is caused by the user.
/// However, these two kinds of command has no difference from architectural viewpoint.
/// It is just an input to the state.
type ChannelCommand =
// open: funder
| ApplyAcceptChannel of AcceptChannelMsg
| CreateFundingTx of fundingTx: FinalizedTx * outIndex: TxOutIndex
| ApplyFundingSigned of FundingSignedMsg
| ApplyFundingLocked of FundingLockedMsg
| ApplyFundingConfirmedOnBC of height: BlockHeight * txIndex: TxIndexInBlock * depth: BlockHeightOffset32

// open: fundee
| ApplyOpenChannel of OpenChannelMsg
| ApplyFundingCreated of FundingCreatedMsg

| CreateChannelReestablish

// normal
| AddHTLC of OperationAddHTLC
| ApplyUpdateAddHTLC of msg: UpdateAddHTLCMsg * currentHeight: BlockHeight
| FulfillHTLC of OperationFulfillHTLC
| ApplyUpdateFulfillHTLC of UpdateFulfillHTLCMsg
| FailHTLC of OperationFailHTLC
| ApplyUpdateFailHTLC of UpdateFailHTLCMsg
| FailMalformedHTLC of OperationFailMalformedHTLC
| ApplyUpdateFailMalformedHTLC of UpdateFailMalformedHTLCMsg
| UpdateFee of OperationUpdateFee
| ApplyUpdateFee of UpdateFeeMsg

| SignCommitment
| ApplyCommitmentSigned of CommitmentSignedMsg
| ApplyRevokeAndACK of RevokeAndACKMsg

// close
| Close of ShutdownScriptPubKey
| ApplyClosingSigned of ClosingSignedMsg
| RemoteShutdown of ShutdownMsg * ShutdownScriptPubKey

// else
| ForceClose
| GetState
| GetStateData
/// Channel config which is static, ie. config parameters which are established
/// during the channel handshake and persist unchagned through the lifetime of
/// the channel.
type StaticChannelConfig = {
AnnounceChannel: bool
RemoteNodeId: NodeId
Network: Network
FundingTxMinimumDepth: BlockHeightOffset32
LocalStaticShutdownScriptPubKey: Option<ShutdownScriptPubKey>
RemoteStaticShutdownScriptPubKey: Option<ShutdownScriptPubKey>
IsFunder: bool
FundingScriptCoin: ScriptCoin
LocalParams: LocalParams
RemoteParams: RemoteParams
RemoteChannelPubKeys: ChannelPubKeys
}
with
member this.ChannelId(): ChannelId =
this.FundingScriptCoin.Outpoint.ToChannelId()

type ChannelOptions = {
MaxFeeRateMismatchRatio: float
// Amount (in millionth of a satoshi) the channel will charge per transferred satoshi.
// This may be allowed to change at runtime in a later update, however doing so must result in
// update messages sent to notify all nodes of our updated relay fee.
FeeProportionalMillionths: uint32
/// We don't exchange more than this many signatures when negotiating the closing fee
MaxClosingNegotiationIterations: int32
FeeEstimator: IFeeEstimator
}
with

static member FeeProportionalMillionths_: Lens<_, _> =
(fun cc -> cc.FeeProportionalMillionths),
(fun v cc -> { cc with FeeProportionalMillionths = v })

259 changes: 62 additions & 197 deletions src/DotNetLightning.Core/Channel/ChannelTypes.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ namespace DotNetLightning.Channel
open DotNetLightning.Chain
open DotNetLightning.Utils
open DotNetLightning.Utils.Aether
open DotNetLightning.DomainUtils.Types
open DotNetLightning.Serialization.Msgs
open DotNetLightning.Transactions
open DotNetLightning.Crypto
Expand All @@ -25,202 +24,68 @@ open NBitcoin

[<AutoOpen>]
module Data =
type ClosingTxProposed = {
UnsignedTx: ClosingTx
LocalClosingSigned: ClosingSignedMsg
}
with
static member LocalClosingSigned_: Lens<_ ,_> =
(fun p -> p.LocalClosingSigned),
(fun v p -> { p with LocalClosingSigned = v })

type LocalCommitPublished = {
CommitTx: CommitTx
ClaimMainDelayedOutputTx: ClaimDelayedOutputTx option
HTLCSuccessTxs: HTLCSuccessTx list
HTLCTimeoutTxs: HTLCTimeoutTx list
}

type RemoteCommitPublished = {
CommitTx: CommitTx
ClaimMainOutputTx: ClaimP2WPKHOutputTx
ClaimHTLCSuccessTxs: ClaimHTLCSuccessTx list
ClaimHTLCTimeoutTxs: ClaimHTLCTimeoutTx list
}

type RevokedCommitPublished = {
CommitTx: CommitTx
ClaimMainOutputTx: ClaimP2WPKHOutputTx option
MainPenaltyTx: MainPenaltyTx option
ClaimHTLCTimeoutTxs: ClaimHTLCTimeoutTx list
HTLCTimeoutTxs: HTLCTimeoutTx list
HTLCPenaltyTxs: HTLCPenaltyTx list
}

type IChannelStateData = interface inherit IStateData end

type WaitForFundingConfirmedData = {
RemoteNextPerCommitmentPointOpt: Option<PerCommitmentPoint>
}

type WaitForFundingLockedData = {
ShortChannelId: ShortChannelId
}

type NormalData = {
ShortChannelId: ShortChannelId
ChannelAnnouncement: Option<ChannelAnnouncementMsg>
ChannelUpdate: ChannelUpdateMsg
LocalShutdown: Option<ShutdownMsg>
RemoteShutdown: Option<ShutdownMsg>
RemoteNextCommitInfo: RemoteNextCommitInfo
}

type ShutdownData = {
RemoteNextCommitInfo: RemoteNextCommitInfo
LocalShutdown: ShutdownMsg
RemoteShutdown: ShutdownMsg
}

type NegotiatingData = {
RemoteNextCommitInfo: RemoteNextCommitInfo
LocalShutdown: ShutdownMsg
RemoteShutdown: ShutdownMsg
ClosingTxProposed: List<List<ClosingTxProposed>>
MaybeBestUnpublishedTx: Option<FinalizedTx>
}

type ClosingData = {
RemoteNextCommitInfo: RemoteNextCommitInfo
MaybeFundingTx: Option<Transaction>
WaitingSince: System.DateTime
MutualCloseProposed: List<ClosingTx>
MutualClosePublished: FinalizedTx
LocalCommitPublished: Option<LocalCommitPublished>
RemoteCommitPublished: Option<RemoteCommitPublished>
NextRemoteCommitPublished: Option<RemoteCommitPublished>
FutureRemoteCommitPublished: Option<RemoteCommitPublished>
RevokedCommitPublished: List<RevokedCommitPublished>
type NegotiatingState = {
LocalRequestedShutdown: Option<ShutdownScriptPubKey>
RemoteRequestedShutdown: Option<ShutdownScriptPubKey>
LocalClosingFeesProposed: List<Money>
RemoteClosingFeeProposed: Option<Money * LNECDSASignature>
} with
member this.FinalizedTx =
this.MutualClosePublished

static member Create (maybeFundingTx: Option<Transaction>)
(waitingSince: System.DateTime)
(mutualCloseProposed: List<ClosingTx>)
(mutualClosePublished: FinalizedTx)
(remoteNextCommitInfo: RemoteNextCommitInfo)
: ClosingData = {
RemoteNextCommitInfo = remoteNextCommitInfo
MaybeFundingTx = maybeFundingTx
WaitingSince = waitingSince
MutualCloseProposed = mutualCloseProposed
MutualClosePublished = mutualClosePublished
LocalCommitPublished = None
RemoteCommitPublished = None
NextRemoteCommitPublished = None
FutureRemoteCommitPublished = None
RevokedCommitPublished = []
static member New(): NegotiatingState = {
LocalRequestedShutdown = None
RemoteRequestedShutdown = None
LocalClosingFeesProposed = List.empty
RemoteClosingFeeProposed = None
}
member this.HasEnteredShutdown(): bool =
this.LocalRequestedShutdown.IsSome && this.RemoteRequestedShutdown.IsSome

type ClosingSignedResponse =
| NewClosingSigned of ClosingSignedMsg
| MutualClose of FinalizedTx * Option<ClosingSignedMsg>

type SavedChannelState = {
StaticChannelConfig: StaticChannelConfig
RemotePerCommitmentSecrets: PerCommitmentSecretStore
ShortChannelId: Option<ShortChannelId>
LocalCommit: LocalCommit
RemoteCommit: RemoteCommit
LocalChanges: LocalChanges
RemoteChanges: RemoteChanges
} with
member internal this.HasNoPendingHTLCs (remoteNextCommitInfo: RemoteNextCommitInfo) =
this.LocalCommit.Spec.OutgoingHTLCs.IsEmpty
&& this.LocalCommit.Spec.IncomingHTLCs.IsEmpty
&& this.RemoteCommit.Spec.OutgoingHTLCs.IsEmpty
&& this.RemoteCommit.Spec.IncomingHTLCs.IsEmpty
&& (remoteNextCommitInfo |> function Waiting _ -> false | Revoked _ -> true)

member internal this.GetOutgoingHTLCCrossSigned (remoteNextCommitInfo: RemoteNextCommitInfo)
(htlcId: HTLCId)
: Option<UpdateAddHTLCMsg> =
let remoteSigned =
Map.tryFind htlcId this.LocalCommit.Spec.OutgoingHTLCs
let localSigned =
let remoteCommit =
match remoteNextCommitInfo with
| Revoked _ -> this.RemoteCommit
| Waiting nextRemoteCommit -> nextRemoteCommit
Map.tryFind htlcId remoteCommit.Spec.IncomingHTLCs
match remoteSigned, localSigned with
| Some _, Some htlcIn -> htlcIn |> Some
| _ -> None

member internal this.GetIncomingHTLCCrossSigned (remoteNextCommitInfo: RemoteNextCommitInfo)
(htlcId: HTLCId)
: Option<UpdateAddHTLCMsg> =
let remoteSigned =
Map.tryFind htlcId this.LocalCommit.Spec.IncomingHTLCs
let localSigned =
let remoteCommit =
match remoteNextCommitInfo with
| Revoked _ -> this.RemoteCommit
| Waiting nextRemoteCommit -> nextRemoteCommit
Map.tryFind htlcId remoteCommit.Spec.OutgoingHTLCs
match remoteSigned, localSigned with
| Some _, Some htlcIn -> htlcIn |> Some
| _ -> None

// 8888888888 888 888 8888888888 888b 888 88888888888 .d8888b.
// 888 888 888 888 8888b 888 888 d88P Y88b
// 888 888 888 888 88888b 888 888 Y88b.
// 8888888 Y88b d88P 8888888 888Y88b 888 888 "Y888b.
// 888 Y88b d88P 888 888 Y88b888 888 "Y88b.
// 888 Y88o88P 888 888 Y88888 888 "888
// 888 Y888P 888 888 Y8888 888 Y88b d88P
// 8888888888 Y8P 8888888888 888 Y888 888 "Y8888P"


/// The one that includes `Operation` in its name is the event which we are the initiator
type ChannelEvent =
// --- ln events ---
/// -------- init both -----
| FundingConfirmed of FundingLockedMsg * nextState: Data.WaitForFundingLockedData
| TheySentFundingLocked of msg: FundingLockedMsg
| WeResumedDelayedFundingLocked of remoteNextPerCommitmentPoint: PerCommitmentPoint
| BothFundingLocked of nextState: Data.NormalData

// -------- normal operation ------
| WeAcceptedOperationAddHTLC of msg: UpdateAddHTLCMsg * newCommitments: Commitments
| WeAcceptedUpdateAddHTLC of newCommitments: Commitments

| WeAcceptedOperationFulfillHTLC of msg: UpdateFulfillHTLCMsg * newCommitments: Commitments
| WeAcceptedFulfillHTLC of msg: UpdateFulfillHTLCMsg * origin: HTLCSource * htlc: UpdateAddHTLCMsg * newCommitments: Commitments

| WeAcceptedOperationFailHTLC of msg: UpdateFailHTLCMsg * newCommitments: Commitments
| WeAcceptedFailHTLC of origin: HTLCSource * msg: UpdateAddHTLCMsg * nextCommitments: Commitments

| WeAcceptedOperationFailMalformedHTLC of msg: UpdateFailMalformedHTLCMsg * newCommitments: Commitments
| WeAcceptedFailMalformedHTLC of origin: HTLCSource * msg: UpdateAddHTLCMsg * newCommitments: Commitments

| WeAcceptedOperationUpdateFee of msg: UpdateFeeMsg * nextCommitments: Commitments
| WeAcceptedUpdateFee of msg: UpdateFeeMsg * newCommitments: Commitments

| WeAcceptedOperationSign of msg: CommitmentSignedMsg * nextCommitments: Commitments * nextRemoteCommit: RemoteCommit
| WeAcceptedCommitmentSigned of msg: RevokeAndACKMsg * nextCommitments: Commitments

| WeAcceptedRevokeAndACK of nextCommitments: Commitments * remoteNextPerCommitmentPoint: PerCommitmentPoint

| AcceptedOperationShutdown of msg: ShutdownMsg
| AcceptedShutdownWhileWeHaveUnsignedOutgoingHTLCs of remoteShutdown: ShutdownMsg * nextCommitments: Commitments
/// We have to send closing_signed to initiate the negotiation only when if we are the funder
| AcceptedShutdownWhenNoPendingHTLCs of msgToSend: ClosingSignedMsg option * nextState: NegotiatingData
| AcceptedShutdownWhenWeHavePendingHTLCs of nextState: ShutdownData

// ------ closing ------
| MutualClosePerformed of txToPublish: FinalizedTx * nextState : ClosingData * nextMsgToSend: Option<ClosingSignedMsg>
| WeProposedNewClosingSigned of msgToSend: ClosingSignedMsg * nextState: NegotiatingData
// -------- else ---------
| Closed
| Disconnected
| ChannelStateRequestedSignCommitment
| WeSentChannelReestablish of msg: ChannelReestablishMsg


// .d8888b. 88888888888 d8888 88888888888 8888888888 .d8888b.
// d88P Y88b 888 d88888 888 888 d88P Y88b
// Y88b. 888 d88P888 888 888 Y88b.
// "Y888b. 888 d88P 888 888 8888888 "Y888b.
// "Y88b. 888 d88P 888 888 888 "Y88b.
// "888 888 d88P 888 888 888 "888
// Y88b d88P 888 d8888888888 888 888 Y88b d88P
// "Y8888P" 888 d88P 888 888 8888888888 "Y8888P"
// --- setup ---

open Data
type ChannelStatePhase =
| Opening
| Normal
| Closing
type ChannelState =
/// Establishing
| WaitForFundingConfirmed of WaitForFundingConfirmedData
| WaitForFundingLocked of WaitForFundingLockedData

/// normal
| Normal of NormalData

/// Closing
| Shutdown of ShutdownData
| Negotiating of NegotiatingData
| Closing of ClosingData
with
interface IState

static member Normal_: Prism<_, _> =
(fun cc -> match cc with
| Normal s -> Some s
| _ -> None ),
(fun v cc -> match cc with
| Normal _ -> Normal v
| _ -> cc )
member this.Phase =
match this with
| WaitForFundingConfirmed _
| WaitForFundingLocked _ -> Opening
| Normal _ -> ChannelStatePhase.Normal
| Shutdown _
| Negotiating _
| Closing _ -> ChannelStatePhase.Closing
Loading