@@ -13,8 +13,9 @@ import fr.acinq.lightning.Lightning.randomBytes32
1313import fr.acinq.lightning.MilliSatoshi
1414import fr.acinq.lightning.blockchain.electrum.WalletState
1515import fr.acinq.lightning.blockchain.fee.FeeratePerKw
16- import fr.acinq.lightning.crypto.Bolt3Derivation.deriveForCommitment
16+ import fr.acinq.lightning.crypto.ChannelKeys
1717import fr.acinq.lightning.crypto.KeyManager
18+ import fr.acinq.lightning.crypto.SwapInOnChainKeys
1819import fr.acinq.lightning.logging.MDCLogger
1920import fr.acinq.lightning.transactions.*
2021import fr.acinq.lightning.utils.*
@@ -29,7 +30,7 @@ import kotlinx.coroutines.CompletableDeferred
2930sealed class SharedFundingInput {
3031 abstract val info: Transactions .InputInfo
3132 abstract val weight: Int
32- abstract fun sign (channelKeys : KeyManager . ChannelKeys , tx : Transaction ): ByteVector64
33+ abstract fun sign (channelKeys : ChannelKeys , tx : Transaction ): ByteVector64
3334
3435 data class Multisig2of2 (override val info : Transactions .InputInfo , val fundingTxIndex : Long , val remoteFundingPubkey : PublicKey ) : SharedFundingInput() {
3536
@@ -42,7 +43,7 @@ sealed class SharedFundingInput {
4243 // This value was computed assuming 73 bytes signatures (worst-case scenario).
4344 override val weight: Int = Multisig2of2 .weight
4445
45- override fun sign (channelKeys : KeyManager . ChannelKeys , tx : Transaction ): ByteVector64 {
46+ override fun sign (channelKeys : ChannelKeys , tx : Transaction ): ByteVector64 {
4647 val fundingKey = channelKeys.fundingKey(fundingTxIndex)
4748 return Transactions .sign(Transactions .TransactionWithInputInfo .SpliceTx (info, tx), fundingKey)
4849 }
@@ -94,9 +95,9 @@ data class InteractiveTxParams(
9495 // BOLT 2: the initiator's serial IDs MUST use even values and the non-initiator odd values.
9596 val serialIdParity = if (isInitiator) 0 else 1
9697
97- fun fundingPubkeyScript (channelKeys : KeyManager . ChannelKeys ): ByteVector {
98+ fun fundingPubkeyScript (channelKeys : ChannelKeys ): ByteVector {
9899 val fundingTxIndex = (sharedInput as ? SharedFundingInput .Multisig2of2 )?.let { it.fundingTxIndex + 1 } ? : 0
99- return Helpers .Funding .makeFundingPubKeyScript(channelKeys.fundingPubKey (fundingTxIndex), remoteFundingPubkey)
100+ return Helpers .Funding .makeFundingPubKeyScript(channelKeys.fundingKey (fundingTxIndex).publicKey( ), remoteFundingPubkey)
100101 }
101102
102103 fun liquidityFees (purchase : LiquidityAds .Purchase ? ): MilliSatoshi = purchase?.let { l ->
@@ -266,8 +267,8 @@ data class FundingContributions(val inputs: List<InteractiveTxInput.Outgoing>, v
266267 * @param walletInputs 2-of-2 swap-in wallet inputs.
267268 */
268269 fun create (
269- channelKeys : KeyManager . ChannelKeys ,
270- swapInKeys : KeyManager . SwapInOnChainKeys ,
270+ channelKeys : ChannelKeys ,
271+ swapInKeys : SwapInOnChainKeys ,
271272 params : InteractiveTxParams ,
272273 walletInputs : List <WalletState .Utxo >,
273274 liquidityPurchase : LiquidityAds .Purchase ?
@@ -282,8 +283,8 @@ data class FundingContributions(val inputs: List<InteractiveTxInput.Outgoing>, v
282283 * @param changePubKey if provided, a corresponding p2wpkh change output will be created.
283284 */
284285 fun create (
285- channelKeys : KeyManager . ChannelKeys ,
286- swapInKeys : KeyManager . SwapInOnChainKeys ,
286+ channelKeys : ChannelKeys ,
287+ swapInKeys : SwapInOnChainKeys ,
287288 params : InteractiveTxParams ,
288289 sharedUtxo : Pair <SharedFundingInput , SharedFundingInputBalances >? ,
289290 walletInputs : List <WalletState .Utxo >,
@@ -460,7 +461,8 @@ data class SharedTransaction(
460461
461462 fun sign (session : InteractiveTxSession , keyManager : KeyManager , fundingParams : InteractiveTxParams , localParams : LocalParams , remoteNodeId : PublicKey ): PartiallySignedSharedTransaction {
462463 val unsignedTx = buildUnsignedTx()
463- val sharedSig = fundingParams.sharedInput?.sign(keyManager.channelKeys(localParams.fundingKeyPath), unsignedTx)
464+ val channelKeys = keyManager.channelKeys(localParams.fundingKeyPath)
465+ val sharedSig = fundingParams.sharedInput?.sign(channelKeys, unsignedTx)
464466 // NB: the order in this list must match the order of the transaction's inputs.
465467 val previousOutputs = unsignedTx.txIn.map { spentOutputs[it.outPoint]!! }
466468
@@ -538,7 +540,7 @@ data class PartiallySignedSharedTransaction(override val tx: SharedTransaction,
538540 override val txId: TxId = localSigs.txId
539541 override val signedTx = null
540542
541- fun addRemoteSigs (channelKeys : KeyManager . ChannelKeys , fundingParams : InteractiveTxParams , remoteSigs : TxSignatures ): FullySignedSharedTransaction ? {
543+ fun addRemoteSigs (channelKeys : ChannelKeys , fundingParams : InteractiveTxParams , remoteSigs : TxSignatures ): FullySignedSharedTransaction ? {
542544 if (localSigs.swapInUserSigs.size != tx.localInputs.filterIsInstance<InteractiveTxInput .LocalLegacySwapIn >().size) return null
543545 if (localSigs.swapInUserPartialSigs.size != tx.localInputs.filterIsInstance<InteractiveTxInput .LocalSwapIn >().size) return null
544546 if (remoteSigs.swapInUserSigs.size != tx.remoteInputs.filterIsInstance<InteractiveTxInput .RemoteLegacySwapIn >().size) return null
@@ -552,7 +554,7 @@ data class PartiallySignedSharedTransaction(override val tx: SharedTransaction,
552554 is SharedFundingInput .Multisig2of2 -> Scripts .witness2of2(
553555 localSigs.previousFundingTxSig ? : return null ,
554556 remoteSigs.previousFundingTxSig ? : return null ,
555- channelKeys.fundingPubKey (it.fundingTxIndex),
557+ channelKeys.fundingKey (it.fundingTxIndex).publicKey( ),
556558 it.remoteFundingPubkey,
557559 )
558560 }
@@ -641,8 +643,8 @@ sealed class InteractiveTxSessionAction {
641643
642644data class InteractiveTxSession (
643645 val remoteNodeId : PublicKey ,
644- val channelKeys : KeyManager . ChannelKeys ,
645- val swapInKeys : KeyManager . SwapInOnChainKeys ,
646+ val channelKeys : ChannelKeys ,
647+ val swapInKeys : SwapInOnChainKeys ,
646648 val fundingParams : InteractiveTxParams ,
647649 val previousFunding : SharedFundingInputBalances ,
648650 val toSend : List <Either <InteractiveTxInput .Outgoing , InteractiveTxOutput .Outgoing >>,
@@ -675,8 +677,8 @@ data class InteractiveTxSession(
675677
676678 constructor (
677679 remoteNodeId: PublicKey ,
678- channelKeys: KeyManager . ChannelKeys ,
679- swapInKeys: KeyManager . SwapInOnChainKeys ,
680+ channelKeys: ChannelKeys ,
681+ swapInKeys: SwapInOnChainKeys ,
680682 fundingParams: InteractiveTxParams ,
681683 previousLocalBalance: MilliSatoshi ,
682684 previousRemoteBalance: MilliSatoshi ,
@@ -1034,12 +1036,22 @@ data class InteractiveTxSigningSession(
10341036 is Either .Right -> localCommit.value.index + 1
10351037 }
10361038
1037- fun receiveCommitSig (channelKeys : KeyManager . ChannelKeys , channelParams : ChannelParams , remoteCommitSig : CommitSig , currentBlockHeight : Long , logger : MDCLogger ): Pair <InteractiveTxSigningSession , InteractiveTxSigningSessionAction > {
1039+ fun receiveCommitSig (channelKeys : ChannelKeys , channelParams : ChannelParams , remoteCommitSig : CommitSig , currentBlockHeight : Long , logger : MDCLogger ): Pair <InteractiveTxSigningSession , InteractiveTxSigningSessionAction > {
10381040 return when (localCommit) {
10391041 is Either .Left -> {
10401042 val localCommitIndex = localCommit.value.index
1041- val localPerCommitmentPoint = channelKeys.commitmentPoint(localCommitIndex)
1042- when (val signedLocalCommit = LocalCommit .fromCommitSig(channelKeys, channelParams, fundingTxIndex, fundingParams.remoteFundingPubkey, commitInput, remoteCommitSig, localCommitIndex, localCommit.value.spec, localPerCommitmentPoint, logger)) {
1043+ val commitKeys = channelKeys.localCommitmentKeys(channelParams, localCommitIndex)
1044+ when (val signedLocalCommit = LocalCommit .fromCommitSig(
1045+ channelParams = channelParams,
1046+ commitKeys = commitKeys,
1047+ fundingKey = channelKeys.fundingKey(fundingTxIndex),
1048+ remoteFundingPubKey = fundingParams.remoteFundingPubkey,
1049+ commitInput = commitInput,
1050+ commit = remoteCommitSig,
1051+ localCommitIndex = localCommitIndex,
1052+ spec = localCommit.value.spec,
1053+ log = logger
1054+ )) {
10431055 is Either .Left -> {
10441056 val fundingKey = channelKeys.fundingKey(fundingTxIndex)
10451057 val localSigOfLocalTx = Transactions .sign(localCommit.value.commitTx, fundingKey)
@@ -1067,7 +1079,7 @@ data class InteractiveTxSigningSession(
10671079 }
10681080 }
10691081
1070- fun receiveTxSigs (channelKeys : KeyManager . ChannelKeys , remoteTxSigs : TxSignatures , currentBlockHeight : Long ): Either <InteractiveTxSigningSessionAction .AbortFundingAttempt , InteractiveTxSigningSessionAction .SendTxSigs > {
1082+ fun receiveTxSigs (channelKeys : ChannelKeys , remoteTxSigs : TxSignatures , currentBlockHeight : Long ): Either <InteractiveTxSigningSessionAction .AbortFundingAttempt , InteractiveTxSigningSessionAction .SendTxSigs > {
10711083 return when (localCommit) {
10721084 is Either .Left -> Either .Left (InteractiveTxSigningSessionAction .AbortFundingAttempt (UnexpectedFundingSignatures (fundingParams.channelId)))
10731085 is Either .Right -> when (val fullySignedTx = fundingTx.addRemoteSigs(channelKeys, fundingParams, remoteTxSigs)) {
@@ -1100,42 +1112,43 @@ data class InteractiveTxSigningSession(
11001112 localHtlcs : Set <DirectedHtlc >
11011113 ): Either <ChannelException , Pair <InteractiveTxSigningSession , CommitSig >> {
11021114 val channelKeys = channelParams.localParams.channelKeys(keyManager)
1115+ val fundingKey = channelKeys.fundingKey(fundingTxIndex)
1116+ val localCommitKeys = channelKeys.localCommitmentKeys(channelParams, localCommitmentIndex)
1117+ val remoteCommitKeys = channelKeys.remoteCommitmentKeys(channelParams, remotePerCommitmentPoint)
11031118 val unsignedTx = sharedTx.buildUnsignedTx()
11041119 val sharedOutputIndex = unsignedTx.txOut.indexOfFirst { it.publicKeyScript == fundingParams.fundingPubkeyScript(channelKeys) }
11051120 val liquidityFees = fundingParams.liquidityFees(liquidityPurchase)
11061121 return Helpers .Funding .makeCommitTxs(
1107- channelKeys,
1108- channelParams.channelId,
1109- channelParams.localParams, channelParams.remoteParams,
1122+ channelParams = channelParams,
11101123 fundingAmount = sharedTx.sharedOutput.amount,
11111124 toLocal = sharedTx.sharedOutput.localAmount - liquidityFees,
11121125 toRemote = sharedTx.sharedOutput.remoteAmount + liquidityFees,
11131126 localHtlcs = localHtlcs,
11141127 localCommitmentIndex = localCommitmentIndex,
11151128 remoteCommitmentIndex = remoteCommitmentIndex,
1116- commitTxFeerate,
1117- fundingTxIndex = fundingTxIndex, fundingTxId = unsignedTx.txid, fundingTxOutputIndex = sharedOutputIndex,
1129+ commitTxFeerate = commitTxFeerate,
1130+ fundingTxId = unsignedTx.txid,
1131+ fundingTxOutputIndex = sharedOutputIndex,
1132+ localFundingKey = fundingKey,
11181133 remoteFundingPubkey = fundingParams.remoteFundingPubkey,
1119- remotePerCommitmentPoint = remotePerCommitmentPoint
1134+ localCommitKeys = localCommitKeys,
1135+ remoteCommitKeys = remoteCommitKeys,
11201136 ).map { firstCommitTx ->
1121- val localSigOfRemoteCommitTx = Transactions .sign(firstCommitTx.remoteCommitTx, channelKeys.fundingKey(fundingTxIndex))
1122- val localSigsOfRemoteHtlcTxs = firstCommitTx.remoteHtlcTxs.map { Transactions .sign(it, channelKeys.htlcKey.deriveForCommitment(remotePerCommitmentPoint), SigHash .SIGHASH_SINGLE or SigHash .SIGHASH_ANYONECANPAY ) }
1123-
1137+ val localSigOfRemoteCommitTx = Transactions .sign(firstCommitTx.remoteCommitTx, fundingKey)
1138+ val localSigsOfRemoteHtlcTxs = firstCommitTx.remoteHtlcTxs.map { Transactions .sign(it, remoteCommitKeys.ourHtlcKey, SigHash .SIGHASH_SINGLE or SigHash .SIGHASH_ANYONECANPAY ) }
11241139 val alternativeSigs = if (firstCommitTx.remoteHtlcTxs.isEmpty()) {
11251140 val commitSigTlvs = Commitments .alternativeFeerates.map { feerate ->
11261141 val alternativeSpec = firstCommitTx.remoteSpec.copy(feerate = feerate)
11271142 val (alternativeRemoteCommitTx, _) = Commitments .makeRemoteTxs(
1128- channelKeys,
1129- remoteCommitmentIndex,
1130- channelParams.localParams,
1131- channelParams.remoteParams,
1132- fundingTxIndex,
1133- fundingParams.remoteFundingPubkey,
1134- firstCommitTx.remoteCommitTx.input,
1135- remotePerCommitmentPoint,
1136- alternativeSpec
1143+ channelParams = channelParams,
1144+ commitKeys = remoteCommitKeys,
1145+ commitTxNumber = remoteCommitmentIndex,
1146+ localFundingKey = fundingKey,
1147+ remoteFundingPubKey = fundingParams.remoteFundingPubkey,
1148+ commitmentInput = firstCommitTx.remoteCommitTx.input,
1149+ spec = alternativeSpec
11371150 )
1138- val sig = Transactions .sign(alternativeRemoteCommitTx, channelKeys. fundingKey(fundingTxIndex) )
1151+ val sig = Transactions .sign(alternativeRemoteCommitTx, fundingKey)
11391152 CommitSigTlv .AlternativeFeerateSig (feerate, sig)
11401153 }
11411154 TlvStream (CommitSigTlv .AlternativeFeerateSigs (commitSigTlvs) as CommitSigTlv )
0 commit comments