From bb70f990ed0956cf88b7f21badc3039964080c8a Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Thu, 26 Nov 2020 18:21:06 +0800 Subject: [PATCH] Remove pre-channel states 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. --- src/DotNetLightning.Core/Channel/Channel.fs | 558 ++++++++++++------ .../Channel/ChannelOperations.fs | 4 +- .../Channel/ChannelTypes.fs | 54 +- 3 files changed, 398 insertions(+), 218 deletions(-) diff --git a/src/DotNetLightning.Core/Channel/Channel.fs b/src/DotNetLightning.Core/Channel/Channel.fs index 582b554ff..5ce2f6c35 100644 --- a/src/DotNetLightning.Core/Channel/Channel.fs +++ b/src/DotNetLightning.Core/Channel/Channel.fs @@ -14,7 +14,235 @@ open ResultUtils open ResultUtils.Portability type ProvideFundingTx = IDestination * Money * FeeRatePerKw -> Result -type Channel = { + +type ChannelWaitingForFundingSigned = { + Config: ChannelConfig + ChannelPrivKeys: ChannelPrivKeys + FeeEstimator: IFeeEstimator + FundingTxProvider:ProvideFundingTx + RemoteNodeId: NodeId + NodeSecret: NodeSecret + Network: Network + WaitForFundingSignedData: WaitForFundingSignedData +} with + member self.ApplyFundingSigned (msg: FundingSignedMsg) + : Result = result { + let state = self.WaitForFundingSignedData + let remoteChannelKeys = state.RemoteParams.ChannelPubKeys + let! finalizedLocalCommitTx = + let theirFundingPk = remoteChannelKeys.FundingPubKey.RawPubKey() + let _, signedLocalCommitTx = + self.ChannelPrivKeys.SignWithFundingPrivKey state.LocalCommitTx.Value + let remoteSigPairOfLocalTx = (theirFundingPk, TransactionSignature(msg.Signature.Value, SigHash.All)) + let sigPairs = seq [ remoteSigPairOfLocalTx; ] + Transactions.checkTxFinalized signedLocalCommitTx state.LocalCommitTx.WhichInput sigPairs |> expectTransactionError + let commitments = { Commitments.LocalParams = state.LocalParams + RemoteParams = state.RemoteParams + ChannelFlags = state.ChannelFlags + FundingScriptCoin = + let amount = state.FundingTx.Value.Outputs.[int state.LastSent.FundingOutputIndex.Value].Value + ChannelHelpers.getFundingScriptCoin + state.LocalParams.ChannelPubKeys.FundingPubKey + remoteChannelKeys.FundingPubKey + state.LastSent.FundingTxId + state.LastSent.FundingOutputIndex + amount + LocalCommit = { Index = CommitmentNumber.FirstCommitment; + Spec = state.LocalSpec; + PublishableTxs = { PublishableTxs.CommitTx = finalizedLocalCommitTx + HTLCTxs = [] } + PendingHTLCSuccessTxs = [] } + RemoteCommit = state.RemoteCommit + LocalChanges = LocalChanges.Zero + RemoteChanges = RemoteChanges.Zero + LocalNextHTLCId = HTLCId.Zero + RemoteNextHTLCId = HTLCId.Zero + OriginChannels = Map.empty + // we will receive their next per-commitment point in the next msg, so we temporarily put a random byte array + RemoteNextCommitInfo = DataEncoders.HexEncoder().DecodeData("0101010101010101010101010101010101010101010101010101010101010101") |> fun h -> new Key(h) |> fun k -> k.PubKey |> PerCommitmentPoint |> RemoteNextCommitInfo.Revoked + RemotePerCommitmentSecrets = PerCommitmentSecretStore() + ChannelId = + msg.ChannelId } + let nextState = { WaitForFundingConfirmedData.Commitments = commitments + Deferred = None + LastSent = Choice1Of2 state.LastSent + InitialFeeRatePerKw = state.InitialFeeRatePerKw + ChannelId = msg.ChannelId } + let channel = { + Config = self.Config + ChannelPrivKeys = self.ChannelPrivKeys + FeeEstimator = self.FeeEstimator + FundingTxProvider = self.FundingTxProvider + RemoteNodeId = self.RemoteNodeId + NodeSecret = self.NodeSecret + State = WaitForFundingConfirmed nextState + Network = self.Network + } + return state.FundingTx, channel + } + +and ChannelWaitingForFundingCreated = { + Config: ChannelConfig + ChannelPrivKeys: ChannelPrivKeys + FeeEstimator: IFeeEstimator + FundingTxProvider:ProvideFundingTx + RemoteNodeId: NodeId + NodeSecret: NodeSecret + Network: Network + WaitForFundingCreatedData: WaitForFundingCreatedData +} with + member self.ApplyFundingCreated (msg: FundingCreatedMsg) + : Result = result { + let state = self.WaitForFundingCreatedData + let remoteChannelKeys = state.RemoteParams.ChannelPubKeys + let! (localSpec, localCommitTx, remoteSpec, remoteCommitTx) = + ChannelHelpers.makeFirstCommitTxs + state.LocalParams + state.RemoteParams + state.FundingSatoshis + state.PushMSat + state.InitialFeeRatePerKw + msg.FundingOutputIndex + msg.FundingTxId + state.LastSent.FirstPerCommitmentPoint + state.RemoteFirstPerCommitmentPoint + self.Network + assert (localCommitTx.Value.IsReadyToSign()) + let _s, signedLocalCommitTx = + self.ChannelPrivKeys.SignWithFundingPrivKey localCommitTx.Value + let remoteTxSig = TransactionSignature(msg.Signature.Value, SigHash.All) + let theirSigPair = (remoteChannelKeys.FundingPubKey.RawPubKey(), remoteTxSig) + let sigPairs = seq [ theirSigPair ] + let! finalizedCommitTx = + Transactions.checkTxFinalized (signedLocalCommitTx) (localCommitTx.WhichInput) sigPairs + |> expectTransactionError + let localSigOfRemoteCommit, _ = + self.ChannelPrivKeys.SignWithFundingPrivKey remoteCommitTx.Value + let channelId = OutPoint(msg.FundingTxId.Value, uint32 msg.FundingOutputIndex.Value).ToChannelId() + let msgToSend: FundingSignedMsg = { ChannelId = channelId; Signature = !>localSigOfRemoteCommit.Signature } + let commitments = { Commitments.LocalParams = state.LocalParams + RemoteParams = state.RemoteParams + ChannelFlags = state.ChannelFlags + FundingScriptCoin = + ChannelHelpers.getFundingScriptCoin + state.LocalParams.ChannelPubKeys.FundingPubKey + remoteChannelKeys.FundingPubKey + msg.FundingTxId + msg.FundingOutputIndex + state.FundingSatoshis + LocalCommit = { LocalCommit.Index = CommitmentNumber.FirstCommitment + Spec = localSpec + PublishableTxs = { PublishableTxs.CommitTx = finalizedCommitTx; + HTLCTxs = [] } + PendingHTLCSuccessTxs = [] } + RemoteCommit = { RemoteCommit.Index = CommitmentNumber.FirstCommitment + Spec = remoteSpec + TxId = remoteCommitTx.Value.GetGlobalTransaction().GetTxId() + RemotePerCommitmentPoint = state.RemoteFirstPerCommitmentPoint } + LocalChanges = LocalChanges.Zero + RemoteChanges = RemoteChanges.Zero + LocalNextHTLCId = HTLCId.Zero + RemoteNextHTLCId = HTLCId.Zero + OriginChannels = Map.empty + RemoteNextCommitInfo = DataEncoders.HexEncoder().DecodeData("0101010101010101010101010101010101010101010101010101010101010101") |> fun h -> new Key(h) |> fun k -> k.PubKey |> PerCommitmentPoint |> RemoteNextCommitInfo.Revoked + RemotePerCommitmentSecrets = PerCommitmentSecretStore() + ChannelId = channelId } + let nextState = { WaitForFundingConfirmedData.Commitments = commitments + Deferred = None + LastSent = msgToSend |> Choice2Of2 + InitialFeeRatePerKw = state.InitialFeeRatePerKw + ChannelId = channelId } + let channel = { + Config = self.Config + ChannelPrivKeys = self.ChannelPrivKeys + FeeEstimator = self.FeeEstimator + FundingTxProvider = self.FundingTxProvider + RemoteNodeId = self.RemoteNodeId + NodeSecret = self.NodeSecret + Network = self.Network + State = WaitForFundingConfirmed nextState + } + return msgToSend, channel + } + +and ChannelWaitingForAcceptChannel = { + Config: ChannelConfig + ChannelPrivKeys: ChannelPrivKeys + FeeEstimator: IFeeEstimator + FundingTxProvider:ProvideFundingTx + RemoteNodeId: NodeId + NodeSecret: NodeSecret + Network: Network + WaitForAcceptChannelData: WaitForAcceptChannelData +} with + member self.ApplyAcceptChannel (msg: AcceptChannelMsg) + : Result = result { + let state = self.WaitForAcceptChannelData + do! Validation.checkAcceptChannelMsgAcceptable (self.Config) state msg + let redeem = + Scripts.funding + (state.InputInitFunder.ChannelPrivKeys.ToChannelPubKeys().FundingPubKey) + msg.FundingPubKey + let! fundingTx, outIndex = + self.FundingTxProvider (redeem.WitHash :> IDestination, state.InputInitFunder.FundingSatoshis, state.InputInitFunder.FundingTxFeeRatePerKw) + |> expectFundingTxError + let remoteParams = RemoteParams.FromAcceptChannel self.RemoteNodeId (state.InputInitFunder.RemoteInit) msg + let localParams = state.InputInitFunder.LocalParams + assert (state.LastSent.FundingPubKey = localParams.ChannelPubKeys.FundingPubKey) + let commitmentSpec = state.InputInitFunder.DeriveCommitmentSpec() + let commitmentSeed = state.InputInitFunder.ChannelPrivKeys.CommitmentSeed + let fundingTxId = fundingTx.Value.GetTxId() + let! (_localSpec, localCommitTx, remoteSpec, remoteCommitTx) = + ChannelHelpers.makeFirstCommitTxs localParams + remoteParams + state.LastSent.FundingSatoshis + state.LastSent.PushMSat + state.LastSent.FeeRatePerKw + outIndex + fundingTxId + (commitmentSeed.DerivePerCommitmentPoint CommitmentNumber.FirstCommitment) + msg.FirstPerCommitmentPoint + self.Network + let localSigOfRemoteCommit, _ = + self.ChannelPrivKeys.SignWithFundingPrivKey remoteCommitTx.Value + let nextMsg: FundingCreatedMsg = { + TemporaryChannelId = msg.TemporaryChannelId + FundingTxId = fundingTxId + FundingOutputIndex = outIndex + Signature = !>localSigOfRemoteCommit.Signature + } + let channelId = OutPoint(fundingTxId.Value, uint32 outIndex.Value).ToChannelId() + let waitForFundingSignedData = { + Data.WaitForFundingSignedData.ChannelId = channelId + LocalParams = localParams + RemoteParams = remoteParams + Data.WaitForFundingSignedData.FundingTx = fundingTx + Data.WaitForFundingSignedData.LocalSpec = commitmentSpec + LocalCommitTx = localCommitTx + RemoteCommit = { + RemoteCommit.Index = CommitmentNumber.FirstCommitment + Spec = remoteSpec + TxId = remoteCommitTx.Value.GetGlobalTransaction().GetTxId() + RemotePerCommitmentPoint = msg.FirstPerCommitmentPoint + } + ChannelFlags = state.InputInitFunder.ChannelFlags + LastSent = nextMsg + InitialFeeRatePerKw = state.InputInitFunder.InitFeeRatePerKw + } + let channelWaitingForFundingSigned = { + Config = self.Config + ChannelPrivKeys = self.ChannelPrivKeys + FeeEstimator = self.FeeEstimator + FundingTxProvider = self.FundingTxProvider + RemoteNodeId = self.RemoteNodeId + NodeSecret = self.NodeSecret + Network = self.Network + WaitForFundingSignedData = waitForFundingSignedData + } + return nextMsg, channelWaitingForFundingSigned + } + +and Channel = { Config: ChannelConfig ChannelPrivKeys: ChannelPrivKeys FeeEstimator: IFeeEstimator @@ -25,14 +253,15 @@ type Channel = { Network: Network } with - static member Create (config: ChannelConfig, - nodeMasterPrivKey: NodeMasterPrivKey, - channelIndex: int, - feeEstimator: IFeeEstimator, - fundingTxProvider: ProvideFundingTx, - n: Network, - remoteNodeId: NodeId - ) = + static member private Create (config: ChannelConfig, + nodeMasterPrivKey: NodeMasterPrivKey, + channelIndex: int, + feeEstimator: IFeeEstimator, + fundingTxProvider: ProvideFundingTx, + n: Network, + remoteNodeId: NodeId, + state: ChannelState + ) = let channelPrivKeys = nodeMasterPrivKey.ChannelPrivKeys channelIndex let nodeSecret = nodeMasterPrivKey.NodeSecret() { @@ -42,10 +271,110 @@ type Channel = { FundingTxProvider = fundingTxProvider RemoteNodeId = remoteNodeId NodeSecret = nodeSecret - State = WaitForInitInternal + State = state Network = n } - static member CreateCurried = curry7 (Channel.Create) + + static member NewOutbound(config: ChannelConfig, + nodeMasterPrivKey: NodeMasterPrivKey, + channelIndex: int, + feeEstimator: IFeeEstimator, + fundingTxProvider: ProvideFundingTx, + network: Network, + remoteNodeId: NodeId, + inputInitFunder: InputInitFunder + ): Result = + let openChannelMsgToSend: OpenChannelMsg = { + Chainhash = network.Consensus.HashGenesisBlock + TemporaryChannelId = inputInitFunder.TemporaryChannelId + FundingSatoshis = inputInitFunder.FundingSatoshis + PushMSat = inputInitFunder.PushMSat + DustLimitSatoshis = inputInitFunder.LocalParams.DustLimitSatoshis + MaxHTLCValueInFlightMsat = inputInitFunder.LocalParams.MaxHTLCValueInFlightMSat + ChannelReserveSatoshis = inputInitFunder.LocalParams.ChannelReserveSatoshis + HTLCMinimumMsat = inputInitFunder.LocalParams.HTLCMinimumMSat + FeeRatePerKw = inputInitFunder.InitFeeRatePerKw + ToSelfDelay = inputInitFunder.LocalParams.ToSelfDelay + MaxAcceptedHTLCs = inputInitFunder.LocalParams.MaxAcceptedHTLCs + FundingPubKey = inputInitFunder.ChannelPrivKeys.FundingPrivKey.FundingPubKey() + RevocationBasepoint = inputInitFunder.ChannelPrivKeys.RevocationBasepointSecret.RevocationBasepoint() + PaymentBasepoint = inputInitFunder.ChannelPrivKeys.PaymentBasepointSecret.PaymentBasepoint() + DelayedPaymentBasepoint = inputInitFunder.ChannelPrivKeys.DelayedPaymentBasepointSecret.DelayedPaymentBasepoint() + HTLCBasepoint = inputInitFunder.ChannelPrivKeys.HtlcBasepointSecret.HtlcBasepoint() + FirstPerCommitmentPoint = inputInitFunder.ChannelPrivKeys.CommitmentSeed.DerivePerCommitmentPoint CommitmentNumber.FirstCommitment + ChannelFlags = inputInitFunder.ChannelFlags + ShutdownScriptPubKey = config.ChannelOptions.ShutdownScriptPubKey + } + result { + do! Validation.checkOurOpenChannelMsgAcceptable config openChannelMsgToSend + let channelPrivKeys = nodeMasterPrivKey.ChannelPrivKeys channelIndex + let nodeSecret = nodeMasterPrivKey.NodeSecret() + let waitForAcceptChannelData = { + InputInitFunder = inputInitFunder + LastSent = openChannelMsgToSend + } + let channelWaitingForAcceptChannel = { + Config = config + ChannelPrivKeys = channelPrivKeys + FeeEstimator = feeEstimator + FundingTxProvider = fundingTxProvider + RemoteNodeId = remoteNodeId + NodeSecret = nodeSecret + Network = network + WaitForAcceptChannelData = waitForAcceptChannelData + } + return (openChannelMsgToSend, channelWaitingForAcceptChannel) + } + + static member NewInbound (config: ChannelConfig, + nodeMasterPrivKey: NodeMasterPrivKey, + channelIndex: int, + feeEstimator: IFeeEstimator, + fundingTxProvider: ProvideFundingTx, + network: Network, + remoteNodeId: NodeId, + inputInitFundee: InputInitFundee, + openChannelMsg: OpenChannelMsg + ): Result = + result { + do! Validation.checkOpenChannelMsgAcceptable feeEstimator config openChannelMsg + let localParams = inputInitFundee.LocalParams + let channelKeys = inputInitFundee.ChannelPrivKeys + let localCommitmentPubKey = channelKeys.CommitmentSeed.DerivePerCommitmentPoint CommitmentNumber.FirstCommitment + let acceptChannelMsg: AcceptChannelMsg = { + TemporaryChannelId = openChannelMsg.TemporaryChannelId + DustLimitSatoshis = localParams.DustLimitSatoshis + MaxHTLCValueInFlightMsat = localParams.MaxHTLCValueInFlightMSat + ChannelReserveSatoshis = localParams.ChannelReserveSatoshis + HTLCMinimumMSat = localParams.HTLCMinimumMSat + MinimumDepth = config.ChannelHandshakeConfig.MinimumDepth + ToSelfDelay = localParams.ToSelfDelay + MaxAcceptedHTLCs = localParams.MaxAcceptedHTLCs + FundingPubKey = channelKeys.FundingPrivKey.FundingPubKey() + RevocationBasepoint = channelKeys.RevocationBasepointSecret.RevocationBasepoint() + PaymentBasepoint = channelKeys.PaymentBasepointSecret.PaymentBasepoint() + DelayedPaymentBasepoint = channelKeys.DelayedPaymentBasepointSecret.DelayedPaymentBasepoint() + HTLCBasepoint = channelKeys.HtlcBasepointSecret.HtlcBasepoint() + FirstPerCommitmentPoint = localCommitmentPubKey + ShutdownScriptPubKey = config.ChannelOptions.ShutdownScriptPubKey + } + let remoteParams = RemoteParams.FromOpenChannel remoteNodeId inputInitFundee.RemoteInit openChannelMsg config.ChannelHandshakeConfig + let waitForFundingCreatedData = Data.WaitForFundingCreatedData.Create localParams remoteParams openChannelMsg acceptChannelMsg + let channelPrivKeys = nodeMasterPrivKey.ChannelPrivKeys channelIndex + let nodeSecret = nodeMasterPrivKey.NodeSecret() + let channelWaitingForFundingCreated = { + Config = config + ChannelPrivKeys = channelPrivKeys + FeeEstimator = feeEstimator + FundingTxProvider = fundingTxProvider + RemoteNodeId = remoteNodeId + NodeSecret = nodeSecret + Network = network + WaitForFundingCreatedData = waitForFundingCreatedData + } + return (acceptChannelMsg, channelWaitingForFundingCreated) + } + //static member CreateCurried = curry7 (Channel.Create) module Channel = @@ -153,6 +482,7 @@ module Channel = match cs.State, command with // --------------- open channel procedure: case we are funder ------------- + (* | WaitForInitInternal, CreateOutbound inputInitFunder -> let openChannelMsgToSend: OpenChannelMsg = { Chainhash = cs.Network.Consensus.HashGenesisBlock @@ -185,109 +515,17 @@ module Channel = }) ] } - | WaitForAcceptChannel state, ApplyAcceptChannel msg -> - result { - do! Validation.checkAcceptChannelMsgAcceptable (cs.Config) state msg - let redeem = - Scripts.funding - (state.InputInitFunder.ChannelPrivKeys.ToChannelPubKeys().FundingPubKey) - msg.FundingPubKey - let! fundingTx, outIndex = - cs.FundingTxProvider (redeem.WitHash :> IDestination, state.InputInitFunder.FundingSatoshis, state.InputInitFunder.FundingTxFeeRatePerKw) - |> expectFundingTxError - let remoteParams = RemoteParams.FromAcceptChannel cs.RemoteNodeId (state.InputInitFunder.RemoteInit) msg - let localParams = state.InputInitFunder.LocalParams - assert (state.LastSent.FundingPubKey = localParams.ChannelPubKeys.FundingPubKey) - let commitmentSpec = state.InputInitFunder.DeriveCommitmentSpec() - let commitmentSeed = state.InputInitFunder.ChannelPrivKeys.CommitmentSeed - let fundingTxId = fundingTx.Value.GetTxId() - let! (_localSpec, localCommitTx, remoteSpec, remoteCommitTx) = - ChannelHelpers.makeFirstCommitTxs localParams - remoteParams - state.LastSent.FundingSatoshis - state.LastSent.PushMSat - state.LastSent.FeeRatePerKw - outIndex - fundingTxId - (commitmentSeed.DerivePerCommitmentPoint CommitmentNumber.FirstCommitment) - msg.FirstPerCommitmentPoint - cs.Network - let localSigOfRemoteCommit, _ = - cs.ChannelPrivKeys.SignWithFundingPrivKey remoteCommitTx.Value - let nextMsg: FundingCreatedMsg = { - TemporaryChannelId = msg.TemporaryChannelId - FundingTxId = fundingTxId - FundingOutputIndex = outIndex - Signature = !>localSigOfRemoteCommit.Signature - } - let channelId = OutPoint(fundingTxId.Value, uint32 outIndex.Value).ToChannelId() - let data = { Data.WaitForFundingSignedData.ChannelId = channelId - LocalParams = localParams - RemoteParams = remoteParams - Data.WaitForFundingSignedData.FundingTx = fundingTx - Data.WaitForFundingSignedData.LocalSpec = commitmentSpec - LocalCommitTx = localCommitTx - RemoteCommit = { RemoteCommit.Index = CommitmentNumber.FirstCommitment - Spec = remoteSpec - TxId = remoteCommitTx.Value.GetGlobalTransaction().GetTxId() - RemotePerCommitmentPoint = msg.FirstPerCommitmentPoint } - ChannelFlags = state.InputInitFunder.ChannelFlags - LastSent = nextMsg - InitialFeeRatePerKw = state.InputInitFunder.InitFeeRatePerKw } - return [ WeAcceptedAcceptChannel(nextMsg, data) ] - } - | WaitForFundingSigned state, ApplyFundingSigned msg -> - result { - let remoteChannelKeys = state.RemoteParams.ChannelPubKeys - let! finalizedLocalCommitTx = - let theirFundingPk = remoteChannelKeys.FundingPubKey.RawPubKey() - let _, signedLocalCommitTx = - cs.ChannelPrivKeys.SignWithFundingPrivKey state.LocalCommitTx.Value - let remoteSigPairOfLocalTx = (theirFundingPk, TransactionSignature(msg.Signature.Value, SigHash.All)) - let sigPairs = seq [ remoteSigPairOfLocalTx; ] - Transactions.checkTxFinalized signedLocalCommitTx state.LocalCommitTx.WhichInput sigPairs |> expectTransactionError - let commitments = { Commitments.LocalParams = state.LocalParams - RemoteParams = state.RemoteParams - ChannelFlags = state.ChannelFlags - FundingScriptCoin = - let amount = state.FundingTx.Value.Outputs.[int state.LastSent.FundingOutputIndex.Value].Value - ChannelHelpers.getFundingScriptCoin - state.LocalParams.ChannelPubKeys.FundingPubKey - remoteChannelKeys.FundingPubKey - state.LastSent.FundingTxId - state.LastSent.FundingOutputIndex - amount - LocalCommit = { Index = CommitmentNumber.FirstCommitment; - Spec = state.LocalSpec; - PublishableTxs = { PublishableTxs.CommitTx = finalizedLocalCommitTx - HTLCTxs = [] } - PendingHTLCSuccessTxs = [] } - RemoteCommit = state.RemoteCommit - LocalChanges = LocalChanges.Zero - RemoteChanges = RemoteChanges.Zero - LocalNextHTLCId = HTLCId.Zero - RemoteNextHTLCId = HTLCId.Zero - OriginChannels = Map.empty - // we will receive their next per-commitment point in the next msg, so we temporarily put a random byte array - RemoteNextCommitInfo = DataEncoders.HexEncoder().DecodeData("0101010101010101010101010101010101010101010101010101010101010101") |> fun h -> new Key(h) |> fun k -> k.PubKey |> PerCommitmentPoint |> RemoteNextCommitInfo.Revoked - RemotePerCommitmentSecrets = PerCommitmentSecretStore() - ChannelId = - msg.ChannelId } - let nextState = { WaitForFundingConfirmedData.Commitments = commitments - Deferred = None - LastSent = Choice1Of2 state.LastSent - InitialFeeRatePerKw = state.InitialFeeRatePerKw - ChannelId = msg.ChannelId } - return [ WeAcceptedFundingSigned(state.FundingTx, nextState) ] - } + *) + //| WaitForFundingSigned state, ApplyFundingSigned msg -> // --------------- open channel procedure: case we are fundee ------------- - | WaitForInitInternal, CreateInbound inputInitFundee -> - [ NewInboundChannelStarted({ InitFundee = inputInitFundee }) ] |> Ok + //| WaitForInitInternal, CreateInbound inputInitFundee -> + //[ NewInboundChannelStarted({ InitFundee = inputInitFundee }) ] |> Ok | WaitForFundingConfirmed state, CreateChannelReestablish -> makeChannelReestablish cs.ChannelPrivKeys state | ChannelState.Normal state, CreateChannelReestablish -> makeChannelReestablish cs.ChannelPrivKeys state + (* | WaitForOpenChannel state, ApplyOpenChannel msg -> result { do! Validation.checkOpenChannelMsgAcceptable (cs.FeeEstimator) (cs.Config) msg @@ -315,71 +553,11 @@ module Channel = let data = Data.WaitForFundingCreatedData.Create localParams remoteParams msg acceptChannelMsg return [ WeAcceptedOpenChannel(acceptChannelMsg, data) ] } - | WaitForOpenChannel _state, ChannelCommand.Close _spk -> - [ ChannelEvent.Closed ] |> Ok + *) + //| WaitForOpenChannel _state, ChannelCommand.Close _spk -> + //[ ChannelEvent.Closed ] |> Ok - | WaitForFundingCreated state, ApplyFundingCreated msg -> - result { - let remoteChannelKeys = state.RemoteParams.ChannelPubKeys - let! (localSpec, localCommitTx, remoteSpec, remoteCommitTx) = - ChannelHelpers.makeFirstCommitTxs - state.LocalParams - state.RemoteParams - state.FundingSatoshis - state.PushMSat - state.InitialFeeRatePerKw - msg.FundingOutputIndex - msg.FundingTxId - state.LastSent.FirstPerCommitmentPoint - state.RemoteFirstPerCommitmentPoint - cs.Network - assert (localCommitTx.Value.IsReadyToSign()) - let _s, signedLocalCommitTx = - cs.ChannelPrivKeys.SignWithFundingPrivKey localCommitTx.Value - let remoteTxSig = TransactionSignature(msg.Signature.Value, SigHash.All) - let theirSigPair = (remoteChannelKeys.FundingPubKey.RawPubKey(), remoteTxSig) - let sigPairs = seq [ theirSigPair ] - let! finalizedCommitTx = - Transactions.checkTxFinalized (signedLocalCommitTx) (localCommitTx.WhichInput) sigPairs - |> expectTransactionError - let localSigOfRemoteCommit, _ = - cs.ChannelPrivKeys.SignWithFundingPrivKey remoteCommitTx.Value - let channelId = OutPoint(msg.FundingTxId.Value, uint32 msg.FundingOutputIndex.Value).ToChannelId() - let msgToSend: FundingSignedMsg = { ChannelId = channelId; Signature = !>localSigOfRemoteCommit.Signature } - let commitments = { Commitments.LocalParams = state.LocalParams - RemoteParams = state.RemoteParams - ChannelFlags = state.ChannelFlags - FundingScriptCoin = - ChannelHelpers.getFundingScriptCoin - state.LocalParams.ChannelPubKeys.FundingPubKey - remoteChannelKeys.FundingPubKey - msg.FundingTxId - msg.FundingOutputIndex - state.FundingSatoshis - LocalCommit = { LocalCommit.Index = CommitmentNumber.FirstCommitment - Spec = localSpec - PublishableTxs = { PublishableTxs.CommitTx = finalizedCommitTx; - HTLCTxs = [] } - PendingHTLCSuccessTxs = [] } - RemoteCommit = { RemoteCommit.Index = CommitmentNumber.FirstCommitment - Spec = remoteSpec - TxId = remoteCommitTx.Value.GetGlobalTransaction().GetTxId() - RemotePerCommitmentPoint = state.RemoteFirstPerCommitmentPoint } - LocalChanges = LocalChanges.Zero - RemoteChanges = RemoteChanges.Zero - LocalNextHTLCId = HTLCId.Zero - RemoteNextHTLCId = HTLCId.Zero - OriginChannels = Map.empty - RemoteNextCommitInfo = DataEncoders.HexEncoder().DecodeData("0101010101010101010101010101010101010101010101010101010101010101") |> fun h -> new Key(h) |> fun k -> k.PubKey |> PerCommitmentPoint |> RemoteNextCommitInfo.Revoked - RemotePerCommitmentSecrets = PerCommitmentSecretStore() - ChannelId = channelId } - let nextState = { WaitForFundingConfirmedData.Commitments = commitments - Deferred = None - LastSent = msgToSend |> Choice2Of2 - InitialFeeRatePerKw = state.InitialFeeRatePerKw - ChannelId = channelId } - return [ WeAcceptedFundingCreated(msgToSend, nextState) ] - } + //| WaitForFundingCreated state, ApplyFundingCreated msg -> | WaitForFundingConfirmed _state, ApplyFundingLocked msg -> [ TheySentFundingLocked msg ] |> Ok | WaitForFundingConfirmed state, ApplyFundingConfirmedOnBC(height, txindex, depth) -> @@ -803,23 +981,23 @@ module Channel = let applyEvent c (e: ChannelEvent): Channel = match e, c.State with - | NewOutboundChannelStarted(_, data), WaitForInitInternal -> - { c with State = (WaitForAcceptChannel data) } - | NewInboundChannelStarted(data), WaitForInitInternal -> - { c with State = (WaitForOpenChannel data) } + //| NewOutboundChannelStarted(_, data), WaitForInitInternal -> + //{ c with State = (WaitForAcceptChannel data) } + //| NewInboundChannelStarted(data), WaitForInitInternal -> + //{ c with State = (WaitForOpenChannel data) } // --------- init fundee ----- - | WeAcceptedOpenChannel(_, data), WaitForOpenChannel _ -> - let state = WaitForFundingCreated data - { c with State = state } - | WeAcceptedFundingCreated(_, data), WaitForFundingCreated _ -> - let state = WaitForFundingConfirmed data - { c with State = state } + //| WeAcceptedOpenChannel(_, data), WaitForOpenChannel _ -> + //let state = WaitForFundingCreated data + //{ c with State = state } + //| WeAcceptedFundingCreated(_, data), WaitForFundingCreated _ -> + //let state = WaitForFundingConfirmed data + //{ c with State = state } // --------- init funder ----- - | WeAcceptedAcceptChannel(_, data), WaitForAcceptChannel _ -> - { c with State = WaitForFundingSigned data } - | WeAcceptedFundingSigned(_, data), WaitForFundingSigned _ -> - { c with State = WaitForFundingConfirmed data } + //| WeAcceptedAcceptChannel(_, data), WaitForAcceptChannel _ -> + //{ c with State = WaitForFundingSigned data } + //| WeAcceptedFundingSigned(_, data), WaitForFundingSigned _ -> + //{ c with State = WaitForFundingConfirmed data } // --------- init both ------ | FundingConfirmed data, WaitForFundingConfirmed _ -> @@ -849,10 +1027,10 @@ module Channel = { c with State = ChannelState.Normal nextState } | WeSentFundingLocked msg, WaitForFundingLocked prevState -> { c with State = WaitForFundingLocked { prevState with OurMessage = msg; HaveWeSentFundingLocked = true } } - | BothFundingLocked data, WaitForFundingSigned _s -> - { c with State = ChannelState.Normal data } - | BothFundingLocked data, WaitForFundingLocked _s -> - { c with State = ChannelState.Normal data } + //| BothFundingLocked data, WaitForFundingSigned _s -> + //{ c with State = ChannelState.Normal data } + //| BothFundingLocked data, WaitForFundingLocked _s -> + //{ c with State = ChannelState.Normal data } // ----- normal operation -------- | WeAcceptedOperationMonoHopUnidirectionalPayment(_, newCommitments), ChannelState.Normal normalData -> diff --git a/src/DotNetLightning.Core/Channel/ChannelOperations.fs b/src/DotNetLightning.Core/Channel/ChannelOperations.fs index 892aab85e..e502c85ff 100644 --- a/src/DotNetLightning.Core/Channel/ChannelOperations.fs +++ b/src/DotNetLightning.Core/Channel/ChannelOperations.fs @@ -192,14 +192,14 @@ and InputInitFundee = { /// It is just an input to the state. type ChannelCommand = // open: funder - | CreateOutbound of InputInitFunder + //| CreateOutbound of InputInitFunder | ApplyAcceptChannel of AcceptChannelMsg | ApplyFundingSigned of FundingSignedMsg | ApplyFundingLocked of FundingLockedMsg | ApplyFundingConfirmedOnBC of height: BlockHeight * txIndex: TxIndexInBlock * depth: BlockHeightOffset32 // open: fundee - | CreateInbound of InputInitFundee + //| CreateInbound of InputInitFundee | ApplyOpenChannel of OpenChannelMsg | ApplyFundingCreated of FundingCreatedMsg diff --git a/src/DotNetLightning.Core/Channel/ChannelTypes.fs b/src/DotNetLightning.Core/Channel/ChannelTypes.fs index 73dafd725..9cb19ba1d 100644 --- a/src/DotNetLightning.Core/Channel/ChannelTypes.fs +++ b/src/DotNetLightning.Core/Channel/ChannelTypes.fs @@ -1,5 +1,6 @@ namespace DotNetLightning.Channel +open DotNetLightning.Chain open DotNetLightning.Utils open DotNetLightning.Utils.Aether open DotNetLightning.DomainUtils.Types @@ -8,6 +9,7 @@ open DotNetLightning.Transactions open DotNetLightning.Crypto open NBitcoin + (* based on eclair's channel state management *) @@ -252,13 +254,13 @@ module Data = type ChannelEvent = // --- ln events --- // --------- init fundee -------- - | NewInboundChannelStarted of nextState: Data.WaitForOpenChannelData - | WeAcceptedOpenChannel of nextMsg: AcceptChannelMsg * nextState: Data.WaitForFundingCreatedData - | WeAcceptedFundingCreated of nextMsg: FundingSignedMsg * nextState: Data.WaitForFundingConfirmedData + //| NewInboundChannelStarted of nextState: Data.WaitForOpenChannelData + //| WeAcceptedOpenChannel of nextMsg: AcceptChannelMsg * nextState: Data.WaitForFundingCreatedData + //| WeAcceptedFundingCreated of nextMsg: FundingSignedMsg * nextState: Data.WaitForFundingConfirmedData // --------- init fender -------- - | NewOutboundChannelStarted of nextMsg: OpenChannelMsg * nextState: Data.WaitForAcceptChannelData - | WeAcceptedAcceptChannel of nextMsg: FundingCreatedMsg * nextState: Data.WaitForFundingSignedData + //| NewOutboundChannelStarted of nextMsg: OpenChannelMsg * nextState: Data.WaitForAcceptChannelData + //| WeAcceptedAcceptChannel of nextMsg: FundingCreatedMsg * nextState: Data.WaitForFundingSignedData | WeAcceptedFundingSigned of txToPublish: FinalizedTx * nextState: Data.WaitForFundingConfirmedData /// -------- init both ----- @@ -327,11 +329,11 @@ type ChannelStatePhase = | Abnormal type ChannelState = /// Establishing - | WaitForInitInternal - | WaitForOpenChannel of WaitForOpenChannelData - | WaitForAcceptChannel of WaitForAcceptChannelData - | WaitForFundingCreated of WaitForFundingCreatedData - | WaitForFundingSigned of WaitForFundingSignedData + //| WaitForInitInternal + //| WaitForOpenChannel of WaitForOpenChannelData + //| WaitForAcceptChannel of WaitForAcceptChannelData + //| WaitForFundingCreated of WaitForFundingCreatedData + //| WaitForFundingSigned of WaitForFundingSignedData | WaitForFundingConfirmed of WaitForFundingConfirmedData | WaitForFundingLocked of WaitForFundingLockedData @@ -355,7 +357,7 @@ type ChannelState = with interface IState - static member Zero = WaitForInitInternal + //static member Zero = WaitForInitInternal static member Normal_: Prism<_, _> = (fun cc -> match cc with | Normal s -> Some s @@ -365,11 +367,11 @@ type ChannelState = | _ -> cc ) member this.ChannelId: Option = match this with - | WaitForInitInternal - | WaitForOpenChannel _ - | WaitForAcceptChannel _ - | WaitForFundingCreated _ -> None - | WaitForFundingSigned data -> Some data.ChannelId + //| WaitForInitInternal + //| WaitForOpenChannel _ + //| WaitForAcceptChannel _ + //| WaitForFundingCreated _ -> None + //| WaitForFundingSigned data -> Some data.ChannelId | WaitForFundingConfirmed data -> Some data.ChannelId | WaitForFundingLocked data -> Some data.ChannelId | Normal data -> Some data.ChannelId @@ -385,11 +387,11 @@ type ChannelState = member this.Phase = match this with - | WaitForInitInternal - | WaitForOpenChannel _ - | WaitForAcceptChannel _ - | WaitForFundingCreated _ - | WaitForFundingSigned _ + //| WaitForInitInternal + //| WaitForOpenChannel _ + //| WaitForAcceptChannel _ + //| WaitForFundingCreated _ + //| WaitForFundingSigned _ | WaitForFundingConfirmed _ | WaitForFundingLocked _ -> Opening | Normal _ -> ChannelStatePhase.Normal @@ -405,11 +407,11 @@ type ChannelState = member this.Commitments: Option = match this with - | WaitForInitInternal - | WaitForOpenChannel _ - | WaitForAcceptChannel _ - | WaitForFundingCreated _ - | WaitForFundingSigned _ -> None + //| WaitForInitInternal + //| WaitForOpenChannel _ + //| WaitForAcceptChannel _ + //| WaitForFundingCreated _ -> None + //| WaitForFundingSigned _ -> None | WaitForFundingConfirmed data -> Some (data :> IHasCommitments).Commitments | WaitForFundingLocked data -> Some (data :> IHasCommitments).Commitments | Normal data -> Some (data :> IHasCommitments).Commitments