@@ -246,7 +246,7 @@ case class LocalCommit(index: Long, spec: CommitmentSpec, commitTxAndRemoteSig:
246
246
object LocalCommit {
247
247
def fromCommitSig (keyManager : ChannelKeyManager , params : ChannelParams , fundingTxId : TxId ,
248
248
fundingTxIndex : Long , remoteFundingPubKey : PublicKey , commitInput : InputInfo ,
249
- commit : CommitSig , localCommitIndex : Long , spec : CommitmentSpec , localPerCommitmentPoint : PublicKey , localNonce_opt : Option [(SecretNonce , IndividualNonce )]): Either [ChannelException , LocalCommit ] = {
249
+ commit : CommitSig , localCommitIndex : Long , spec : CommitmentSpec , localPerCommitmentPoint : PublicKey , localNonce_opt : Option [(SecretNonce , IndividualNonce )])( implicit log : LoggingAdapter ) : Either [ChannelException , LocalCommit ] = {
250
250
val (localCommitTx, htlcTxs) = Commitment .makeLocalTxs(keyManager, params.channelConfig, params.channelFeatures, localCommitIndex, params.localParams, params.remoteParams, fundingTxIndex, remoteFundingPubKey, commitInput, localPerCommitmentPoint, spec)
251
251
commit.sigOrPartialSig match {
252
252
case Left (sig) =>
@@ -257,6 +257,10 @@ object LocalCommit {
257
257
val fundingPubkey = keyManager.fundingPublicKey(params.localParams.fundingKeyPath, fundingTxIndex).publicKey
258
258
val Some (localNonce) = localNonce_opt
259
259
if (! localCommitTx.checkPartialSignature(psig, fundingPubkey, localNonce._2, remoteFundingPubKey)) {
260
+ log.debug(s " fromCommitSig: invalid partial signature $psig fundingPubkey = $fundingPubkey, fundingTxIndex = $fundingTxIndex localCommitIndex = $localCommitIndex localNonce = $localNonce remoteFundingPubKey = $remoteFundingPubKey" )
261
+
262
+ val localNonce1 = keyManager.verificationNonce(params.localParams.fundingKeyPath, fundingTxIndex, keyManager.keyPath(params.localParams, params.channelConfig), localCommitIndex)
263
+ log.debug(s " with $localNonce1 ${localCommitTx.checkPartialSignature(psig, fundingPubkey, localNonce1._2, remoteFundingPubKey)}" )
260
264
return Left (InvalidCommitmentSignature (params.channelId, fundingTxId, fundingTxIndex, localCommitTx.tx))
261
265
}
262
266
}
@@ -285,9 +289,10 @@ case class RemoteCommit(index: Long, spec: CommitmentSpec, txid: TxId, remotePer
285
289
def sign (keyManager : ChannelKeyManager , params : ChannelParams , fundingTxIndex : Long , remoteFundingPubKey : PublicKey , commitInput : InputInfo , remoteNonce_opt : Option [IndividualNonce ])(implicit log : LoggingAdapter ): CommitSig = {
286
290
val (remoteCommitTx, htlcTxs) = Commitment .makeRemoteTxs(keyManager, params.channelConfig, params.channelFeatures, index, params.localParams, params.remoteParams, fundingTxIndex, remoteFundingPubKey, commitInput, remotePerCommitmentPoint, spec)
287
291
val (sig, tlvStream) = if (params.commitmentFormat.useTaproot) {
288
- val localNonce = keyManager.verificationNonce (params.localParams.fundingKeyPath, fundingTxIndex, keyManager.keyPath(params.localParams, params.channelConfig), index )
292
+ val localNonce = keyManager.signingNonce (params.localParams.fundingKeyPath, fundingTxIndex)
289
293
val Some (remoteNonce) = remoteNonce_opt
290
294
val Right (localPartialSigOfRemoteTx) = keyManager.partialSign(remoteCommitTx, keyManager.fundingPublicKey(params.localParams.fundingKeyPath, fundingTxIndex), remoteFundingPubKey, TxOwner .Remote , localNonce, remoteNonce)
295
+ log.debug(s " RemoteCommit.sign localPartialSigOfRemoteTx = $localPartialSigOfRemoteTx fundingTxIndex = $fundingTxIndex remote commit index = $index remote nonce = $remoteNonce" )
291
296
val tlvStream : TlvStream [CommitSigTlv ] = TlvStream (CommitSigTlv .PartialSignatureWithNonceTlv (PartialSignatureWithNonce (localPartialSigOfRemoteTx, localNonce._2)))
292
297
(ByteVector64 .Zeroes , tlvStream)
293
298
} else {
@@ -679,7 +684,7 @@ case class Commitment(fundingTxIndex: Long,
679
684
val localNonce = keyManager.signingNonce(params.localParams.fundingKeyPath, fundingTxIndex)
680
685
val Some (remoteNonce) = nextRemoteNonce_opt
681
686
val Right (psig) = keyManager.partialSign(remoteCommitTx, keyManager.fundingPublicKey(params.localParams.fundingKeyPath, fundingTxIndex), remoteFundingPubKey, TxOwner .Remote , localNonce, remoteNonce)
682
- log.debug(s " sendCommit: creating partial sig $psig for remote commit tx ${remoteCommitTx.tx.txid} with remote nonce $remoteNonce and remoteNextPerCommitmentPoint = $remoteNextPerCommitmentPoint" )
687
+ log.debug(s " sendCommit: creating partial sig $psig for remote commit tx ${remoteCommitTx.tx.txid} with fundingTxIndex = $fundingTxIndex remoteCommit.index (should add +1) = ${remoteCommit.index} remote nonce $remoteNonce and remoteNextPerCommitmentPoint = $remoteNextPerCommitmentPoint" )
683
688
Set (CommitSigTlv .PartialSignatureWithNonceTlv (PartialSignatureWithNonce (psig, localNonce._2)))
684
689
} else {
685
690
Set .empty
@@ -1101,6 +1106,10 @@ case class Commitments(params: ChannelParams,
1101
1106
}
1102
1107
val channelKeyPath = keyManager.keyPath(params.localParams, params.channelConfig)
1103
1108
val localPerCommitmentPoint = keyManager.commitmentPoint(channelKeyPath, localCommitIndex + 1 )
1109
+
1110
+ val fundingIndexes = active.map(_.fundingTxIndex).toSet
1111
+ if (fundingIndexes.size > 1 ) log.warning(s " more than 1 funding tx index " )
1112
+
1104
1113
// Signatures are sent in order (most recent first), calling `zip` will drop trailing sigs that are for deactivated/pruned commitments.
1105
1114
val active1 = active.zip(commits).map { case (commitment, commit) =>
1106
1115
val localNonce_opt = if (params.commitmentFormat.useTaproot) {
@@ -1247,12 +1256,20 @@ case class Commitments(params: ChannelParams,
1247
1256
}
1248
1257
1249
1258
/** This function should be used to ignore a commit_sig that we've already received. */
1250
- def ignoreRetransmittedCommitSig (commitSig : CommitSig ): Boolean = {
1251
- val latestRemoteSigOrPartialSig = latest.localCommit.commitTxAndRemoteSig.remoteSig match {
1252
- case RemoteSignature .FullSignature (sig) => Left (sig)
1253
- case _ : RemoteSignature .PartialSignatureWithNonce => Right (latest.localCommit.commitTxAndRemoteSig.remoteSig)
1254
- }
1255
- params.channelFeatures.hasFeature(Features .DualFunding ) && commitSig.batchSize == 1 && latestRemoteSigOrPartialSig == commitSig.sigOrPartialSig
1259
+ def ignoreRetransmittedCommitSig (commitSig : CommitSig , keyManager : ChannelKeyManager ): Boolean = commitSig.sigOrPartialSig match {
1260
+ case _ if ! params.channelFeatures.hasFeature(Features .DualFunding ) => false
1261
+ case _ if commitSig.batchSize != 1 => false
1262
+ case Left (sig) =>
1263
+ latest.localCommit.commitTxAndRemoteSig.remoteSig match {
1264
+ case f : RemoteSignature .FullSignature => f.sig == sig
1265
+ case _ : RemoteSignature .PartialSignatureWithNonce => false
1266
+ }
1267
+ case Right (psig) =>
1268
+ // we cannot compare partial signatures directly as they are not deterministic (a new signing nonce is used every time a signature is computed)
1269
+ // => instead we simply check that the provided partial signature is valid for our latest commit tx
1270
+ val localFundingKey = keyManager.fundingPublicKey(params.localParams.fundingKeyPath, latest.fundingTxIndex).publicKey
1271
+ val Some (localNonce) = generateLocalNonce(keyManager, latest.fundingTxIndex, latest.localCommit.index)
1272
+ latest.localCommit.commitTxAndRemoteSig.commitTx.checkPartialSignature(psig, localFundingKey, localNonce, latest.remoteFundingPubKey)
1256
1273
}
1257
1274
1258
1275
def localFundingSigs (fundingTxId : TxId ): Option [TxSignatures ] = {
@@ -1372,32 +1389,33 @@ case class Commitments(params: ChannelParams,
1372
1389
}
1373
1390
1374
1391
/**
1375
- * Create local verification nonces for the next funding tx
1392
+ * Generate local verification nonces for a specific funding tx index and commit tx index
1376
1393
*
1377
- * @param keyManager key manager that will generate actual nonces
1378
- * @return a list of 2 verification nonces for the next funding tx: one for the current commitment index, one for the next commitment index
1394
+ * @param keyManager key manager that will generate actual nonces
1395
+ * @param fundingIndex funding tx index
1396
+ * @param commitIndex commit tx index
1397
+ * @return a public nonce for thr provided fundint tx index and commit tx index if taproot is used, None otherwise
1379
1398
*/
1380
- def generateLocalNonces (keyManager : ChannelKeyManager , fundingIndex : Long ): List [IndividualNonce ] = {
1399
+ def generateLocalNonce (keyManager : ChannelKeyManager , fundingIndex : Long , commitIndex : Long ): Option [IndividualNonce ] = {
1381
1400
if (latest.params.commitmentFormat.useTaproot) {
1382
-
1383
- def localNonce (commitIndex : Long ) = {
1384
- val (_, nonce) = keyManager.verificationNonce(params.localParams.fundingKeyPath, fundingIndex, keyManager.keyPath(params.localParams, params.channelConfig), commitIndex)
1385
- nonce
1386
- }
1387
-
1388
- List (localNonce(localCommitIndex), localNonce(localCommitIndex + 1 ))
1401
+ Some (keyManager.verificationNonce(params.localParams.fundingKeyPath, fundingIndex, keyManager.keyPath(params.localParams, params.channelConfig), commitIndex)._2)
1389
1402
} else {
1390
- List .empty
1403
+ None
1391
1404
}
1392
1405
}
1393
1406
1394
1407
/**
1395
- * Create local verification nonces for the next funding tx
1408
+ * Create local verification nonces a specific funding tx index and a range of commit tx indexes
1396
1409
*
1397
1410
* @param keyManager key manager that will generate actual nonces
1398
- * @return a list of 2 verification nonces for the next funding tx: one for the current commitment index, one for the next commitment index
1411
+ * @param fundingIndex funding tx index
1412
+ * @param commitIndexes range of commit tx indexes
1413
+ * @return a list of nonces if raproot is used, or an empty list
1399
1414
*/
1400
- def generateLocalNonces (keyManager : ChannelKeyManager ): List [IndividualNonce ] = generateLocalNonces(keyManager, latest.commitment.fundingTxIndex + 1 )
1415
+ def generateLocalNonces (keyManager : ChannelKeyManager , fundingIndex : Long , commitIndexes : Long * ): List [IndividualNonce ] = {
1416
+ commitIndexes.toList.flatMap(commitIndex => generateLocalNonce(keyManager, fundingIndex, commitIndex))
1417
+ }
1418
+
1401
1419
}
1402
1420
1403
1421
object Commitments {
0 commit comments