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