From 452c0e02c85eb36cf932b4af1da5eac442c5361a 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. --- eclair-core/pom.xml | 15 --------------- .../fr/acinq/eclair/channel/Commitments.scala | 11 +++++++---- .../channel/fsm/ChannelOpenSingleFunded.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 +++-- 12 files changed, 42 insertions(+), 34 deletions(-) diff --git a/eclair-core/pom.xml b/eclair-core/pom.xml index 3d0b506735..20f3814e34 100644 --- a/eclair-core/pom.xml +++ b/eclair-core/pom.xml @@ -188,21 +188,6 @@ 4.1.94.Final - - fr.acinq.bitcoin - bitcoin-kmp-jvm - 0.20.0-SNAPSHOT - - - fr.acinq.secp256k1 - secp256k1-kmp-jvm - 0.15.0 - - - fr.acinq.secp256k1 - secp256k1-kmp-jni-jvm - 0.15.0 - fr.acinq bitcoin-lib_${scala.version.short} 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 b17e88119f..d4f7fcd44f 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} @@ -217,8 +218,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]) @@ -243,7 +246,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)) } } @@ -666,7 +669,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") @@ -1149,7 +1152,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 4eaf218f91..eb2768525c 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/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 953e4c254d..2d8547eccd 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/write 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 988d7f3e45..a1f97c0cf2 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 @@ -168,6 +169,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 3351149b89..040af9f366 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 5a959adeb4..8ae45fd09c 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 4f971a620d..889d834d1e 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 7e03b21807..804c01aab9 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)