Skip to content

Commit

Permalink
Merge pull request joemphilips#108 from canndrew/revocation-types
Browse files Browse the repository at this point in the history
Add and switch to new types for revocation
  • Loading branch information
joemphilips authored Jun 10, 2020
2 parents c63b168 + 973ce39 commit 50dce21
Show file tree
Hide file tree
Showing 30 changed files with 889 additions and 225 deletions.
6 changes: 2 additions & 4 deletions src/DotNetLightning.Core/Chain/KeysInterface.fs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ type ChannelKeys = {
PaymentBaseKey: Key
DelayedPaymentBaseKey: Key
HTLCBaseKey: Key
CommitmentSeed: uint256
CommitmentSeed: CommitmentSeed
}

with
Expand All @@ -65,7 +65,6 @@ type ChannelKeys = {
PaymentBasePubKey = this.PaymentBaseKey.PubKey
DelayedPaymentBasePubKey = this.DelayedPaymentBaseKey.PubKey
HTLCBasePubKey = this.HTLCBaseKey.PubKey
CommitmentSeed = this.CommitmentSeed
}

/// In usual operation we should not hold secrets on memory. So only hold pubkey
Expand All @@ -75,7 +74,6 @@ and ChannelPubKeys = {
PaymentBasePubKey: PubKey
DelayedPaymentBasePubKey: PubKey
HTLCBasePubKey: PubKey
CommitmentSeed: uint256
}


Expand Down Expand Up @@ -108,7 +106,7 @@ type DefaultKeyRepository(nodeSecret: ExtKey, channelIndex: int) =

let destinationKey = channelMasterKey.Derive(1, true).PrivateKey
let shutdownKey = channelMasterKey.Derive(2, true).PrivateKey
let commitmentSeed = channelMasterKey.Derive(3, true).PrivateKey.ToBytes() |> uint256
let commitmentSeed = channelMasterKey.Derive(3, true).PrivateKey |> CommitmentSeed

let fundingKey = channelMasterKey.Derive(4, true).PrivateKey
let fundingPubKey = fundingKey.PubKey
Expand Down
81 changes: 48 additions & 33 deletions src/DotNetLightning.Core/Channel/Channel.fs
Original file line number Diff line number Diff line change
Expand Up @@ -99,25 +99,34 @@ module Channel =
[ MutualClosePerformed nextData ]
|> Ok

let claimCurrentLocalCommitTxOutputs (_keyRepo: IKeysRepository, channelPubKeys: ChannelPubKeys, commitments: Commitments, commitTx: CommitTx) =
let claimCurrentLocalCommitTxOutputs (keyRepo: IKeysRepository, channelPubKeys: ChannelPubKeys, commitments: Commitments, commitTx: CommitTx) =
result {
let chanPrivateKeys = keyRepo.GetChannelKeys commitments.LocalParams.IsFunder
let commitmentSeed = chanPrivateKeys.CommitmentSeed
do! check (commitments.LocalCommit.PublishableTxs.CommitTx.Value.GetTxId()) (=) (commitTx.Value.GetTxId()) "txid mismatch. provided txid (%A) does not match current local commit tx (%A)"
let _localPerCommitmentPoint = ChannelUtils.buildCommitmentPoint (channelPubKeys.CommitmentSeed, commitments.LocalCommit.Index)
let _localPerCommitmentPoint =
commitmentSeed.DeriveCommitmentPubKey commitments.LocalCommit.Index
let _localRevocationPubKey = Generators.revocationPubKey
failwith "TODO"
}

