From 65e74f608df3c85a9c8f9f87b9e8eb7db7ca7040 Mon Sep 17 00:00:00 2001 From: sstone Date: Tue, 6 Aug 2024 19:42:54 +0200 Subject: [PATCH] Get ready to store partial signatures We currently store our peer's signature for our remote commit tx, so we can publish it if needed. If we upgrade funding tx to use musig2 instead of multisig 2-of-2 we will need to store a partial signature instead. --- .../fr/acinq/eclair/channel/Commitments.scala | 11 +++++++---- .../channel/fsm/ChannelOpenSingleFunded.scala | 4 ++-- .../channel/fund/InteractiveTxBuilder.scala | 2 +- .../remote/LightningMessageSerializer.scala | 4 ++-- .../channel/version0/ChannelTypes0.scala | 2 +- .../channel/version3/ChannelCodecs3.scala | 2 +- .../channel/version4/ChannelCodecs4.scala | 16 +++++++++++++--- .../eclair/wire/protocol/CommonCodecs.scala | 10 +++++++++- .../acinq/eclair/channel/CommitmentsSpec.scala | 4 ++-- .../publish/ReplaceableTxFunderSpec.scala | 2 +- .../integration/ChannelIntegrationSpec.scala | 3 ++- .../acinq/eclair/json/JsonSerializersSpec.scala | 2 +- .../internal/channel/ChannelCodecsSpec.scala | 5 +++-- 13 files changed, 45 insertions(+), 22 deletions(-) diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/channel/Commitments.scala b/eclair-core/src/main/scala/fr/acinq/eclair/channel/Commitments.scala index 36e5b0dfac..672675a6e0 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/channel/Commitments.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/channel/Commitments.scala @@ -1,6 +1,7 @@ package fr.acinq.eclair.channel import akka.event.LoggingAdapter +import fr.acinq.bitcoin.crypto.musig2.IndividualNonce import fr.acinq.bitcoin.scalacompat.Crypto.{PrivateKey, PublicKey} import fr.acinq.bitcoin.scalacompat.{ByteVector32, ByteVector64, Crypto, Satoshi, SatoshiLong, Script, Transaction, TxId} import fr.acinq.eclair.blockchain.fee.{FeeratePerByte, FeeratePerKw, FeeratesPerKw, OnChainFeeConf} @@ -216,8 +217,10 @@ object CommitmentChanges { case class HtlcTxAndRemoteSig(htlcTx: HtlcTx, remoteSig: ByteVector64) +case class PartialSignatureWithNonce(partialSig: ByteVector32, nonce: IndividualNonce) + /** We don't store the fully signed transaction, otherwise someone with read access to our database could force-close our channels. */ -case class CommitTxAndRemoteSig(commitTx: CommitTx, remoteSig: ByteVector64) +case class CommitTxAndRemoteSig(commitTx: CommitTx, remoteSig: Either[ByteVector64, PartialSignatureWithNonce]) /** The local commitment maps to a commitment transaction that we can sign and broadcast if necessary. */ case class LocalCommit(index: Long, spec: CommitmentSpec, commitTxAndRemoteSig: CommitTxAndRemoteSig, htlcTxsAndRemoteSigs: List[HtlcTxAndRemoteSig]) @@ -242,7 +245,7 @@ object LocalCommit { } HtlcTxAndRemoteSig(htlcTx, remoteSig) } - Right(LocalCommit(localCommitIndex, spec, CommitTxAndRemoteSig(localCommitTx, commit.signature), htlcTxsAndRemoteSigs)) + Right(LocalCommit(localCommitIndex, spec, CommitTxAndRemoteSig(localCommitTx, Left(commit.signature)), htlcTxsAndRemoteSigs)) } } @@ -665,7 +668,7 @@ case class Commitment(fundingTxIndex: Long, def fullySignedLocalCommitTx(params: ChannelParams, keyManager: ChannelKeyManager): CommitTx = { val unsignedCommitTx = localCommit.commitTxAndRemoteSig.commitTx val localSig = keyManager.sign(unsignedCommitTx, keyManager.fundingPublicKey(params.localParams.fundingKeyPath, fundingTxIndex), TxOwner.Local, params.commitmentFormat) - val remoteSig = localCommit.commitTxAndRemoteSig.remoteSig + val Left(remoteSig) = localCommit.commitTxAndRemoteSig.remoteSig val commitTx = addSigs(unsignedCommitTx, keyManager.fundingPublicKey(params.localParams.fundingKeyPath, fundingTxIndex).publicKey, remoteFundingPubKey, localSig, remoteSig) // We verify the remote signature when receiving their commit_sig, so this check should always pass. require(checkSpendable(commitTx).isSuccess, "commit signatures are invalid") @@ -1148,7 +1151,7 @@ case class Commitments(params: ChannelParams, /** This function should be used to ignore a commit_sig that we've already received. */ def ignoreRetransmittedCommitSig(commitSig: CommitSig): Boolean = { - val latestRemoteSig = latest.localCommit.commitTxAndRemoteSig.remoteSig + val Left(latestRemoteSig) = latest.localCommit.commitTxAndRemoteSig.remoteSig params.channelFeatures.hasFeature(Features.DualFunding) && commitSig.batchSize == 1 && latestRemoteSig == commitSig.signature } diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/ChannelOpenSingleFunded.scala b/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/ChannelOpenSingleFunded.scala index 7cd37bca2f..a57db942b5 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/ChannelOpenSingleFunded.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/channel/fsm/ChannelOpenSingleFunded.scala @@ -281,7 +281,7 @@ trait ChannelOpenSingleFunded extends SingleFundingHandlers with ErrorHandlers { remoteFundingPubKey = remoteFundingPubKey, localFundingStatus = SingleFundedUnconfirmedFundingTx(None), remoteFundingStatus = RemoteFundingStatus.NotLocked, - localCommit = LocalCommit(0, localSpec, CommitTxAndRemoteSig(localCommitTx, remoteSig), htlcTxsAndRemoteSigs = Nil), + localCommit = LocalCommit(0, localSpec, CommitTxAndRemoteSig(localCommitTx, Left(remoteSig)), htlcTxsAndRemoteSigs = Nil), remoteCommit = RemoteCommit(0, remoteSpec, remoteCommitTx.tx.txid, remoteFirstPerCommitmentPoint), nextRemoteCommit_opt = None) val commitments = Commitments( @@ -328,7 +328,7 @@ trait ChannelOpenSingleFunded extends SingleFundingHandlers with ErrorHandlers { remoteFundingPubKey = remoteFundingPubKey, localFundingStatus = SingleFundedUnconfirmedFundingTx(Some(fundingTx)), remoteFundingStatus = RemoteFundingStatus.NotLocked, - localCommit = LocalCommit(0, localSpec, CommitTxAndRemoteSig(localCommitTx, remoteSig), htlcTxsAndRemoteSigs = Nil), + localCommit = LocalCommit(0, localSpec, CommitTxAndRemoteSig(localCommitTx, Left(remoteSig)), htlcTxsAndRemoteSigs = Nil), remoteCommit = remoteCommit, nextRemoteCommit_opt = None ) diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/channel/fund/InteractiveTxBuilder.scala b/eclair-core/src/main/scala/fr/acinq/eclair/channel/fund/InteractiveTxBuilder.scala index 29f41c4a7b..1c9c2a7440 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/channel/fund/InteractiveTxBuilder.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/channel/fund/InteractiveTxBuilder.scala @@ -1008,7 +1008,7 @@ object InteractiveTxSigningSession { case class UnsignedLocalCommit(index: Long, spec: CommitmentSpec, commitTx: CommitTx, htlcTxs: List[HtlcTx]) private def shouldSignFirst(isInitiator: Boolean, channelParams: ChannelParams, tx: SharedTransaction): Boolean = { - val sharedAmountIn = tx.sharedInput_opt.map(_.txOut.amount).getOrElse(0 sat) + val sharedAmountIn = tx.sharedInput_opt.map(i => i.localAmount + i.remoteAmount + i.htlcAmount).getOrElse(0 msat).truncateToSatoshi val (localAmountIn, remoteAmountIn) = if (isInitiator) { (sharedAmountIn + tx.localInputs.map(i => i.txOut.amount).sum, tx.remoteInputs.map(i => i.txOut.amount).sum) } else { diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/remote/LightningMessageSerializer.scala b/eclair-core/src/main/scala/fr/acinq/eclair/remote/LightningMessageSerializer.scala index b7481c6cfd..5df94923b2 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/remote/LightningMessageSerializer.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/remote/LightningMessageSerializer.scala @@ -16,6 +16,6 @@ package fr.acinq.eclair.remote -import fr.acinq.eclair.wire.protocol.LightningMessageCodecs.lightningMessageCodecWithFallback +import fr.acinq.eclair.wire.protocol.LightningMessageCodecs.lightningMessageCodec -class LightningMessageSerializer extends ScodecSerializer(42, lightningMessageCodecWithFallback) \ No newline at end of file +class LightningMessageSerializer extends ScodecSerializer(42, lightningMessageCodec) \ No newline at end of file diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version0/ChannelTypes0.scala b/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version0/ChannelTypes0.scala index 390c0b5335..ada305b959 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version0/ChannelTypes0.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version0/ChannelTypes0.scala @@ -121,7 +121,7 @@ private[channel] object ChannelTypes0 { def migrate(remoteFundingPubKey: PublicKey): channel.LocalCommit = { val remoteSig = extractRemoteSig(publishableTxs.commitTx, remoteFundingPubKey) val unsignedCommitTx = publishableTxs.commitTx.modify(_.tx.txIn.each.witness).setTo(ScriptWitness.empty) - val commitTxAndRemoteSig = CommitTxAndRemoteSig(unsignedCommitTx, remoteSig) + val commitTxAndRemoteSig = CommitTxAndRemoteSig(unsignedCommitTx, Left(remoteSig)) val htlcTxsAndRemoteSigs = publishableTxs.htlcTxsAndSigs map { case HtlcTxAndSigs(htlcTx: HtlcSuccessTx, _, remoteSig) => val unsignedHtlcTx = htlcTx.modify(_.tx.txIn.each.witness).setTo(ScriptWitness.empty) diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version3/ChannelCodecs3.scala b/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version3/ChannelCodecs3.scala index 36521f3db7..309c43f9df 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version3/ChannelCodecs3.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version3/ChannelCodecs3.scala @@ -207,7 +207,7 @@ private[channel] object ChannelCodecs3 { val commitTxAndRemoteSigCodec: Codec[CommitTxAndRemoteSig] = ( ("commitTx" | commitTxCodec) :: - ("remoteSig" | bytes64)).as[CommitTxAndRemoteSig] + ("remoteSig" | either(provide(false), bytes64, partialSignatureWithNonce))).as[CommitTxAndRemoteSig] val localCommitCodec: Codec[LocalCommit] = ( ("index" | uint64overflow) :: diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version4/ChannelCodecs4.scala b/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version4/ChannelCodecs4.scala index 44e406c647..ca71e1ac0d 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version4/ChannelCodecs4.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version4/ChannelCodecs4.scala @@ -4,7 +4,7 @@ import fr.acinq.bitcoin.ScriptTree import fr.acinq.bitcoin.io.ByteArrayInput import fr.acinq.bitcoin.scalacompat.Crypto.PublicKey import fr.acinq.bitcoin.scalacompat.DeterministicWallet.KeyPath -import fr.acinq.bitcoin.scalacompat.{OutPoint, ScriptWitness, Transaction, TxOut} +import fr.acinq.bitcoin.scalacompat.{ByteVector64, OutPoint, ScriptWitness, Transaction, TxOut} import fr.acinq.eclair.blockchain.fee.{ConfirmationPriority, ConfirmationTarget} import fr.acinq.eclair.channel.LocalFundingStatus._ import fr.acinq.eclair.channel._ @@ -201,9 +201,19 @@ private[channel] object ChannelCodecs4 { ("txinfo" | htlcTxCodec) :: ("remoteSig" | bytes64)).as[HtlcTxAndRemoteSig] - val commitTxAndRemoteSigCodec: Codec[CommitTxAndRemoteSig] = ( + private case class CommitTxAndRemoteSigEx(commitTx: CommitTx, remoteSig: ByteVector64, partialSig: Either[ByteVector64, PartialSignatureWithNonce], dummy: Boolean) + + // remoteSig is now either a signature or a partial signature with nonce. To retain compatibility with the previous codec, we use remoteSig as a left/right indicator, + // a value of all zeroes meaning right (a valid signature cannot be all zeroes) + private val commitTxAndRemoteSigExCodec: Codec[CommitTxAndRemoteSigEx] = ( ("commitTx" | commitTxCodec) :: - ("remoteSig" | bytes64)).as[CommitTxAndRemoteSig] + (("remoteSig" | bytes64) >>:~ { remoteSig => either(provide(remoteSig == ByteVector64.Zeroes), provide(remoteSig), partialSignatureWithNonce) :: ("dummy" | provide(false)) }) + ).as[CommitTxAndRemoteSigEx] + + val commitTxAndRemoteSigCodec: Codec[CommitTxAndRemoteSig] = commitTxAndRemoteSigExCodec.xmap( + ce => CommitTxAndRemoteSig(ce.commitTx, ce.partialSig), + c => CommitTxAndRemoteSigEx(c.commitTx, c.remoteSig.swap.toOption.getOrElse(fr.acinq.bitcoin.scalacompat.ByteVector64.Zeroes), c.remoteSig, false) + ) val updateMessageCodec: Codec[UpdateMessage] = lengthDelimited(lightningMessageCodec.narrow[UpdateMessage](f => Attempt.successful(f.asInstanceOf[UpdateMessage]), g => g)) diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/CommonCodecs.scala b/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/CommonCodecs.scala index 53cfee271e..0db4be7d53 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/CommonCodecs.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/CommonCodecs.scala @@ -16,10 +16,11 @@ package fr.acinq.eclair.wire.protocol +import fr.acinq.bitcoin.crypto.musig2.IndividualNonce import fr.acinq.bitcoin.scalacompat.Crypto.{PrivateKey, PublicKey, XonlyPublicKey} import fr.acinq.bitcoin.scalacompat.{BlockHash, ByteVector32, ByteVector64, Satoshi, Transaction, TxHash, TxId} import fr.acinq.eclair.blockchain.fee.FeeratePerKw -import fr.acinq.eclair.channel.{ChannelFlags, RealScidStatus, ShortIds} +import fr.acinq.eclair.channel.{ChannelFlags, PartialSignatureWithNonce, RealScidStatus, ShortIds} import fr.acinq.eclair.crypto.Mac32 import fr.acinq.eclair.{Alias, BlockHeight, CltvExpiry, CltvExpiryDelta, Feature, Features, InitFeature, MilliSatoshi, RealShortChannelId, ShortChannelId, TimestampSecond, UInt64, UnspecifiedShortChannelId} import org.apache.commons.codec.binary.Base32 @@ -169,6 +170,13 @@ object CommonCodecs { val xonlyPublicKey: Codec[XonlyPublicKey] = publicKey.xmap(p => p.xOnly, x => x.publicKey) + val publicNonce: Codec[IndividualNonce] = Codec[IndividualNonce]( + (pub: IndividualNonce) => bytes(66).encode(ByteVector.view(pub.toByteArray)), + (wire: BitVector) => bytes(66).decode(wire).map(_.map(b => new IndividualNonce(b.toArray))) + ) + + val partialSignatureWithNonce: Codec[PartialSignatureWithNonce] = (bytes32 :: publicNonce).as[PartialSignatureWithNonce] + val rgb: Codec[Color] = bytes(3).xmap(buf => Color(buf(0), buf(1), buf(2)), t => ByteVector(t.r, t.g, t.b)) val txCodec: Codec[Transaction] = bytes.xmap(d => Transaction.read(d.toArray), d => Transaction.write(d)) diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/channel/CommitmentsSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/channel/CommitmentsSpec.scala index 62180a9cd6..df325b9cfd 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/channel/CommitmentsSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/channel/CommitmentsSpec.scala @@ -491,7 +491,7 @@ object CommitmentsSpec { val remoteParams = RemoteParams(randomKey().publicKey, dustLimit, UInt64.MaxValue, Some(channelReserve), 1 msat, CltvExpiryDelta(144), 50, randomKey().publicKey, randomKey().publicKey, randomKey().publicKey, randomKey().publicKey, Features.empty, None) val remoteFundingPubKey = randomKey().publicKey val commitmentInput = Funding.makeFundingInputInfo(randomTxId(), 0, (toLocal + toRemote).truncateToSatoshi, randomKey().publicKey, remoteFundingPubKey) - val localCommit = LocalCommit(0, CommitmentSpec(Set.empty, feeRatePerKw, toLocal, toRemote), CommitTxAndRemoteSig(CommitTx(commitmentInput, Transaction(2, Nil, Nil, 0)), ByteVector64.Zeroes), Nil) + val localCommit = LocalCommit(0, CommitmentSpec(Set.empty, feeRatePerKw, toLocal, toRemote), CommitTxAndRemoteSig(CommitTx(commitmentInput, Transaction(2, Nil, Nil, 0)), Left(ByteVector64.Zeroes)), Nil) val remoteCommit = RemoteCommit(0, CommitmentSpec(Set.empty, feeRatePerKw, toRemote, toLocal), randomTxId(), randomKey().publicKey) Commitments( ChannelParams(randomBytes32(), ChannelConfig.standard, ChannelFeatures(), localParams, remoteParams, ChannelFlags(announceChannel = announceChannel)), @@ -510,7 +510,7 @@ object CommitmentsSpec { val remoteParams = RemoteParams(remoteNodeId, 0 sat, UInt64.MaxValue, Some(channelReserve), 1 msat, CltvExpiryDelta(144), 50, randomKey().publicKey, randomKey().publicKey, randomKey().publicKey, randomKey().publicKey, Features.empty, None) val remoteFundingPubKey = randomKey().publicKey val commitmentInput = Funding.makeFundingInputInfo(randomTxId(), 0, (toLocal + toRemote).truncateToSatoshi, randomKey().publicKey, remoteFundingPubKey) - val localCommit = LocalCommit(0, CommitmentSpec(Set.empty, FeeratePerKw(0 sat), toLocal, toRemote), CommitTxAndRemoteSig(CommitTx(commitmentInput, Transaction(2, Nil, Nil, 0)), ByteVector64.Zeroes), Nil) + val localCommit = LocalCommit(0, CommitmentSpec(Set.empty, FeeratePerKw(0 sat), toLocal, toRemote), CommitTxAndRemoteSig(CommitTx(commitmentInput, Transaction(2, Nil, Nil, 0)), Left(ByteVector64.Zeroes)), Nil) val remoteCommit = RemoteCommit(0, CommitmentSpec(Set.empty, FeeratePerKw(0 sat), toRemote, toLocal), randomTxId(), randomKey().publicKey) Commitments( ChannelParams(randomBytes32(), ChannelConfig.standard, ChannelFeatures(), localParams, remoteParams, ChannelFlags(announceChannel = announceChannel)), diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/channel/publish/ReplaceableTxFunderSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/channel/publish/ReplaceableTxFunderSpec.scala index 1577b1bcea..b76deb10ee 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/channel/publish/ReplaceableTxFunderSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/channel/publish/ReplaceableTxFunderSpec.scala @@ -146,7 +146,7 @@ class ReplaceableTxFunderSpec extends TestKitBaseClass with AnyFunSuiteLike { localParams.dustLimit.returns(1000 sat) commitment.localParams.returns(localParams) val localCommit = mock[LocalCommit] - localCommit.commitTxAndRemoteSig.returns(CommitTxAndRemoteSig(commitTx, PlaceHolderSig)) + localCommit.commitTxAndRemoteSig.returns(CommitTxAndRemoteSig(commitTx, Left(PlaceHolderSig))) commitment.localCommit.returns(localCommit) // We can handle a small feerate update by lowering the change output. diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/integration/ChannelIntegrationSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/integration/ChannelIntegrationSpec.scala index 6c8ecc90b4..6ad862b0a6 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/integration/ChannelIntegrationSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/integration/ChannelIntegrationSpec.scala @@ -447,7 +447,8 @@ abstract class ChannelIntegrationSpec extends IntegrationSpec { val revokedCommitTx = { val commitTx = localCommitF.commitTxAndRemoteSig.commitTx val localSig = keyManagerF.sign(commitTx, keyManagerF.fundingPublicKey(commitmentsF.params.localParams.fundingKeyPath, commitmentsF.latest.fundingTxIndex), TxOwner.Local, commitmentFormat) - Transactions.addSigs(commitTx, keyManagerF.fundingPublicKey(commitmentsF.params.localParams.fundingKeyPath, commitmentsF.latest.fundingTxIndex).publicKey, commitmentsF.latest.remoteFundingPubKey, localSig, localCommitF.commitTxAndRemoteSig.remoteSig).tx + val Left(remoteSig) = localCommitF.commitTxAndRemoteSig.remoteSig + Transactions.addSigs(commitTx, keyManagerF.fundingPublicKey(commitmentsF.params.localParams.fundingKeyPath, commitmentsF.latest.fundingTxIndex).publicKey, commitmentsF.latest.remoteFundingPubKey, localSig, remoteSig).tx } val htlcSuccess = htlcSuccessTxs.zip(Seq(preimage1, preimage2)).map { case (htlcTxAndSigs, preimage) => diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/json/JsonSerializersSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/json/JsonSerializersSpec.scala index 743e3e13a8..590bbb84f2 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/json/JsonSerializersSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/json/JsonSerializersSpec.scala @@ -122,7 +122,7 @@ class JsonSerializersSpec extends TestKitBaseClass with AnyFunSuiteLike with Mat val localParams = LocalParams(dummyPublicKey, DeterministicWallet.KeyPath(Seq(42L)), 546 sat, Long.MaxValue.msat, Some(1000 sat), 1 msat, CltvExpiryDelta(144), 50, isChannelOpener = true, paysCommitTxFees = true, None, None, Features.empty) val remoteParams = RemoteParams(dummyPublicKey, 546 sat, UInt64.MaxValue, Some(1000 sat), 1 msat, CltvExpiryDelta(144), 50, dummyPublicKey, dummyPublicKey, dummyPublicKey, dummyPublicKey, Features.empty, None) val commitmentInput = Funding.makeFundingInputInfo(TxId(dummyBytes32), 0, 150_000 sat, dummyPublicKey, dummyPublicKey) - val localCommit = LocalCommit(0, CommitmentSpec(Set.empty, FeeratePerKw(2500 sat), 100_000_000 msat, 50_000_000 msat), CommitTxAndRemoteSig(CommitTx(commitmentInput, Transaction(2, Nil, Nil, 0)), ByteVector64.Zeroes), Nil) + val localCommit = LocalCommit(0, CommitmentSpec(Set.empty, FeeratePerKw(2500 sat), 100_000_000 msat, 50_000_000 msat), CommitTxAndRemoteSig(CommitTx(commitmentInput, Transaction(2, Nil, Nil, 0)), Left(ByteVector64.Zeroes)), Nil) val remoteCommit = RemoteCommit(0, CommitmentSpec(Set.empty, FeeratePerKw(2500 sat), 50_000_000 msat, 100_000_000 msat), TxId(dummyBytes32), dummyPublicKey) val channelInfo = RES_GET_CHANNEL_INFO( PublicKey(hex"0270685ca81a8e4d4d01beec5781f4cc924684072ae52c507f8ebe9daf0caaab7b"), diff --git a/eclair-core/src/test/scala/fr/acinq/eclair/wire/internal/channel/ChannelCodecsSpec.scala b/eclair-core/src/test/scala/fr/acinq/eclair/wire/internal/channel/ChannelCodecsSpec.scala index 1c4620db64..6d27613e37 100644 --- a/eclair-core/src/test/scala/fr/acinq/eclair/wire/internal/channel/ChannelCodecsSpec.scala +++ b/eclair-core/src/test/scala/fr/acinq/eclair/wire/internal/channel/ChannelCodecsSpec.scala @@ -242,7 +242,8 @@ class ChannelCodecsSpec extends AnyFunSuite { assert(newnormal.commitments.latest.localCommit.commitTxAndRemoteSig.commitTx.tx.txIn.forall(_.witness.stack.isEmpty)) assert(newnormal.commitments.latest.localCommit.htlcTxsAndRemoteSigs.forall(_.htlcTx.tx.txIn.forall(_.witness.stack.isEmpty))) // make sure that we have extracted the remote sig of the local tx - newnormal.commitments.latest.localCommit.commitTxAndRemoteSig.commitTx.checkSig(newnormal.commitments.latest.localCommit.commitTxAndRemoteSig.remoteSig, newnormal.commitments.remoteNodeId, TxOwner.Remote, newnormal.commitments.params.commitmentFormat) + val Left(remoteSig) = newnormal.commitments.latest.localCommit.commitTxAndRemoteSig.remoteSig + newnormal.commitments.latest.localCommit.commitTxAndRemoteSig.commitTx.checkSig(remoteSig, newnormal.commitments.remoteNodeId, TxOwner.Remote, newnormal.commitments.params.commitmentFormat) } } @@ -324,7 +325,7 @@ object ChannelCodecsSpec { txOut = Nil, lockTime = 0 ) - val localCommit = LocalCommit(0, CommitmentSpec(htlcs.toSet, FeeratePerKw(1500 sat), 50000000 msat, 70000000 msat), CommitTxAndRemoteSig(CommitTx(commitmentInput, commitTx), remoteSig), Nil) + val localCommit = LocalCommit(0, CommitmentSpec(htlcs.toSet, FeeratePerKw(1500 sat), 50000000 msat, 70000000 msat), CommitTxAndRemoteSig(CommitTx(commitmentInput, commitTx), Left(remoteSig)), Nil) val remoteCommit = RemoteCommit(0, CommitmentSpec(htlcs.map(_.opposite).toSet, FeeratePerKw(1500 sat), 50000 msat, 700000 msat), TxId.fromValidHex("0303030303030303030303030303030303030303030303030303030303030303"), PrivateKey(ByteVector.fill(32)(4)).publicKey) val channelId = htlcs.headOption.map(_.add.channelId).getOrElse(ByteVector32.Zeroes) val channelFlags = ChannelFlags(announceChannel = true)