let makeChannelReestablish (data: Data.IHasCommitments): Result<ChannelEvent list, ChannelError> =
let commitmentSeed = data.Commitments.LocalParams.ChannelPubKeys.CommitmentSeed
let makeChannelReestablish (keyRepo: IKeysRepository)
(data: Data.IHasCommitments)
: Result<ChannelEvent list, ChannelError> =
let chanPrivateKeys = keyRepo.GetChannelKeys data.Commitments.LocalParams.IsFunder
let commitmentSeed = chanPrivateKeys.CommitmentSeed
let ourChannelReestablish =
{
ChannelId = data.ChannelId
NextLocalCommitmentNumber = 1UL
NextRemoteCommitmentNumber = 0UL
DataLossProtect = OptionalField.Some({
YourLastPerCommitmentSecret = PaymentPreimage.Create([|for _ in 0..31 -> 0uy|])
MyCurrentPerCommitmentPoint = ChannelUtils.buildCommitmentPoint(commitmentSeed, 0UL)
})
DataLossProtect = OptionalField.Some <| {
YourLastPerCommitmentSecret =
RevocationKey.FromBytes [|for _ in 0..31 -> 0uy|]
MyCurrentPerCommitmentPoint =
let revocationKey = commitmentSeed.DeriveRevocationKey CommitmentNumber.LastCommitment
revocationKey.CommitmentPubKey
}
}
[ WeSentChannelReestablish ourChannelReestablish ] |> Ok

Expand All @@ -143,7 +152,7 @@ module Channel =
PaymentBasepoint = inputInitFunder.ChannelKeys.PaymentBaseKey.PubKey
DelayedPaymentBasepoint = inputInitFunder.ChannelKeys.DelayedPaymentBaseKey.PubKey
HTLCBasepoint = inputInitFunder.ChannelKeys.HTLCBaseKey.PubKey
FirstPerCommitmentPoint = ChannelUtils.buildCommitmentPoint(inputInitFunder.ChannelKeys.CommitmentSeed, 0UL)
FirstPerCommitmentPoint = inputInitFunder.ChannelKeys.CommitmentSeed.DeriveCommitmentPubKey CommitmentNumber.FirstCommitment
ChannelFlags = inputInitFunder.ChannelFlags
ShutdownScriptPubKey = cs.Config.ChannelOptions.ShutdownScriptPubKey
}
Expand Down Expand Up @@ -177,7 +186,7 @@ module Channel =
state.LastSent.FeeRatePerKw
outIndex
(fundingTx.Value.GetHash() |> TxId)
(ChannelUtils.buildCommitmentPoint(commitmentSeed, 0UL))
(commitmentSeed.DeriveCommitmentPubKey CommitmentNumber.FirstCommitment)
msg.FirstPerCommitmentPoint
cs.Secp256k1Context
cs.Network
Expand All @@ -194,7 +203,7 @@ module Channel =
Data.WaitForFundingSignedData.FundingTx = fundingTx
Data.WaitForFundingSignedData.LocalSpec = commitmentSpec
LocalCommitTx = localCommitTx
RemoteCommit = { RemoteCommit.Index = 0UL;
RemoteCommit = { RemoteCommit.Index = CommitmentNumber.FirstCommitment
Spec = remoteSpec
TxId = remoteCommitTx.Value.GetGlobalTransaction().GetTxId()
RemotePerCommitmentPoint = msg.FirstPerCommitmentPoint }
Expand All @@ -221,7 +230,7 @@ module Channel =
state.LastSent.FundingTxId
state.LastSent.FundingOutputIndex
amount
LocalCommit = { Index = 0UL;
LocalCommit = { Index = CommitmentNumber.FirstCommitment;
Spec = state.LocalSpec;
PublishableTxs = { PublishableTxs.CommitTx = finalizedLocalCommitTx
HTLCTxs = [] }
Expand All @@ -233,8 +242,8 @@ module Channel =
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") |> Key |> fun k -> k.PubKey |> RemoteNextCommitInfo.Revoked
RemotePerCommitmentSecrets = ShaChain.Zero
RemoteNextCommitInfo = DataEncoders.HexEncoder().DecodeData("0101010101010101010101010101010101010101010101010101010101010101") |> Key |> fun k -> k.PubKey |> CommitmentPubKey |> RemoteNextCommitInfo.Revoked
RemotePerCommitmentSecrets = RevocationSet()
ChannelId =
msg.ChannelId }
let nextState = { WaitForFundingConfirmedData.Commitments = commitments
Expand All @@ -249,15 +258,15 @@ module Channel =
[ NewInboundChannelStarted({ InitFundee = inputInitFundee }) ] |> Ok

| WaitForFundingConfirmed state, CreateChannelReestablish ->
makeChannelReestablish state
makeChannelReestablish cs.KeysRepository state
| ChannelState.Normal state, CreateChannelReestablish ->
makeChannelReestablish state
makeChannelReestablish cs.KeysRepository state
| WaitForOpenChannel state, ApplyOpenChannel msg ->
result {
do! Validation.checkOpenChannelMsgAcceptable (cs.FeeEstimator) (cs.Config) msg
let localParams = state.InitFundee.LocalParams
let channelKeys = state.InitFundee.ChannelKeys
let localCommitmentSecret = ChannelUtils.buildCommitmentSecret (channelKeys.CommitmentSeed, 0UL)
let localCommitmentPubKey = channelKeys.CommitmentSeed.DeriveCommitmentPubKey CommitmentNumber.FirstCommitment
let acceptChannelMsg: AcceptChannelMsg = {
TemporaryChannelId = msg.TemporaryChannelId
DustLimitSatoshis = localParams.DustLimitSatoshis
Expand All @@ -272,7 +281,7 @@ module Channel =
PaymentBasepoint = channelKeys.PaymentBaseKey.PubKey
DelayedPaymentBasepoint = channelKeys.DelayedPaymentBaseKey.PubKey
HTLCBasepoint = channelKeys.HTLCBaseKey.PubKey
FirstPerCommitmentPoint = localCommitmentSecret.PubKey
FirstPerCommitmentPoint = localCommitmentPubKey
ShutdownScriptPubKey = cs.Config.ChannelOptions.ShutdownScriptPubKey
}
let remoteParams = RemoteParams.FromOpenChannel cs.RemoteNodeId state.InitFundee.RemoteInit msg cs.Config.ChannelHandshakeConfig
Expand Down Expand Up @@ -313,12 +322,12 @@ module Channel =
RemoteParams = state.RemoteParams
ChannelFlags = state.ChannelFlags
FundingScriptCoin = ChannelHelpers.getFundingScriptCoin state.LocalParams.ChannelPubKeys state.RemoteParams.FundingPubKey msg.FundingTxId msg.FundingOutputIndex state.FundingSatoshis
LocalCommit = { LocalCommit.Index = 0UL;
LocalCommit = { LocalCommit.Index = CommitmentNumber.FirstCommitment
Spec = localSpec
PublishableTxs = { PublishableTxs.CommitTx = finalizedCommitTx;
HTLCTxs = [] }
PendingHTLCSuccessTxs = [] }
RemoteCommit = { RemoteCommit.Index = 0UL;
RemoteCommit = { RemoteCommit.Index = CommitmentNumber.FirstCommitment
Spec = remoteSpec
TxId = remoteCommitTx.Value.GetGlobalTransaction().GetTxId()
RemotePerCommitmentPoint = state.RemoteFirstPerCommitmentPoint }
Expand All @@ -327,8 +336,8 @@ module Channel =
LocalNextHTLCId = HTLCId.Zero
RemoteNextHTLCId = HTLCId.Zero
OriginChannels = Map.empty
RemoteNextCommitInfo = DataEncoders.HexEncoder() .DecodeData("0101010101010101010101010101010101010101010101010101010101010101") |> Key |> fun k -> k.PubKey |> RemoteNextCommitInfo.Revoked
RemotePerCommitmentSecrets = ShaChain.Zero
RemoteNextCommitInfo = DataEncoders.HexEncoder().DecodeData("0101010101010101010101010101010101010101010101010101010101010101") |> Key |> fun k -> k.PubKey |> CommitmentPubKey |> RemoteNextCommitInfo.Revoked
RemotePerCommitmentSecrets = RevocationSet()
ChannelId = channelId }
let nextState = { WaitForFundingConfirmedData.Commitments = commitments
Deferred = None
Expand All @@ -343,8 +352,9 @@ module Channel =
if state.Commitments.RemoteParams.MinimumDepth > depth then
[] |> Ok
else
let chanPrivateKeys = cs.KeysRepository.GetChannelKeys state.Commitments.LocalParams.IsFunder
let nextPerCommitmentPoint =
ChannelUtils.buildCommitmentPoint (state.Commitments.LocalParams.ChannelPubKeys.CommitmentSeed, 1UL)
chanPrivateKeys.CommitmentSeed.DeriveCommitmentPubKey CommitmentNumber.FirstCommitment.NextCommitment
let msgToSend: FundingLockedMsg = { ChannelId = state.Commitments.ChannelId; NextPerCommitmentPoint = nextPerCommitmentPoint }

// This is temporary channel id that we will use in our channel_update message, the goal is to be able to use our channel
Expand Down Expand Up @@ -485,22 +495,27 @@ module Channel =
| ChannelState.Normal state, ApplyRevokeAndACK msg ->
let cm = state.Commitments
match cm.RemoteNextCommitInfo with
| RemoteNextCommitInfo.Waiting _ when (msg.PerCommitmentSecret.ToPubKey() <> cm.RemoteCommit.RemotePerCommitmentPoint) ->
| RemoteNextCommitInfo.Waiting _ when (msg.PerCommitmentSecret.CommitmentPubKey <> cm.RemoteCommit.RemotePerCommitmentPoint) ->
let errorMsg = sprintf "Invalid revoke_and_ack %A; must be %A" msg.PerCommitmentSecret cm.RemoteCommit.RemotePerCommitmentPoint
invalidRevokeAndACK msg errorMsg
| RemoteNextCommitInfo.Revoked _ ->
let errorMsg = sprintf "Unexpected revocation"
invalidRevokeAndACK msg errorMsg
| RemoteNextCommitInfo.Waiting({ NextRemoteCommit = theirNextCommit }) ->
let commitments1 = { cm with LocalChanges = { cm.LocalChanges with Signed = []; ACKed = cm.LocalChanges.ACKed @ cm.LocalChanges.Signed }
RemoteChanges = { cm.RemoteChanges with Signed = [] }
RemoteCommit = theirNextCommit
RemoteNextCommitInfo = RemoteNextCommitInfo.Revoked(msg.NextPerCommitmentPoint)
RemotePerCommitmentSecrets = cm.RemotePerCommitmentSecrets.AddHash (msg.PerCommitmentSecret.ToByteArray(), 0xffffffffffffUL - cm.RemoteCommit.Index) }
let result = [ WeAcceptedRevokeAndACK(commitments1) ]
result |> Ok
failwith "needs update"

let remotePerCommitmentSecretsOpt =
cm.RemotePerCommitmentSecrets.InsertRevocationKey
cm.RemoteCommit.Index
msg.PerCommitmentSecret
match remotePerCommitmentSecretsOpt with
| Error err -> invalidRevokeAndACK msg err.Message
| Ok remotePerCommitmentSecrets ->
let commitments1 = { cm with LocalChanges = { cm.LocalChanges with Signed = []; ACKed = cm.LocalChanges.ACKed @ cm.LocalChanges.Signed }
RemoteChanges = { cm.RemoteChanges with Signed = [] }
RemoteCommit = theirNextCommit
RemoteNextCommitInfo = RemoteNextCommitInfo.Revoked msg.NextPerCommitmentPoint
RemotePerCommitmentSecrets = remotePerCommitmentSecrets }
let result = Ok [ WeAcceptedRevokeAndACK(commitments1) ]
failwith "needs update"

| ChannelState.Normal state, ChannelCommand.Close cmd ->
let localSPK = cmd.ScriptPubKey |> Option.defaultValue (state.Commitments.LocalParams.DefaultFinalScriptPubKey)
Expand Down
4 changes: 2 additions & 2 deletions src/DotNetLightning.Core/Channel/ChannelTypes.fs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ module Data =
FundingSatoshis: Money
PushMsat: LNMoney
InitialFeeRatePerKw: FeeRatePerKw
RemoteFirstPerCommitmentPoint: PubKey
RemoteFirstPerCommitmentPoint: CommitmentPubKey
LastSent: OpenChannelMsg
}
with interface IChannelStateData
Expand All @@ -88,7 +88,7 @@ module Data =
FundingSatoshis: Money
PushMSat: LNMoney
InitialFeeRatePerKw: FeeRatePerKw
RemoteFirstPerCommitmentPoint: PubKey
RemoteFirstPerCommitmentPoint: CommitmentPubKey
ChannelFlags: uint8
LastSent: AcceptChannelMsg
}
Expand Down
20 changes: 0 additions & 20 deletions src/DotNetLightning.Core/Channel/ChannelUtils.fs

This file was deleted.

Loading

0 comments on commit 50dce21

Please sign in to comment.