From 48b734833d93744bbba50f244143e396ea8fb854 Mon Sep 17 00:00:00 2001 From: t-bast Date: Fri, 9 Feb 2024 15:44:18 +0100 Subject: [PATCH] Implement the option_simple_close protocol We update the `Negotiating` state to exchange the `closing_complete` and `closing_sig` messages, and allow RBF-ing previous transactions and updating our closing script. We stay in that state until one of the transactions confirms, or a force close is detected. This is important to ensure we're able to correctly reconnect and negotiate RBF candidates. --- .../kotlin/fr/acinq/lightning/NodeParams.kt | 3 + .../acinq/lightning/channel/ChannelCommand.kt | 3 +- .../fr/acinq/lightning/channel/ChannelData.kt | 7 +- .../lightning/channel/ChannelException.kt | 2 + .../fr/acinq/lightning/channel/Helpers.kt | 178 +++-- .../acinq/lightning/channel/states/Channel.kt | 80 +-- .../acinq/lightning/channel/states/Closing.kt | 15 - .../lightning/channel/states/Negotiating.kt | 311 ++++---- .../acinq/lightning/channel/states/Normal.kt | 73 +- .../acinq/lightning/channel/states/Offline.kt | 34 +- .../lightning/channel/states/ShuttingDown.kt | 129 ++-- .../acinq/lightning/channel/states/Syncing.kt | 65 +- .../acinq/lightning/json/JsonSerializers.kt | 33 +- .../serialization/v2/ChannelState.kt | 37 +- .../serialization/v2/Serialization.kt | 1 - .../serialization/v3/ChannelState.kt | 60 +- .../serialization/v3/Serialization.kt | 1 - .../serialization/v4/Deserialization.kt | 97 ++- .../serialization/v4/Serialization.kt | 32 +- .../lightning/transactions/Transactions.kt | 68 +- .../fr/acinq/lightning/wire/ChannelTlv.kt | 26 - .../acinq/lightning/wire/LightningMessages.kt | 39 - .../fr/acinq/lightning/channel/TestsHelper.kt | 49 +- .../channel/states/ClosingTestsCommon.kt | 186 +---- .../channel/states/NegotiatingTestsCommon.kt | 675 ++++++++---------- .../channel/states/NormalTestsCommon.kt | 40 +- .../channel/states/QuiescenceTestsCommon.kt | 3 +- .../channel/states/ShutdownTestsCommon.kt | 21 +- .../OutgoingPaymentHandlerTestsCommon.kt | 7 +- .../fr/acinq/lightning/tests/TestConstants.kt | 2 + .../transactions/TransactionsTestsCommon.kt | 77 +- .../wire/LightningCodecsTestsCommon.kt | 56 -- .../nonreg/v2/Negotiating_c8d15808/data.bin | 1 - .../nonreg/v2/Negotiating_c8d15808/data.json | 655 ----------------- .../nonreg/v2/Negotiating_d9b4cd96/data.bin | 1 - .../nonreg/v2/Negotiating_d9b4cd96/data.json | 186 ----- .../nonreg/v2/Negotiating_ee10091c/data.bin | 1 - .../nonreg/v2/Negotiating_ee10091c/data.json | 225 ------ .../nonreg/v2/Negotiating_f52b19b8/data.bin | 1 - .../nonreg/v2/Negotiating_f52b19b8/data.json | 227 ------ .../nonreg/v2/Normal_748a735b/data.json | 2 +- .../nonreg/v2/Normal_e2253ddd/data.json | 2 +- .../nonreg/v2/Normal_ff248f8d/data.json | 2 +- .../nonreg/v2/Normal_ff4a71b6/data.json | 2 +- .../nonreg/v2/Normal_ffd9f5db/data.json | 2 +- .../nonreg/v2/ShuttingDown_c321b947/data.json | 2 +- .../nonreg/v2/ShuttingDown_f89ecd50/data.json | 2 +- .../nonreg/v3/Negotiating_da44c6e2/data.bin | 1 - .../nonreg/v3/Negotiating_da44c6e2/data.json | 289 -------- .../nonreg/v3/Negotiating_dabbed55/data.bin | 1 - .../nonreg/v3/Negotiating_dabbed55/data.json | 401 ----------- .../nonreg/v3/Negotiating_fadb50c1/data.bin | 1 - .../nonreg/v3/Negotiating_fadb50c1/data.json | 186 ----- .../nonreg/v3/Normal_fd10d3cc/data.json | 2 +- .../nonreg/v3/Normal_fe897b64/data.json | 2 +- .../nonreg/v3/Normal_ff248f8d/data.json | 2 +- .../nonreg/v3/Normal_ff4a71b6/data.json | 2 +- .../nonreg/v3/ShuttingDown_ef41a1a5/data.json | 2 +- .../nonreg/v3/ShuttingDown_ef7081a1/data.json | 2 +- 59 files changed, 1135 insertions(+), 3477 deletions(-) delete mode 100644 src/commonTest/resources/nonreg/v2/Negotiating_c8d15808/data.bin delete mode 100644 src/commonTest/resources/nonreg/v2/Negotiating_c8d15808/data.json delete mode 100644 src/commonTest/resources/nonreg/v2/Negotiating_d9b4cd96/data.bin delete mode 100644 src/commonTest/resources/nonreg/v2/Negotiating_d9b4cd96/data.json delete mode 100644 src/commonTest/resources/nonreg/v2/Negotiating_ee10091c/data.bin delete mode 100644 src/commonTest/resources/nonreg/v2/Negotiating_ee10091c/data.json delete mode 100644 src/commonTest/resources/nonreg/v2/Negotiating_f52b19b8/data.bin delete mode 100644 src/commonTest/resources/nonreg/v2/Negotiating_f52b19b8/data.json delete mode 100644 src/commonTest/resources/nonreg/v3/Negotiating_da44c6e2/data.bin delete mode 100644 src/commonTest/resources/nonreg/v3/Negotiating_da44c6e2/data.json delete mode 100644 src/commonTest/resources/nonreg/v3/Negotiating_dabbed55/data.bin delete mode 100644 src/commonTest/resources/nonreg/v3/Negotiating_dabbed55/data.json delete mode 100644 src/commonTest/resources/nonreg/v3/Negotiating_fadb50c1/data.bin delete mode 100644 src/commonTest/resources/nonreg/v3/Negotiating_fadb50c1/data.json diff --git a/src/commonMain/kotlin/fr/acinq/lightning/NodeParams.kt b/src/commonMain/kotlin/fr/acinq/lightning/NodeParams.kt index f82ce2fab..f2f7b3fa1 100644 --- a/src/commonMain/kotlin/fr/acinq/lightning/NodeParams.kt +++ b/src/commonMain/kotlin/fr/acinq/lightning/NodeParams.kt @@ -160,6 +160,8 @@ data class NodeParams( require(features.hasFeature(Feature.PaymentSecret, FeatureSupport.Mandatory)) { "${Feature.PaymentSecret.rfcName} should be mandatory" } require(features.hasFeature(Feature.ChannelType, FeatureSupport.Mandatory)) { "${Feature.ChannelType.rfcName} should be mandatory" } require(features.hasFeature(Feature.DualFunding, FeatureSupport.Mandatory)) { "${Feature.DualFunding.rfcName} should be mandatory" } + require(features.hasFeature(Feature.ShutdownAnySegwit, FeatureSupport.Mandatory)) { "${Feature.ShutdownAnySegwit.rfcName} should be mandatory" } + require(features.hasFeature(Feature.SimpleClose, FeatureSupport.Mandatory)) { "${Feature.SimpleClose.rfcName} should be mandatory" } require(!features.hasFeature(Feature.ZeroConfChannels)) { "${Feature.ZeroConfChannels.rfcName} has been deprecated: use the zeroConfPeers whitelist instead" } require(!features.hasFeature(Feature.TrustedSwapInClient)) { "${Feature.TrustedSwapInClient.rfcName} has been deprecated" } require(!features.hasFeature(Feature.TrustedSwapInProvider)) { "${Feature.TrustedSwapInProvider.rfcName} has been deprecated" } @@ -185,6 +187,7 @@ data class NodeParams( Feature.ShutdownAnySegwit to FeatureSupport.Mandatory, Feature.ChannelType to FeatureSupport.Mandatory, Feature.PaymentMetadata to FeatureSupport.Optional, + Feature.SimpleClose to FeatureSupport.Mandatory, Feature.ExperimentalTrampolinePayment to FeatureSupport.Optional, Feature.ZeroReserveChannels to FeatureSupport.Optional, Feature.WakeUpNotificationClient to FeatureSupport.Optional, diff --git a/src/commonMain/kotlin/fr/acinq/lightning/channel/ChannelCommand.kt b/src/commonMain/kotlin/fr/acinq/lightning/channel/ChannelCommand.kt index 0a3f7643c..5c5834c10 100644 --- a/src/commonMain/kotlin/fr/acinq/lightning/channel/ChannelCommand.kt +++ b/src/commonMain/kotlin/fr/acinq/lightning/channel/ChannelCommand.kt @@ -6,7 +6,6 @@ import fr.acinq.lightning.MilliSatoshi import fr.acinq.lightning.blockchain.WatchEvent import fr.acinq.lightning.blockchain.electrum.WalletState import fr.acinq.lightning.blockchain.fee.FeeratePerKw -import fr.acinq.lightning.channel.states.ClosingFeerates import fr.acinq.lightning.channel.states.PersistedChannelState import fr.acinq.lightning.crypto.KeyManager import fr.acinq.lightning.utils.UUID @@ -132,7 +131,7 @@ sealed class ChannelCommand { } sealed class Close : ChannelCommand() { - data class MutualClose(val scriptPubKey: ByteVector?, val feerates: ClosingFeerates?) : Close(), ForbiddenDuringSplice, ForbiddenDuringQuiescence + data class MutualClose(val scriptPubKey: ByteVector?, val feerate: FeeratePerKw?) : Close(), ForbiddenDuringSplice, ForbiddenDuringQuiescence data object ForceClose : Close() } diff --git a/src/commonMain/kotlin/fr/acinq/lightning/channel/ChannelData.kt b/src/commonMain/kotlin/fr/acinq/lightning/channel/ChannelData.kt index 248ba9eab..66fa7e6db 100644 --- a/src/commonMain/kotlin/fr/acinq/lightning/channel/ChannelData.kt +++ b/src/commonMain/kotlin/fr/acinq/lightning/channel/ChannelData.kt @@ -9,10 +9,9 @@ import fr.acinq.lightning.channel.Helpers.publishIfNeeded import fr.acinq.lightning.channel.Helpers.watchConfirmedIfNeeded import fr.acinq.lightning.channel.Helpers.watchSpentIfNeeded import fr.acinq.lightning.crypto.KeyManager -import fr.acinq.lightning.logging.* +import fr.acinq.lightning.logging.LoggingContext import fr.acinq.lightning.transactions.Scripts import fr.acinq.lightning.transactions.Transactions.TransactionWithInputInfo.* -import fr.acinq.lightning.wire.ClosingSigned /** * Details about a force-close where we published our commitment. @@ -354,7 +353,7 @@ data class LocalParams( val defaultFinalScriptPubKey: ByteVector, val features: Features ) { - constructor(nodeParams: NodeParams, isInitiator: Boolean): this( + constructor(nodeParams: NodeParams, isInitiator: Boolean) : this( nodeId = nodeParams.nodeId, fundingKeyPath = nodeParams.keyManager.newFundingKeyPath(isInitiator), // we make sure that initiator and non-initiator key path end differently dustLimit = nodeParams.dustLimit, @@ -389,8 +388,6 @@ object ChannelFlags { const val Empty = 0x00.toByte() } -data class ClosingTxProposed(val unsignedTx: ClosingTx, val localClosingSigned: ClosingSigned) - /** Reason for creating a new channel or a splice. */ // @formatter:off sealed class Origin { diff --git a/src/commonMain/kotlin/fr/acinq/lightning/channel/ChannelException.kt b/src/commonMain/kotlin/fr/acinq/lightning/channel/ChannelException.kt index 3f08d7cc2..09c8c4428 100644 --- a/src/commonMain/kotlin/fr/acinq/lightning/channel/ChannelException.kt +++ b/src/commonMain/kotlin/fr/acinq/lightning/channel/ChannelException.kt @@ -60,6 +60,8 @@ data class FeerateTooSmall (override val channelId: Byte data class FeerateTooDifferent (override val channelId: ByteVector32, val localFeeratePerKw: FeeratePerKw, val remoteFeeratePerKw: FeeratePerKw) : ChannelException(channelId, "local/remote feerates are too different: remoteFeeratePerKw=${remoteFeeratePerKw.toLong()} localFeeratePerKw=${localFeeratePerKw.toLong()}") data class InvalidCommitmentSignature (override val channelId: ByteVector32, val txId: TxId) : ChannelException(channelId, "invalid commitment signature: txId=$txId") data class InvalidHtlcSignature (override val channelId: ByteVector32, val txId: TxId) : ChannelException(channelId, "invalid htlc signature: txId=$txId") +data class CannotGenerateClosingTx (override val channelId: ByteVector32) : ChannelException(channelId, "failed to generate closing transaction: all outputs are trimmed") +data class MissingCloseSignature (override val channelId: ByteVector32) : ChannelException(channelId, "closing_complete is missing a signature for a closing transaction including our output") data class InvalidCloseSignature (override val channelId: ByteVector32, val txId: TxId) : ChannelException(channelId, "invalid close signature: txId=$txId") data class InvalidCloseAmountBelowDust (override val channelId: ByteVector32, val txId: TxId) : ChannelException(channelId, "invalid closing tx: some outputs are below dust: txId=$txId") data class CommitSigCountMismatch (override val channelId: ByteVector32, val expected: Int, val actual: Int) : ChannelException(channelId, "commit sig count mismatch: expected=$expected actual=$actual") diff --git a/src/commonMain/kotlin/fr/acinq/lightning/channel/Helpers.kt b/src/commonMain/kotlin/fr/acinq/lightning/channel/Helpers.kt index 6aabdd0fe..fc1666ad3 100644 --- a/src/commonMain/kotlin/fr/acinq/lightning/channel/Helpers.kt +++ b/src/commonMain/kotlin/fr/acinq/lightning/channel/Helpers.kt @@ -21,13 +21,11 @@ import fr.acinq.lightning.blockchain.fee.FeerateTolerance import fr.acinq.lightning.blockchain.fee.OnChainFeerates import fr.acinq.lightning.channel.Helpers.Closing.inputsAlreadySpent import fr.acinq.lightning.channel.states.Channel -import fr.acinq.lightning.channel.states.ClosingFeerates -import fr.acinq.lightning.channel.states.ClosingFees import fr.acinq.lightning.crypto.Bolt3Derivation.deriveForCommitment import fr.acinq.lightning.crypto.Bolt3Derivation.deriveForRevocation import fr.acinq.lightning.crypto.KeyManager import fr.acinq.lightning.crypto.ShaChain -import fr.acinq.lightning.logging.* +import fr.acinq.lightning.logging.LoggingContext import fr.acinq.lightning.transactions.* import fr.acinq.lightning.transactions.Scripts.multiSig2of2 import fr.acinq.lightning.transactions.Transactions.TransactionWithInputInfo.ClaimHtlcDelayedOutputPenaltyTx @@ -281,7 +279,14 @@ object Helpers { ) } - data class PairOfCommitTxs(val localSpec: CommitmentSpec, val localCommitTx: Transactions.TransactionWithInputInfo.CommitTx, val localHtlcTxs: List, val remoteSpec: CommitmentSpec, val remoteCommitTx: Transactions.TransactionWithInputInfo.CommitTx, val remoteHtlcTxs: List) + data class PairOfCommitTxs( + val localSpec: CommitmentSpec, + val localCommitTx: Transactions.TransactionWithInputInfo.CommitTx, + val localHtlcTxs: List, + val remoteSpec: CommitmentSpec, + val remoteCommitTx: Transactions.TransactionWithInputInfo.CommitTx, + val remoteHtlcTxs: List + ) /** * Creates both sides' first commitment transaction. @@ -307,7 +312,7 @@ object Helpers { remotePerCommitmentPoint: PublicKey ): Either { val localSpec = CommitmentSpec(localHtlcs, commitTxFeerate, toLocal = toLocal, toRemote = toRemote) - val remoteSpec = CommitmentSpec(localHtlcs.map{ it.opposite() }.toSet(), commitTxFeerate, toLocal = toRemote, toRemote = toLocal) + val remoteSpec = CommitmentSpec(localHtlcs.map { it.opposite() }.toSet(), commitTxFeerate, toLocal = toRemote, toRemote = toLocal) if (!localParams.isInitiator) { // They initiated the channel open, therefore they pay the fee: we need to make sure they can afford it! @@ -374,74 +379,129 @@ object Helpers { fun isValidFinalScriptPubkey(scriptPubKey: ByteVector, allowAnySegwit: Boolean, allowOpReturn: Boolean): Boolean = isValidFinalScriptPubkey(scriptPubKey.toByteArray(), allowAnySegwit, allowOpReturn) - private fun firstClosingFee(commitment: FullCommitment, localScriptPubkey: ByteArray, remoteScriptPubkey: ByteArray, requestedFeerate: ClosingFeerates): ClosingFees { - // this is just to estimate the weight which depends on the size of the pubkey scripts - val dummyClosingTx = Transactions.makeClosingTx(commitment.commitInput, localScriptPubkey, remoteScriptPubkey, commitment.params.localParams.isInitiator, Satoshi(0), Satoshi(0), commitment.localCommit.spec) - val closingWeight = Transaction.weight(Transactions.addSigs(dummyClosingTx, dummyPublicKey, commitment.remoteFundingPubkey, Transactions.PlaceHolderSig, Transactions.PlaceHolderSig).tx) - return requestedFeerate.computeFees(closingWeight) + /** + * Check that all closing outputs are above bitcoin's dust limit for their script type, otherwise there is a risk + * that the closing transaction will not be relayed to miners' mempool and will not confirm. + * The various dust limits are detailed in https://github.com/lightningnetwork/lightning-rfc/blob/master/03-transactions.md#dust-limits + */ + fun checkClosingDustAmounts(closingTx: ClosingTx): Boolean { + return closingTx.tx.txOut.all { txOut -> txOut.amount >= Transactions.dustLimit(txOut.publicKeyScript) } } - fun firstClosingFee(commitment: FullCommitment, localScriptPubkey: ByteVector, remoteScriptPubkey: ByteVector, requestedFeerate: ClosingFeerates): ClosingFees = - firstClosingFee(commitment, localScriptPubkey.toByteArray(), remoteScriptPubkey.toByteArray(), requestedFeerate) - - fun nextClosingFee(localClosingFee: Satoshi, remoteClosingFee: Satoshi): Satoshi = ((localClosingFee + remoteClosingFee) / 4) * 2 - - fun makeFirstClosingTx( + /** We are the closer: we sign closing transactions for which we pay the fees. */ + fun makeClosingTxs( channelKeys: KeyManager.ChannelKeys, commitment: FullCommitment, - localScriptPubkey: ByteArray, - remoteScriptPubkey: ByteArray, - requestedFeerate: ClosingFeerates - ): Pair { - val closingFees = firstClosingFee(commitment, localScriptPubkey, remoteScriptPubkey, requestedFeerate) - return makeClosingTx(channelKeys, commitment, localScriptPubkey, remoteScriptPubkey, closingFees) + localScriptPubkey: ByteVector, + remoteScriptPubkey: ByteVector, + feerate: FeeratePerKw, + ): Either> { + require(isValidFinalScriptPubkey(localScriptPubkey, allowAnySegwit = true, allowOpReturn = true)) { "invalid localScriptPubkey" } + require(isValidFinalScriptPubkey(remoteScriptPubkey, allowAnySegwit = true, allowOpReturn = true)) { "invalid remoteScriptPubkey" } + val lockTime = 0L + val closingFee = run { + val dummyClosingTxs = Transactions.makeClosingTxs(commitment.commitInput, commitment.localCommit.spec, Transactions.ClosingTxFee.PaidByUs(0.sat), lockTime, localScriptPubkey, remoteScriptPubkey) + when (val dummyTx = dummyClosingTxs.preferred) { + null -> return Either.Left(CannotGenerateClosingTx(commitment.channelId)) + else -> { + val dummySignedTx = Transactions.addSigs(dummyTx, Transactions.PlaceHolderPubKey, Transactions.PlaceHolderPubKey, Transactions.PlaceHolderSig, Transactions.PlaceHolderSig) + Transactions.ClosingTxFee.PaidByUs(Transactions.weight2fee(feerate, dummySignedTx.tx.weight())) + } + } + } + val closingTxs = Transactions.makeClosingTxs(commitment.commitInput, commitment.localCommit.spec, closingFee, lockTime, localScriptPubkey, remoteScriptPubkey) + // The actual fee we're paying will be bigger than the one we previously computed if we omit our output. + val actualFee = closingTxs.preferred?.fee ?: 0.sat + if (actualFee == 0.sat) { + return Either.Left(CannotGenerateClosingTx(commitment.channelId)) + } + val localFundingKey = channelKeys.fundingKey(commitment.fundingTxIndex) + val tlvs = TlvStream( + setOfNotNull( + closingTxs.localAndRemote?.let { tx -> ClosingCompleteTlv.CloserAndClosee(Transactions.sign(tx, localFundingKey)) }, + closingTxs.localOnly?.let { tx -> ClosingCompleteTlv.CloserNoClosee(Transactions.sign(tx, localFundingKey)) }, + closingTxs.remoteOnly?.let { tx -> ClosingCompleteTlv.NoCloserClosee(Transactions.sign(tx, localFundingKey)) }, + ) + ) + val closingComplete = ClosingComplete(commitment.channelId, actualFee, lockTime, tlvs) + return Either.Right(Pair(closingTxs, closingComplete)) } - fun makeClosingTx( - channelKeys: KeyManager.ChannelKeys, - commitment: FullCommitment, - localScriptPubkey: ByteArray, - remoteScriptPubkey: ByteArray, - closingFees: ClosingFees - ): Pair { - val allowAnySegwit = Features.canUseFeature(commitment.params.localParams.features, commitment.params.remoteParams.features, Feature.ShutdownAnySegwit) - val allowOpReturn = Features.canUseFeature(commitment.params.localParams.features, commitment.params.remoteParams.features, Feature.SimpleClose) - require(isValidFinalScriptPubkey(localScriptPubkey, allowAnySegwit, allowOpReturn)) { "invalid localScriptPubkey" } - require(isValidFinalScriptPubkey(remoteScriptPubkey, allowAnySegwit, allowOpReturn)) { "invalid remoteScriptPubkey" } - val dustLimit = commitment.params.localParams.dustLimit.max(commitment.params.remoteParams.dustLimit) - val closingTx = Transactions.makeClosingTx(commitment.commitInput, localScriptPubkey, remoteScriptPubkey, commitment.params.localParams.isInitiator, dustLimit, closingFees.preferred, commitment.localCommit.spec) - val localClosingSig = Transactions.sign(closingTx, channelKeys.fundingKey(commitment.fundingTxIndex)) - val closingSigned = ClosingSigned(commitment.channelId, closingFees.preferred, localClosingSig, TlvStream(ClosingSignedTlv.FeeRange(closingFees.min, closingFees.max))) - return Pair(closingTx, closingSigned) - } - - fun checkClosingSignature( + /** + * We are the closee: we choose one of the closer's transactions and sign it back. + * Callers should ignore failures: since the protocol is fully asynchronous, failures here simply mean that the + * closing_complete doesn't match the latest state of the closing negotiation (someone changed their script). + */ + fun signClosingTx( channelKeys: KeyManager.ChannelKeys, commitment: FullCommitment, - localScriptPubkey: ByteArray, - remoteScriptPubkey: ByteArray, - remoteClosingFee: Satoshi, - remoteClosingSig: ByteVector64 - ): Either> { - val (closingTx, closingSigned) = makeClosingTx(channelKeys, commitment, localScriptPubkey, remoteScriptPubkey, ClosingFees(remoteClosingFee)) - return if (checkClosingDustAmounts(closingTx)) { - val signedClosingTx = Transactions.addSigs(closingTx, channelKeys.fundingPubKey(commitment.fundingTxIndex), commitment.remoteFundingPubkey, closingSigned.signature, remoteClosingSig) - when (Transactions.checkSpendable(signedClosingTx)) { - is Try.Success -> Either.Right(Pair(signedClosingTx, closingSigned)) - is Try.Failure -> Either.Left(InvalidCloseSignature(commitment.channelId, signedClosingTx.tx.txid)) + localScriptPubkey: ByteVector, + remoteScriptPubkey: ByteVector, + closingComplete: ClosingComplete + ): Either> { + val closingFee = Transactions.ClosingTxFee.PaidByThem(closingComplete.fees) + val closingTxs = Transactions.makeClosingTxs(commitment.commitInput, commitment.localCommit.spec, closingFee, closingComplete.lockTime, localScriptPubkey, remoteScriptPubkey) + // If our output isn't dust, they must provide a signature for a transaction that includes it. + // Note that we're the closee, so we look for signatures including the closee output. + if (closingTxs.localAndRemote != null && closingTxs.localOnly != null && closingComplete.closerAndCloseeSig == null && closingComplete.noCloserCloseeSig == null) { + return Either.Left(MissingCloseSignature(commitment.channelId)) + } + if (closingTxs.localAndRemote != null && closingTxs.localOnly == null && closingComplete.closerAndCloseeSig == null) { + return Either.Left(MissingCloseSignature(commitment.channelId)) + } + if (closingTxs.localAndRemote == null && closingTxs.localOnly != null && closingComplete.noCloserCloseeSig == null) { + return Either.Left(MissingCloseSignature(commitment.channelId)) + } + // We choose the closing signature that matches our preferred closing transaction. + val closingTxsWithSigs = listOfNotNull ClosingSigTlv>>( + closingComplete.closerAndCloseeSig?.let { remoteSig -> closingTxs.localAndRemote?.let { tx -> Triple(tx, remoteSig) { localSig: ByteVector64 -> ClosingSigTlv.CloserAndClosee(localSig) } } }, + closingComplete.noCloserCloseeSig?.let { remoteSig -> closingTxs.localOnly?.let { tx -> Triple(tx, remoteSig) { localSig -> ClosingSigTlv.NoCloserClosee(localSig) } } }, + closingComplete.closerNoCloseeSig?.let { remoteSig -> closingTxs.remoteOnly?.let { tx -> Triple(tx, remoteSig) { localSig -> ClosingSigTlv.CloserNoClosee(localSig) } } }, + ) + return when (val preferred = closingTxsWithSigs.firstOrNull()) { + null -> Either.Left(MissingCloseSignature(commitment.channelId)) + else -> { + val (closingTx, remoteSig, sigToTlv) = preferred + val localFundingKey = channelKeys.fundingKey(commitment.fundingTxIndex) + val localSig = Transactions.sign(closingTx, localFundingKey) + val signedClosingTx = Transactions.addSigs(closingTx, localFundingKey.publicKey(), commitment.remoteFundingPubkey, localSig, remoteSig) + when (Transactions.checkSpendable(signedClosingTx)) { + is Try.Failure -> Either.Left(InvalidCloseSignature(commitment.channelId, signedClosingTx.tx.txid)) + is Try.Success -> Either.Right(Pair(signedClosingTx, ClosingSig(commitment.channelId, TlvStream(sigToTlv(localSig))))) + } } - } else { - Either.Left(InvalidCloseAmountBelowDust(commitment.channelId, closingTx.tx.txid)) } } /** - * Check that all closing outputs are above bitcoin's dust limit for their script type, otherwise there is a risk - * that the closing transaction will not be relayed to miners' mempool and will not confirm. - * The various dust limits are detailed in https://github.com/lightningnetwork/lightning-rfc/blob/master/03-transactions.md#dust-limits + * We are the closer: they sent us their signature so we should now have a fully signed closing transaction. + * Callers should ignore failures: since the protocol is fully asynchronous, failures here simply mean that the + * closing_sig doesn't match the latest state of the closing negotiation (someone changed their script). */ - fun checkClosingDustAmounts(closingTx: ClosingTx): Boolean { - return closingTx.tx.txOut.all { txOut -> txOut.amount >= Transactions.dustLimit(txOut.publicKeyScript) } + fun receiveClosingSig( + channelKeys: KeyManager.ChannelKeys, + commitment: FullCommitment, + closingTxs: Transactions.ClosingTxs, + closingSig: ClosingSig + ): Either { + val closingTxsWithSig = listOfNotNull( + closingSig.closerAndCloseeSig?.let { sig -> closingTxs.localAndRemote?.let { tx -> Pair(tx, sig) } }, + closingSig.closerNoCloseeSig?.let { sig -> closingTxs.localOnly?.let { tx -> Pair(tx, sig) } }, + closingSig.noCloserCloseeSig?.let { sig -> closingTxs.remoteOnly?.let { tx -> Pair(tx, sig) } }, + ) + return when (val preferred = closingTxsWithSig.firstOrNull()) { + null -> Either.Left(MissingCloseSignature(commitment.channelId)) + else -> { + val (closingTx, remoteSig) = preferred + val localFundingKey = channelKeys.fundingKey(commitment.fundingTxIndex) + val localSig = Transactions.sign(closingTx, localFundingKey) + val signedClosingTx = Transactions.addSigs(closingTx, localFundingKey.publicKey(), commitment.remoteFundingPubkey, localSig, remoteSig) + when (Transactions.checkSpendable(signedClosingTx)) { + is Try.Failure -> Either.Left(InvalidCloseSignature(commitment.channelId, signedClosingTx.tx.txid)) + is Try.Success -> Either.Right(signedClosingTx) + } + } + } } /** diff --git a/src/commonMain/kotlin/fr/acinq/lightning/channel/states/Channel.kt b/src/commonMain/kotlin/fr/acinq/lightning/channel/states/Channel.kt index b0f57c89b..f370b125d 100644 --- a/src/commonMain/kotlin/fr/acinq/lightning/channel/states/Channel.kt +++ b/src/commonMain/kotlin/fr/acinq/lightning/channel/states/Channel.kt @@ -16,10 +16,12 @@ import fr.acinq.lightning.channel.Helpers.Closing.claimRevokedRemoteCommitTxOutp import fr.acinq.lightning.channel.Helpers.Closing.getRemotePerCommitmentSecret import fr.acinq.lightning.crypto.KeyManager import fr.acinq.lightning.db.ChannelClosingType -import fr.acinq.lightning.logging.* +import fr.acinq.lightning.logging.LoggingContext +import fr.acinq.lightning.logging.MDCLogger import fr.acinq.lightning.serialization.Encryption.from import fr.acinq.lightning.transactions.Transactions.TransactionWithInputInfo.ClosingTx -import fr.acinq.lightning.utils.* +import fr.acinq.lightning.utils.msat +import fr.acinq.lightning.utils.sat import fr.acinq.lightning.wire.* /* @@ -69,7 +71,8 @@ sealed class ChannelState { it is ChannelAction.Message.Send && it.message is CommitSig -> it.copy(message = it.message.withChannelData(EncryptedChannelData.from(privateKey, this@ChannelState), logger)) it is ChannelAction.Message.Send && it.message is RevokeAndAck -> it.copy(message = it.message.withChannelData(EncryptedChannelData.from(privateKey, this@ChannelState), logger)) it is ChannelAction.Message.Send && it.message is Shutdown -> it.copy(message = it.message.withChannelData(EncryptedChannelData.from(privateKey, this@ChannelState), logger)) - it is ChannelAction.Message.Send && it.message is ClosingSigned -> it.copy(message = it.message.withChannelData(EncryptedChannelData.from(privateKey, this@ChannelState), logger)) + it is ChannelAction.Message.Send && it.message is ClosingComplete -> it.copy(message = it.message.withChannelData(EncryptedChannelData.from(privateKey, this@ChannelState), logger)) + it is ChannelAction.Message.Send && it.message is ClosingSig -> it.copy(message = it.message.withChannelData(EncryptedChannelData.from(privateKey, this@ChannelState), logger)) else -> it } } @@ -106,7 +109,7 @@ sealed class ChannelState { } } - private fun ChannelContext.emitClosingEvents(oldState: ChannelStateWithCommitments, newState: Closing): List { + internal fun ChannelContext.emitClosingEvents(oldState: ChannelStateWithCommitments, newState: Closing): List { val channelBalance = oldState.commitments.latest.localCommit.spec.toLocal return if (channelBalance > 0.msat) { when { @@ -215,20 +218,15 @@ sealed class ChannelState { is Normal -> forceClose(state) is ShuttingDown -> forceClose(state) is Negotiating -> when { - state.bestUnpublishedClosingTx != null -> { - // if we were in the process of closing and already received a closing sig from the counterparty, it's always better to use that + state.publishedClosingTxs.isNotEmpty() -> { + // If we were in the process of closing and already received a closing sig from the counterparty, it's always better to use that. val nextState = Closing( state.commitments, - waitingSinceBlock = currentBlockHeight.toLong(), - mutualCloseProposed = state.closingTxProposed.flatten().map { it.unsignedTx } + listOf(state.bestUnpublishedClosingTx), - mutualClosePublished = listOf(state.bestUnpublishedClosingTx) - ) - val actions = listOf( - ChannelAction.Storage.StoreState(nextState), - ChannelAction.Blockchain.PublishTx(state.bestUnpublishedClosingTx), - ChannelAction.Blockchain.SendWatch(WatchConfirmed(state.channelId, state.bestUnpublishedClosingTx.tx, staticParams.nodeParams.minDepthBlocks.toLong(), BITCOIN_TX_CONFIRMED(state.bestUnpublishedClosingTx.tx))) + waitingSinceBlock = state.waitingSinceBlock, + mutualCloseProposed = state.proposedClosingTxs.flatMap { it.all }, + mutualClosePublished = state.publishedClosingTxs ) - Pair(nextState, actions) + Pair(nextState, listOf(ChannelAction.Storage.StoreState(nextState))) } else -> forceClose(state) } @@ -258,20 +256,18 @@ sealed class ChannelState { logger.error { "peer sent error: ascii='${e.toAscii()}' bin=${e.data.toHex()}" } return when (this@ChannelState) { is Closing -> Pair(this@ChannelState, listOf()) // nothing to do, there is already a spending tx published - is Negotiating -> when (this@ChannelState.bestUnpublishedClosingTx) { - null -> this.spendLocalCurrent() - else -> { + is Negotiating -> when { + publishedClosingTxs.isNotEmpty() -> { + // If we were in the process of closing and already received a closing sig from the counterparty, it's always better to use that. val nexState = Closing( commitments = commitments, - waitingSinceBlock = currentBlockHeight.toLong(), - mutualCloseProposed = closingTxProposed.flatten().map { it.unsignedTx }, - mutualClosePublished = listOfNotNull(bestUnpublishedClosingTx) + waitingSinceBlock = waitingSinceBlock, + mutualCloseProposed = proposedClosingTxs.flatMap { it.all }, + mutualClosePublished = publishedClosingTxs ) - Pair(nexState, buildList { - add(ChannelAction.Storage.StoreState(nexState)) - addAll(doPublish(bestUnpublishedClosingTx, nexState.channelId)) - }) + Pair(nexState, listOf(ChannelAction.Storage.StoreState(nexState))) } + else -> this.spendLocalCurrent() } is WaitForFundingSigned -> Pair(Aborted, listOf(ChannelAction.Storage.RemoveChannel(this@ChannelState))) // NB: we publish the commitment even if we have nothing at stake (in a dataloss situation our peer will send us an error just for that) @@ -424,8 +420,9 @@ sealed class ChannelStateWithCommitments : PersistedChannelState() { is Closing -> this@ChannelStateWithCommitments.copy(remoteCommitPublished = remoteCommitPublished) is Negotiating -> Closing( commitments = commitments, - waitingSinceBlock = currentBlockHeight.toLong(), - mutualCloseProposed = closingTxProposed.flatten().map { it.unsignedTx }, + waitingSinceBlock = waitingSinceBlock, + mutualCloseProposed = proposedClosingTxs.flatMap { it.all }, + mutualClosePublished = publishedClosingTxs, remoteCommitPublished = remoteCommitPublished ) else -> Closing( @@ -453,8 +450,9 @@ sealed class ChannelStateWithCommitments : PersistedChannelState() { is Closing -> copy(nextRemoteCommitPublished = remoteCommitPublished) is Negotiating -> Closing( commitments = commitments, - waitingSinceBlock = currentBlockHeight.toLong(), - mutualCloseProposed = closingTxProposed.flatten().map { it.unsignedTx }, + waitingSinceBlock = waitingSinceBlock, + mutualCloseProposed = proposedClosingTxs.flatMap { it.all }, + mutualClosePublished = publishedClosingTxs, nextRemoteCommitPublished = remoteCommitPublished ) else -> Closing( @@ -485,8 +483,9 @@ sealed class ChannelStateWithCommitments : PersistedChannelState() { } is Negotiating -> Closing( commitments = commitments, - waitingSinceBlock = currentBlockHeight.toLong(), - mutualCloseProposed = closingTxProposed.flatten().map { it.unsignedTx }, + waitingSinceBlock = waitingSinceBlock, + mutualCloseProposed = proposedClosingTxs.flatMap { it.all }, + mutualClosePublished = publishedClosingTxs, revokedCommitPublished = listOf(revokedCommitPublished) ) else -> Closing( @@ -538,7 +537,7 @@ sealed class ChannelStateWithCommitments : PersistedChannelState() { val remoteCommitPublished = claimRemoteCommitMainOutput(channelKeys(), commitments.params, tx, currentOnChainFeerates.claimMainFeerate) val nextState = when (this@ChannelStateWithCommitments) { is Closing -> this@ChannelStateWithCommitments.copy(remoteCommitPublished = remoteCommitPublished) - is Negotiating -> Closing(commitments, waitingSinceBlock = currentBlockHeight.toLong(), mutualCloseProposed = closingTxProposed.flatten().map { it.unsignedTx }, remoteCommitPublished = remoteCommitPublished) + is Negotiating -> Closing(commitments, waitingSinceBlock, proposedClosingTxs.flatMap { it.all }, publishedClosingTxs, remoteCommitPublished = remoteCommitPublished) else -> Closing(commitments, waitingSinceBlock = currentBlockHeight.toLong(), remoteCommitPublished = remoteCommitPublished) } return Pair(nextState, buildList { @@ -574,8 +573,9 @@ sealed class ChannelStateWithCommitments : PersistedChannelState() { is Closing -> copy(localCommitPublished = localCommitPublished) is Negotiating -> Closing( commitments = commitments, - waitingSinceBlock = currentBlockHeight.toLong(), - mutualCloseProposed = closingTxProposed.flatten().map { it.unsignedTx }, + waitingSinceBlock = waitingSinceBlock, + mutualCloseProposed = proposedClosingTxs.flatMap { it.all }, + mutualClosePublished = publishedClosingTxs, localCommitPublished = localCommitPublished ) else -> Closing( @@ -611,18 +611,6 @@ sealed class ChannelStateWithCommitments : PersistedChannelState() { logger.error { channelEx.message } when { this@ChannelStateWithCommitments is Closing -> Pair(this@ChannelStateWithCommitments, listOf()) // nothing to do, there is already a spending tx published - this@ChannelStateWithCommitments is Negotiating && this@ChannelStateWithCommitments.bestUnpublishedClosingTx != null -> { - val nexState = Closing( - commitments, - waitingSinceBlock = currentBlockHeight.toLong(), - mutualCloseProposed = closingTxProposed.flatten().map { it.unsignedTx }, - mutualClosePublished = listOfNotNull(bestUnpublishedClosingTx) - ) - Pair(nexState, buildList { - add(ChannelAction.Storage.StoreState(nexState)) - addAll(doPublish(bestUnpublishedClosingTx, nexState.channelId)) - }) - } else -> { val error = Error(channelId, channelEx.message) spendLocalCurrent().run { copy(second = second + ChannelAction.Message.Send(error)) } diff --git a/src/commonMain/kotlin/fr/acinq/lightning/channel/states/Closing.kt b/src/commonMain/kotlin/fr/acinq/lightning/channel/states/Closing.kt index baee55dcd..36fd4409a 100644 --- a/src/commonMain/kotlin/fr/acinq/lightning/channel/states/Closing.kt +++ b/src/commonMain/kotlin/fr/acinq/lightning/channel/states/Closing.kt @@ -1,11 +1,9 @@ package fr.acinq.lightning.channel.states -import fr.acinq.bitcoin.Satoshi import fr.acinq.bitcoin.Transaction import fr.acinq.bitcoin.updated import fr.acinq.bitcoin.utils.Either import fr.acinq.lightning.blockchain.* -import fr.acinq.lightning.blockchain.fee.FeeratePerKw import fr.acinq.lightning.channel.* import fr.acinq.lightning.channel.Helpers.Closing.claimCurrentLocalCommitTxOutputs import fr.acinq.lightning.channel.Helpers.Closing.claimRemoteCommitTxOutputs @@ -15,24 +13,11 @@ import fr.acinq.lightning.channel.Helpers.Closing.extractPreimages import fr.acinq.lightning.channel.Helpers.Closing.onChainOutgoingHtlcs import fr.acinq.lightning.channel.Helpers.Closing.overriddenOutgoingHtlcs import fr.acinq.lightning.channel.Helpers.Closing.timedOutHtlcs -import fr.acinq.lightning.transactions.Transactions import fr.acinq.lightning.transactions.Transactions.TransactionWithInputInfo.ClosingTx import fr.acinq.lightning.utils.getValue import fr.acinq.lightning.wire.ChannelReestablish import fr.acinq.lightning.wire.Error -data class ClosingFees(val preferred: Satoshi, val min: Satoshi, val max: Satoshi) { - constructor(preferred: Satoshi) : this(preferred, preferred, preferred) -} - -data class ClosingFeerates(val preferred: FeeratePerKw, val min: FeeratePerKw, val max: FeeratePerKw) { - fun computeFees(closingTxWeight: Int): ClosingFees = ClosingFees(Transactions.weight2fee(preferred, closingTxWeight), Transactions.weight2fee(min, closingTxWeight), Transactions.weight2fee(max, closingTxWeight)) - - companion object { - operator fun invoke(preferred: FeeratePerKw): ClosingFeerates = ClosingFeerates(preferred, preferred / 2, preferred * 2) - } -} - sealed class ClosingType data class MutualClose(val tx: ClosingTx) : ClosingType() data class LocalClose(val localCommit: LocalCommit, val localCommitPublished: LocalCommitPublished) : ClosingType() diff --git a/src/commonMain/kotlin/fr/acinq/lightning/channel/states/Negotiating.kt b/src/commonMain/kotlin/fr/acinq/lightning/channel/states/Negotiating.kt index b50299edb..8d767c6fd 100644 --- a/src/commonMain/kotlin/fr/acinq/lightning/channel/states/Negotiating.kt +++ b/src/commonMain/kotlin/fr/acinq/lightning/channel/states/Negotiating.kt @@ -1,15 +1,14 @@ package fr.acinq.lightning.channel.states import fr.acinq.bitcoin.Transaction -import fr.acinq.bitcoin.updated import fr.acinq.bitcoin.utils.Either import fr.acinq.lightning.blockchain.* +import fr.acinq.lightning.blockchain.fee.FeeratePerKw import fr.acinq.lightning.channel.* -import fr.acinq.lightning.channel.states.Channel.MAX_NEGOTIATION_ITERATIONS +import fr.acinq.lightning.transactions.Transactions import fr.acinq.lightning.transactions.Transactions.TransactionWithInputInfo.ClosingTx -import fr.acinq.lightning.utils.msat -import fr.acinq.lightning.wire.ClosingSigned -import fr.acinq.lightning.wire.ClosingSignedTlv +import fr.acinq.lightning.wire.ClosingComplete +import fr.acinq.lightning.wire.ClosingSig import fr.acinq.lightning.wire.Error import fr.acinq.lightning.wire.Shutdown @@ -17,147 +16,136 @@ data class Negotiating( override val commitments: Commitments, val localShutdown: Shutdown, val remoteShutdown: Shutdown, - val closingTxProposed: List>, // one list for every negotiation (there can be several in case of disconnection) - val bestUnpublishedClosingTx: ClosingTx?, - val closingFeerates: ClosingFeerates? + // Closing transactions we created, where we pay the fees (unsigned). + val proposedClosingTxs: List, + // Closing transactions we published: this contains our local transactions for + // which they sent a signature, and their closing transactions that we signed. + val publishedClosingTxs: List, + val closingFeerate: FeeratePerKw?, + val waitingSinceBlock: Long, // how many blocks since we initiated the closing ) : ChannelStateWithCommitments() { - init { - require(closingTxProposed.isNotEmpty()) { "there must always be a list for the current negotiation" } - require(!commitments.params.localParams.isInitiator || !closingTxProposed.any { it.isEmpty() }) { "initiator must have at least one closing signature for every negotiation attempt because it initiates the closing" } - } - override fun updateCommitments(input: Commitments): ChannelStateWithCommitments = this.copy(commitments = input) override fun ChannelContext.processInternal(cmd: ChannelCommand): Pair> { return when (cmd) { is ChannelCommand.MessageReceived -> when (cmd.message) { - is ClosingSigned -> { - val remoteClosingFee = cmd.message.feeSatoshis - logger.info { "received closing fee=$remoteClosingFee" } - when (val result = - Helpers.Closing.checkClosingSignature(channelKeys(), commitments.latest, localShutdown.scriptPubKey.toByteArray(), remoteShutdown.scriptPubKey.toByteArray(), cmd.message.feeSatoshis, cmd.message.signature)) { - is Either.Left -> handleLocalError(cmd, result.value) + is ClosingComplete -> { + val result = Helpers.Closing.signClosingTx( + channelKeys(), + commitments.latest, + localShutdown.scriptPubKey, + remoteShutdown.scriptPubKey, + cmd.message + ) + when (result) { + is Either.Left -> { + // This may happen if scripts were updated concurrently, so we simply ignore failures. + // Bolt 2: + // - If the signature field is not valid for the corresponding closing transaction: + // - MUST ignore `closing_complete`. + logger.warning { "invalid closing_complete: ${result.value.message}" } + Pair(this@Negotiating, listOf()) + } + is Either.Right -> { + val (closingTx, closingSig) = result.value + val nextState = this@Negotiating.copy(publishedClosingTxs = publishedClosingTxs + closingTx) + val actions = listOf( + ChannelAction.Storage.StoreState(nextState), + ChannelAction.Blockchain.PublishTx(closingTx), + ChannelAction.Blockchain.SendWatch(WatchConfirmed(channelId, closingTx.tx, staticParams.nodeParams.minDepthBlocks.toLong(), BITCOIN_TX_CONFIRMED(closingTx.tx))), + ChannelAction.Message.Send(closingSig) + ) + Pair(nextState, actions) + } + } + } + is ClosingSig -> { + val result = Helpers.Closing.receiveClosingSig( + channelKeys(), + commitments.latest, + proposedClosingTxs.last(), + cmd.message + ) + when (result) { + is Either.Left -> { + // This may happen if scripts were updated concurrently, so we simply ignore failures. + // Bolt 2: + // - If the signature field is not valid for the corresponding closing transaction: + // - MUST ignore `closing_sig`. + logger.warning { "invalid closing_sig: ${result.value.message}" } + Pair(this@Negotiating, listOf()) + } is Either.Right -> { - val (signedClosingTx, closingSignedRemoteFees) = result.value - val lastLocalClosingSigned = closingTxProposed.last().lastOrNull()?.localClosingSigned - when { - lastLocalClosingSigned?.feeSatoshis == remoteClosingFee -> { - logger.info { "they accepted our fee, publishing closing tx: closingTxId=${signedClosingTx.tx.txid}" } - completeMutualClose(signedClosingTx, null) - } - closingTxProposed.flatten().size >= MAX_NEGOTIATION_ITERATIONS -> { - logger.warning { "could not agree on closing fees after $MAX_NEGOTIATION_ITERATIONS iterations, publishing closing tx: closingTxId=${signedClosingTx.tx.txid}" } - completeMutualClose(signedClosingTx, closingSignedRemoteFees) - } - lastLocalClosingSigned?.tlvStream?.get()?.let { it.min <= remoteClosingFee && remoteClosingFee <= it.max } == true -> { - val localFeeRange = lastLocalClosingSigned.tlvStream.get()!! - logger.info { "they chose closing fee=$remoteClosingFee within our fee range (min=${localFeeRange.max} max=${localFeeRange.max}), publishing closing tx: closingTxId=${signedClosingTx.tx.txid}" } - completeMutualClose(signedClosingTx, closingSignedRemoteFees) - } - commitments.latest.localCommit.spec.toLocal == 0.msat -> { - logger.info { "we have nothing at stake, publishing closing tx: closingTxId=${signedClosingTx.tx.txid}" } - completeMutualClose(signedClosingTx, closingSignedRemoteFees) - } - else -> { - val theirFeeRange = cmd.message.tlvStream.get() - val ourFeeRange = closingFeerates ?: ClosingFeerates(currentOnChainFeerates.mutualCloseFeerate) - when { - theirFeeRange != null && !commitments.params.localParams.isInitiator -> { - // if we are not the initiator and they proposed a fee range, we pick a value in that range and they should accept it without further negotiation - // we don't care much about the closing fee since they're paying it (not us) and we can use CPFP if we want to speed up confirmation - val closingFees = Helpers.Closing.firstClosingFee(commitments.latest, localShutdown.scriptPubKey, remoteShutdown.scriptPubKey, ourFeeRange) - val closingFee = when { - closingFees.preferred > theirFeeRange.max -> theirFeeRange.max - // if we underestimate the fee, then we're happy with whatever they propose (it will confirm more quickly and we're not paying it) - closingFees.preferred < remoteClosingFee -> remoteClosingFee - else -> closingFees.preferred - } - if (closingFee == remoteClosingFee) { - logger.info { "accepting their closing fee=$remoteClosingFee, publishing closing tx: closingTxId=${signedClosingTx.tx.txid}" } - completeMutualClose(signedClosingTx, closingSignedRemoteFees) - } else { - val (closingTx, closingSigned) = Helpers.Closing.makeClosingTx( - channelKeys(), - commitments.latest, - localShutdown.scriptPubKey.toByteArray(), - remoteShutdown.scriptPubKey.toByteArray(), - ClosingFees(closingFee, theirFeeRange.min, theirFeeRange.max) - ) - logger.info { "proposing closing fee=${closingSigned.feeSatoshis}" } - val closingProposed1 = closingTxProposed.updated( - closingTxProposed.lastIndex, - closingTxProposed.last() + listOf(ClosingTxProposed(closingTx, closingSigned)) - ) - val nextState = this@Negotiating.copy( - commitments = commitments.copy(remoteChannelData = cmd.message.channelData), - closingTxProposed = closingProposed1, - bestUnpublishedClosingTx = signedClosingTx - ) - val actions = listOf(ChannelAction.Storage.StoreState(nextState), ChannelAction.Message.Send(closingSigned)) - Pair(nextState, actions) - } - } - else -> { - val (closingTx, closingSigned) = run { - // if we are not the initiator and we were waiting for them to send their first closing_signed, we compute our firstClosingFee, otherwise we use the last one we sent - val localClosingFees = Helpers.Closing.firstClosingFee(commitments.latest, localShutdown.scriptPubKey, remoteShutdown.scriptPubKey, ourFeeRange) - val nextPreferredFee = Helpers.Closing.nextClosingFee(lastLocalClosingSigned?.feeSatoshis ?: localClosingFees.preferred, remoteClosingFee) - Helpers.Closing.makeClosingTx( - channelKeys(), - commitments.latest, - localShutdown.scriptPubKey.toByteArray(), - remoteShutdown.scriptPubKey.toByteArray(), - localClosingFees.copy(preferred = nextPreferredFee) - ) - } - when { - lastLocalClosingSigned?.feeSatoshis == closingSigned.feeSatoshis -> { - // next computed fee is the same than the one we previously sent (probably because of rounding) - logger.info { "accepting their closing fee=$remoteClosingFee, publishing closing tx: closingTxId=${signedClosingTx.tx.txid}" } - completeMutualClose(signedClosingTx, null) - } - closingSigned.feeSatoshis == remoteClosingFee -> { - logger.info { "we have converged, publishing closing tx: closingTxId=${signedClosingTx.tx.txid}" } - completeMutualClose(signedClosingTx, closingSigned) - } - else -> { - logger.info { "proposing closing fee=${closingSigned.feeSatoshis}" } - val closingProposed1 = closingTxProposed.updated( - closingTxProposed.lastIndex, - closingTxProposed.last() + listOf(ClosingTxProposed(closingTx, closingSigned)) - ) - val nextState = this@Negotiating.copy( - commitments = commitments.copy(remoteChannelData = cmd.message.channelData), - closingTxProposed = closingProposed1, - bestUnpublishedClosingTx = signedClosingTx - ) - val actions = listOf(ChannelAction.Storage.StoreState(nextState), ChannelAction.Message.Send(closingSigned)) - Pair(nextState, actions) - } - } - } - } - } + val closingTx = result.value + val nextState = this@Negotiating.copy(publishedClosingTxs = publishedClosingTxs + closingTx) + val actions = listOf( + ChannelAction.Storage.StoreState(nextState), + ChannelAction.Blockchain.PublishTx(closingTx), + ChannelAction.Blockchain.SendWatch(WatchConfirmed(channelId, closingTx.tx, staticParams.nodeParams.minDepthBlocks.toLong(), BITCOIN_TX_CONFIRMED(closingTx.tx))), + ) + Pair(nextState, actions) + } + } + } + is Shutdown -> { + if (cmd.message.scriptPubKey != remoteShutdown.scriptPubKey) { + // Our peer changed their closing script: we sign a new version of our closing transaction using the new script. + logger.info { "our peer updated their shutdown script (previous=${remoteShutdown.scriptPubKey}, current=${cmd.message.scriptPubKey})" } + val result = Helpers.Closing.makeClosingTxs( + channelKeys(), + commitments.latest, + localShutdown.scriptPubKey, + cmd.message.scriptPubKey, + closingFeerate ?: currentOnChainFeerates.mutualCloseFeerate, + ) + when (result) { + is Either.Left -> { + logger.warning { "cannot create local closing txs for new remote script, waiting for remote closing_complete: ${result.value.message}" } + val nextState = this@Negotiating.copy(remoteShutdown = cmd.message) + Pair(nextState, listOf(ChannelAction.Storage.StoreState(nextState))) + } + is Either.Right -> { + val (closingTxs, closingComplete) = result.value + val nextState = this@Negotiating.copy(remoteShutdown = cmd.message, proposedClosingTxs = proposedClosingTxs + closingTxs) + val actions = listOf( + ChannelAction.Storage.StoreState(nextState), + ChannelAction.Message.Send(closingComplete) + ) + Pair(nextState, actions) } } + } else { + // This is a retransmission of their previous shutdown, we can ignore it. + Pair(this@Negotiating, listOf()) } } is Error -> handleRemoteError(cmd.message) else -> unhandled(cmd) } is ChannelCommand.WatchReceived -> when (val watch = cmd.watch) { - is WatchEventConfirmed -> updateFundingTxStatus(watch) + is WatchEventConfirmed -> when { + publishedClosingTxs.any { it.tx.txid == watch.tx.txid } -> { + // One of our published transactions confirmed, the channel is now closed. + completeMutualClose(publishedClosingTxs.first { it.tx.txid == watch.tx.txid }) + } + proposedClosingTxs.flatMap { it.all }.any { it.tx.txid == watch.tx.txid } -> { + // A transaction that we proposed for which they didn't send us their signature was confirmed, the channel is now closed. + completeMutualClose(getMutualClosePublished(watch.tx)) + } + else -> { + // Otherwise, this must be a funding transaction that just got confirmed. + updateFundingTxStatus(watch) + } + } is WatchEventSpent -> when { - watch.event is BITCOIN_FUNDING_SPENT && closingTxProposed.flatten().any { it.unsignedTx.tx.txid == watch.tx.txid } -> { - // they can publish a closing tx with any sig we sent them, even if we are not done negotiating - logger.info { "closing tx published: closingTxId=${watch.tx.txid}" } + watch.event is BITCOIN_FUNDING_SPENT && publishedClosingTxs.any { it.tx.txid == watch.tx.txid } -> { + // This is one of the transactions we already published, we have nothing to do. + Pair(this@Negotiating, listOf()) + } + watch.event is BITCOIN_FUNDING_SPENT && proposedClosingTxs.flatMap { it.all }.any { it.tx.txid == watch.tx.txid } -> { + // They published one of our closing transactions without sending us their signature. val closingTx = getMutualClosePublished(watch.tx) - val nextState = Closing( - commitments, - waitingSinceBlock = currentBlockHeight.toLong(), - mutualCloseProposed = closingTxProposed.flatten().map { it.unsignedTx }, - mutualClosePublished = listOf(closingTx) - ) + val nextState = this@Negotiating.copy(publishedClosingTxs = publishedClosingTxs + closingTx) val actions = listOf( ChannelAction.Storage.StoreState(nextState), ChannelAction.Blockchain.PublishTx(closingTx), @@ -173,7 +161,42 @@ data class Negotiating( is ChannelCommand.Htlc.Add -> handleCommandError(cmd, ChannelUnavailable(channelId)) is ChannelCommand.Htlc -> unhandled(cmd) is ChannelCommand.Close.ForceClose -> handleLocalError(cmd, ForcedLocalCommit(channelId)) - is ChannelCommand.Close.MutualClose -> handleCommandError(cmd, ClosingAlreadyInProgress(channelId)) + is ChannelCommand.Close.MutualClose -> { + if (cmd.scriptPubKey != null || cmd.feerate != null) { + // We're updating our script or feerate (or both), so we generate a new set of closing transactions. + val localShutdown1 = cmd.scriptPubKey?.let { localShutdown.copy(scriptPubKey = it) } ?: localShutdown + val result = Helpers.Closing.makeClosingTxs( + channelKeys(), + commitments.latest, + localShutdown1.scriptPubKey, + remoteShutdown.scriptPubKey, + cmd.feerate ?: closingFeerate ?: currentOnChainFeerates.mutualCloseFeerate, + ) + when (result) { + is Either.Left -> { + logger.warning { "cannot create local closing txs, waiting for remote closing_complete: ${result.value.message}" } + val nextState = this@Negotiating.copy(localShutdown = localShutdown1, closingFeerate = cmd.feerate ?: closingFeerate) + val actions = buildList { + add(ChannelAction.Storage.StoreState(nextState)) + if (cmd.scriptPubKey != null) add(ChannelAction.Message.Send(localShutdown1)) + } + Pair(nextState, actions) + } + is Either.Right -> { + val (closingTxs, closingComplete) = result.value + val nextState = this@Negotiating.copy(localShutdown = localShutdown1, closingFeerate = cmd.feerate ?: closingFeerate, proposedClosingTxs = proposedClosingTxs + closingTxs) + val actions = buildList { + add(ChannelAction.Storage.StoreState(nextState)) + if (cmd.scriptPubKey != null) add(ChannelAction.Message.Send(localShutdown1)) + add(ChannelAction.Message.Send(closingComplete)) + } + Pair(nextState, actions) + } + } + } else { + handleCommandError(cmd, ClosingAlreadyInProgress(channelId)) + } + } is ChannelCommand.Init -> unhandled(cmd) is ChannelCommand.Funding -> unhandled(cmd) is ChannelCommand.Closing -> unhandled(cmd) @@ -182,25 +205,27 @@ data class Negotiating( } } - /** Return full information about a known closing tx. */ + /** Return full information about a closing tx that we proposed and they then published. */ internal fun getMutualClosePublished(tx: Transaction): ClosingTx { - // they can publish a closing tx with any sig we sent them, even if we are not done negotiating - // they added their signature, so we use their version of the transaction - return closingTxProposed.flatten().first { it.unsignedTx.tx.txid == tx.txid }.unsignedTx.copy(tx = tx) + // They can publish a closing tx with any sig we sent them, even if we are not done negotiating. + // They added their signature, so we use their version of the transaction. + return proposedClosingTxs.flatMap { it.all }.first { it.tx.txid == tx.txid }.copy(tx = tx) } - private fun ChannelContext.completeMutualClose(signedClosingTx: ClosingTx, closingSigned: ClosingSigned?): Pair> { - val nextState = Closing( - commitments, - waitingSinceBlock = currentBlockHeight.toLong(), - mutualCloseProposed = closingTxProposed.flatten().map { it.unsignedTx }, - mutualClosePublished = listOf(signedClosingTx) + internal fun ChannelContext.completeMutualClose(signedClosingTx: ClosingTx): Pair> { + logger.info { "channel was closed with txId=${signedClosingTx.tx.txid}" } + val nextState = Closed( + Closing( + commitments, + waitingSinceBlock = waitingSinceBlock, + mutualCloseProposed = proposedClosingTxs.flatMap { it.all }, + mutualClosePublished = listOf(signedClosingTx) + ) ) val actions = buildList { add(ChannelAction.Storage.StoreState(nextState)) - closingSigned?.let { add(ChannelAction.Message.Send(it)) } - add(ChannelAction.Blockchain.PublishTx(signedClosingTx)) - add(ChannelAction.Blockchain.SendWatch(WatchConfirmed(channelId, signedClosingTx.tx, staticParams.nodeParams.minDepthBlocks.toLong(), BITCOIN_TX_CONFIRMED(signedClosingTx.tx)))) + addAll(emitClosingEvents(this@Negotiating, nextState.state)) + add(ChannelAction.Storage.SetLocked(signedClosingTx.tx.txid)) } return Pair(nextState, actions) } diff --git a/src/commonMain/kotlin/fr/acinq/lightning/channel/states/Normal.kt b/src/commonMain/kotlin/fr/acinq/lightning/channel/states/Normal.kt index 2633b1689..0df63c669 100644 --- a/src/commonMain/kotlin/fr/acinq/lightning/channel/states/Normal.kt +++ b/src/commonMain/kotlin/fr/acinq/lightning/channel/states/Normal.kt @@ -11,6 +11,7 @@ import fr.acinq.lightning.blockchain.BITCOIN_FUNDING_DEPTHOK import fr.acinq.lightning.blockchain.WatchConfirmed import fr.acinq.lightning.blockchain.WatchEventConfirmed import fr.acinq.lightning.blockchain.WatchEventSpent +import fr.acinq.lightning.blockchain.fee.FeeratePerKw import fr.acinq.lightning.channel.* import fr.acinq.lightning.transactions.Scripts import fr.acinq.lightning.transactions.Transactions @@ -24,7 +25,7 @@ data class Normal( val remoteChannelUpdate: ChannelUpdate?, val localShutdown: Shutdown?, val remoteShutdown: Shutdown?, - val closingFeerates: ClosingFeerates?, + val closingFeerate: FeeratePerKw?, val spliceStatus: SpliceStatus, val liquidityLeases: List, ) : ChannelStateWithCommitments() { @@ -101,7 +102,7 @@ data class Normal( !Helpers.Closing.isValidFinalScriptPubkey(localScriptPubkey, allowAnySegwit, allowOpReturn) -> handleCommandError(cmd, InvalidFinalScript(channelId), channelUpdate) else -> { val shutdown = Shutdown(channelId, localScriptPubkey) - val newState = this@Normal.copy(localShutdown = shutdown, closingFeerates = cmd.feerates) + val newState = this@Normal.copy(localShutdown = shutdown, closingFeerate = cmd.feerate) val actions = listOf(ChannelAction.Storage.StoreState(newState), ChannelAction.Message.Send(shutdown)) Pair(newState, actions) } @@ -240,22 +241,28 @@ data class Normal( actions.add(ChannelAction.Message.Send(localShutdown)) if (commitments1.latest.remoteCommit.spec.htlcs.isNotEmpty()) { // we just signed htlcs that need to be resolved now - ShuttingDown(commitments1, localShutdown, remoteShutdown, closingFeerates) + ShuttingDown(commitments1, localShutdown, remoteShutdown, closingFeerate) } else { logger.warning { "we have no htlcs but have not replied with our Shutdown yet, this should never happen" } - val closingTxProposed = if (isInitiator) { - val (closingTx, closingSigned) = Helpers.Closing.makeFirstClosingTx( - channelKeys(), - commitments1.latest, - localShutdown.scriptPubKey.toByteArray(), - remoteShutdown.scriptPubKey.toByteArray(), - closingFeerates ?: ClosingFeerates(currentOnChainFeerates.mutualCloseFeerate), - ) - listOf(listOf(ClosingTxProposed(closingTx, closingSigned))) - } else { - listOf(listOf()) + val closingResult = Helpers.Closing.makeClosingTxs( + channelKeys(), + commitments1.latest, + localShutdown.scriptPubKey, + remoteShutdown.scriptPubKey, + closingFeerate ?: currentOnChainFeerates.mutualCloseFeerate + ) + val proposedClosingTxs = when (closingResult) { + is Either.Left -> { + logger.warning { "cannot create local closing txs, waiting for remote closing_complete: ${closingResult.value.message}" } + listOf() + } + is Either.Right -> { + val (closingTxs, closingComplete) = closingResult.value + actions.add(ChannelAction.Message.Send(closingComplete)) + listOf(closingTxs) + } } - Negotiating(commitments1, localShutdown, remoteShutdown, closingTxProposed, bestUnpublishedClosingTx = null, closingFeerates) + Negotiating(commitments1, localShutdown, remoteShutdown, proposedClosingTxs, listOf(), closingFeerate, currentBlockHeight.toLong()) } } else { this@Normal.copy(commitments = commitments1) @@ -315,33 +322,31 @@ data class Normal( if (this@Normal.localShutdown == null) actions.add(ChannelAction.Message.Send(localShutdown)) val commitments1 = commitments.copy(remoteChannelData = cmd.message.channelData) when { - commitments1.hasNoPendingHtlcsOrFeeUpdate() && commitments1.params.localParams.isInitiator -> { - val (closingTx, closingSigned) = Helpers.Closing.makeFirstClosingTx( + commitments1.hasNoPendingHtlcsOrFeeUpdate() -> { + val closingResult = Helpers.Closing.makeClosingTxs( channelKeys(), commitments1.latest, - localShutdown.scriptPubKey.toByteArray(), - cmd.message.scriptPubKey.toByteArray(), - closingFeerates ?: ClosingFeerates(currentOnChainFeerates.mutualCloseFeerate), - ) - val nextState = Negotiating( - commitments1, - localShutdown, - cmd.message, - listOf(listOf(ClosingTxProposed(closingTx, closingSigned))), - bestUnpublishedClosingTx = null, - closingFeerates + localShutdown.scriptPubKey, + cmd.message.scriptPubKey, + closingFeerate ?: currentOnChainFeerates.mutualCloseFeerate ) - actions.addAll(listOf(ChannelAction.Storage.StoreState(nextState), ChannelAction.Message.Send(closingSigned))) - Pair(nextState, actions) - } - commitments1.hasNoPendingHtlcsOrFeeUpdate() -> { - val nextState = Negotiating(commitments1, localShutdown, cmd.message, listOf(listOf()), null, closingFeerates) + val nextState = when (closingResult) { + is Either.Left -> { + logger.warning { "cannot create local closing txs, waiting for remote closing_complete: ${closingResult.value.message}" } + Negotiating(commitments1, localShutdown, cmd.message, listOf(), listOf(), closingFeerate, currentBlockHeight.toLong()) + } + is Either.Right -> { + val (closingTxs, closingComplete) = closingResult.value + actions.add(ChannelAction.Message.Send(closingComplete)) + Negotiating(commitments1, localShutdown, cmd.message, listOf(closingTxs), listOf(), closingFeerate, currentBlockHeight.toLong()) + } + } actions.add(ChannelAction.Storage.StoreState(nextState)) Pair(nextState, actions) } else -> { // there are some pending changes, we need to wait for them to be settled (fail/fulfill htlcs and sign fee updates) - val nextState = ShuttingDown(commitments1, localShutdown, cmd.message, closingFeerates) + val nextState = ShuttingDown(commitments1, localShutdown, cmd.message, closingFeerate) actions.add(ChannelAction.Storage.StoreState(nextState)) Pair(nextState, actions) } diff --git a/src/commonMain/kotlin/fr/acinq/lightning/channel/states/Offline.kt b/src/commonMain/kotlin/fr/acinq/lightning/channel/states/Offline.kt index 978e12a4f..4a258f27b 100644 --- a/src/commonMain/kotlin/fr/acinq/lightning/channel/states/Offline.kt +++ b/src/commonMain/kotlin/fr/acinq/lightning/channel/states/Offline.kt @@ -56,8 +56,8 @@ data class Offline(val state: PersistedChannelState) : ChannelState() { is ChannelCommand.MessageReceived -> unhandled(cmd) is ChannelCommand.WatchReceived -> when (state) { is ChannelStateWithCommitments -> when (val watch = cmd.watch) { - is WatchEventConfirmed -> { - if (watch.event is BITCOIN_FUNDING_DEPTHOK) { + is WatchEventConfirmed -> when { + watch.event is BITCOIN_FUNDING_DEPTHOK -> { when (val res = state.run { acceptFundingTxConfirmed(watch) }) { is Either.Left -> Pair(this@Offline, listOf()) is Either.Right -> { @@ -75,26 +75,32 @@ data class Offline(val state: PersistedChannelState) : ChannelState() { Pair(this@Offline.copy(state = nextState), actions + listOf(ChannelAction.Storage.StoreState(nextState))) } } - } else { - Pair(this@Offline, listOf()) } + state is Negotiating && state.publishedClosingTxs.any { it.tx.txid == watch.tx.txid } -> { + // One of our published transactions confirmed, the channel is now closed. + state.run { completeMutualClose(publishedClosingTxs.first { it.tx.txid == watch.tx.txid }) } + } + state is Negotiating && state.proposedClosingTxs.flatMap { it.all }.any { it.tx.txid == watch.tx.txid } -> { + // A transaction that we proposed for which they didn't send us their signature was confirmed, the channel is now closed. + state.run { completeMutualClose(getMutualClosePublished(watch.tx)) } + } + else -> Pair(this@Offline, listOf()) } is WatchEventSpent -> when { - state is Negotiating && state.closingTxProposed.flatten().any { it.unsignedTx.tx.txid == watch.tx.txid } -> { - logger.info { "closing tx published: closingTxId=${watch.tx.txid}" } - val closingTx = state.getMutualClosePublished(watch.tx) - val nextState = Closing( - state.commitments, - waitingSinceBlock = currentBlockHeight.toLong(), - mutualCloseProposed = state.closingTxProposed.flatten().map { it.unsignedTx }, - mutualClosePublished = listOf(closingTx) - ) + state is Negotiating && state.publishedClosingTxs.any { it.tx.txid == watch.tx.txid } -> { + // This is one of the transactions we already published, we have nothing to do. + Pair(this@Offline, listOf()) + } + state is Negotiating && state.proposedClosingTxs.flatMap { it.all }.any { it.tx.txid == watch.tx.txid } -> { + // They published one of our closing transactions without sending us their signature. + val closingTx = state.run { getMutualClosePublished(watch.tx) } + val nextState = state.copy(publishedClosingTxs = state.publishedClosingTxs + closingTx) val actions = listOf( ChannelAction.Storage.StoreState(nextState), ChannelAction.Blockchain.PublishTx(closingTx), ChannelAction.Blockchain.SendWatch(WatchConfirmed(channelId, watch.tx, staticParams.nodeParams.minDepthBlocks.toLong(), BITCOIN_TX_CONFIRMED(watch.tx))) ) - Pair(nextState, actions) + Pair(Offline(nextState), actions) } else -> { val (nextState, actions) = state.run { handlePotentialForceClose(watch) } diff --git a/src/commonMain/kotlin/fr/acinq/lightning/channel/states/ShuttingDown.kt b/src/commonMain/kotlin/fr/acinq/lightning/channel/states/ShuttingDown.kt index b9bb26da7..88dbb935e 100644 --- a/src/commonMain/kotlin/fr/acinq/lightning/channel/states/ShuttingDown.kt +++ b/src/commonMain/kotlin/fr/acinq/lightning/channel/states/ShuttingDown.kt @@ -3,6 +3,7 @@ package fr.acinq.lightning.channel.states import fr.acinq.bitcoin.utils.Either import fr.acinq.lightning.blockchain.WatchEventConfirmed import fr.acinq.lightning.blockchain.WatchEventSpent +import fr.acinq.lightning.blockchain.fee.FeeratePerKw import fr.acinq.lightning.channel.* import fr.acinq.lightning.transactions.Transactions import fr.acinq.lightning.wire.* @@ -11,10 +12,12 @@ data class ShuttingDown( override val commitments: Commitments, val localShutdown: Shutdown, val remoteShutdown: Shutdown, - val closingFeerates: ClosingFeerates? + val closingFeerate: FeeratePerKw? ) : ChannelStateWithCommitments() { override fun updateCommitments(input: Commitments): ChannelStateWithCommitments = this.copy(commitments = input) + private fun ChannelContext.closingFeerate(): FeeratePerKw = closingFeerate ?: currentOnChainFeerates.mutualCloseFeerate + override fun ChannelContext.processInternal(cmd: ChannelCommand): Pair> { return when (cmd) { is ChannelCommand.MessageReceived -> { @@ -45,33 +48,35 @@ data class ShuttingDown( is Either.Right -> { val (commitments1, revocation) = result.value when { - commitments1.hasNoPendingHtlcsOrFeeUpdate() && commitments1.params.localParams.isInitiator -> { - val (closingTx, closingSigned) = Helpers.Closing.makeFirstClosingTx( + commitments1.hasNoPendingHtlcsOrFeeUpdate() -> { + val closingResult = Helpers.Closing.makeClosingTxs( channelKeys(), commitments1.latest, - localShutdown.scriptPubKey.toByteArray(), - remoteShutdown.scriptPubKey.toByteArray(), - closingFeerates ?: ClosingFeerates(currentOnChainFeerates.mutualCloseFeerate) - ) - val nextState = Negotiating( - commitments1, - localShutdown, - remoteShutdown, - listOf(listOf(ClosingTxProposed(closingTx, closingSigned))), - bestUnpublishedClosingTx = null, - closingFeerates - ) - val actions = listOf( - ChannelAction.Storage.StoreState(nextState), - ChannelAction.Message.Send(revocation), - ChannelAction.Message.Send(closingSigned) + localShutdown.scriptPubKey, + remoteShutdown.scriptPubKey, + closingFeerate() ) - Pair(nextState, actions) - } - commitments1.hasNoPendingHtlcsOrFeeUpdate() -> { - val nextState = Negotiating(commitments1, localShutdown, remoteShutdown, listOf(listOf()), null, closingFeerates) - val actions = listOf(ChannelAction.Storage.StoreState(nextState), ChannelAction.Message.Send(revocation)) - Pair(nextState, actions) + when (closingResult) { + is Either.Left -> { + logger.warning { "cannot create local closing txs, waiting for remote closing_complete: ${closingResult.value.message}" } + val nextState = Negotiating(commitments1, localShutdown, remoteShutdown, listOf(), listOf(), closingFeerate, currentBlockHeight.toLong()) + val actions = listOf( + ChannelAction.Storage.StoreState(nextState), + ChannelAction.Message.Send(revocation), + ) + Pair(nextState, actions) + } + is Either.Right -> { + val (closingTxs, closingComplete) = closingResult.value + val nextState = Negotiating(commitments1, localShutdown, remoteShutdown, listOf(closingTxs), listOf(), closingFeerate, currentBlockHeight.toLong()) + val actions = listOf( + ChannelAction.Storage.StoreState(nextState), + ChannelAction.Message.Send(revocation), + ChannelAction.Message.Send(closingComplete) + ) + Pair(nextState, actions) + } + } } else -> { val nextState = this@ShuttingDown.copy(commitments = commitments1) @@ -93,29 +98,28 @@ data class ShuttingDown( val (commitments1, actions) = result.value val actions1 = actions.toMutableList() when { - commitments1.hasNoPendingHtlcsOrFeeUpdate() && commitments1.params.localParams.isInitiator -> { - val (closingTx, closingSigned) = Helpers.Closing.makeFirstClosingTx( + commitments1.hasNoPendingHtlcsOrFeeUpdate() -> { + val closingResult = Helpers.Closing.makeClosingTxs( channelKeys(), commitments1.latest, - localShutdown.scriptPubKey.toByteArray(), - remoteShutdown.scriptPubKey.toByteArray(), - closingFeerates ?: ClosingFeerates(currentOnChainFeerates.mutualCloseFeerate) - ) - val nextState = Negotiating( - commitments1, - localShutdown, - remoteShutdown, - listOf(listOf(ClosingTxProposed(closingTx, closingSigned))), - bestUnpublishedClosingTx = null, - closingFeerates + localShutdown.scriptPubKey, + remoteShutdown.scriptPubKey, + closingFeerate() ) - actions1.addAll(listOf(ChannelAction.Storage.StoreState(nextState), ChannelAction.Message.Send(closingSigned))) - Pair(nextState, actions1) - } - commitments1.hasNoPendingHtlcsOrFeeUpdate() -> { - val nextState = Negotiating(commitments1, localShutdown, remoteShutdown, listOf(listOf()), null, closingFeerates) - actions1.add(ChannelAction.Storage.StoreState(nextState)) - Pair(nextState, actions1) + when (closingResult) { + is Either.Left -> { + logger.warning { "cannot create local closing txs, waiting for remote closing_complete: ${closingResult.value.message}" } + val nextState = Negotiating(commitments1, localShutdown, remoteShutdown, listOf(), listOf(), closingFeerate, currentBlockHeight.toLong()) + actions1.add(ChannelAction.Storage.StoreState(nextState)) + Pair(nextState, actions1) + } + is Either.Right -> { + val (closingTxs, closingComplete) = closingResult.value + val nextState = Negotiating(commitments1, localShutdown, remoteShutdown, listOf(closingTxs), listOf(), closingFeerate, currentBlockHeight.toLong()) + actions1.addAll(listOf(ChannelAction.Storage.StoreState(nextState), ChannelAction.Message.Send(closingComplete))) + Pair(nextState, actions1) + } + } } else -> { val nextState = this@ShuttingDown.copy(commitments = commitments1) @@ -128,6 +132,16 @@ data class ShuttingDown( } } } + is Shutdown -> { + if (cmd.message.scriptPubKey != remoteShutdown.scriptPubKey) { + logger.debug { "our peer updated their shutdown script (previous=${remoteShutdown.scriptPubKey}, current=${cmd.message.scriptPubKey})" } + val nextState = this@ShuttingDown.copy(remoteShutdown = cmd.message) + Pair(nextState, listOf(ChannelAction.Storage.StoreState(nextState))) + } else { + // This is a retransmission of their previous shutdown, we can ignore it. + Pair(this@ShuttingDown, listOf()) + } + } is Error -> { handleRemoteError(cmd.message) } @@ -174,7 +188,30 @@ data class ShuttingDown( is ChannelCommand.Htlc.Settlement.Fail -> handleCommandResult(cmd, commitments.sendFail(cmd, staticParams.nodeParams.nodePrivateKey), cmd.commit) is ChannelCommand.Htlc.Settlement.FailMalformed -> handleCommandResult(cmd, commitments.sendFailMalformed(cmd), cmd.commit) is ChannelCommand.Commitment.UpdateFee -> handleCommandResult(cmd, commitments.sendFee(cmd), cmd.commit) - is ChannelCommand.Close.MutualClose -> handleCommandError(cmd, ClosingAlreadyInProgress(channelId)) + is ChannelCommand.Close.MutualClose -> { + // We may be updating our closing script or feerate. + when (cmd.scriptPubKey) { + null -> when (cmd.feerate) { + null -> Pair(this@ShuttingDown, listOf()) + else -> { + val nextState = this@ShuttingDown.copy(closingFeerate = cmd.feerate) + Pair(nextState, listOf(ChannelAction.Storage.StoreState(nextState))) + } + } + else -> { + val localShutdown1 = localShutdown.copy(scriptPubKey = cmd.scriptPubKey) + val nextState = when (cmd.feerate) { + null -> this@ShuttingDown.copy(localShutdown = localShutdown1) + else -> this@ShuttingDown.copy(localShutdown = localShutdown1, closingFeerate = cmd.feerate) + } + val actions = listOf( + ChannelAction.Storage.StoreState(nextState), + ChannelAction.Message.Send(localShutdown1), + ) + Pair(nextState, actions) + } + } + } is ChannelCommand.Close.ForceClose -> handleLocalError(cmd, ForcedLocalCommit(channelId)) is ChannelCommand.WatchReceived -> when (val watch = cmd.watch) { is WatchEventConfirmed -> updateFundingTxStatus(watch) diff --git a/src/commonMain/kotlin/fr/acinq/lightning/channel/states/Syncing.kt b/src/commonMain/kotlin/fr/acinq/lightning/channel/states/Syncing.kt index c95250824..ae1c0d8d4 100644 --- a/src/commonMain/kotlin/fr/acinq/lightning/channel/states/Syncing.kt +++ b/src/commonMain/kotlin/fr/acinq/lightning/channel/states/Syncing.kt @@ -235,36 +235,9 @@ data class Syncing(val state: PersistedChannelState, val channelReestablishSent: } } } - // BOLT 2: A node if it has sent a previous shutdown MUST retransmit shutdown. - // negotiation restarts from the beginning, and is initialized by the initiator - // note: in any case we still need to keep all previously sent closing_signed, because they may publish one of them - state is Negotiating && state.commitments.params.localParams.isInitiator -> { - // we could use the last closing_signed we sent, but network fees may have changed while we were offline so it is better to restart from scratch - val (closingTx, closingSigned) = Helpers.Closing.makeFirstClosingTx( - channelKeys(), - state.commitments.latest, - state.localShutdown.scriptPubKey.toByteArray(), - state.remoteShutdown.scriptPubKey.toByteArray(), - state.closingFeerates ?: ClosingFeerates(currentOnChainFeerates.mutualCloseFeerate) - ) - val closingTxProposed1 = state.closingTxProposed + listOf(listOf(ClosingTxProposed(closingTx, closingSigned))) - val nextState = state.copy(closingTxProposed = closingTxProposed1) - val actions = listOf( - ChannelAction.Storage.StoreState(nextState), - ChannelAction.Message.Send(state.localShutdown), - ChannelAction.Message.Send(closingSigned) - ) - return Pair(nextState, actions) - } state is Negotiating -> { - // we start a new round of negotiation - val closingTxProposed1 = if (state.closingTxProposed.last().isEmpty()) state.closingTxProposed else state.closingTxProposed + listOf(listOf()) - val nextState = state.copy(closingTxProposed = closingTxProposed1) - val actions = listOf( - ChannelAction.Storage.StoreState(nextState), - ChannelAction.Message.Send(state.localShutdown) - ) - return Pair(nextState, actions) + // BOLT 2: A node if it has sent a previous shutdown MUST retransmit shutdown. + return Pair(this@Syncing, listOf(ChannelAction.Message.Send(state.localShutdown))) } else -> unhandled(cmd) } @@ -282,21 +255,20 @@ data class Syncing(val state: PersistedChannelState, val channelReestablishSent: is ChannelCommand.WatchReceived -> when (state) { is ChannelStateWithCommitments -> when (val watch = cmd.watch) { is WatchEventSpent -> when { - state is Negotiating && state.closingTxProposed.flatten().any { it.unsignedTx.tx.txid == watch.tx.txid } -> { - logger.info { "closing tx published: closingTxId=${watch.tx.txid}" } - val closingTx = state.getMutualClosePublished(watch.tx) - val nextState = Closing( - state.commitments, - waitingSinceBlock = currentBlockHeight.toLong(), - mutualCloseProposed = state.closingTxProposed.flatten().map { it.unsignedTx }, - mutualClosePublished = listOf(closingTx) - ) + state is Negotiating && state.publishedClosingTxs.any { it.tx.txid == watch.tx.txid } -> { + // This is one of the transactions we already published, we have nothing to do. + Pair(this@Syncing, listOf()) + } + state is Negotiating && state.proposedClosingTxs.flatMap { it.all }.any { it.tx.txid == watch.tx.txid } -> { + // They published one of our closing transactions without sending us their signature. + val closingTx = state.run { getMutualClosePublished(watch.tx) } + val nextState = state.copy(publishedClosingTxs = state.publishedClosingTxs + closingTx) val actions = listOf( ChannelAction.Storage.StoreState(nextState), ChannelAction.Blockchain.PublishTx(closingTx), ChannelAction.Blockchain.SendWatch(WatchConfirmed(channelId, watch.tx, staticParams.nodeParams.minDepthBlocks.toLong(), BITCOIN_TX_CONFIRMED(watch.tx))) ) - Pair(nextState, actions) + Pair(this@Syncing.copy(state = nextState), actions) } else -> { val (nextState, actions) = state.run { handlePotentialForceClose(watch) } @@ -307,8 +279,8 @@ data class Syncing(val state: PersistedChannelState, val channelReestablishSent: } } } - is WatchEventConfirmed -> { - if (watch.event is BITCOIN_FUNDING_DEPTHOK) { + is WatchEventConfirmed -> when { + watch.event is BITCOIN_FUNDING_DEPTHOK -> { when (val res = state.run { acceptFundingTxConfirmed(watch) }) { is Either.Left -> Pair(this@Syncing, listOf()) is Either.Right -> { @@ -326,9 +298,16 @@ data class Syncing(val state: PersistedChannelState, val channelReestablishSent: Pair(this@Syncing.copy(state = nextState), actions + listOf(ChannelAction.Storage.StoreState(nextState))) } } - } else { - Pair(this@Syncing, listOf()) } + state is Negotiating && state.publishedClosingTxs.any { it.tx.txid == watch.tx.txid } -> { + // One of our published transactions confirmed, the channel is now closed. + state.run { completeMutualClose(publishedClosingTxs.first { it.tx.txid == watch.tx.txid }) } + } + state is Negotiating && state.proposedClosingTxs.flatMap { it.all }.any { it.tx.txid == watch.tx.txid } -> { + // A transaction that we proposed for which they didn't send us their signature was confirmed, the channel is now closed. + state.run { completeMutualClose(getMutualClosePublished(watch.tx)) } + } + else -> Pair(this@Syncing, listOf()) } } is WaitForFundingSigned -> Pair(this@Syncing, listOf()) diff --git a/src/commonMain/kotlin/fr/acinq/lightning/json/JsonSerializers.kt b/src/commonMain/kotlin/fr/acinq/lightning/json/JsonSerializers.kt index 8852a8f35..daa004baf 100644 --- a/src/commonMain/kotlin/fr/acinq/lightning/json/JsonSerializers.kt +++ b/src/commonMain/kotlin/fr/acinq/lightning/json/JsonSerializers.kt @@ -7,7 +7,6 @@ // serialization code in this file. JsonSerializers.CommitmentSerializer::class, JsonSerializers.CommitmentsSerializer::class, - JsonSerializers.ClosingFeeratesSerializer::class, JsonSerializers.LocalParamsSerializer::class, JsonSerializers.RemoteParamsSerializer::class, JsonSerializers.LocalCommitSerializer::class, @@ -41,7 +40,6 @@ JsonSerializers.TransactionSerializer::class, JsonSerializers.OutPointSerializer::class, JsonSerializers.TxOutSerializer::class, - JsonSerializers.ClosingTxProposedSerializer::class, JsonSerializers.LocalCommitPublishedSerializer::class, JsonSerializers.RemoteCommitPublishedSerializer::class, JsonSerializers.RevokedCommitPublishedSerializer::class, @@ -70,7 +68,8 @@ JsonSerializers.LocalFundingStatusSerializer::class, JsonSerializers.RemoteFundingStatusSerializer::class, JsonSerializers.ShutdownSerializer::class, - JsonSerializers.ClosingSignedSerializer::class, + JsonSerializers.ClosingCompleteSerializer::class, + JsonSerializers.ClosingSigSerializer::class, JsonSerializers.UpdateAddHtlcSerializer::class, JsonSerializers.CommitSigSerializer::class, JsonSerializers.EncryptedChannelDataSerializer::class, @@ -78,12 +77,12 @@ JsonSerializers.FundingCreatedSerializer::class, JsonSerializers.ChannelReadySerializer::class, JsonSerializers.ChannelReadyTlvShortChannelIdTlvSerializer::class, - JsonSerializers.ClosingSignedTlvFeeRangeSerializer::class, JsonSerializers.ShutdownTlvChannelDataSerializer::class, JsonSerializers.GenericTlvSerializer::class, JsonSerializers.TlvStreamSerializer::class, JsonSerializers.ShutdownTlvSerializer::class, - JsonSerializers.ClosingSignedTlvSerializer::class, + JsonSerializers.ClosingCompleteTlvSerializer::class, + JsonSerializers.ClosingSigTlvSerializer::class, JsonSerializers.ChannelReestablishTlvSerializer::class, JsonSerializers.ChannelReadyTlvSerializer::class, JsonSerializers.CommitSigTlvAlternativeFeerateSigSerializer::class, @@ -196,7 +195,6 @@ object JsonSerializers { subclass(CommitSigTlv.AlternativeFeerateSigs::class, CommitSigTlvAlternativeFeerateSigsSerializer) subclass(CommitSigTlv.Batch::class, CommitSigTlvBatchSerializer) subclass(ShutdownTlv.ChannelData::class, ShutdownTlvChannelDataSerializer) - subclass(ClosingSignedTlv.FeeRange::class, ClosingSignedTlvFeeRangeSerializer) } // TODO The following declarations are required because serializers for [TransactionWithInputInfo] // depend themselves on @Contextual serializers. Once we get rid of v2/v3 serialization and we @@ -333,9 +331,6 @@ object JsonSerializers { @Serializer(forClass = Commitments::class) object CommitmentsSerializer - @Serializer(forClass = ClosingFeerates::class) - object ClosingFeeratesSerializer - @Serializer(forClass = LocalParams::class) object LocalParamsSerializer @@ -439,9 +434,6 @@ object JsonSerializers { delegateSerializer = KeyPathSerializer ) - @Serializer(forClass = ClosingTxProposed::class) - object ClosingTxProposedSerializer - @Serializer(forClass = LocalCommitPublished::class) object LocalCommitPublishedSerializer @@ -481,8 +473,11 @@ object JsonSerializers { @Serializer(forClass = Shutdown::class) object ShutdownSerializer - @Serializer(forClass = ClosingSigned::class) - object ClosingSignedSerializer + @Serializer(forClass = ClosingComplete::class) + object ClosingCompleteSerializer + + @Serializer(forClass = ClosingSig::class) + object ClosingSigSerializer @Serializer(forClass = CommitSig::class) object CommitSigSerializer @@ -499,9 +494,6 @@ object JsonSerializers { @Serializer(forClass = ChannelReadyTlv.ShortChannelIdTlv::class) object ChannelReadyTlvShortChannelIdTlvSerializer - @Serializer(forClass = ClosingSignedTlv.FeeRange::class) - object ClosingSignedTlvFeeRangeSerializer - @Serializer(forClass = ShutdownTlv.ChannelData::class) object ShutdownTlvChannelDataSerializer @@ -520,8 +512,11 @@ object JsonSerializers { @Serializer(forClass = CommitSigTlv::class) object CommitSigTlvSerializer - @Serializer(forClass = ClosingSignedTlv::class) - object ClosingSignedTlvSerializer + @Serializer(forClass = ClosingCompleteTlv::class) + object ClosingCompleteTlvSerializer + + @Serializer(forClass = ClosingSigTlv::class) + object ClosingSigTlvSerializer @Serializer(forClass = ChannelReadyTlv::class) object ChannelReadyTlvSerializer diff --git a/src/commonMain/kotlin/fr/acinq/lightning/serialization/v2/ChannelState.kt b/src/commonMain/kotlin/fr/acinq/lightning/serialization/v2/ChannelState.kt index 5e4a7c017..08ec2a952 100644 --- a/src/commonMain/kotlin/fr/acinq/lightning/serialization/v2/ChannelState.kt +++ b/src/commonMain/kotlin/fr/acinq/lightning/serialization/v2/ChannelState.kt @@ -14,7 +14,8 @@ PublicKeyKSerializer::class, PrivateKeyKSerializer::class, ShutdownSerializer::class, - ClosingSignedSerializer::class, + ClosingCompleteSerializer::class, + ClosingSigSerializer::class, SatoshiKSerializer::class, UpdateAddHtlcSerializer::class, CommitSigSerializer::class, @@ -23,7 +24,8 @@ FundingCreatedSerializer::class, CommitSigTlvSerializer::class, ShutdownTlvSerializer::class, - ClosingSignedTlvSerializer::class, + ClosingCompleteTlvSerializer::class, + ClosingSigTlvSerializer::class, ChannelReadyTlvSerializer::class, ChannelReestablishTlvSerializer::class, TlvStreamSerializer::class, @@ -67,8 +69,11 @@ object FundingSignedSerializer @Serializer(forClass = Shutdown::class) object ShutdownSerializer -@Serializer(forClass = ClosingSigned::class) -object ClosingSignedSerializer +@Serializer(forClass = ClosingComplete::class) +object ClosingCompleteSerializer + +@Serializer(forClass = ClosingSig::class) +object ClosingSigSerializer @Serializer(forClass = ChannelUpdate::class) object ChannelUpdateSerializer @@ -112,9 +117,6 @@ object FundingCreatedSerializer @Serializer(forClass = ChannelReadyTlv.ShortChannelIdTlv::class) object ChannelReadyTlvShortChannelIdTlvSerializer -@Serializer(forClass = ClosingSignedTlv.FeeRange::class) -object ClosingSignedTlvFeeRangeSerializer - @Serializer(forClass = ShutdownTlv.ChannelData::class) object ShutdownTlvChannelDataSerializer @@ -124,8 +126,11 @@ object ShutdownTlvSerializer @Serializer(forClass = CommitSigTlv::class) object CommitSigTlvSerializer -@Serializer(forClass = ClosingSignedTlv::class) -object ClosingSignedTlvSerializer +@Serializer(forClass = ClosingCompleteTlv::class) +object ClosingCompleteTlvSerializer + +@Serializer(forClass = ClosingSigTlv::class) +object ClosingSigTlvSerializer @Serializer(forClass = ChannelReadyTlv::class) object ChannelReadyTlvSerializer @@ -358,9 +363,10 @@ internal data class ChannelVersion(val bits: ByteVector) { } @Serializable -internal data class ClosingTxProposed(val unsignedTx: Transactions.TransactionWithInputInfo.ClosingTx, val localClosingSigned: ClosingSigned) { - fun export() = fr.acinq.lightning.channel.ClosingTxProposed(unsignedTx, localClosingSigned) -} +internal data class ClosingSigned(val channelId: ByteVector32, val feeSatoshis: Satoshi, val signature: ByteVector64) + +@Serializable +internal data class ClosingTxProposed(val unsignedTx: Transactions.TransactionWithInputInfo.ClosingTx, val localClosingSigned: ClosingSigned) @Serializable internal data class Commitments( @@ -553,9 +559,10 @@ internal data class Negotiating( commitments.export(), localShutdown, remoteShutdown, - closingTxProposed.map { x -> x.map { it.export() } }, - bestUnpublishedClosingTx, - null + listOf(), + listOf(), + null, + 0 ) } diff --git a/src/commonMain/kotlin/fr/acinq/lightning/serialization/v2/Serialization.kt b/src/commonMain/kotlin/fr/acinq/lightning/serialization/v2/Serialization.kt index 7099fc9c3..ec4e25460 100644 --- a/src/commonMain/kotlin/fr/acinq/lightning/serialization/v2/Serialization.kt +++ b/src/commonMain/kotlin/fr/acinq/lightning/serialization/v2/Serialization.kt @@ -44,7 +44,6 @@ object Serialization { private val tlvSerializersModule = SerializersModule { polymorphic(Tlv::class) { subclass(ChannelReadyTlvShortChannelIdTlvSerializer) - subclass(ClosingSignedTlvFeeRangeSerializer) subclass(ShutdownTlvChannelDataSerializer) subclass(GenericTlvSerializer) } diff --git a/src/commonMain/kotlin/fr/acinq/lightning/serialization/v3/ChannelState.kt b/src/commonMain/kotlin/fr/acinq/lightning/serialization/v3/ChannelState.kt index a22d32396..9efb104b6 100644 --- a/src/commonMain/kotlin/fr/acinq/lightning/serialization/v3/ChannelState.kt +++ b/src/commonMain/kotlin/fr/acinq/lightning/serialization/v3/ChannelState.kt @@ -14,7 +14,8 @@ PublicKeyKSerializer::class, PrivateKeyKSerializer::class, ShutdownSerializer::class, - ClosingSignedSerializer::class, + ClosingCompleteSerializer::class, + ClosingSigSerializer::class, SatoshiKSerializer::class, UpdateAddHtlcSerializer::class, CommitSigSerializer::class, @@ -23,7 +24,8 @@ FundingCreatedSerializer::class, CommitSigTlvSerializer::class, ShutdownTlvSerializer::class, - ClosingSignedTlvSerializer::class, + ClosingCompleteTlvSerializer::class, + ClosingSigTlvSerializer::class, ChannelReadyTlvSerializer::class, ChannelReestablishTlvSerializer::class, TlvStreamSerializer::class, @@ -41,7 +43,10 @@ package fr.acinq.lightning.serialization.v3 import fr.acinq.bitcoin.* import fr.acinq.bitcoin.utils.Either -import fr.acinq.lightning.* +import fr.acinq.lightning.CltvExpiryDelta +import fr.acinq.lightning.Features +import fr.acinq.lightning.MilliSatoshi +import fr.acinq.lightning.ShortChannelId import fr.acinq.lightning.blockchain.fee.FeeratePerKw import fr.acinq.lightning.channel.InteractiveTxOutput import fr.acinq.lightning.channel.SpliceStatus @@ -67,8 +72,11 @@ object FundingSignedSerializer @Serializer(forClass = Shutdown::class) object ShutdownSerializer -@Serializer(forClass = ClosingSigned::class) -object ClosingSignedSerializer +@Serializer(forClass = ClosingComplete::class) +object ClosingCompleteSerializer + +@Serializer(forClass = ClosingSig::class) +object ClosingSigSerializer @Serializer(forClass = ChannelUpdate::class) object ChannelUpdateSerializer @@ -112,9 +120,6 @@ object FundingCreatedSerializer @Serializer(forClass = ChannelReadyTlv.ShortChannelIdTlv::class) object ChannelReadyTlvShortChannelIdTlvSerializer -@Serializer(forClass = ClosingSignedTlv.FeeRange::class) -object ClosingSignedTlvFeeRangeSerializer - @Serializer(forClass = ShutdownTlv.ChannelData::class) object ShutdownTlvChannelDataSerializer @@ -124,8 +129,11 @@ object ShutdownTlvSerializer @Serializer(forClass = CommitSigTlv::class) object CommitSigTlvSerializer -@Serializer(forClass = ClosingSignedTlv::class) -object ClosingSignedTlvSerializer +@Serializer(forClass = ClosingCompleteTlv::class) +object ClosingCompleteTlvSerializer + +@Serializer(forClass = ClosingSigTlv::class) +object ClosingSigTlvSerializer @Serializer(forClass = ChannelReadyTlv::class) object ChannelReadyTlvSerializer @@ -345,14 +353,13 @@ internal data class ChannelFeatures(val bin: ByteVector) { } @Serializable -internal data class ClosingFeerates(val preferred: FeeratePerKw, val min: FeeratePerKw, val max: FeeratePerKw) { - fun export() = fr.acinq.lightning.channel.states.ClosingFeerates(preferred, min, max) -} +internal data class ClosingSigned(val channelId: ByteVector32, val feeSatoshis: Satoshi, val signature: ByteVector64) @Serializable -internal data class ClosingTxProposed(val unsignedTx: Transactions.TransactionWithInputInfo.ClosingTx, val localClosingSigned: ClosingSigned) { - fun export() = fr.acinq.lightning.channel.ClosingTxProposed(unsignedTx, localClosingSigned) -} +internal data class ClosingFeerates(val preferred: FeeratePerKw, val min: FeeratePerKw, val max: FeeratePerKw) + +@Serializable +internal data class ClosingTxProposed(val unsignedTx: Transactions.TransactionWithInputInfo.ClosingTx, val localClosingSigned: ClosingSigned) @Serializable internal data class Commitments( @@ -397,7 +404,15 @@ internal data class Commitments( // We will put a WatchConfirmed when starting, which will return the confirmed transaction. fr.acinq.lightning.channel.LocalFundingStatus.UnconfirmedFundingTx( fr.acinq.lightning.channel.PartiallySignedSharedTransaction( - fr.acinq.lightning.channel.SharedTransaction(null, InteractiveTxOutput.Shared(0, commitInput.txOut.publicKeyScript, localCommit.spec.toLocal, localCommit.spec.toRemote, 0.msat), listOf(), listOf(), listOf(), listOf(), 0), + fr.acinq.lightning.channel.SharedTransaction( + null, + InteractiveTxOutput.Shared(0, commitInput.txOut.publicKeyScript, localCommit.spec.toLocal, localCommit.spec.toRemote, 0.msat), + listOf(), + listOf(), + listOf(), + listOf(), + 0 + ), // We must correctly set the txId here. TxSignatures(channelId, commitInput.outPoint.txid, listOf()), ), @@ -512,7 +527,7 @@ internal data class Normal( remoteChannelUpdate, localShutdown, remoteShutdown, - closingFeerates?.export(), + closingFeerates?.preferred, SpliceStatus.None, listOf(), ) @@ -532,7 +547,7 @@ internal data class ShuttingDown( commitments.export(), localShutdown, remoteShutdown, - closingFeerates?.export() + closingFeerates?.preferred ) } @@ -557,9 +572,10 @@ internal data class Negotiating( commitments.export(), localShutdown, remoteShutdown, - closingTxProposed.map { x -> x.map { it.export() } }, - bestUnpublishedClosingTx, - closingFeerates?.export() + listOf(), + listOf(), + closingFeerates?.preferred, + 0 ) } diff --git a/src/commonMain/kotlin/fr/acinq/lightning/serialization/v3/Serialization.kt b/src/commonMain/kotlin/fr/acinq/lightning/serialization/v3/Serialization.kt index 6df2513f3..34a20fb20 100644 --- a/src/commonMain/kotlin/fr/acinq/lightning/serialization/v3/Serialization.kt +++ b/src/commonMain/kotlin/fr/acinq/lightning/serialization/v3/Serialization.kt @@ -44,7 +44,6 @@ object Serialization { private val tlvSerializersModule = SerializersModule { polymorphic(Tlv::class) { subclass(ChannelReadyTlvShortChannelIdTlvSerializer) - subclass(ClosingSignedTlvFeeRangeSerializer) subclass(ShutdownTlvChannelDataSerializer) subclass(GenericTlvSerializer) } diff --git a/src/commonMain/kotlin/fr/acinq/lightning/serialization/v4/Deserialization.kt b/src/commonMain/kotlin/fr/acinq/lightning/serialization/v4/Deserialization.kt index d7d5ff33a..f9d17886e 100644 --- a/src/commonMain/kotlin/fr/acinq/lightning/serialization/v4/Deserialization.kt +++ b/src/commonMain/kotlin/fr/acinq/lightning/serialization/v4/Deserialization.kt @@ -32,13 +32,16 @@ object Deserialization { 0x09 -> readLegacyWaitForFundingLocked() 0x00 -> readWaitForFundingConfirmed() 0x01 -> readWaitForChannelReady() - 0x02 -> readNormal() - 0x03 -> readShuttingDown() - 0x04 -> readNegotiating() + 0x02 -> readNormal02() + 0x03 -> readShuttingDown03() + 0x04 -> readNegotiating04() 0x05 -> readClosing() 0x06 -> readWaitForRemotePublishFutureCommitment() 0x07 -> readClosed() 0x0a -> readWaitForFundingSigned() + 0x0b -> readNormal() + 0x0c -> readShuttingDown() + 0x0d -> readNegotiating() else -> error("unknown discriminator $discriminator for class ${PersistedChannelState::class}") } @@ -87,6 +90,37 @@ object Deserialization { lastSent = readLightningMessage() as ChannelReady ) + private fun Input.readNormal02(): Normal = Normal( + commitments = readCommitments(), + shortChannelId = ShortChannelId(readNumber()), + channelUpdate = readLightningMessage() as ChannelUpdate, + remoteChannelUpdate = readNullable { readLightningMessage() as ChannelUpdate }, + localShutdown = readNullable { readLightningMessage() as Shutdown }, + remoteShutdown = readNullable { readLightningMessage() as Shutdown }, + closingFeerate = readNullable { + // We used to store three closing feerates for fee range negotiation. + val preferred = FeeratePerKw(readNumber().sat) + readNumber() + readNumber() + preferred + }, + spliceStatus = when (val discriminator = read()) { + 0x00 -> SpliceStatus.None + 0x01 -> SpliceStatus.WaitingForSigs( + session = readInteractiveTxSigningSession(), + origins = readCollection { readChannelOrigin() as Origin.PayToOpenOrigin }.toList() + ) + else -> error("unknown discriminator $discriminator for class ${SpliceStatus::class}") + }, + liquidityLeases = when { + availableBytes == 0 -> listOf() + else -> when (val discriminator = read()) { + 0x01 -> readCollection { readLiquidityLease() }.toList() + else -> error("unknown discriminator $discriminator for class ${Normal::class}") + } + } + ) + private fun Input.readNormal(): Normal = Normal( commitments = readCommitments(), shortChannelId = ShortChannelId(readNumber()), @@ -94,7 +128,7 @@ object Deserialization { remoteChannelUpdate = readNullable { readLightningMessage() as ChannelUpdate }, localShutdown = readNullable { readLightningMessage() as Shutdown }, remoteShutdown = readNullable { readLightningMessage() as Shutdown }, - closingFeerates = readNullable { readClosingFeerates() }, + closingFeerate = readNullable { FeeratePerKw(readNumber().sat) }, spliceStatus = when (val discriminator = read()) { 0x00 -> SpliceStatus.None 0x01 -> SpliceStatus.WaitingForSigs( @@ -112,27 +146,56 @@ object Deserialization { } ) - private fun Input.readShuttingDown(): ShuttingDown = ShuttingDown( + private fun Input.readShuttingDown03(): ShuttingDown = ShuttingDown( commitments = readCommitments(), localShutdown = readLightningMessage() as Shutdown, remoteShutdown = readLightningMessage() as Shutdown, - closingFeerates = readNullable { readClosingFeerates() } + closingFeerate = readNullable { + // We used to store three closing feerates for fee range negotiation. + val preferred = FeeratePerKw(readNumber().sat) + readNumber() + readNumber() + preferred + } ) - private fun Input.readNegotiating(): Negotiating = Negotiating( + private fun Input.readShuttingDown(): ShuttingDown = ShuttingDown( commitments = readCommitments(), localShutdown = readLightningMessage() as Shutdown, remoteShutdown = readLightningMessage() as Shutdown, - closingTxProposed = readCollection { + closingFeerate = readNullable { FeeratePerKw(readNumber().sat) } + ) + + private fun Input.readNegotiating04(): Negotiating { + val commitments = readCommitments() + val localShutdown = readLightningMessage() as Shutdown + val remoteShutdown = readLightningMessage() as Shutdown + // We cannot convert the closing transactions created with the old closing protocol to the new one. + // We simply ignore them, which will lead to a force-close if one of the proposed transactions is published. + readCollection { readCollection { - ClosingTxProposed( - unsignedTx = readTransactionWithInputInfo() as ClosingTx, - localClosingSigned = readLightningMessage() as ClosingSigned - ) + readTransactionWithInputInfo() // unsigned closing tx + readDelimitedByteArray() // closing_signed message }.toList() + }.toList() + val bestUnpublishedClosingTx = readNullable { readTransactionWithInputInfo() as ClosingTx } + return Negotiating(commitments, localShutdown, remoteShutdown, listOf(), listOfNotNull(bestUnpublishedClosingTx), closingFeerate = null, waitingSinceBlock = 0) + } + + private fun Input.readNegotiating(): Negotiating = Negotiating( + commitments = readCommitments(), + localShutdown = readLightningMessage() as Shutdown, + remoteShutdown = readLightningMessage() as Shutdown, + proposedClosingTxs = readCollection { + Transactions.ClosingTxs( + readNullable { readTransactionWithInputInfo() as ClosingTx }, + readNullable { readTransactionWithInputInfo() as ClosingTx }, + readNullable { readTransactionWithInputInfo() as ClosingTx }, + ) }.toList(), - bestUnpublishedClosingTx = readNullable { readTransactionWithInputInfo() as ClosingTx }, - closingFeerates = readNullable { readClosingFeerates() } + publishedClosingTxs = readCollection { readTransactionWithInputInfo() as ClosingTx }.toList(), + closingFeerate = readNullable { FeeratePerKw(readNumber().sat) }, + waitingSinceBlock = readNumber() ) private fun Input.readClosing(): Closing = Closing( @@ -636,12 +699,6 @@ object Deserialization { else -> error("unknown discriminator $discriminator for class ${Transactions.TransactionWithInputInfo::class}") } - private fun Input.readClosingFeerates(): ClosingFeerates = ClosingFeerates( - preferred = FeeratePerKw(readNumber().sat), - min = FeeratePerKw(readNumber().sat), - max = FeeratePerKw(readNumber().sat) - ) - private fun Input.readNumber(): Long = LightningCodecs.bigSize(this) private fun Input.readBoolean(): Boolean = read() == 1 diff --git a/src/commonMain/kotlin/fr/acinq/lightning/serialization/v4/Serialization.kt b/src/commonMain/kotlin/fr/acinq/lightning/serialization/v4/Serialization.kt index 48aab0206..0aab20db8 100644 --- a/src/commonMain/kotlin/fr/acinq/lightning/serialization/v4/Serialization.kt +++ b/src/commonMain/kotlin/fr/acinq/lightning/serialization/v4/Serialization.kt @@ -57,13 +57,13 @@ object Serialization { write(0x01); writeWaitForChannelReady(o) } is Normal -> { - write(0x02); writeNormal(o) + write(0x0b); writeNormal(o) } is ShuttingDown -> { - write(0x03); writeShuttingDown(o) + write(0x0c); writeShuttingDown(o) } is Negotiating -> { - write(0x04); writeNegotiating(o) + write(0x0d); writeNegotiating(o) } is Closing -> { write(0x05); writeClosing(o) @@ -135,7 +135,7 @@ object Serialization { writeNullable(remoteChannelUpdate) { writeLightningMessage(it) } writeNullable(localShutdown) { writeLightningMessage(it) } writeNullable(remoteShutdown) { writeLightningMessage(it) } - writeNullable(closingFeerates) { writeClosingFeerates(it) } + writeNullable(closingFeerate) { writeNumber(it.toLong()) } when (spliceStatus) { is SpliceStatus.WaitingForSigs -> { write(0x01) @@ -154,23 +154,21 @@ object Serialization { writeCommitments(commitments) writeLightningMessage(localShutdown) writeLightningMessage(remoteShutdown) - writeNullable(closingFeerates) { writeClosingFeerates(it) } + writeNullable(closingFeerate) { writeNumber(it.toLong()) } } private fun Output.writeNegotiating(o: Negotiating) = o.run { writeCommitments(commitments) writeLightningMessage(localShutdown) writeLightningMessage(remoteShutdown) - writeCollection(closingTxProposed) { - writeCollection(it) { closingTxProposed -> - closingTxProposed.run { - writeTransactionWithInputInfo(unsignedTx) - writeLightningMessage(localClosingSigned) - } - } + writeCollection(proposedClosingTxs) { + writeNullable(it.localAndRemote) { tx -> writeTransactionWithInputInfo(tx) } + writeNullable(it.localOnly) { tx -> writeTransactionWithInputInfo(tx) } + writeNullable(it.remoteOnly) { tx -> writeTransactionWithInputInfo(tx) } } - writeNullable(bestUnpublishedClosingTx) { writeTransactionWithInputInfo(it) } - writeNullable(closingFeerates) { writeClosingFeerates(it) } + writeCollection(publishedClosingTxs) { writeTransactionWithInputInfo(it) } + writeNullable(closingFeerate) { writeNumber(it.toLong()) } + writeNumber(waitingSinceBlock) } private fun Output.writeClosing(o: Closing) = o.run { @@ -693,12 +691,6 @@ object Serialization { } } - private fun Output.writeClosingFeerates(o: ClosingFeerates): Unit = o.run { - writeNumber(preferred.toLong()) - writeNumber(min.toLong()) - writeNumber(max.toLong()) - } - private fun Output.writeNumber(o: Number): Unit = LightningCodecs.writeBigSize(o.toLong(), this) private fun Output.writeBoolean(o: Boolean): Unit = if (o) write(1) else write(0) diff --git a/src/commonMain/kotlin/fr/acinq/lightning/transactions/Transactions.kt b/src/commonMain/kotlin/fr/acinq/lightning/transactions/Transactions.kt index 238095c38..00b0c8b84 100644 --- a/src/commonMain/kotlin/fr/acinq/lightning/transactions/Transactions.kt +++ b/src/commonMain/kotlin/fr/acinq/lightning/transactions/Transactions.kt @@ -139,6 +139,17 @@ object Transactions { } } + sealed class ClosingTxFee { + data class PaidByUs(val fee: Satoshi) : ClosingTxFee() + data class PaidByThem(val fee: Satoshi) : ClosingTxFee() + } + + @Serializable + data class ClosingTxs(val localAndRemote: TransactionWithInputInfo.ClosingTx?, val localOnly: TransactionWithInputInfo.ClosingTx?, val remoteOnly: TransactionWithInputInfo.ClosingTx?) { + val preferred: TransactionWithInputInfo.ClosingTx? = localAndRemote ?: localOnly ?: remoteOnly + val all: List = listOfNotNull(localAndRemote, localOnly, remoteOnly) + } + /** * When *local* *current* [[CommitTx]] is published: * - [[ClaimDelayedOutputTx]] spends to-local output of [[CommitTx]] after a delay @@ -736,39 +747,44 @@ object Transactions { } } - fun makeClosingTx( - commitTxInput: InputInfo, - localScriptPubKey: ByteArray, - remoteScriptPubKey: ByteArray, - localIsInitiator: Boolean, - dustLimit: Satoshi, - closingFee: Satoshi, - spec: CommitmentSpec - ): TransactionWithInputInfo.ClosingTx { + fun makeClosingTxs(input: InputInfo, spec: CommitmentSpec, fee: ClosingTxFee, lockTime: Long, localScriptPubKey: ByteVector, remoteScriptPubKey: ByteVector): ClosingTxs { require(spec.htlcs.isEmpty()) { "there shouldn't be any pending htlcs" } - val (toLocalAmount, toRemoteAmount) = if (localIsInitiator) { - Pair(spec.toLocal.truncateToSatoshi() - closingFee, spec.toRemote.truncateToSatoshi()) - } else { - Pair(spec.toLocal.truncateToSatoshi(), spec.toRemote.truncateToSatoshi() - closingFee) + val (toLocalAmount, toRemoteAmount) = when (fee) { + is ClosingTxFee.PaidByUs -> Pair(spec.toLocal.truncateToSatoshi() - fee.fee, spec.toRemote.truncateToSatoshi()) + is ClosingTxFee.PaidByThem -> Pair(spec.toLocal.truncateToSatoshi(), spec.toRemote.truncateToSatoshi() - fee.fee) } // NB: we don't care if values are < 0, they will be trimmed if they are < dust limit anyway - val toLocalOutputOpt = toLocalAmount.takeIf { it >= dustLimit }?.let { TxOut(it, localScriptPubKey) } - val toRemoteOutputOpt = toRemoteAmount.takeIf { it >= dustLimit }?.let { TxOut(it, remoteScriptPubKey) } + val txNoOutput = Transaction(2, listOf(TxIn(input.outPoint, listOf(), sequence = 0xFFFFFFFDL)), listOf(), lockTime) + val toLocalOutput = if (toLocalAmount >= dustLimit(localScriptPubKey)) TxOut(toLocalAmount, localScriptPubKey) else null + val toRemoteOutput = if (toRemoteAmount >= dustLimit(remoteScriptPubKey)) TxOut(toRemoteAmount, remoteScriptPubKey) else null - val tx = LexicographicalOrdering.sort( - Transaction( - version = 2, - txIn = listOf(TxIn(commitTxInput.outPoint, ByteVector.empty, sequence = 0xffffffffL)), - txOut = listOfNotNull(toLocalOutputOpt, toRemoteOutputOpt), - lockTime = 0 + return when { + toLocalOutput != null && toRemoteOutput != null -> { + val txLocalAndRemote = LexicographicalOrdering.sort(txNoOutput.copy(txOut = listOf(toLocalOutput, toRemoteOutput))) + val toLocalIndex = when (val i = findPubKeyScriptIndex(txLocalAndRemote, localScriptPubKey.toByteArray())) { + is TxResult.Skipped -> null + is TxResult.Success -> i.result + } + ClosingTxs( + localAndRemote = TransactionWithInputInfo.ClosingTx(input, txLocalAndRemote, toLocalIndex), + // We also provide a version of the transaction without the remote output, which they may want to omit if not economical to spend. + localOnly = TransactionWithInputInfo.ClosingTx(input, txNoOutput.copy(txOut = listOf(toLocalOutput)), 0), + remoteOnly = null + ) + } + toLocalOutput != null -> ClosingTxs( + localAndRemote = null, + localOnly = TransactionWithInputInfo.ClosingTx(input, txNoOutput.copy(txOut = listOf(toLocalOutput)), 0), + remoteOnly = null, ) - ) - val toLocalOutput = when (val toLocalIndex = findPubKeyScriptIndex(tx, localScriptPubKey)) { - is TxResult.Skipped -> null - is TxResult.Success -> toLocalIndex.result + toRemoteOutput != null -> ClosingTxs( + localAndRemote = null, + localOnly = null, + remoteOnly = TransactionWithInputInfo.ClosingTx(input, txNoOutput.copy(txOut = listOf(toRemoteOutput)), null) + ) + else -> ClosingTxs(localAndRemote = null, localOnly = null, remoteOnly = null) } - return TransactionWithInputInfo.ClosingTx(commitTxInput, tx, toLocalOutput) } private fun findPubKeyScriptIndex(tx: Transaction, pubkeyScript: ByteArray): TxResult { diff --git a/src/commonMain/kotlin/fr/acinq/lightning/wire/ChannelTlv.kt b/src/commonMain/kotlin/fr/acinq/lightning/wire/ChannelTlv.kt index 76a268efd..101b937ae 100644 --- a/src/commonMain/kotlin/fr/acinq/lightning/wire/ChannelTlv.kt +++ b/src/commonMain/kotlin/fr/acinq/lightning/wire/ChannelTlv.kt @@ -314,32 +314,6 @@ sealed class ShutdownTlv : Tlv { } } -sealed class ClosingSignedTlv : Tlv { - data class FeeRange(val min: Satoshi, val max: Satoshi) : ClosingSignedTlv() { - override val tag: Long get() = FeeRange.tag - - override fun write(out: Output) { - LightningCodecs.writeU64(min.toLong(), out) - LightningCodecs.writeU64(max.toLong(), out) - } - - companion object : TlvValueReader { - const val tag: Long = 1 - override fun read(input: Input): FeeRange = FeeRange(Satoshi(LightningCodecs.u64(input)), Satoshi(LightningCodecs.u64(input))) - } - } - - data class ChannelData(val ecb: EncryptedChannelData) : ClosingSignedTlv() { - override val tag: Long get() = ChannelData.tag - override fun write(out: Output) = LightningCodecs.writeBytes(ecb.data, out) - - companion object : TlvValueReader { - const val tag: Long = 0x47010000 - override fun read(input: Input): ChannelData = ChannelData(EncryptedChannelData(LightningCodecs.bytes(input, input.availableBytes).toByteVector())) - } - } -} - sealed class ClosingCompleteTlv : Tlv { /** Signature for a closing transaction containing only the closer's output. */ data class CloserNoClosee(val sig: ByteVector64) : ClosingCompleteTlv() { diff --git a/src/commonMain/kotlin/fr/acinq/lightning/wire/LightningMessages.kt b/src/commonMain/kotlin/fr/acinq/lightning/wire/LightningMessages.kt index d5ba2728b..dd1237a9b 100644 --- a/src/commonMain/kotlin/fr/acinq/lightning/wire/LightningMessages.kt +++ b/src/commonMain/kotlin/fr/acinq/lightning/wire/LightningMessages.kt @@ -75,7 +75,6 @@ interface LightningMessage { ChannelAnnouncement.type -> ChannelAnnouncement.read(stream) ChannelUpdate.type -> ChannelUpdate.read(stream) Shutdown.type -> Shutdown.read(stream) - ClosingSigned.type -> ClosingSigned.read(stream) ClosingComplete.type -> ClosingComplete.read(stream) ClosingSig.type -> ClosingSig.read(stream) OnionMessage.type -> OnionMessage.read(stream) @@ -1512,44 +1511,6 @@ data class Shutdown( } } -data class ClosingSigned( - override val channelId: ByteVector32, - val feeSatoshis: Satoshi, - val signature: ByteVector64, - val tlvStream: TlvStream = TlvStream.empty() -) : ChannelMessage, HasChannelId, HasEncryptedChannelData { - override val type: Long get() = ClosingSigned.type - - override val channelData: EncryptedChannelData get() = tlvStream.get()?.ecb ?: EncryptedChannelData.empty - override fun withNonEmptyChannelData(ecd: EncryptedChannelData): ClosingSigned = copy(tlvStream = tlvStream.addOrUpdate(ClosingSignedTlv.ChannelData(ecd))) - - override fun write(out: Output) { - LightningCodecs.writeBytes(channelId, out) - LightningCodecs.writeU64(feeSatoshis.toLong(), out) - LightningCodecs.writeBytes(signature, out) - TlvStreamSerializer(false, readers).write(tlvStream, out) - } - - companion object : LightningMessageReader { - const val type: Long = 39 - - @Suppress("UNCHECKED_CAST") - val readers = mapOf( - ClosingSignedTlv.FeeRange.tag to ClosingSignedTlv.FeeRange.Companion as TlvValueReader, - ClosingSignedTlv.ChannelData.tag to ClosingSignedTlv.ChannelData.Companion as TlvValueReader - ) - - override fun read(input: Input): ClosingSigned { - return ClosingSigned( - ByteVector32(LightningCodecs.bytes(input, 32)), - Satoshi(LightningCodecs.u64(input)), - ByteVector64(LightningCodecs.bytes(input, 64)), - TlvStreamSerializer(false, readers).read(input) - ) - } - } -} - data class ClosingComplete( override val channelId: ByteVector32, val fees: Satoshi, diff --git a/src/commonTest/kotlin/fr/acinq/lightning/channel/TestsHelper.kt b/src/commonTest/kotlin/fr/acinq/lightning/channel/TestsHelper.kt index b2fc90955..7f34c84c9 100644 --- a/src/commonTest/kotlin/fr/acinq/lightning/channel/TestsHelper.kt +++ b/src/commonTest/kotlin/fr/acinq/lightning/channel/TestsHelper.kt @@ -11,7 +11,8 @@ import fr.acinq.lightning.channel.states.* import fr.acinq.lightning.crypto.KeyManager import fr.acinq.lightning.db.ChannelClosingType import fr.acinq.lightning.json.JsonSerializers -import fr.acinq.lightning.logging.* +import fr.acinq.lightning.logging.MDCLogger +import fr.acinq.lightning.logging.mdc import fr.acinq.lightning.payment.OutgoingPaymentPacket import fr.acinq.lightning.router.ChannelHop import fr.acinq.lightning.serialization.Serialization @@ -230,38 +231,60 @@ object TestsHelper { return Triple(alice1, bob1, fundingTx) } - fun mutualCloseAlice(alice: LNChannel, bob: LNChannel, scriptPubKey: ByteVector? = null, feerates: ClosingFeerates? = null): Triple, LNChannel, ClosingSigned> { - val (alice1, actionsAlice1) = alice.process(ChannelCommand.Close.MutualClose(scriptPubKey, feerates)) + fun mutualCloseAlice(alice: LNChannel, bob: LNChannel, scriptPubKey: ByteVector? = null, closingFeerate: FeeratePerKw? = null): Triple, LNChannel, Transaction> { + val (alice1, actionsAlice1) = alice.process(ChannelCommand.Close.MutualClose(scriptPubKey, closingFeerate)) assertIs>(alice1) val shutdownAlice = actionsAlice1.findOutgoingMessage() - assertNull(actionsAlice1.findOutgoingMessageOpt()) + assertNull(actionsAlice1.findOutgoingMessageOpt()) val (bob1, actionsBob1) = bob.process(ChannelCommand.MessageReceived(shutdownAlice)) assertIs>(bob1) val shutdownBob = actionsBob1.findOutgoingMessage() - assertNull(actionsBob1.findOutgoingMessageOpt()) + actionsBob1.findOutgoingMessage() val (alice2, actionsAlice2) = alice1.process(ChannelCommand.MessageReceived(shutdownBob)) assertIs>(alice2) - val closingSignedAlice = actionsAlice2.findOutgoingMessage() - return Triple(alice2, bob1, closingSignedAlice) + val closingComplete = actionsAlice2.findOutgoingMessage() + + val (bob2, actionsBob2) = bob1.process(ChannelCommand.MessageReceived(closingComplete)) + assertIs>(bob2) + val closingSig = actionsBob2.findOutgoingMessage() + + val (alice3, actionsAlice3) = alice2.process(ChannelCommand.MessageReceived(closingSig)) + assertIs>(alice3) + val closingTx = actionsAlice3.findPublishTxs().first() + actionsAlice3.hasWatchConfirmed(closingTx.txid) + val commitInput = alice1.commitments.latest.commitInput + Transaction.correctlySpends(closingTx, mapOf(commitInput.outPoint to commitInput.txOut), ScriptFlags.STANDARD_SCRIPT_VERIFY_FLAGS) + return Triple(alice3, bob2, closingTx) } - fun mutualCloseBob(alice: LNChannel, bob: LNChannel, scriptPubKey: ByteVector? = null, feerates: ClosingFeerates? = null): Triple, LNChannel, ClosingSigned> { - val (bob1, actionsBob1) = bob.process(ChannelCommand.Close.MutualClose(scriptPubKey, feerates)) + fun mutualCloseBob(alice: LNChannel, bob: LNChannel, scriptPubKey: ByteVector? = null, closingFeerate: FeeratePerKw? = null): Triple, LNChannel, Transaction> { + val (bob1, actionsBob1) = bob.process(ChannelCommand.Close.MutualClose(scriptPubKey, closingFeerate)) assertIs>(bob1) val shutdownBob = actionsBob1.findOutgoingMessage() - assertNull(actionsBob1.findOutgoingMessageOpt()) + assertNull(actionsBob1.findOutgoingMessageOpt()) val (alice1, actionsAlice1) = alice.process(ChannelCommand.MessageReceived(shutdownBob)) assertIs>(alice1) val shutdownAlice = actionsAlice1.findOutgoingMessage() - val closingSignedAlice = actionsAlice1.findOutgoingMessage() + actionsAlice1.findOutgoingMessage() val (bob2, actionsBob2) = bob1.process(ChannelCommand.MessageReceived(shutdownAlice)) assertIs>(bob2) - assertNull(actionsBob2.findOutgoingMessageOpt()) - return Triple(alice1, bob2, closingSignedAlice) + val closingComplete = actionsBob2.findOutgoingMessage() + + val (alice2, actionsAlice2) = alice1.process(ChannelCommand.MessageReceived(closingComplete)) + assertIs>(alice2) + val closingSig = actionsAlice2.findOutgoingMessage() + + val (bob3, actionsBob3) = bob2.process(ChannelCommand.MessageReceived(closingSig)) + assertIs>(bob3) + val closingTx = actionsBob3.findPublishTxs().first() + actionsBob3.hasWatchConfirmed(closingTx.txid) + val commitInput = alice1.commitments.latest.commitInput + Transaction.correctlySpends(closingTx, mapOf(commitInput.outPoint to commitInput.txOut), ScriptFlags.STANDARD_SCRIPT_VERIFY_FLAGS) + return Triple(alice2, bob3, closingTx) } fun localClose(s: LNChannel): Pair, LocalCommitPublished> { diff --git a/src/commonTest/kotlin/fr/acinq/lightning/channel/states/ClosingTestsCommon.kt b/src/commonTest/kotlin/fr/acinq/lightning/channel/states/ClosingTestsCommon.kt index 63af10dcb..e21548db6 100644 --- a/src/commonTest/kotlin/fr/acinq/lightning/channel/states/ClosingTestsCommon.kt +++ b/src/commonTest/kotlin/fr/acinq/lightning/channel/states/ClosingTestsCommon.kt @@ -1,12 +1,10 @@ package fr.acinq.lightning.channel.states import fr.acinq.bitcoin.* -import fr.acinq.bitcoin.Bitcoin.computeP2PkhAddress import fr.acinq.lightning.CltvExpiryDelta import fr.acinq.lightning.Feature import fr.acinq.lightning.Lightning import fr.acinq.lightning.blockchain.* -import fr.acinq.lightning.blockchain.fee.FeeratePerKw import fr.acinq.lightning.channel.* import fr.acinq.lightning.channel.TestsHelper.addHtlc import fr.acinq.lightning.channel.TestsHelper.claimHtlcSuccessTxs @@ -18,8 +16,6 @@ import fr.acinq.lightning.channel.TestsHelper.htlcSuccessTxs import fr.acinq.lightning.channel.TestsHelper.htlcTimeoutTxs import fr.acinq.lightning.channel.TestsHelper.localClose import fr.acinq.lightning.channel.TestsHelper.makeCmdAdd -import fr.acinq.lightning.channel.TestsHelper.mutualCloseAlice -import fr.acinq.lightning.channel.TestsHelper.mutualCloseBob import fr.acinq.lightning.channel.TestsHelper.reachNormal import fr.acinq.lightning.channel.TestsHelper.remoteClose import fr.acinq.lightning.channel.TestsHelper.useAlternativeCommitSig @@ -28,7 +24,10 @@ import fr.acinq.lightning.tests.TestConstants import fr.acinq.lightning.tests.utils.LightningTestSuite import fr.acinq.lightning.transactions.Scripts import fr.acinq.lightning.transactions.Transactions -import fr.acinq.lightning.utils.* +import fr.acinq.lightning.utils.UUID +import fr.acinq.lightning.utils.msat +import fr.acinq.lightning.utils.sat +import fr.acinq.lightning.utils.toMilliSatoshi import fr.acinq.lightning.wire.* import kotlin.test.* @@ -36,8 +35,9 @@ class ClosingTestsCommon : LightningTestSuite() { @Test fun `recv ChannelCommand_Htlc_Add`() { - val (alice, _, _) = initMutualClose() - val (_, actions) = alice.process( + val (alice, _) = reachNormal() + val (alice1, _) = localClose(alice) + val (_, actions) = alice1.process( ChannelCommand.Htlc.Add( 1000000.msat, ByteVector32.Zeroes, @@ -47,91 +47,7 @@ class ClosingTestsCommon : LightningTestSuite() { ) ) assertEquals(1, actions.size) - assertTrue { (actions.first() as ChannelAction.ProcessCmdRes.AddFailed).error == ChannelUnavailable(alice.state.channelId) } - } - - @Test - fun `recv ChannelCommand_Htlc_Settlement_Fulfill -- nonexistent htlc`() { - val (alice, _, _) = initMutualClose() - val (_, actions) = alice.process(ChannelCommand.Htlc.Settlement.Fulfill(1, ByteVector32.Zeroes)) - assertTrue { actions.size == 1 && (actions.first() as ChannelAction.ProcessCmdRes.NotExecuted).t is UnknownHtlcId } - } - - @Test - fun `recv BITCOIN_FUNDING_SPENT -- mutual close before converging`() { - val (alice0, bob0) = reachNormal() - // alice initiates a closing with a low fee - val (alice1, aliceActions1) = alice0.process(ChannelCommand.Close.MutualClose(null, ClosingFeerates(FeeratePerKw(500.sat), FeeratePerKw(250.sat), FeeratePerKw(1000.sat)))) - val shutdown0 = aliceActions1.findOutgoingMessage() - val (bob1, bobActions1) = bob0.process(ChannelCommand.MessageReceived(shutdown0)) - assertIs(bob1.state) - val shutdown1 = bobActions1.findOutgoingMessage() - val (alice2, aliceActions2) = alice1.process(ChannelCommand.MessageReceived(shutdown1)) - assertIs(alice2.state) - val closingSigned0 = aliceActions2.findOutgoingMessage() - - // they don't converge yet, but bob has a publishable commit tx now - val (bob2, bobActions2) = bob1.process(ChannelCommand.MessageReceived(closingSigned0)) - assertIs(bob2.state) - val mutualCloseTx = bob2.state.bestUnpublishedClosingTx - assertNotNull(mutualCloseTx) - val closingSigned1 = bobActions2.findOutgoingMessage() - assertNotEquals(closingSigned0.feeSatoshis, closingSigned1.feeSatoshis) - - // let's make bob publish this closing tx - val (bob3, bobActions3) = bob2.process(ChannelCommand.MessageReceived(Error(ByteVector32.Zeroes, ""))) - assertIs(bob3.state) - assertEquals(ChannelAction.Blockchain.PublishTx(mutualCloseTx), bobActions3.filterIsInstance().first()) - assertEquals(mutualCloseTx, bob3.state.mutualClosePublished.last()) - bobActions3.find().also { - assertEquals(mutualCloseTx.tx.txid, it.txId) - assertEquals(ChannelClosingType.Mutual, it.closingType) - assertTrue(it.isSentToDefaultAddress) - } - - // actual test starts here - val (bob4, _) = bob3.process(ChannelCommand.WatchReceived(WatchEventSpent(ByteVector32.Zeroes, BITCOIN_FUNDING_SPENT, mutualCloseTx.tx))) - val (bob5, bobActions5) = bob4.process(ChannelCommand.WatchReceived(WatchEventConfirmed(ByteVector32.Zeroes, BITCOIN_TX_CONFIRMED(mutualCloseTx.tx), 0, 0, mutualCloseTx.tx))) - assertIs(bob5.state) - assertContains(bobActions5, ChannelAction.Storage.SetLocked(mutualCloseTx.tx.txid)) - } - - @Test - fun `recv BITCOIN_TX_CONFIRMED -- mutual close`() { - val (alice0, _, _) = initMutualClose() - val mutualCloseTx = alice0.state.mutualClosePublished.last() - - // actual test starts here - val (alice1, actions1) = alice0.process(ChannelCommand.WatchReceived(WatchEventConfirmed(ByteVector32.Zeroes, BITCOIN_TX_CONFIRMED(mutualCloseTx.tx), 0, 0, mutualCloseTx.tx))) - assertIs(alice1.state) - assertContains(actions1, ChannelAction.Storage.SetLocked(mutualCloseTx.tx.txid)) - } - - @Test - fun `recv BITCOIN_TX_CONFIRMED -- mutual close with external btc address`() { - val pubKey = Lightning.randomKey().publicKey() - val bobBtcAddr = computeP2PkhAddress(pubKey, TestConstants.Bob.nodeParams.chainHash) - val bobFinalScript = Script.write(Script.pay2pkh(pubKey)).toByteVector() - - val (alice1, bob1) = reachNormal() - val (_, bob2, aliceClosingSigned) = mutualCloseBob(alice1, bob1, scriptPubKey = bobFinalScript) - - val (bob3, bobActions3) = bob2.process(ChannelCommand.MessageReceived(aliceClosingSigned)) - assertIs(bob3.state) - val bobClosingSigned = bobActions3.findOutgoingMessageOpt() - assertNotNull(bobClosingSigned) - val mutualCloseTx = bob3.state.mutualClosePublished.last() - bobActions3.find().also { - assertEquals(mutualCloseTx.tx.txid, it.txId) - assertEquals(ChannelClosingType.Mutual, it.closingType) - assertFalse(it.isSentToDefaultAddress) - assertEquals(bobBtcAddr, it.address) - } - - // actual test starts here - val (bob4, bobActions4) = bob3.process(ChannelCommand.WatchReceived(WatchEventConfirmed(ByteVector32.Zeroes, BITCOIN_TX_CONFIRMED(mutualCloseTx.tx), 0, 0, mutualCloseTx.tx))) - assertIs(bob4.state) - assertContains(bobActions4, ChannelAction.Storage.SetLocked(mutualCloseTx.tx.txid)) + assertEquals((actions.first() as ChannelAction.ProcessCmdRes.AddFailed).error, ChannelUnavailable(alice.state.channelId)) } @Test @@ -539,15 +455,13 @@ class ClosingTestsCommon : LightningTestSuite() { @Test fun `recv BITCOIN_FUNDING_SPENT -- remote commit`() { - val (alice, _, bobCommitTxs) = initMutualClose(withPayments = true) - // bob publishes his last current commit tx, the one it had when entering NEGOTIATING state - val bobCommitTx = bobCommitTxs.last().commitTx.tx + val (alice0, bob0) = reachNormal() + val bobCommitTx = bob0.commitments.latest.localCommit.publishableTxs.commitTx.tx assertEquals(4, bobCommitTx.txOut.size) // main outputs and anchors - val (aliceClosing, remoteCommitPublished) = remoteClose(bobCommitTx, alice) + val (_, remoteCommitPublished) = remoteClose(bobCommitTx, alice0) assertNotNull(remoteCommitPublished.claimMainOutputTx) assertTrue(remoteCommitPublished.claimHtlcSuccessTxs().isEmpty()) assertTrue(remoteCommitPublished.claimHtlcTimeoutTxs().isEmpty()) - assertEquals(alice.state, aliceClosing.state.copy(remoteCommitPublished = null)) } @Test @@ -1683,26 +1597,17 @@ class ClosingTestsCommon : LightningTestSuite() { @Test fun `recv ChannelReestablish`() { - val (alice0, bob0, _) = initMutualClose() - val bobCurrentPerCommitmentPoint = bob0.commitments.params.localParams.channelKeys(bob0.ctx.keyManager).commitmentPoint(bob0.commitments.localCommitIndex) - val channelReestablish = ChannelReestablish(bob0.channelId, 42, 42, PrivateKey(ByteVector32.Zeroes), bobCurrentPerCommitmentPoint) - val (alice1, actions1) = alice0.process(ChannelCommand.MessageReceived(channelReestablish)) - assertIs(alice1.state) - assertNull(alice1.state.localCommitPublished) - assertNull(alice1.state.remoteCommitPublished) - assertTrue(alice1.state.mutualClosePublished.isNotEmpty()) - val error = actions1.hasOutgoingMessage() - assertEquals(error.toAscii(), FundingTxSpent(alice0.channelId, alice0.state.mutualClosePublished.first().tx.txid).message) - } - - @Test - fun `recv ChannelCommand_Close_MutualClose`() { - val (alice0, _, _) = initMutualClose() - val cmdClose = ChannelCommand.Close.MutualClose(null, null) - val (_, actions) = alice0.process(cmdClose) - val commandError = actions.filterIsInstance().first() - assertEquals(cmdClose, commandError.cmd) - assertEquals(ClosingAlreadyInProgress(alice0.channelId), commandError.t) + val (alice, bob) = reachNormal() + val (alice1, lcp) = localClose(alice) + val bobCurrentPerCommitmentPoint = bob.commitments.params.localParams.channelKeys(bob.ctx.keyManager).commitmentPoint(bob.commitments.localCommitIndex) + val channelReestablish = ChannelReestablish(bob.channelId, 42, 42, PrivateKey(ByteVector32.Zeroes), bobCurrentPerCommitmentPoint) + val (alice2, actions2) = alice1.process(ChannelCommand.MessageReceived(channelReestablish)) + assertIs(alice2.state) + assertNotNull(alice2.state.localCommitPublished) + assertEquals(lcp, alice2.state.localCommitPublished) + assertNull(alice2.state.remoteCommitPublished) + val error = actions2.hasOutgoingMessage() + assertEquals(error.toAscii(), FundingTxSpent(alice.channelId, lcp.commitTx.txid).message) } @Test @@ -1726,52 +1631,13 @@ class ClosingTestsCommon : LightningTestSuite() { @Test fun `recv Disconnected`() { - val (alice0, _, _) = initMutualClose() - val (alice1, _) = alice0.process(ChannelCommand.Disconnected) - assertTrue { alice1.state is Closing } + val (alice, _) = reachNormal() + val (alice1, _) = localClose(alice) + val (alice2, _) = alice1.process(ChannelCommand.Disconnected) + assertIs(alice2.state) } companion object { - fun initMutualClose(withPayments: Boolean = false): Triple, LNChannel, List> { - val (aliceInit, bobInit) = reachNormal() - var mutableAlice: LNChannel = aliceInit - var mutableBob: LNChannel = bobInit - - val bobCommitTxs = if (!withPayments) { - listOf() - } else { - listOf(100_000_000.msat, 200_000_000.msat, 300_000_000.msat).map { amount -> - val (nodes, r, htlc) = addHtlc(amount, payer = mutableAlice, payee = mutableBob) - mutableAlice = nodes.first - mutableBob = nodes.second - - with(crossSign(mutableAlice, mutableBob)) { - mutableAlice = first - mutableBob = second - } - - val bobCommitTx1 = mutableBob.commitments.latest.localCommit.publishableTxs - - with(fulfillHtlc(htlc.id, r, payer = mutableAlice, payee = mutableBob)) { - mutableAlice = first - mutableBob = second - } - with(crossSign(mutableBob, mutableAlice)) { - mutableBob = first - mutableAlice = second - } - - val bobCommitTx2 = mutableBob.commitments.latest.localCommit.publishableTxs - listOf(bobCommitTx1, bobCommitTx2) - }.flatten() - } - - val (alice1, bob1, aliceCloseSig) = mutualCloseAlice(mutableAlice, mutableBob) - val (alice2, bob2) = NegotiatingTestsCommon.converge(alice1, bob1, aliceCloseSig) ?: error("converge should not return null") - - return Triple(alice2, bob2, bobCommitTxs) - } - data class RevokedCloseFixture(val alice: LNChannel, val bob: LNChannel, val bobRevokedTxs: List, val htlcsAlice: List, val htlcsBob: List) fun prepareRevokedClose(): RevokedCloseFixture { diff --git a/src/commonTest/kotlin/fr/acinq/lightning/channel/states/NegotiatingTestsCommon.kt b/src/commonTest/kotlin/fr/acinq/lightning/channel/states/NegotiatingTestsCommon.kt index ac2d1f30c..782cb309e 100644 --- a/src/commonTest/kotlin/fr/acinq/lightning/channel/states/NegotiatingTestsCommon.kt +++ b/src/commonTest/kotlin/fr/acinq/lightning/channel/states/NegotiatingTestsCommon.kt @@ -2,15 +2,18 @@ package fr.acinq.lightning.channel.states import fr.acinq.bitcoin.* import fr.acinq.lightning.Feature +import fr.acinq.lightning.Lightning.randomBytes64 import fr.acinq.lightning.Lightning.randomKey import fr.acinq.lightning.MilliSatoshi import fr.acinq.lightning.blockchain.* import fr.acinq.lightning.blockchain.fee.FeeratePerKw import fr.acinq.lightning.channel.* +import fr.acinq.lightning.channel.TestsHelper.addHtlc +import fr.acinq.lightning.channel.TestsHelper.crossSign +import fr.acinq.lightning.channel.TestsHelper.fulfillHtlc import fr.acinq.lightning.channel.TestsHelper.makeCmdAdd -import fr.acinq.lightning.channel.TestsHelper.mutualCloseAlice -import fr.acinq.lightning.channel.TestsHelper.mutualCloseBob import fr.acinq.lightning.channel.TestsHelper.reachNormal +import fr.acinq.lightning.db.ChannelClosingType import fr.acinq.lightning.tests.TestConstants import fr.acinq.lightning.tests.utils.LightningTestSuite import fr.acinq.lightning.utils.msat @@ -31,399 +34,293 @@ class NegotiatingTestsCommon : LightningTestSuite() { actions1.hasCommandError() } - private fun testClosingSignedDifferentFees(alice: LNChannel, bob: LNChannel, bobInitiates: Boolean = false) { - // alice and bob see different on-chain feerates - val alice1 = alice.updateFeerate(FeeratePerKw(5_000.sat)) - val bob1 = bob.updateFeerate(FeeratePerKw(7_500.sat)) - val (alice2, bob2, aliceCloseSig1) = if (bobInitiates) mutualCloseBob(alice1, bob1) else mutualCloseAlice(alice1, bob1) - - // alice is initiator so she initiates the negotiation - assertEquals(aliceCloseSig1.feeSatoshis, 3370.sat) // matches a feerate of 5000 sat/kw - val aliceFeeRange = aliceCloseSig1.tlvStream.get() - assertNotNull(aliceFeeRange) - assertTrue(aliceFeeRange.min < aliceCloseSig1.feeSatoshis) - assertTrue(aliceCloseSig1.feeSatoshis < aliceFeeRange.max) - assertEquals(alice2.state.closingTxProposed.size, 1) - assertEquals(alice2.state.closingTxProposed.last().size, 1) - assertNull(alice2.state.bestUnpublishedClosingTx) - - // bob answers with a counter proposition in alice's fee range - val (bob3, bobActions3) = bob2.process(ChannelCommand.MessageReceived(aliceCloseSig1)) - assertIs>(bob3) - val bobCloseSig1 = bobActions3.findOutgoingMessage() - assertTrue(aliceFeeRange.min < bobCloseSig1.feeSatoshis) - assertTrue(bobCloseSig1.feeSatoshis < aliceFeeRange.max) - assertNotNull(bobCloseSig1.tlvStream.get()) - assertTrue(aliceCloseSig1.feeSatoshis < bobCloseSig1.feeSatoshis) - assertNotNull(bob3.state.bestUnpublishedClosingTx) - - // alice accepts this proposition - val (alice3, aliceActions3) = alice2.process(ChannelCommand.MessageReceived(bobCloseSig1)) - assertIs>(alice3) - val mutualCloseTx = aliceActions3.findPublishTxs().first() - assertEquals(aliceActions3.findWatch().txId, mutualCloseTx.txid) - assertEquals(mutualCloseTx.txOut.size, 2) // NB: anchors are removed from the closing tx - val aliceCloseSig2 = aliceActions3.findOutgoingMessage() - assertEquals(aliceCloseSig2.feeSatoshis, bobCloseSig1.feeSatoshis) - val (bob4, bobActions4) = bob3.process(ChannelCommand.MessageReceived(aliceCloseSig2)) - assertIs>(bob4) - bobActions4.hasPublishTx(mutualCloseTx) - assertEquals(bobActions4.findWatch().txId, mutualCloseTx.txid) - assertEquals(alice3.state.mutualClosePublished.map { it.tx }, listOf(mutualCloseTx)) - assertEquals(bob4.state.mutualClosePublished.map { it.tx }, listOf(mutualCloseTx)) - } - @Test - fun `recv ClosingSigned -- theirCloseFee != ourCloseFee`() { - val (alice, bob) = reachNormal() - testClosingSignedDifferentFees(alice, bob) + fun `recv ClosingComplete -- both outputs`() { + val (alice, bob, closingCompleteAlice, closingCompleteBob) = init() + + val (alice1, actionsAlice1) = alice.process(ChannelCommand.MessageReceived(closingCompleteBob)) + assertEquals(4, actionsAlice1.size) + actionsAlice1.has() + val closingTxBob = actionsAlice1.findPublishTxs().first() + actionsAlice1.hasWatchConfirmed(closingTxBob.txid) + val closingSigAlice = actionsAlice1.findOutgoingMessage() + + val (bob1, actionsBob1) = bob.process(ChannelCommand.MessageReceived(closingCompleteAlice)) + assertEquals(4, actionsBob1.size) + actionsBob1.has() + val closingTxAlice = actionsBob1.findPublishTxs().first() + actionsBob1.hasWatchConfirmed(closingTxAlice.txid) + val closingSigBob = actionsBob1.findOutgoingMessage() + + val (alice2, actionsAlice2) = alice1.process(ChannelCommand.MessageReceived(closingSigBob)) + assertIs(alice2.state) + assertEquals(3, actionsAlice2.size) + actionsAlice2.has() + assertTrue(actionsAlice2.findPublishTxs().contains(closingTxAlice)) + actionsAlice2.hasWatchConfirmed(closingTxAlice.txid) + + val (bob2, actionsBob2) = bob1.process(ChannelCommand.MessageReceived(closingSigAlice)) + assertIs(bob2.state) + assertEquals(3, actionsBob2.size) + actionsBob2.has() + assertTrue(actionsBob2.findPublishTxs().contains(closingTxBob)) + actionsBob2.hasWatchConfirmed(closingTxBob.txid) } @Test - fun `recv ClosingSigned -- theirCloseFee != ourCloseFee + bob starts closing`() { - val (alice, bob) = reachNormal() - testClosingSignedDifferentFees(alice, bob, bobInitiates = true) + fun `recv ClosingComplete -- both outputs -- external address`() { + val closingScript = Script.write(Script.pay2wpkh(randomKey().publicKey())).toByteVector() + val (alice, bob, closingComplete, _) = init(closingScript = closingScript) + + val (bob1, actionsBob1) = bob.process(ChannelCommand.MessageReceived(closingComplete)) + assertIs(bob1.state) + val closingTx = actionsBob1.findPublishTxs().first() + assertTrue(closingTx.txOut.any { it.publicKeyScript == closingScript }) + val closingSig = actionsBob1.findOutgoingMessage() + + val (alice1, actionsAlice1) = alice.process(ChannelCommand.MessageReceived(closingSig)) + assertIs(alice1.state) + assertTrue(actionsAlice1.findPublishTxs().contains(closingTx)) } @Test - fun `recv ClosingSigned -- theirMinCloseFee greater than ourCloseFee`() { - val (alice, bob) = reachNormal() - val alice1 = alice.updateFeerate(FeeratePerKw(10_000.sat)) - val bob1 = bob.updateFeerate(FeeratePerKw(2_500.sat)) - - val (_, bob2, aliceCloseSig) = mutualCloseAlice(alice1, bob1) - val (bob3, actions) = bob2.process(ChannelCommand.MessageReceived(aliceCloseSig)) - assertIs>(bob3) - val bobCloseSig = actions.findOutgoingMessage() - assertEquals(bobCloseSig.feeSatoshis, aliceCloseSig.feeSatoshis) + fun `recv ClosingComplete -- single output`() { + val (alice, bob) = reachNormal(bobFundingAmount = 0.sat, alicePushAmount = 0.msat) + val (alice1, actionsAlice1) = alice.process(ChannelCommand.Close.MutualClose(null, null)) + val shutdownAlice = actionsAlice1.findOutgoingMessage() + val (bob1, actionsBob1) = bob.process(ChannelCommand.MessageReceived(shutdownAlice)) + val shutdownBob = actionsBob1.findOutgoingMessage() + assertNull(actionsBob1.findOutgoingMessageOpt()) // Bob cannot pay mutual close fees. + + val (alice2, actionsAlice2) = alice1.process(ChannelCommand.MessageReceived(shutdownBob)) + val closingCompleteAlice = actionsAlice2.findOutgoingMessage() + assertNull(closingCompleteAlice.closerAndCloseeSig) + assertNotNull(closingCompleteAlice.closerNoCloseeSig) + + val (bob2, actionsBob2) = bob1.process(ChannelCommand.MessageReceived(closingCompleteAlice)) + assertIs(bob2.state) + val closingTxAlice = actionsBob2.findPublishTxs().first() + assertEquals(1, closingTxAlice.txOut.size) + val closingSigBob = actionsBob2.findOutgoingMessage() + assertNotNull(closingSigBob.closerNoCloseeSig) + + val (alice3, actionsAlice3) = alice2.process(ChannelCommand.MessageReceived(closingSigBob)) + assertIs(alice3.state) + assertTrue(actionsAlice3.findPublishTxs().contains(closingTxAlice)) + actionsAlice3.hasWatchConfirmed(closingTxAlice.txid) } @Test - fun `recv ClosingSigned -- theirMaxCloseFee smaller than ourCloseFee`() { - val (alice, bob) = reachNormal() - val alice1 = alice.updateFeerate(FeeratePerKw(5_000.sat)) - val bob1 = bob.updateFeerate(FeeratePerKw(20_000.sat)) - - val (_, bob2, aliceCloseSig) = mutualCloseAlice(alice1, bob1) - val (_, actions) = bob2.process(ChannelCommand.MessageReceived(aliceCloseSig)) - val bobCloseSig = actions.findOutgoingMessage() - assertEquals(bobCloseSig.feeSatoshis, aliceCloseSig.tlvStream.get()!!.max) - } - - private fun testClosingSignedSameFees(alice: LNChannel, bob: LNChannel, bobInitiates: Boolean = false) { - val alice1 = alice.updateFeerate(FeeratePerKw(5_000.sat)) - val bob1 = bob.updateFeerate(FeeratePerKw(5_000.sat)) - val (alice2, bob2, aliceCloseSig1) = if (bobInitiates) mutualCloseBob(alice1, bob1) else mutualCloseAlice(alice1, bob1) - - // alice is initiator so she initiates the negotiation - assertEquals(aliceCloseSig1.feeSatoshis, 3370.sat) // matches a feerate of 5000 sat/kw - val aliceFeeRange = aliceCloseSig1.tlvStream.get() - assertNotNull(aliceFeeRange) - - // bob agrees with that proposal - val (bob3, bobActions3) = bob2.process(ChannelCommand.MessageReceived(aliceCloseSig1)) - assertIs>(bob3) - val bobCloseSig1 = bobActions3.findOutgoingMessage() - assertNotNull(bobCloseSig1.tlvStream.get()) - assertEquals(aliceCloseSig1.feeSatoshis, bobCloseSig1.feeSatoshis) - val mutualCloseTx = bobActions3.findPublishTxs().first() - assertEquals(mutualCloseTx.txOut.size, 2) // NB: anchors are removed from the closing tx - - val (alice3, aliceActions3) = alice2.process(ChannelCommand.MessageReceived(bobCloseSig1)) - assertIs>(alice3) - aliceActions3.hasPublishTx(mutualCloseTx) + fun `recv ClosingComplete -- with concurrent shutdown`() { + val (alice, bob, oldClosingComplete, _) = init() + + // Bob updates his closing script before receiving Alice's closing_complete. + val closingScript = Script.write(Script.pay2wpkh(randomKey().publicKey())).byteVector() + val (bob1, actionsBob1) = bob.process(ChannelCommand.Close.MutualClose(closingScript, null)) + assertEquals(3, actionsBob1.size) + actionsBob1.has() + val shutdown = actionsBob1.findOutgoingMessage() + actionsBob1.findOutgoingMessage() + + // Bob ignores Alice's obsolete closing_complete. + val (bob2, actionsBob2) = bob1.process(ChannelCommand.MessageReceived(oldClosingComplete)) + assertTrue(actionsBob2.isEmpty()) + + // Alice sends a new closing_complete when receiving Bob's shutdown. + val (alice1, actionsAlice1) = alice.process(ChannelCommand.MessageReceived(shutdown)) + assertEquals(2, actionsAlice1.size) + actionsAlice1.has() + val closingComplete = actionsAlice1.findOutgoingMessage() + + val (bob3, actionsBob3) = bob2.process(ChannelCommand.MessageReceived(closingComplete)) + assertIs(bob3.state) + assertEquals(4, actionsBob3.size) + actionsBob3.has() + val closingTx = actionsBob3.findPublishTxs().first() + assertTrue(closingTx.txOut.any { it.publicKeyScript == closingScript }) + actionsBob3.hasWatchConfirmed(closingTx.txid) + val closingSig = actionsBob3.findOutgoingMessage() + + val (alice2, actionsAlice2) = alice1.process(ChannelCommand.MessageReceived(closingSig)) + assertIs(alice2.state) + assertEquals(3, actionsAlice2.size) + actionsAlice2.has() + assertEquals(closingTx, actionsAlice2.findPublishTxs().first()) + actionsAlice2.hasWatchConfirmed(closingTx.txid) } @Test - fun `recv ClosingSigned -- theirCloseFee == ourCloseFee`() { - val (alice, bob) = reachNormal() - testClosingSignedSameFees(alice, bob) + fun `recv ClosingComplete -- missing closee output`() { + val (_, bob, closingComplete, _) = init() + + // Bob expects to receive a signature for a closing transaction containing his output, so he ignores Alice's + // closing_complete instead of sending back his closing_sig. + val (bob1, actionsBob1) = bob.process(ChannelCommand.MessageReceived(closingComplete.copy(tlvStream = TlvStream(ClosingCompleteTlv.CloserNoClosee(closingComplete.closerNoCloseeSig!!))))) + assertIs(bob1.state) + assertTrue(actionsBob1.isEmpty()) + + val (bob2, actionsBob2) = bob1.process(ChannelCommand.MessageReceived(closingComplete)) + assertIs(bob2.state) + val closingTxAlice = actionsBob2.findPublishTxs().first() + assertTrue(closingTxAlice.txOut.size == 2) + actionsBob2.findOutgoingMessage() } @Test - fun `recv ClosingSigned -- theirCloseFee == ourCloseFee + bob starts closing`() { - val (alice, bob) = reachNormal() - testClosingSignedSameFees(alice, bob, bobInitiates = true) - } + fun `recv ClosingSig -- missing signature`() { + val (alice, bob, closingComplete, _) = init() - @Test - fun `override on-chain fee estimator -- initiator`() { - val (alice, bob) = reachNormal() - val alice1 = alice.updateFeerate(FeeratePerKw(10_000.sat)) - val bob1 = bob.updateFeerate(FeeratePerKw(10_000.sat)) - - // alice initiates the negotiation with a very low feerate - val (alice2, bob2, aliceCloseSig) = mutualCloseAlice(alice1, bob1, feerates = ClosingFeerates(FeeratePerKw(2_500.sat), FeeratePerKw(2_000.sat), FeeratePerKw(3_000.sat))) - assertEquals(aliceCloseSig.feeSatoshis, 1685.sat) - assertEquals(aliceCloseSig.tlvStream.get(), ClosingSignedTlv.FeeRange(1348.sat, 2022.sat)) - - // bob chooses alice's highest fee - val (bob3, bobActions3) = bob2.process(ChannelCommand.MessageReceived(aliceCloseSig)) - val bobCloseSig = bobActions3.findOutgoingMessage() - assertEquals(bobCloseSig.feeSatoshis, 2022.sat) - - // alice accepts this proposition - val (alice3, aliceActions3) = alice2.process(ChannelCommand.MessageReceived(bobCloseSig)) - assertIs>(alice3) - val mutualCloseTx = aliceActions3.findPublishTxs().first() - val aliceCloseSig2 = aliceActions3.findOutgoingMessage() - assertEquals(aliceCloseSig2.feeSatoshis, 2022.sat) - - val (bob4, bobActions4) = bob3.process(ChannelCommand.MessageReceived(aliceCloseSig2)) - assertIs>(bob4) - bobActions4.hasPublishTx(mutualCloseTx) - } + val (_, actionsBob1) = bob.process(ChannelCommand.MessageReceived(closingComplete)) + val closingSig = actionsBob1.findOutgoingMessage() - @Test - fun `override on-chain fee estimator -- non-initiator`() { - val (alice, bob) = reachNormal() - val alice1 = alice.updateFeerate(FeeratePerKw(10_000.sat)) - val bob1 = bob.updateFeerate(FeeratePerKw(10_000.sat)) - - // alice is initiator, so bob's override will simply be ignored - val (alice2, bob2, aliceCloseSig) = mutualCloseBob(alice1, bob1, feerates = ClosingFeerates(FeeratePerKw(2_500.sat), FeeratePerKw(2_000.sat), FeeratePerKw(3_000.sat))) - assertEquals(aliceCloseSig.feeSatoshis, 6740.sat) // matches a feerate of 10 000 sat/kw - - // bob directly agrees because their fee estimator matches - val (bob3, bobActions3) = bob2.process(ChannelCommand.MessageReceived(aliceCloseSig)) - assertIs>(bob3) - val mutualCloseTx = bobActions3.findPublishTxs().first() - val bobCloseSig = bobActions3.findOutgoingMessage() - assertEquals(bobCloseSig.feeSatoshis, aliceCloseSig.feeSatoshis) - - // alice accepts this proposition - val (alice3, aliceActions3) = alice2.process(ChannelCommand.MessageReceived(bobCloseSig)) - assertIs>(alice3) - aliceActions3.hasPublishTx(mutualCloseTx) + val (alice1, actionsAlice1) = alice.process(ChannelCommand.MessageReceived(closingSig.copy(tlvStream = TlvStream.empty()))) + assertIs(alice1.state) + assertTrue(actionsAlice1.isEmpty()) } @Test - fun `recv ClosingSigned -- nothing at stake`() { - val (alice, bob) = reachNormal(bobFundingAmount = 0.sat, alicePushAmount = 0.msat) - val alice1 = alice.updateFeerate(FeeratePerKw(5_000.sat)) - val bob1 = bob.updateFeerate(FeeratePerKw(10_000.sat)) - - // Bob has nothing at stake - val (_, bob2, aliceCloseSig) = mutualCloseBob(alice1, bob1) - val (bob3, bobActions3) = bob2.process(ChannelCommand.MessageReceived(aliceCloseSig)) - assertIs>(bob3) - val mutualCloseTx = bobActions3.findPublishTxs().first() - assertEquals(bob3.state.mutualClosePublished.map { it.tx }, listOf(mutualCloseTx)) - assertEquals(bobActions3.findWatches().map { it.event }, listOf(BITCOIN_TX_CONFIRMED(mutualCloseTx))) - } + fun `recv ClosingSig -- invalid signature`() { + val (alice, bob, closingComplete, _) = init() - @Test - fun `recv ClosingSigned -- other side ignores our fee range + initiator`() { - val (alice, bob) = reachNormal() - val alice1 = alice.updateFeerate(FeeratePerKw(1_000.sat)) - val (alice2, bob2, aliceCloseSig1) = mutualCloseAlice(alice1, bob) - val aliceFeeRange = aliceCloseSig1.tlvStream.get() - assertNotNull(aliceFeeRange) - assertEquals(aliceCloseSig1.feeSatoshis, 674.sat) - assertEquals(aliceFeeRange.max, 1348.sat) - assertEquals(alice2.state.closingTxProposed.last().size, 1) - assertNull(alice2.state.bestUnpublishedClosingTx) - - // bob makes a proposal outside our fee range - val (_, bobCloseSig1) = makeLegacyClosingSigned(alice2, bob2, 2_500.sat) - val (alice3, actions3) = alice2.process(ChannelCommand.MessageReceived(bobCloseSig1)) - assertIs>(alice3) - val aliceCloseSig2 = actions3.findOutgoingMessage() - assertTrue(aliceCloseSig1.feeSatoshis < aliceCloseSig2.feeSatoshis) - assertTrue(aliceCloseSig2.feeSatoshis < 1600.sat) - assertEquals(alice3.state.closingTxProposed.last().size, 2) - assertNotNull(alice3.state.bestUnpublishedClosingTx) - - val (_, bobCloseSig2) = makeLegacyClosingSigned(alice2, bob2, 2_000.sat) - val (alice4, actions4) = alice3.process(ChannelCommand.MessageReceived(bobCloseSig2)) - assertIs>(alice4) - val aliceCloseSig3 = actions4.findOutgoingMessage() - assertTrue(aliceCloseSig2.feeSatoshis < aliceCloseSig3.feeSatoshis) - assertTrue(aliceCloseSig3.feeSatoshis < 1800.sat) - assertEquals(alice4.state.closingTxProposed.last().size, 3) - assertNotNull(alice4.state.bestUnpublishedClosingTx) - - val (_, bobCloseSig3) = makeLegacyClosingSigned(alice2, bob2, 1_800.sat) - val (alice5, actions5) = alice4.process(ChannelCommand.MessageReceived(bobCloseSig3)) - assertIs>(alice5) - val aliceCloseSig4 = actions5.findOutgoingMessage() - assertTrue(aliceCloseSig3.feeSatoshis < aliceCloseSig4.feeSatoshis) - assertTrue(aliceCloseSig4.feeSatoshis < 1800.sat) - assertEquals(alice5.state.closingTxProposed.last().size, 4) - assertNotNull(alice5.state.bestUnpublishedClosingTx) - - val (_, bobCloseSig4) = makeLegacyClosingSigned(alice2, bob2, aliceCloseSig4.feeSatoshis) - val (alice6, actions6) = alice5.process(ChannelCommand.MessageReceived(bobCloseSig4)) - assertIs>(alice6) - val mutualCloseTx = actions6.findPublishTxs().first() - assertEquals(alice6.state.mutualClosePublished.size, 1) - assertEquals(mutualCloseTx, alice6.state.mutualClosePublished.first().tx) + val (_, actionsBob1) = bob.process(ChannelCommand.MessageReceived(closingComplete)) + val closingSig = actionsBob1.findOutgoingMessage() + + val (alice1, actionsAlice1) = alice.process(ChannelCommand.MessageReceived(closingSig.copy(tlvStream = TlvStream(ClosingSigTlv.CloserAndClosee(randomBytes64()))))) + assertIs(alice1.state) + assertTrue(actionsAlice1.isEmpty()) } @Test - fun `recv ClosingSigned -- other side ignores our fee range + non-initiator`() { - val (alice, bob) = reachNormal() - val bob1 = bob.updateFeerate(FeeratePerKw(10_000.sat)) - val (alice2, bob2, _) = mutualCloseBob(alice, bob1) - - // alice starts with a very low proposal - val (aliceCloseSig1, _) = makeLegacyClosingSigned(alice2, bob2, 500.sat) - val (bob3, actions3) = bob2.process(ChannelCommand.MessageReceived(aliceCloseSig1)) - assertIs>(bob3) - val bobCloseSig1 = actions3.findOutgoingMessage() - assertTrue(3000.sat < bobCloseSig1.feeSatoshis) - assertEquals(bob3.state.closingTxProposed.last().size, 1) - assertNotNull(bob3.state.bestUnpublishedClosingTx) - - val (aliceCloseSig2, _) = makeLegacyClosingSigned(alice2, bob2, 750.sat) - val (bob4, actions4) = bob3.process(ChannelCommand.MessageReceived(aliceCloseSig2)) - assertIs>(bob4) - val bobCloseSig2 = actions4.findOutgoingMessage() - assertTrue(2000.sat < bobCloseSig2.feeSatoshis) - assertEquals(bob4.state.closingTxProposed.last().size, 2) - assertNotNull(bob4.state.bestUnpublishedClosingTx) - - val (aliceCloseSig3, _) = makeLegacyClosingSigned(alice2, bob2, 1000.sat) - val (bob5, actions5) = bob4.process(ChannelCommand.MessageReceived(aliceCloseSig3)) - assertIs>(bob5) - val bobCloseSig3 = actions5.findOutgoingMessage() - assertTrue(1500.sat < bobCloseSig3.feeSatoshis) - assertEquals(bob5.state.closingTxProposed.last().size, 3) - assertNotNull(bob5.state.bestUnpublishedClosingTx) - - val (aliceCloseSig4, _) = makeLegacyClosingSigned(alice2, bob2, 1300.sat) - val (bob6, actions6) = bob5.process(ChannelCommand.MessageReceived(aliceCloseSig4)) - assertIs>(bob6) - val bobCloseSig4 = actions6.findOutgoingMessage() - assertTrue(1300.sat < bobCloseSig4.feeSatoshis) - assertEquals(bob6.state.closingTxProposed.last().size, 4) - assertNotNull(bob6.state.bestUnpublishedClosingTx) - - val (aliceCloseSig5, _) = makeLegacyClosingSigned(alice2, bob2, bobCloseSig4.feeSatoshis) - val (bob7, actions7) = bob6.process(ChannelCommand.MessageReceived(aliceCloseSig5)) - assertIs>(bob7) - val mutualCloseTx = actions7.findPublishTxs().first() - assertEquals(bob7.state.mutualClosePublished.size, 1) - assertEquals(mutualCloseTx, bob7.state.mutualClosePublished.first().tx) + fun `recv ClosingComplete and ClosingSig with encrypted channel data`() { + val (alice, bob, closingCompleteAlice, closingCompleteBob) = init() + assertTrue(alice.commitments.params.localParams.features.hasFeature(Feature.ChannelBackupProvider)) + assertTrue(bob.commitments.params.localParams.features.hasFeature(Feature.ChannelBackupClient)) + assertTrue(closingCompleteAlice.channelData.isEmpty()) + assertFalse(closingCompleteBob.channelData.isEmpty()) + val (_, actions1) = bob.process(ChannelCommand.MessageReceived(closingCompleteAlice)) + val closingSigBob = actions1.hasOutgoingMessage() + assertFalse(closingSigBob.channelData.isEmpty()) } @Test - fun `recv ClosingSigned -- other side ignores our fee range + max iterations reached`() { - val (alice, bob) = reachNormal() - val alice1 = alice.updateFeerate(FeeratePerKw(1_000.sat)) - val (alice2, bob2, aliceCloseSig1) = mutualCloseAlice(alice1, bob) - assertIs>(alice2) - var mutableAlice: LNChannel = alice2 - var aliceCloseSig = aliceCloseSig1 - - for (i in 1..Channel.MAX_NEGOTIATION_ITERATIONS) { - val feeRange = aliceCloseSig.tlvStream.get() - assertNotNull(feeRange) - val bobNextFee = (aliceCloseSig.feeSatoshis + 500.sat).max(feeRange.max + 1.sat) - val (_, bobClosing) = makeLegacyClosingSigned(alice2, bob2, bobNextFee) - val (aliceNew, actions) = mutableAlice.process(ChannelCommand.MessageReceived(bobClosing)) - aliceCloseSig = actions.findOutgoingMessage() - assertIs>(aliceNew) - mutableAlice = aliceNew + fun `recv BITCOIN_TX_CONFIRMED -- signed mutual close`() { + val (alice, bob, closingComplete, _) = init() + + val (bob1, actionsBob1) = bob.process(ChannelCommand.MessageReceived(closingComplete)) + val closingTx = actionsBob1.findPublishTxs().first() + val closingSig = actionsBob1.findOutgoingMessage() + + val (alice1, actionsAlice1) = alice.process(ChannelCommand.MessageReceived(closingSig)) + assertTrue(actionsAlice1.findPublishTxs().contains(closingTx)) + actionsAlice1.hasWatchConfirmed(closingTx.txid) + + val (alice2, actionsAlice2) = alice1.process(ChannelCommand.WatchReceived(WatchEventConfirmed(alice.channelId, BITCOIN_TX_CONFIRMED(closingTx), 0, 0, closingTx))) + assertIs(alice2.state) + assertEquals(3, actionsAlice2.size) + actionsAlice2.has() + actionsAlice2.find().also { + assertEquals(closingTx.txid, it.txId) + assertEquals(ChannelClosingType.Mutual, it.closingType) + assertTrue(it.miningFees > 0.sat) + assertEquals(800_000.sat, it.amount + it.miningFees) } - - assertIs>(mutableAlice) - assertEquals(mutableAlice.state.mutualClosePublished.size, 1) + actionsAlice2.find().also { assertEquals(closingTx.txid, it.txId) } + + val (bob2, actionsBob2) = bob1.process(ChannelCommand.WatchReceived(WatchEventConfirmed(bob.channelId, BITCOIN_TX_CONFIRMED(closingTx), 0, 0, closingTx))) + assertIs(bob2.state) + assertEquals(3, actionsBob2.size) + actionsBob2.has() + actionsBob2.find().also { + assertEquals(closingTx.txid, it.txId) + assertEquals(ChannelClosingType.Mutual, it.closingType) + assertEquals(200_000.sat, it.amount) + } + actionsBob2.find().also { assertEquals(closingTx.txid, it.txId) } } @Test - fun `recv ClosingSigned -- invalid signature`() { - val (_, bob, aliceCloseSig) = init() - val (bob1, actions) = bob.process(ChannelCommand.MessageReceived(aliceCloseSig.copy(feeSatoshis = 99_000.sat))) - assertIs>(bob1) - actions.hasOutgoingMessage() - actions.hasWatch() - actions.findPublishTxs().contains(bob.commitments.latest.localCommit.publishableTxs.commitTx.tx) + fun `recv BITCOIN_TX_CONFIRMED -- proposed mutual close`() { + val (alice, bob, closingComplete, _) = init() + + val (bob1, actionsBob1) = bob.process(ChannelCommand.MessageReceived(closingComplete)) + val closingTx = actionsBob1.findPublishTxs().first() + actionsBob1.findOutgoingMessage() + + val (alice1, actionsAlice1) = alice.process(ChannelCommand.WatchReceived(WatchEventConfirmed(alice.channelId, BITCOIN_TX_CONFIRMED(closingTx), 0, 0, closingTx))) + assertIs(alice1.state) + assertEquals(3, actionsAlice1.size) + actionsAlice1.has() + actionsAlice1.find().also { + assertEquals(closingTx.txid, it.txId) + assertEquals(ChannelClosingType.Mutual, it.closingType) + assertTrue(it.miningFees > 0.sat) + assertEquals(800_000.sat, it.amount + it.miningFees) + } + actionsAlice1.find().also { assertEquals(closingTx.txid, it.txId) } + + val (bob2, actionsBob2) = bob1.process(ChannelCommand.WatchReceived(WatchEventConfirmed(bob.channelId, BITCOIN_TX_CONFIRMED(closingTx), 0, 0, closingTx))) + assertIs(bob2.state) + assertEquals(3, actionsBob2.size) + actionsBob2.has() + actionsBob2.find().also { + assertEquals(closingTx.txid, it.txId) + assertEquals(ChannelClosingType.Mutual, it.closingType) + assertEquals(200_000.sat, it.amount) + } + actionsBob2.find().also { assertEquals(closingTx.txid, it.txId) } } @Test - fun `recv ClosingSigned with encrypted channel data`() { - val (alice, bob, aliceCloseSig) = init() - assertTrue(alice.commitments.params.localParams.features.hasFeature(Feature.ChannelBackupProvider)) - assertTrue(bob.commitments.params.localParams.features.hasFeature(Feature.ChannelBackupClient)) - assertTrue(aliceCloseSig.channelData.isEmpty()) - val (_, actions1) = bob.process(ChannelCommand.MessageReceived(aliceCloseSig)) - val bobCloseSig = actions1.hasOutgoingMessage() - assertFalse(bobCloseSig.channelData.isEmpty()) + fun `recv BITCOIN_FUNDING_SPENT -- their commit`() { + val (alice, bob, closingComplete, _) = init() + val (alice1, bob1) = signClosingTxAlice(alice, bob, closingComplete) + + val bobCommitTx = bob1.commitments.latest.localCommit.publishableTxs.commitTx.tx + val (alice2, actions2) = alice1.process(ChannelCommand.WatchReceived(WatchEventSpent(alice.channelId, BITCOIN_FUNDING_SPENT, bobCommitTx))) + assertIs>(alice2) + assertEquals(5, actions2.size) + assertNotNull(alice2.state.remoteCommitPublished) + assertTrue(alice2.state.mutualClosePublished.isNotEmpty()) + actions2.has() + val claimMain = actions2.hasPublishTx(ChannelAction.Blockchain.PublishTx.Type.ClaimRemoteDelayedOutputTx) + actions2.hasWatchConfirmed(bobCommitTx.txid) + actions2.hasWatchConfirmed(claimMain.txid) + actions2.has() } @Test - fun `recv BITCOIN_FUNDING_SPENT -- counterparty's mutual close`() { - // NB: we're not the initiator here - val (bob, alice, fundingTx) = reachNormal() - val priv = randomKey() - - // Alice initiates a mutual close with a custom final script - val finalScript = Script.write(Script.pay2pkh(priv.publicKey())).toByteVector() - val (alice1, actions1) = alice.process(ChannelCommand.Close.MutualClose(finalScript, null)) - val shutdownA = actions1.findOutgoingMessage() - - // Bob replies with Shutdown + ClosingSigned - val (bob1, actions2) = bob.process(ChannelCommand.MessageReceived(shutdownA)) - val shutdownB = actions2.findOutgoingMessage() - val closingSignedB = actions2.findOutgoingMessage() - - // Alice agrees with Bob's closing fee, publishes her closing tx and replies with her own ClosingSigned - val (alice2, _) = alice1.process(ChannelCommand.MessageReceived(shutdownB)) - val (alice3, actions4) = alice2.process(ChannelCommand.MessageReceived(closingSignedB)) - assertIs>(alice3) - val closingTxA = actions4.filterIsInstance().first().tx - val closingSignedA = actions4.findOutgoingMessage() - val watch = actions4.findWatch() - assertEquals(watch.txId, closingTxA.txid) - - assertEquals(fundingTx.txid, closingTxA.txIn[0].outPoint.txid) - // check that our closing tx is correctly signed - Transaction.correctlySpends(closingTxA, fundingTx, ScriptFlags.STANDARD_SCRIPT_VERIFY_FLAGS) - - // Bob published his closing tx (which should be the same as Alice's) - val (bob2, actions5) = bob1.process(ChannelCommand.MessageReceived(closingSignedA)) - assertIs>(bob2) - val closingTxB = actions5.filterIsInstance().first().tx - assertEquals(closingTxA, closingTxB) - - // Alice sees Bob's closing tx (which should be the same as the one she published) - val (alice4, _) = alice3.process(ChannelCommand.WatchReceived(WatchEventSpent(alice3.channelId, BITCOIN_FUNDING_SPENT, closingTxB))) - assertIs>(alice4) - - val (alice5, _) = alice4.process(ChannelCommand.WatchReceived(WatchEventConfirmed(alice3.channelId, BITCOIN_TX_CONFIRMED(closingTxA), 144, 0, closingTxA))) - assertIs>(alice5) - } + fun `recv BITCOIN_FUNDING_SPENT -- revoked tx`() { + val (alice, bob, revokedCommit) = run { + val (alice0, bob0) = reachNormal() + val revokedCommit = bob0.commitments.latest.localCommit.publishableTxs.commitTx.tx + val (nodes1, r, htlc) = addHtlc(50_000_000.msat, alice0, bob0) + val (alice2, bob2) = crossSign(nodes1.first, nodes1.second) + val (alice3, bob3) = fulfillHtlc(htlc.id, r, alice2, bob2) + val (bob4, alice4) = crossSign(bob3, alice3) + Triple(alice4, bob4, revokedCommit) + } - @Test - fun `recv BITCOIN_FUNDING_SPENT -- an older mutual close`() { - val (alice, bob) = reachNormal() - val alice1 = alice.updateFeerate(FeeratePerKw(1_000.sat)) - val bob1 = bob.updateFeerate(FeeratePerKw(10_000.sat)) - val (alice2, bob2, aliceCloseSig1) = mutualCloseAlice(alice1, bob1) - - val (bob3, bobActions3) = bob2.process(ChannelCommand.MessageReceived(aliceCloseSig1)) - assertIs>(bob3) - bobActions3.findOutgoingMessage() - val firstMutualCloseTx = bob3.state.bestUnpublishedClosingTx - assertNotNull(firstMutualCloseTx) - - val (_, bobCloseSig1) = makeLegacyClosingSigned(alice2, bob2, 3_000.sat) - assertNotEquals(bobCloseSig1.feeSatoshis, aliceCloseSig1.feeSatoshis) - val (alice3, aliceActions3) = alice2.process(ChannelCommand.MessageReceived(bobCloseSig1)) - assertIs>(alice3) - val aliceCloseSig2 = aliceActions3.findOutgoingMessage() - assertNotEquals(aliceCloseSig2.feeSatoshis, bobCloseSig1.feeSatoshis) - val latestMutualCloseTx = alice3.state.bestUnpublishedClosingTx - assertNotNull(latestMutualCloseTx) - assertNotEquals(firstMutualCloseTx.tx.txid, latestMutualCloseTx.tx.txid) - - // at this point bob will receive a new signature, but he decides instead to publish the first mutual close - val (alice4, aliceActions4) = alice3.process(ChannelCommand.WatchReceived(WatchEventSpent(alice3.channelId, BITCOIN_FUNDING_SPENT, firstMutualCloseTx.tx))) + val (alice1, actionsAlice1) = alice.process(ChannelCommand.Close.MutualClose(null, null)) + val shutdownAlice = actionsAlice1.findOutgoingMessage() + val (bob1, actionsBob1) = bob.process(ChannelCommand.MessageReceived(shutdownAlice)) + assertIs>(bob1) + val shutdownBob = actionsBob1.findOutgoingMessage() + actionsBob1.findOutgoingMessage() + val (alice2, actionsAlice2) = alice1.process(ChannelCommand.MessageReceived(shutdownBob)) + assertIs>(alice2) + val closingComplete = actionsAlice2.findOutgoingMessage() + val (alice3, _) = signClosingTxAlice(alice2, bob1, closingComplete) + + val (alice4, actionsAlice4) = alice3.process(ChannelCommand.WatchReceived(WatchEventSpent(alice.channelId, BITCOIN_FUNDING_SPENT, revokedCommit))) assertIs>(alice4) - aliceActions4.has() - aliceActions4.hasPublishTx(firstMutualCloseTx.tx) - assertEquals(aliceActions4.hasWatch().txId, firstMutualCloseTx.tx.txid) + assertTrue(alice4.state.revokedCommitPublished.isNotEmpty()) + assertTrue(alice4.state.mutualClosePublished.isNotEmpty()) + actionsAlice4.has() + val claimMain = actionsAlice4.hasPublishTx(ChannelAction.Blockchain.PublishTx.Type.ClaimRemoteDelayedOutputTx) + actionsAlice4.hasPublishTx(ChannelAction.Blockchain.PublishTx.Type.MainPenaltyTx) + actionsAlice4.hasWatchConfirmed(revokedCommit.txid) + actionsAlice4.hasWatchConfirmed(claimMain.txid) + actionsAlice4.has() } @Test @@ -444,46 +341,42 @@ class NegotiatingTestsCommon : LightningTestSuite() { } companion object { + data class Fixture(val alice: LNChannel, val bob: LNChannel, val closingCompleteAlice: ClosingComplete, val closingCompleteBob: ClosingComplete) + fun init( channelType: ChannelType.SupportedChannelType = ChannelType.SupportedChannelType.AnchorOutputs, - alicePushAmount: MilliSatoshi = TestConstants.alicePushAmount - ): Triple, LNChannel, ClosingSigned> { - val (alice, bob) = reachNormal(channelType = channelType, alicePushAmount = alicePushAmount) - return mutualCloseAlice(alice, bob) - } - - private fun makeLegacyClosingSigned(alice: LNChannel, bob: LNChannel, closingFee: Satoshi): Pair { - val aliceScript = alice.state.localShutdown.scriptPubKey.toByteArray() - val bobScript = bob.state.localShutdown.scriptPubKey.toByteArray() - val aliceKeys = alice.ctx.keyManager.channelKeys(alice.commitments.params.localParams.fundingKeyPath) - val bobKeys = bob.ctx.keyManager.channelKeys(bob.commitments.params.localParams.fundingKeyPath) - val (_, aliceClosingSigned) = Helpers.Closing.makeClosingTx(aliceKeys, alice.commitments.latest, aliceScript, bobScript, ClosingFees(closingFee, closingFee, closingFee)) - val (_, bobClosingSigned) = Helpers.Closing.makeClosingTx(bobKeys, bob.commitments.latest, bobScript, aliceScript, ClosingFees(closingFee, closingFee, closingFee)) - return Pair(aliceClosingSigned.copy(tlvStream = TlvStream.empty()), bobClosingSigned.copy(tlvStream = TlvStream.empty())) + aliceFundingAmount: Satoshi = TestConstants.aliceFundingAmount, + bobFundingAmount: Satoshi = TestConstants.bobFundingAmount, + alicePushAmount: MilliSatoshi = TestConstants.alicePushAmount, + closingFeerate: FeeratePerKw? = null, + closingScript: ByteVector? = null, + ): Fixture { + val (alice, bob) = reachNormal(channelType = channelType, aliceFundingAmount = aliceFundingAmount, bobFundingAmount = bobFundingAmount, alicePushAmount = alicePushAmount) + val (alice1, actionsAlice1) = alice.process(ChannelCommand.Close.MutualClose(closingScript, closingFeerate)) + val shutdownAlice = actionsAlice1.findOutgoingMessage() + assertNull(actionsAlice1.findOutgoingMessageOpt()) + + val (bob1, actionsBob1) = bob.process(ChannelCommand.MessageReceived(shutdownAlice)) + assertIs>(bob1) + val shutdownBob = actionsBob1.findOutgoingMessage() + val closingCompleteBob = actionsBob1.findOutgoingMessage() + + val (alice2, actionsAlice2) = alice1.process(ChannelCommand.MessageReceived(shutdownBob)) + assertIs>(alice2) + val closingCompleteAlice = actionsAlice2.findOutgoingMessage() + + return Fixture(alice2, bob1, closingCompleteAlice, closingCompleteBob) } - tailrec fun converge(a: LNChannel, b: LNChannel, aliceCloseSig: ClosingSigned?): Pair, LNChannel>? { - return when { - a.state !is ChannelStateWithCommitments || b.state !is ChannelStateWithCommitments -> null - a.state is Closing && b.state is Closing -> Pair(LNChannel(a.ctx, a.state), LNChannel(b.ctx, b.state)) - aliceCloseSig != null -> { - val (b1, actions) = b.process(ChannelCommand.MessageReceived(aliceCloseSig)) - val bobCloseSig = actions.findOutgoingMessageOpt() - if (bobCloseSig != null) { - val (a1, actions2) = a.process(ChannelCommand.MessageReceived(bobCloseSig)) - return converge(a1, b1, actions2.findOutgoingMessageOpt()) - } - val bobClosingTx = actions.filterIsInstance().map { it.tx }.firstOrNull() - if (bobClosingTx != null && bobClosingTx.txIn[0].outPoint == a.commitments.latest.localCommit.publishableTxs.commitTx.input.outPoint && a.state !is Closing) { - // Bob just spent the funding tx - val (a1, actions2) = a.process(ChannelCommand.WatchReceived(WatchEventSpent(a.channelId, BITCOIN_FUNDING_SPENT, bobClosingTx))) - actions2.find().also { assertEquals(bobClosingTx.txid, it.txId) } - return converge(a1, b1, actions2.findOutgoingMessageOpt()) - } - converge(a, b1, null) - } - else -> null - } + fun signClosingTxAlice(alice: LNChannel, bob: LNChannel, closingComplete: ClosingComplete): Pair, LNChannel> { + val (bob1, actionsBob1) = bob.process(ChannelCommand.MessageReceived(closingComplete)) + assertIs>(bob1) + val closingTx = actionsBob1.findPublishTxs().first() + val closingSig = actionsBob1.findOutgoingMessage() + val (alice1, actionsAlice1) = alice.process(ChannelCommand.MessageReceived(closingSig)) + assertIs>(alice1) + assertTrue(actionsAlice1.findPublishTxs().contains(closingTx)) + return Pair(alice1, bob1) } } diff --git a/src/commonTest/kotlin/fr/acinq/lightning/channel/states/NormalTestsCommon.kt b/src/commonTest/kotlin/fr/acinq/lightning/channel/states/NormalTestsCommon.kt index f80517101..d664cd9fe 100644 --- a/src/commonTest/kotlin/fr/acinq/lightning/channel/states/NormalTestsCommon.kt +++ b/src/commonTest/kotlin/fr/acinq/lightning/channel/states/NormalTestsCommon.kt @@ -2,8 +2,11 @@ package fr.acinq.lightning.channel.states import fr.acinq.bitcoin.* import fr.acinq.bitcoin.utils.Either -import fr.acinq.lightning.* +import fr.acinq.lightning.CltvExpiry +import fr.acinq.lightning.CltvExpiryDelta +import fr.acinq.lightning.Feature import fr.acinq.lightning.Lightning.randomBytes32 +import fr.acinq.lightning.ShortChannelId import fr.acinq.lightning.blockchain.* import fr.acinq.lightning.blockchain.fee.FeeratePerKw import fr.acinq.lightning.channel.* @@ -1527,21 +1530,9 @@ class NormalTestsCommon : LightningTestSuite() { actions1.hasCommandError() } - @Test - fun `recv ChannelCommand_Close_MutualClose -- with unsupported native segwit script`() { - val (alice, _) = reachNormal() - assertNull(alice.state.localShutdown) - val (alice1, actions1) = alice.process(ChannelCommand.Close.MutualClose(ByteVector("51050102030405"), null)) - assertIs>(alice1) - actions1.hasCommandError() - } - @Test fun `recv ChannelCommand_Close_MutualClose -- with native segwit script`() { - val (alice, _) = reachNormal( - aliceFeatures = TestConstants.Alice.nodeParams.features.copy(TestConstants.Alice.nodeParams.features.activated + (Feature.ShutdownAnySegwit to FeatureSupport.Optional)), - bobFeatures = TestConstants.Bob.nodeParams.features.copy(TestConstants.Bob.nodeParams.features.activated + (Feature.ShutdownAnySegwit to FeatureSupport.Optional)), - ) + val (alice, _) = reachNormal() assertNull(alice.state.localShutdown) val (alice1, actions1) = alice.process(ChannelCommand.Close.MutualClose(ByteVector("51050102030405"), null)) actions1.hasOutgoingMessage() @@ -1604,7 +1595,7 @@ class NormalTestsCommon : LightningTestSuite() { val (alice1, actions1) = alice.process(ChannelCommand.MessageReceived(Shutdown(alice.channelId, bob.commitments.params.localParams.defaultFinalScriptPubKey))) assertIs>(alice1) actions1.hasOutgoingMessage() - actions1.hasOutgoingMessage() + actions1.hasOutgoingMessage() } @Test @@ -1666,13 +1657,13 @@ class NormalTestsCommon : LightningTestSuite() { val (alice5, aliceActions5) = alice4.process(ChannelCommand.MessageReceived(sigBob)) assertIs>(alice5) val revAlice = aliceActions5.hasOutgoingMessage() - val closingAlice = aliceActions5.hasOutgoingMessage() + val closingAlice = aliceActions5.hasOutgoingMessage() val (bob5, _) = bob4.process(ChannelCommand.MessageReceived(shutdownAlice)) val (bob6, _) = bob5.process(ChannelCommand.MessageReceived(revAlice)) val (bob7, bobActions7) = bob6.process(ChannelCommand.MessageReceived(closingAlice)) assertIs>(bob7) - val closingBob = bobActions7.hasOutgoingMessage() + val closingBob = bobActions7.hasOutgoingMessage() val (alice6, _) = alice5.process(ChannelCommand.MessageReceived(closingBob)) assertIs>(alice6) } @@ -1687,22 +1678,9 @@ class NormalTestsCommon : LightningTestSuite() { actions1.hasWatch() } - @Test - fun `recv Shutdown -- with unsupported native segwit script`() { - val (_, bob) = reachNormal() - val (bob1, actions1) = bob.process(ChannelCommand.MessageReceived(Shutdown(bob.channelId, ByteVector("51050102030405")))) - assertIs>(bob1) - actions1.hasOutgoingMessage() - assertEquals(2, actions1.filterIsInstance().count()) - actions1.hasWatch() - } - @Test fun `recv Shutdown -- with native segwit script`() { - val (_, bob) = reachNormal( - aliceFeatures = TestConstants.Alice.nodeParams.features.copy(TestConstants.Alice.nodeParams.features.activated + (Feature.ShutdownAnySegwit to FeatureSupport.Optional)), - bobFeatures = TestConstants.Bob.nodeParams.features.copy(TestConstants.Bob.nodeParams.features.activated + (Feature.ShutdownAnySegwit to FeatureSupport.Optional)), - ) + val (_, bob) = reachNormal() val (bob1, actions1) = bob.process(ChannelCommand.MessageReceived(Shutdown(bob.channelId, ByteVector("51050102030405")))) assertIs>(bob1) actions1.hasOutgoingMessage() diff --git a/src/commonTest/kotlin/fr/acinq/lightning/channel/states/QuiescenceTestsCommon.kt b/src/commonTest/kotlin/fr/acinq/lightning/channel/states/QuiescenceTestsCommon.kt index 430b971de..ad0bd7ef8 100644 --- a/src/commonTest/kotlin/fr/acinq/lightning/channel/states/QuiescenceTestsCommon.kt +++ b/src/commonTest/kotlin/fr/acinq/lightning/channel/states/QuiescenceTestsCommon.kt @@ -321,9 +321,10 @@ class QuiescenceTestsCommon : LightningTestSuite() { val (alice2, actionsAlice2) = alice1.process(ChannelCommand.MessageReceived(shutdownBob)) assertIs(alice2.state) val shutdownAlice = actionsAlice2.findOutgoingMessage() - actionsAlice2.findOutgoingMessage() + actionsAlice2.findOutgoingMessage() val (bob3, actionsBob3) = bob2.process(ChannelCommand.MessageReceived(shutdownAlice)) assertIs(bob3.state) + actionsBob3.findOutgoingMessage() actionsBob3.has() } diff --git a/src/commonTest/kotlin/fr/acinq/lightning/channel/states/ShutdownTestsCommon.kt b/src/commonTest/kotlin/fr/acinq/lightning/channel/states/ShutdownTestsCommon.kt index 50b4685ff..902ba047c 100644 --- a/src/commonTest/kotlin/fr/acinq/lightning/channel/states/ShutdownTestsCommon.kt +++ b/src/commonTest/kotlin/fr/acinq/lightning/channel/states/ShutdownTestsCommon.kt @@ -11,6 +11,7 @@ import fr.acinq.lightning.blockchain.BITCOIN_FUNDING_SPENT import fr.acinq.lightning.blockchain.WatchConfirmed import fr.acinq.lightning.blockchain.WatchEventSpent import fr.acinq.lightning.blockchain.WatchSpent +import fr.acinq.lightning.blockchain.fee.FeeratePerKw import fr.acinq.lightning.channel.* import fr.acinq.lightning.channel.TestsHelper.addHtlc import fr.acinq.lightning.channel.TestsHelper.claimHtlcSuccessTxs @@ -472,9 +473,23 @@ class ShutdownTestsCommon : LightningTestSuite() { @Test fun `recv ChannelCommand_Close_MutualClose`() { val (alice, _) = init() - val (alice1, actions) = alice.process(ChannelCommand.Close.MutualClose(null, null)) - assertEquals(alice1, alice) - assertEquals(actions, listOf(ChannelAction.ProcessCmdRes.NotExecuted(ChannelCommand.Close.MutualClose(null, null), ClosingAlreadyInProgress(alice.channelId)))) + + // Update our closing feerate. + val (alice1, actions1) = alice.process(ChannelCommand.Close.MutualClose(null, FeeratePerKw(5000.sat()))) + assertIs(alice1.state) + assertEquals(FeeratePerKw(5000.sat()), alice1.state.closingFeerate) + assertEquals(1, actions1.size) + actions1.has() + + // Update our closing script. + val closingScript = Script.write(Script.pay2wpkh(randomKey().publicKey())).byteVector() + val (alice2, actions2) = alice1.process(ChannelCommand.Close.MutualClose(closingScript, null)) + assertIs(alice2.state) + assertEquals(FeeratePerKw(5000.sat()), alice2.state.closingFeerate) + assertEquals(2, actions2.size) + actions2.has() + val shutdown = actions2.findOutgoingMessage() + assertEquals(shutdown, alice2.state.localShutdown) } private fun testLocalForceClose(alice: LNChannel, actions: List) { diff --git a/src/commonTest/kotlin/fr/acinq/lightning/payment/OutgoingPaymentHandlerTestsCommon.kt b/src/commonTest/kotlin/fr/acinq/lightning/payment/OutgoingPaymentHandlerTestsCommon.kt index 868530494..9082c1cf8 100644 --- a/src/commonTest/kotlin/fr/acinq/lightning/payment/OutgoingPaymentHandlerTestsCommon.kt +++ b/src/commonTest/kotlin/fr/acinq/lightning/payment/OutgoingPaymentHandlerTestsCommon.kt @@ -53,11 +53,12 @@ class OutgoingPaymentHandlerTestsCommon : LightningTestSuite() { Feature.VariableLengthOnion to FeatureSupport.Mandatory, Feature.PaymentSecret to FeatureSupport.Mandatory, Feature.BasicMultiPartPayment to FeatureSupport.Optional, - Feature.DualFunding to FeatureSupport.Mandatory + Feature.DualFunding to FeatureSupport.Mandatory, + Feature.ShutdownAnySegwit to FeatureSupport.Mandatory, + Feature.SimpleClose to FeatureSupport.Mandatory, ) // The following invoice requires payment_metadata. - val invoice1 = - Bolt11InvoiceTestsCommon.createInvoiceUnsafe(features = Features(Feature.VariableLengthOnion to FeatureSupport.Mandatory, Feature.PaymentSecret to FeatureSupport.Mandatory, Feature.PaymentMetadata to FeatureSupport.Mandatory)) + val invoice1 = Bolt11InvoiceTestsCommon.createInvoiceUnsafe(features = Features(Feature.VariableLengthOnion to FeatureSupport.Mandatory, Feature.PaymentSecret to FeatureSupport.Mandatory, Feature.PaymentMetadata to FeatureSupport.Mandatory)) // The following invoice requires unknown feature bit 188. val invoice2 = Bolt11InvoiceTestsCommon.createInvoiceUnsafe(features = Features(mapOf(Feature.VariableLengthOnion to FeatureSupport.Mandatory, Feature.PaymentSecret to FeatureSupport.Mandatory), setOf(UnknownFeature(188)))) for (invoice in listOf(invoice1, invoice2)) { diff --git a/src/commonTest/kotlin/fr/acinq/lightning/tests/TestConstants.kt b/src/commonTest/kotlin/fr/acinq/lightning/tests/TestConstants.kt index e7eec6023..0084af51c 100644 --- a/src/commonTest/kotlin/fr/acinq/lightning/tests/TestConstants.kt +++ b/src/commonTest/kotlin/fr/acinq/lightning/tests/TestConstants.kt @@ -63,6 +63,8 @@ object TestConstants { Feature.DualFunding to FeatureSupport.Mandatory, Feature.ChannelType to FeatureSupport.Mandatory, Feature.PaymentMetadata to FeatureSupport.Optional, + Feature.ShutdownAnySegwit to FeatureSupport.Mandatory, + Feature.SimpleClose to FeatureSupport.Mandatory, Feature.ExperimentalTrampolinePayment to FeatureSupport.Optional, Feature.WakeUpNotificationProvider to FeatureSupport.Optional, Feature.PayToOpenProvider to FeatureSupport.Optional, diff --git a/src/commonTest/kotlin/fr/acinq/lightning/transactions/TransactionsTestsCommon.kt b/src/commonTest/kotlin/fr/acinq/lightning/transactions/TransactionsTestsCommon.kt index eccfc4e4d..bb11df266 100644 --- a/src/commonTest/kotlin/fr/acinq/lightning/transactions/TransactionsTestsCommon.kt +++ b/src/commonTest/kotlin/fr/acinq/lightning/transactions/TransactionsTestsCommon.kt @@ -43,7 +43,7 @@ import fr.acinq.lightning.transactions.Transactions.makeClaimHtlcSuccessTx import fr.acinq.lightning.transactions.Transactions.makeClaimHtlcTimeoutTx import fr.acinq.lightning.transactions.Transactions.makeClaimLocalDelayedOutputTx import fr.acinq.lightning.transactions.Transactions.makeClaimRemoteDelayedOutputTx -import fr.acinq.lightning.transactions.Transactions.makeClosingTx +import fr.acinq.lightning.transactions.Transactions.makeClosingTxs import fr.acinq.lightning.transactions.Transactions.makeCommitTx import fr.acinq.lightning.transactions.Transactions.makeCommitTxOutputs import fr.acinq.lightning.transactions.Transactions.makeHtlcPenaltyTx @@ -650,54 +650,63 @@ class TransactionsTestsCommon : LightningTestSuite() { @Test fun `find our output in closing tx`() { - val localPubKeyScript = write(pay2wpkh(PrivateKey(randomBytes32()).publicKey())) - val remotePubKeyScript = write(pay2wpkh(PrivateKey(randomBytes32()).publicKey())) + val localPubKeyScript = write(pay2wpkh(PrivateKey(randomBytes32()).publicKey())).byteVector() + val remotePubKeyScript = write(pay2wpkh(PrivateKey(randomBytes32()).publicKey())).byteVector() run { - // Different amounts, both outputs untrimmed, local is the initiator: + // Different amounts, both outputs untrimmed, local is closer: val spec = CommitmentSpec(setOf(), feerate, 150_000_000.msat, 250_000_000.msat) - val closingTx = makeClosingTx(commitInput, localPubKeyScript, remotePubKeyScript, localIsInitiator = true, localDustLimit, 1000.sat, spec) - assertEquals(2, closingTx.tx.txOut.size) - assertNotNull(closingTx.toLocalIndex) - assertEquals(localPubKeyScript.toByteVector(), closingTx.toLocalOutput!!.publicKeyScript) - assertEquals(149_000.sat, closingTx.toLocalOutput!!.amount) // initiator pays the fee - val toRemoteIndex = (closingTx.toLocalIndex!! + 1) % 2 - assertEquals(250_000.sat, closingTx.tx.txOut[toRemoteIndex].amount) + val closingTxs = makeClosingTxs(commitInput, spec, Transactions.ClosingTxFee.PaidByUs(5_000.sat), 0, localPubKeyScript, remotePubKeyScript) + assertNotNull(closingTxs.localAndRemote) + assertNotNull(closingTxs.localOnly) + assertNull(closingTxs.remoteOnly) + val localAndRemote = closingTxs.localAndRemote?.toLocalOutput!! + assertEquals(localPubKeyScript, localAndRemote.publicKeyScript) + assertEquals(145_000.sat, localAndRemote.amount) + val localOnly = closingTxs.localOnly?.toLocalOutput!! + assertEquals(localPubKeyScript, localOnly.publicKeyScript) + assertEquals(145_000.sat, localOnly.amount) } run { - // Same amounts, both outputs untrimmed, local is not the initiator: - val spec = CommitmentSpec(setOf(), feerate, 150_000_000.msat, 150_000_000.msat) - val closingTx = makeClosingTx(commitInput, localPubKeyScript, remotePubKeyScript, localIsInitiator = false, localDustLimit, 1000.sat, spec) - assertEquals(2, closingTx.tx.txOut.size) - assertNotNull(closingTx.toLocalIndex) - assertEquals(localPubKeyScript.toByteVector(), closingTx.toLocalOutput!!.publicKeyScript) - assertEquals(150_000.sat, closingTx.toLocalOutput!!.amount) - val toRemoteIndex = (closingTx.toLocalIndex!! + 1) % 2 - assertEquals(149_000.sat, closingTx.tx.txOut[toRemoteIndex].amount) + // Same amounts, both outputs untrimmed, remote is closer: + val spec = CommitmentSpec(setOf(), feerate, 150_000_000.msat, 250_000_000.msat) + val closingTxs = makeClosingTxs(commitInput, spec, Transactions.ClosingTxFee.PaidByThem(5_000.sat), 0, localPubKeyScript, remotePubKeyScript) + assertNotNull(closingTxs.localAndRemote) + assertNotNull(closingTxs.localOnly) + assertNull(closingTxs.remoteOnly) + val localAndRemote = closingTxs.localAndRemote?.toLocalOutput!! + assertEquals(localPubKeyScript, localAndRemote.publicKeyScript) + assertEquals(150_000.sat, localAndRemote.amount) + val localOnly = closingTxs.localOnly?.toLocalOutput!! + assertEquals(localPubKeyScript, localOnly.publicKeyScript) + assertEquals(150_000.sat, localOnly.amount) } run { // Their output is trimmed: - val spec = CommitmentSpec(setOf(), feerate, 150_000_000.msat, 1_000.msat) - val closingTx = makeClosingTx(commitInput, localPubKeyScript, remotePubKeyScript, localIsInitiator = false, localDustLimit, 1000.sat, spec) - assertEquals(1, closingTx.tx.txOut.size) - assertNotNull(closingTx.toLocalOutput) - assertEquals(localPubKeyScript.toByteVector(), closingTx.toLocalOutput!!.publicKeyScript) - assertEquals(150_000.sat, closingTx.toLocalOutput!!.amount) - assertEquals(0, closingTx.toLocalIndex!!) + val spec = CommitmentSpec(setOf(), feerate, 150_000_000.msat, 1_000_000.msat) + val closingTxs = makeClosingTxs(commitInput, spec, Transactions.ClosingTxFee.PaidByThem(800.sat), 0, localPubKeyScript, remotePubKeyScript) + assertEquals(1, closingTxs.all.size) + assertNotNull(closingTxs.localOnly) + assertEquals(1, closingTxs.localOnly!!.tx.txOut.size) + val toLocal = closingTxs.localOnly?.toLocalOutput!! + assertEquals(localPubKeyScript, toLocal.publicKeyScript) + assertEquals(150_000.sat, toLocal.amount) } run { // Our output is trimmed: - val spec = CommitmentSpec(setOf(), feerate, 50_000.msat, 150_000_000.msat) - val closingTx = makeClosingTx(commitInput, localPubKeyScript, remotePubKeyScript, localIsInitiator = true, localDustLimit, 1000.sat, spec) - assertEquals(1, closingTx.tx.txOut.size) - assertNull(closingTx.toLocalOutput) + val spec = CommitmentSpec(setOf(), feerate, 1_000_000.msat, 150_000_000.msat) + val closingTxs = makeClosingTxs(commitInput, spec, Transactions.ClosingTxFee.PaidByUs(800.sat), 0, localPubKeyScript, remotePubKeyScript) + assertEquals(1, closingTxs.all.size) + assertNotNull(closingTxs.remoteOnly) + assertNull(closingTxs.remoteOnly?.toLocalOutput) } run { // Both outputs are trimmed: val spec = CommitmentSpec(setOf(), feerate, 50_000.msat, 10_000.msat) - val closingTx = makeClosingTx(commitInput, localPubKeyScript, remotePubKeyScript, localIsInitiator = true, localDustLimit, 1000.sat, spec) - assertTrue(closingTx.tx.txOut.isEmpty()) - assertNull(closingTx.toLocalOutput) + val closingTxs = makeClosingTxs(commitInput, spec, Transactions.ClosingTxFee.PaidByUs(10.sat), 0, localPubKeyScript, remotePubKeyScript) + assertNull(closingTxs.localAndRemote) + assertNull(closingTxs.localOnly) + assertNull(closingTxs.remoteOnly) } } diff --git a/src/commonTest/kotlin/fr/acinq/lightning/wire/LightningCodecsTestsCommon.kt b/src/commonTest/kotlin/fr/acinq/lightning/wire/LightningCodecsTestsCommon.kt index 3cd5db8ab..fa63a3bd4 100644 --- a/src/commonTest/kotlin/fr/acinq/lightning/wire/LightningCodecsTestsCommon.kt +++ b/src/commonTest/kotlin/fr/acinq/lightning/wire/LightningCodecsTestsCommon.kt @@ -612,54 +612,6 @@ class LightningCodecsTestsCommon : LightningTestSuite() { } } - @Test - fun `encode - decode closing_signed`() { - val defaultSig = ByteVector64("01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101") - val testCases = listOf( - Hex.decode("0027 0100000000000000000000000000000000000000000000000000000000000000 0000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") to ClosingSigned( - ByteVector32.One, - 0.sat, - ByteVector64.Zeroes - ), - Hex.decode("0027 0100000000000000000000000000000000000000000000000000000000000000 00000000000003e8 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") to ClosingSigned( - ByteVector32.One, - 1000.sat, - ByteVector64.Zeroes - ), - Hex.decode("0027 0100000000000000000000000000000000000000000000000000000000000000 00000000000005dc 01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101") to ClosingSigned( - ByteVector32.One, - 1500.sat, - defaultSig - ), - Hex.decode("0027 0100000000000000000000000000000000000000000000000000000000000000 00000000000005dc 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0110000000000000006400000000000007d0") to ClosingSigned( - ByteVector32.One, - 1500.sat, - ByteVector64.Zeroes, - TlvStream(ClosingSignedTlv.FeeRange(100.sat, 2000.sat)) - ), - Hex.decode("0027 0100000000000000000000000000000000000000000000000000000000000000 00000000000003e8 01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101 0110000000000000006400000000000007d0") to ClosingSigned( - ByteVector32.One, - 1000.sat, - defaultSig, - TlvStream(ClosingSignedTlv.FeeRange(100.sat, 2000.sat)) - ), - Hex.decode("0027 0100000000000000000000000000000000000000000000000000000000000000 0000000000000064 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0110000000000000006400000000000003e8 030401020304") to ClosingSigned( - ByteVector32.One, - 100.sat, - ByteVector64.Zeroes, - TlvStream(setOf(ClosingSignedTlv.FeeRange(100.sat, 1000.sat)), setOf(GenericTlv(3, ByteVector("01020304")))) - ), - ) - - testCases.forEach { - val decoded = LightningMessage.decode(it.first) - assertNotNull(decoded) - assertEquals(decoded, it.second) - val reEncoded = LightningMessage.encode(decoded) - assertArrayEquals(reEncoded, it.first) - } - } - @Test fun `encode - decode closing messages`() { val channelId = ByteVector32("58a00a6f14e69a2e97b18cf76f755c8551fea9947cf7b6ece9d641013eba5f86") @@ -732,13 +684,6 @@ class LightningCodecsTestsCommon : LightningTestSuite() { Hex.decode("0026") + channelId.toByteArray() + Hex.decode("002a") + randomData + Hex.decode("01 02 0102") + Hex.decode("fe47010000 00") to Shutdown(channelId, randomData.toByteVector(), TlvStream(setOf(ShutdownTlv.ChannelData(EncryptedChannelData.empty)), setOf(GenericTlv(1, ByteVector("0102"))))), Hex.decode("0026") + channelId.toByteArray() + Hex.decode("002a") + randomData + Hex.decode("fe47010000 07 cccccccccccccc") to Shutdown(channelId, randomData.toByteVector()).withChannelData(ByteVector("cccccccccccccc")), Hex.decode("0026") + channelId.toByteArray() + Hex.decode("002a") + randomData + Hex.decode("01 02 0102") + Hex.decode("fe47010000 07 cccccccccccccc") to Shutdown(channelId, randomData.toByteVector(), TlvStream(setOf(ShutdownTlv.ChannelData(EncryptedChannelData(ByteVector("cccccccccccccc")))), setOf(GenericTlv(1, ByteVector("0102"))))), - // closing_signed - Hex.decode("0027") + channelId.toByteArray() + Hex.decode("00000000075bcd15") + signature.toByteArray() to ClosingSigned(channelId, 123456789.sat, signature), - Hex.decode("0027") + channelId.toByteArray() + Hex.decode("00000000075bcd15") + signature.toByteArray() + Hex.decode("03 02 0102") to ClosingSigned(channelId, 123456789.sat, signature, TlvStream(setOf(), setOf(GenericTlv(3, ByteVector("0102"))))), - Hex.decode("0027") + channelId.toByteArray() + Hex.decode("00000000075bcd15") + signature.toByteArray() + Hex.decode("fe47010000 00") to ClosingSigned(channelId, 123456789.sat, signature, TlvStream(ClosingSignedTlv.ChannelData(EncryptedChannelData.empty))), - Hex.decode("0027") + channelId.toByteArray() + Hex.decode("00000000075bcd15") + signature.toByteArray() + Hex.decode("03 02 0102") + Hex.decode("fe47010000 00") to ClosingSigned(channelId, 123456789.sat, signature, TlvStream(setOf(ClosingSignedTlv.ChannelData(EncryptedChannelData.empty)), setOf(GenericTlv(3, ByteVector("0102"))))), - Hex.decode("0027") + channelId.toByteArray() + Hex.decode("00000000075bcd15") + signature.toByteArray() + Hex.decode("fe47010000 07 cccccccccccccc") to ClosingSigned(channelId, 123456789.sat, signature).withChannelData(ByteVector("cccccccccccccc")), - Hex.decode("0027") + channelId.toByteArray() + Hex.decode("00000000075bcd15") + signature.toByteArray() + Hex.decode("03 02 0102") + Hex.decode("fe47010000 07 cccccccccccccc") to ClosingSigned(channelId, 123456789.sat, signature, TlvStream(setOf(ClosingSignedTlv.ChannelData(EncryptedChannelData(ByteVector("cccccccccccccc")))), setOf(GenericTlv(3, ByteVector("0102"))))) // closing_complete Hex.decode("0028") + channelId.toByteArray() + Hex.decode("0000000000000451 00000000") + Hex.decode("fe47010000 00") to ClosingComplete(channelId, 1105.sat, 0, TlvStream(ClosingCompleteTlv.ChannelData(EncryptedChannelData.empty))), Hex.decode("0028") + channelId.toByteArray() + Hex.decode("0000000000000451 00000000") + Hex.decode("fe47010000 07 cccccccccccccc") to ClosingComplete(channelId, 1105.sat, 0).withChannelData(ByteVector("cccccccccccccc")), @@ -767,7 +712,6 @@ class LightningCodecsTestsCommon : LightningTestSuite() { CommitSig(randomBytes32(), randomBytes64(), listOf()), RevokeAndAck(randomBytes32(), randomKey(), randomKey().publicKey()), Shutdown(randomBytes32(), ByteVector("deadbeef")), - ClosingSigned(randomBytes32(), 0.sat, randomBytes64()), ClosingComplete(randomBytes32(), 250.sat, 0), ClosingSig(randomBytes32()), ) diff --git a/src/commonTest/resources/nonreg/v2/Negotiating_c8d15808/data.bin b/src/commonTest/resources/nonreg/v2/Negotiating_c8d15808/data.bin deleted file mode 100644 index a008b8107..000000000 --- a/src/commonTest/resources/nonreg/v2/Negotiating_c8d15808/data.bin +++ /dev/null @@ -1 +0,0 @@ -0000000200003f060000002f66722e6163696e712e6c696768746e696e672e73657269616c697a6174696f6e2e76322e4e65676f74696174696e670000002006226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f000000210362b19a83930389b4468be40308efb3f352b23142ae25e6aba0465a8220f95b0600061a800000000b426c6f636b486561646572000000500100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5494dffff7f200200000000000000000003e800000000000003e800000000000003e8000000040000000f00000021037108815ff0128f7ed22640485c226d9ad64a9fd6d8b41b6623565aed6b34812c000000090000000016f35f4f0000000075d70557000000002409cee6000000000b01aa72000000002e461aea00000000b8953c1600000000909117b700000000fa26717f0000000080000001000000000000044c0000000059682f000000000000002710000000000000000000000090000000640100000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c000000110000002d66722e6163696e712e6c696768746e696e672e466561747572652e496e697469616c526f7574696e6753796e63010000003066722e6163696e712e6c696768746e696e672e466561747572652e4f7074696f6e446174614c6f737350726f74656374010000002e66722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c52616e676551756572696573010000003666722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c52616e676551756572696573457874656e646564010000002e66722e6163696e712e6c696768746e696e672e466561747572652e5661726961626c654c656e6774684f6e696f6e000000002866722e6163696e712e6c696768746e696e672e466561747572652e5061796d656e74536563726574000000003066722e6163696e712e6c696768746e696e672e466561747572652e42617369634d756c7469506172745061796d656e74010000002066722e6163696e712e6c696768746e696e672e466561747572652e57756d626f010000002a66722e6163696e712e6c696768746e696e672e466561747572652e53746174696352656d6f74654b6579000000002866722e6163696e712e6c696768746e696e672e466561747572652e416e63686f724f757470757473000000002666722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c54797065000000002a66722e6163696e712e6c696768746e696e672e466561747572652e5061796d656e744d65746164617461010000003866722e6163696e712e6c696768746e696e672e466561747572652e4578706572696d656e74616c5472616d706f6c696e655061796d656e74010000003566722e6163696e712e6c696768746e696e672e466561747572652e57616b6555704e6f74696669636174696f6e50726f7669646572010000002c66722e6163696e712e6c696768746e696e672e466561747572652e506179546f4f70656e50726f7669646572010000003066722e6163696e712e6c696768746e696e672e466561747572652e5472757374656453776170496e50726f7669646572010000003066722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c4261636b757050726f76696465720100000000000000210362b19a83930389b4468be40308efb3f352b23142ae25e6aba0465a8220f95b0600000000000003e80000000059682f000000000000004e2000000000000003e80000009000000064000000210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa40000002103a42aef6d1c860caffa6c71a6f8ac2b16eec25bab0c3950cdb1fad7fb38a5f2a50000002102508e1845b8bbe0773f6bf8f3f04f59a5896426765c7b6b23e6e466c95381182b0000002102d62233b7c33f8fd0911922461a651007f1de09d8c474029caa8f2c229c10de260000002103d05c8245bdc12efd8b070b22b276e7db4254f4693e22b3f7c978c08e67b36236000000110000003066722e6163696e712e6c696768746e696e672e466561747572652e4f7074696f6e446174614c6f737350726f74656374010000002d66722e6163696e712e6c696768746e696e672e466561747572652e496e697469616c526f7574696e6753796e63010000002e66722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c52616e676551756572696573010000002e66722e6163696e712e6c696768746e696e672e466561747572652e5661726961626c654c656e6774684f6e696f6e000000003666722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c52616e676551756572696573457874656e646564010000002a66722e6163696e712e6c696768746e696e672e466561747572652e53746174696352656d6f74654b6579000000002866722e6163696e712e6c696768746e696e672e466561747572652e5061796d656e74536563726574000000003066722e6163696e712e6c696768746e696e672e466561747572652e42617369634d756c7469506172745061796d656e74010000002066722e6163696e712e6c696768746e696e672e466561747572652e57756d626f010000002866722e6163696e712e6c696768746e696e672e466561747572652e416e63686f724f757470757473000000002666722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c54797065000000002a66722e6163696e712e6c696768746e696e672e466561747572652e5061796d656e744d65746164617461010000003366722e6163696e712e6c696768746e696e672e466561747572652e57616b6555704e6f74696669636174696f6e436c69656e74010000002a66722e6163696e712e6c696768746e696e672e466561747572652e506179546f4f70656e436c69656e74010000002e66722e6163696e712e6c696768746e696e672e466561747572652e5472757374656453776170496e436c69656e74010000002e66722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c4261636b7570436c69656e74010000003866722e6163696e712e6c696768746e696e672e466561747572652e4578706572696d656e74616c5472616d706f6c696e655061796d656e740100000000000000000000000000000000000000000000001388000000002faf0800000000000bebc200000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e000001bc020000000001012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000b77080044a0100000000000022002046672803839d10e21d43eafb532bc37cd21bd97dec7f9b50d45380cd1cce69654a01000000000000220020bbd7f17366848d8f624c28438128ce4dc8c72ea21deb0ccf25bee110920da032400d030000000000220020cb93e3adb8d213704e9a07ea2a6ce91dca51a9b76fcb6bef3cc9b5b7e10a7990781c0c00000000002200202f0860cd1fe361a1aaf5708f75b6511c92cd5a51bdaaccfbda77aead550d875104004730440220672323ca34b85c2a43e3e93ac8a642a8293b1483392f531736db975d05f3ad3c022019f7b5044cd2a230dc49484c219fd96485f98d21c6add317566f4b21816a2fb101483045022100956b481822da569bc75c1f7ab6ec34c0a1e14dd5b4701ea8473e5bfe6b6ad41702202b1a987850611c0f52cccbb6016c735a08572f61fe03616a186ca39a8b2e07970147522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452aede99dc20000000000000000000000000000000000000000000001388000000000bebc200000000002faf0800000000206498095b8d064f46673e7c0d919636e1dff0c0a76ed61dd96938a178253ea4cb0000002102365f9a5e4822956750faa46230f54e47d4b6ef9d58eb8c488d80a5efed938d5b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100010000002103c57839fd412868a398bea05d01678a752661126a2d1357a0f7cb6f0c60311125000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000000000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd00000000000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd00000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c0000000000000000000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd00000016001434947cfb2e8f6054ddf12daed4308cbe342580d1000000010000002f66722e6163696e712e6c696768746e696e672e776972652e53687574646f776e546c762e4368616e6e656c4461746100000e8556ac7d2006dabb7b7e26a032ac384ce15362f230e007a713e45ee0a514aef433db46a55d4650585517be36dc68babddf369cbfa743e9ad976640545119c378548729fd5750f0772ae26e1ac80a288f3baa7ae2416e9ea796403fe0b2111a919370021aba83cc9c3abd6671ddb7e2c54eaa64701b86d5b70ac2a44f723e399c449ff1b9ccb8e20481ea1ab6b9a752b38601fb202f4cf960cfdf3c77c91829747fbff494ab3701148abfb09bdee3bffe1bc46d157ae16e9d701764532db299530a3679b6ecce62fab88a75a8524b1b7484faf08b9347e1e3e92623286b98a27f8236f9d94831c489c9b66846d2e65b4c75a2850bf30b3268a3122589a58223265e5d62df74cf77ab3e781c3c1612142810b30c5e45775c70e6f17b3829688d69b5ed8769bd70018bc19de67fce65240ed94f1179087e74ca49212edd8d735f015a077e5cf6328d426d69e31898c0aafafe6d21b5784bf337508ba33a13c88a34a2d04e9f48e0f3ce7ad704524b9360adbf70d91b7900ccd2a53ce4da6f7b66226c860936f5549c7065f572e9e6debcec7560d5f2ec49bd257cd23a0da2dab7b72cc3118ee72826c15cc033bced6d35187d955019d1988549be9712ce4561ca1247497a6e60b506cb7f21dea80205fc66d2e13382998538a5c0dae806d18b8fce515a7538a881c5a12f67bc11e838b1154901f4fc84eb3165477f4bdf02dcf3d8ab42ba2ade55ee22cdf07bacf2b561cf05ebd3f8eca283c451ec09f0a8cd7b3ecbb83d17157e9830bb3d85d7143ebab10306544820b3811e89b7ce013d96db368bd9eff243e575dc10b2e7c576b9df66ad6c7379e6dda3423bde90a564d9995ade0a72842816996bbdbfaae0946ed2747c3247904fafae4bbe792bbba66ca29b1f9b0179a4093bb363dd3abbc6478441528b28daf1797d2d8fd3f200f0a6fdb8bfd4dfb02506bb16d4db103531d6f13d9c46613d4f03b84be135e19c4ede30717613efc50d6f28b6a36b5e61839ccd7a36a0d8ad6e81691f0772cff88f0e800bb9539e71ea3f1a52f281a9ba7c469fa917dbc75d8b7dc9e702c6a70d5d46b453804771adb6bc8cf85476ac31657776e674b632358f1e49ac1a9a4934736830224a136d76be62cf925af87746be07ef128b11a06d798ac7780843d46a2a5d3dd12eac27ef1af0a12581ec423df8be05aa0473b7cc30e55cf77d7255d1b2f9d0223e3dea9912552aee6fc1c9d3266d69266d40c8b85730e1a4327c956a51e06705e8b3f47463ab4bac168253ae55583523ed4220d97908932efc57616b4977e2418f26eb1077a4320386abf788ff8456bf044f5b95821520f8985f734a97dbcd5ad21d66d1b870a73f5bba1c4f382d369a3c8ebff86ce0b7fa29cd589053f1fbdc1fc392ccac7d548f11326ccc22cf641b7f10afa5d79c1b2015b768bda455fe573bd15001259a9ef3a0c47e3e4937065a4712d2d8d49c989bd59e3d8c130913fef431d954fd34b09947d40dce38a6301602ef65bcd1d874ae23bde4436cd0c0c2d8c671f0f73b42ee20fe083de4ce2380b4a33568eee72b82e6bf157dcee288091f9ffcc0837ae75ab3aba9eb7e081a5e491239a19e778dca132b958ee845a8de97876721766507191e74dd6b5ed4c08ba9b9547525fc0b809c46a4a7dc529df6f9b33f27905f355043c31f4a32cf2d1f7086a6af0455fc424da920ec2906a7464823b9f8bab0d693c8ea8a55317df43e6c6bda79015814558da1fc2c92ed6c80863544788dac519f418349a7707d59a1dcd160ea4867a562dd04c780c954d3e43bff6c8186eb4b80359ed267e216c96b0ef3d57fd3d39a99cc7e034afd2d3f6c62cfcdea85eec1f2ef1f2fc5f272a6117034b6c8b5085a1d02892d942b952a17fef041d4082296a0fc800497b86760d89b7eaf03a90c5482fe5304fe81fd4bda06a8a333a03a819b3341ab9335f12dcdb8fbdb27c235d80ee0d41844c564f9c84de48c198064a9111d236e6c3e60f36e3c656216c191097f17b285fba088391f5b65a430e92eeaae792b243fe05c88887bc9d52480bc63628e5a1e4821a977e1411dd22d343aca4aebe1b9b6efd23197bb3701fcbbbab1d5f2f426b85601c5ff37d79377f41dd8ebd16af52ae50ed0b45d4db319b1d6789cd2b6c3fa2e1ba2abb2a00d1267e0fe7467aa2be5a76af028c15f9ce9f5edb31c1aea177795ee1ccee5b667bac787f6115659a264fd5be27cd77e4eab64c4ac30a57eec78bcf3b13a0119ea60a0e8953d2f955c10295a5b0ffe4e653042deed40473a143e6201a1f64052f0d6edaa5796a4956e477745b0e00805f4cf4e0e3300ce338d8f27e8bd6c3fb626222f3e09ce38ac076bb49726e31aa4e48372f3638e7ddb66451496387e4a8c9d0ed3268f368455c3a055e70edb94bcf7961a51c740c9e1de1cbbc70c189dd48c1208a86b0fc85264659597bcd3c0980c87146446d6d2edee022b91573f8f734d2d8e21b6b1b78873c39ec34dad9b90d9b6214c33dec5dc087c108c9c8a70de64b6e5cb794cc35f581af2416831968d0021ce6e7d56e4880c34481e99cc6ac41a36619fc0de2628196f4d6f4b10ac82ff810302bab14cd58b6c10143a758f93a4bc99893d6d0a6391c5a4cd9c90ca2ce6e8310d4293305548a618cd0a5d4477dbb7911ce5bf92fc8810d549cb440ff9d5607811ecc5a0e878b780c51814fda3826dc4f108f63ac9e2a74cc0a375a5be4c9eed9dc836dfd3761f966f58a6eb60ca6d8102d34d5640cab6c253b7fbb6a17e0eece493f2541dbb9c43b6ea618deecb816cc5af8ad9b1914d445d622656cbfe9e5e22aa341412fdfb0b59b6baee4c56a9fe1ae146e47e7d3aa3f9b2eec7492e6ec1d01eb9ecdf1c9488c3c8a02b5582e145256cc6df17bd3947e4528941e358a83bc32802a047d7c3564e8c8f4f3869a5d66a34421efdc67dde9cafc5fbe685be01d0c420f764d3a7f027225d9b3ac980a7b3af4536b7bf89abbce5d9a4474f461240097ec5d81e21d969a41065b3818b7936231d28f208b066c272641d011c2412e0ecff7115feeca6bf137068a0da8d88360e9741fd1c9147208355b0eb466dc00b48e1845868834dcdc21d2719eea5e0f40df5e04dbb45a87ef473212f0ffd2ea97f82487938a25893eb834ca6b9c27b1910c9e3a4fa57d7c453e25bb9a193d3b71df314f93f10b7ee2dbc0498e16dff70aa79cb61c2b22cf471014f4046f71358ed17082dd0a797c8e4a624bf79d774ef1892232c7f2fb8cb9958b3912d120e84adab1f4f9c943311212f9f006870741dd47d109fde5de7f3973aad517bafb3b83c9249c7283e5e8b977488068e6f7a90418b87824b55abb62e045d3605cfe8271339a0e6d5090629d33882c9339533ec4ae2436d6e0fd48e853c56d68744cec5b5acb0c3246c301d5dbc96db9f8bc38adb66fb9e5d8712f3f6761abaaea03a57a57a9dd8c4fdab4969770fd3f3afe8545e7f12152d01eada01133a0578391a2ff9a57d828dbfeb558cfba31dafdba1b629dd497352b8f92d630aa20ce9e95d416f5d65ce95efec6bc62fa3822127b19285e9a3420a48227bac6dcda6d3531ce57f401250cf581fa8bba6f1c23fc3269d6b01a347369225619a784f08f9a84b03a2b2d44874fe943712811555898f4812f4c9cb622dc2a9cd49996d086d6a7df33eb0436746ff3180d408e19aea960f4beb0ca12170549e874c23fdf27654fd870708bde5ff98f26d26defdfdf5d2dab2e29db10d53579a6913a1ea31c49d0bc6aaca7ec0babff6e5c251d72198adbd5b1192c33d756ecd4fe4b1e35a2d43dcd4a3ed292cb4a26b236d986d83cca36b4e31ed3d1cb1409b3dff0f437b2b3897300cb8de1672e6b878a7bfff9dd75e01e16b6bff56d06b392c0349cd85b99de6cfffdf9e93c3ecb2f688d3b2b7442dd257b0893572cfbf348b2f28989eba7b8579384884b0352a77207af3d5c18d9acb09f944e6881d9deb9a1a9248c4b9f74f341982122777e95da9667cd0f1f09dcad04de4899aa0cc6bd2ee428ef3a4224c37e911c202328262192ec8180d0cd8329e569caf9bfb515819872e65066433b92ec6ee289f278e8fde4eba02a6c09e695643ff3f439687dbb3a20e7cc4d99ccc54727bc19f831ff28efb29717036dbf78465ca8b63e2d1154d6629b4f4c576bd967f9a5cc554862728fd2a7bd7ac9c1f9b628b3542acf023013baf6a8002feb051e2d2ac8ca66c97d428026cea6e428aa72d96b7ef53bb185360a3ac0f079e9e9d11f51829262eb18b1682d48bfc5024e65fd7af0f94f5b940c5e7b2760ff841def1506855cf85e679cb904dcf829687aede7fb70840e9ad6d9b7ad7b27ffb6def8a840f40d11f794bde4bbced2b5b63fc2c263461ade7f02fee63a4e0907a7f1b44a0e3656c8e4ccc6f00731972e9b1337dbe72d70fe715b93ee4e106ca3c330356a5983e74dec3a5e75d20b5e5fad7e51f28ce38f966bf83a44bb83a6a9ec694a2d61d71f536f6bb3da3c787f2c763cc2045067d56d2600aa0f4f24bfaf43b37fb8fece78d91ec511fcce7680bbda8684cdb0e9a619cd9888321bbd3d60ebec5ce4787b9ce687ffcd136db1f2a2877143c7dcb17bcbbdc7c8b5e3850097e7a12691211b4e607361a4834bf6f8f73575c3009a0dc6f2fc257c23404fc293933e3b1c31d0975968da2d4e54ac082289ab76c725f38913d0480cb61c6bff80b3f30b25662a39459619417d820cd25b34265bea62809d9e52b57a7e1c604ee4390e39d6185f6391dbd46f514dd6af3978de827adf594da0f0d430a5f9e216a003f128533bf40377b5c0c5bcd391f77c9e3e9aed8994a514c21ab5e38ca0176c8427d742e66db449d5657a05266d96f4fa3f2adefcafed21bc955c9b26cffe1f98e3a17b002387c14eddd1cc3ddda603e1076669bd0d6eda1079c9fc976437cd999c37b655ae612587c74b7cd00ae658e54572818be38c62f9c2ac0c97cae81c4eddfe4940ba79a545e54b0cfb439b81336e7d8f191b5885d19138c3d57badcaec8a1320715304bccd54c7f04a0577a80f0c600a92719982844f27130cee8932577e5b237c8432fcbf80e0c1dc97e5ae31a9eb4027964465cbf531cc9ebe8fd1750d681bfb1590265801bf7c8bbb876b17daa008876961fc7db1a7e4d896075248d845035817e1aafa68ce8f4a6cb1f344d11056ecbe423f3df6b2c9d22db72f9cb35860c096d3c6a960012420b4133c6b567000000000000000100000010000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e0000007102000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d15e320c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c000000000100000001000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd00000000000002a2000000409fbce74a05823e5ff30227d6d96abf1adea0e2c3e225f19011d2c26fbc955b8758877c062bfe97f7a311988946421561dec3009292133c7b9c7153044c793949000000010000003166722e6163696e712e6c696768746e696e672e776972652e436c6f73696e675369676e6564546c762e46656552616e67650000000000000151000000000000054400000000000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e0000007102000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d10e310c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c000000000100000001000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd00000000000003f200000040959c687c87ee014e988275260a28f5522b9aa7df58201780e8da0714c80466db75747a0cbe30ad56656ed9f7d05599fc959758ed23566b815565dc20177d366c000000010000003166722e6163696e712e6c696768746e696e672e776972652e436c6f73696e675369676e6564546c762e46656552616e67650000000000000151000000000000054400000000000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e0000007102000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d114300c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c000000000100000001000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd00000000000004ec000000407ba4aab1322712d9ac5b12b0ead3c2386eab48e380fb0e93218de67de109f1d5552694f878c64a8b536e7be333bbec781fe2838845852db3905de3fcb46aa536000000010000003166722e6163696e712e6c696768746e696e672e776972652e436c6f73696e675369676e6564546c762e46656552616e67650000000000000151000000000000054400000000000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e0000007102000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d11a2f0c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c000000000100000001000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd00000000000005e60000004012804a6c0c36c336baffe28a211042a1fc1cdd3c0626e06643a29a30d282b2b076487caa9a6e619ab141ffd6775bd4e1da32d55f87a548ea27421720a3e8ad08000000010000003166722e6163696e712e6c696768746e696e672e776972652e436c6f73696e675369676e6564546c762e46656552616e67650000000000000151000000000000054400000000000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e0000007102000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d1202e0c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c000000000100000001000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd00000000000006e0000000404214aa761eaec84f0bc571ad5bd2a427ba9ce6fc363adcb3c4b81aa5ced969d92361859b2eb9557afab41ebe54dcd18d645781085e3aa534819e57d8bea9d2e2000000010000003166722e6163696e712e6c696768746e696e672e776972652e436c6f73696e675369676e6564546c762e46656552616e67650000000000000151000000000000054400000000000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e0000007102000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d1262d0c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c000000000100000001000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd00000000000007da00000040a66e4ad93233f6add8965f12ecb66f7c06a3e7a8ee42f692bb50426a7a32d470323c560e5069cc1801f85ad13a3bf149601a1a4b86d5d82cfb934b75f4dd5757000000010000003166722e6163696e712e6c696768746e696e672e776972652e436c6f73696e675369676e6564546c762e46656552616e67650000000000000151000000000000054400000000000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e0000007102000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d12c2c0c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c000000000100000001000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd00000000000008d40000004086c58c46963050df8fb7babb0dbbada4f4275c07089c9c7ac56a1b032b00bfd82244dc56d99ecff8f117e0b11bcf589a33f40c2248c7dd37eb84caa97e6000f5000000010000003166722e6163696e712e6c696768746e696e672e776972652e436c6f73696e675369676e6564546c762e46656552616e67650000000000000151000000000000054400000000000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e0000007102000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d1322b0c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c000000000100000001000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd00000000000009ce000000406395a7e0db7cffd3d87b3edff6cee0d9fc0cd75a7d968b4ec4ff013bb27d368460e4e35277d0019d55dda79d7fab336ee1332452a406b273808c36ed3a7ea379000000010000003166722e6163696e712e6c696768746e696e672e776972652e436c6f73696e675369676e6564546c762e46656552616e67650000000000000151000000000000054400000000000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e0000007102000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d1382a0c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c000000000100000001000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000000ac800000040cc97e4cbd3048272c8da6e3abb8bfb0c00e0febbd91b7d73ca9be4769ac69a115b481bf55291214e5e479f5749eb183562dda84c57d292066522671462ac4f80000000010000003166722e6163696e712e6c696768746e696e672e776972652e436c6f73696e675369676e6564546c762e46656552616e67650000000000000151000000000000054400000000000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e0000007102000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d13e290c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c000000000100000001000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000000bc2000000407da842faca84a073d474dfac71b0a15052216c8b398b4609cac8d7fd336787c046507e39739109f4c69d40ba6dbe79f17d250d0a95defb1004f3c3c790491cd8000000010000003166722e6163696e712e6c696768746e696e672e776972652e436c6f73696e675369676e6564546c762e46656552616e67650000000000000151000000000000054400000000000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e0000007102000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d144280c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c000000000100000001000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000000cbc00000040e0cab5a41fb2ac378593652d7c4b54b9662ca6bbe5b17ad1e87c7b206b4c1ee826200fae1897061ef33fe0f393e4b48fb3cf37b7922cf128fd69a277535f09d9000000010000003166722e6163696e712e6c696768746e696e672e776972652e436c6f73696e675369676e6564546c762e46656552616e67650000000000000151000000000000054400000000000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e0000007102000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d14a270c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c000000000100000001000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000000db600000040c1a543b0bc4a8093d70d9e952b2e6a7d62ec8bb189297089109ab71f81d61f8024c79a176321c1402b41463c3eda28f2c544cbf6b8197e077eb4e20a5f9b7533000000010000003166722e6163696e712e6c696768746e696e672e776972652e436c6f73696e675369676e6564546c762e46656552616e67650000000000000151000000000000054400000000000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e0000007102000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d150260c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c000000000100000001000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000000eb0000000404279947219b647ca78f9f61028bec3c646e4045bbcd2f0a2aee2e14096a0843e7646e6a9f4be01aafe9093464d8db418ac9ec40f46951b9af8360137eda02dee000000010000003166722e6163696e712e6c696768746e696e672e776972652e436c6f73696e675369676e6564546c762e46656552616e67650000000000000151000000000000054400000000000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e0000007102000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d156250c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c000000000100000001000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000000faa0000004045e552dfea26356bfe073bda30d91bd009dd7bded18259bb484dab76736366656d7b5f387c4d7d6fa61390e14bedbe96f0f632b41160156932ed09647c29e3d9000000010000003166722e6163696e712e6c696768746e696e672e776972652e436c6f73696e675369676e6564546c762e46656552616e67650000000000000151000000000000054400000000000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e0000007102000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d15c240c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c000000000100000001000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd00000000000010a40000004025662fe3ce073f2fec18372d52ef37c8bf42b462de18ca3589a7cd6044637f90174880f091d10052e8a8de8c64114f27403491c4484cebf7f2b9207417486d54000000010000003166722e6163696e712e6c696768746e696e672e776972652e436c6f73696e675369676e6564546c762e46656552616e67650000000000000151000000000000054400000000000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e0000007102000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d162230c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c000000000100000001000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000119e00000040c6d02f7322fd5d333acbd3204b68dbaf8748e10c164b771b1c939dca5af948aa0767de9d5b1f528c388aa5ee21f9f2b0d9260a24604021356aabe272cd205053000000010000003166722e6163696e712e6c696768746e696e672e776972652e436c6f73696e675369676e6564546c762e46656552616e6765000000000000015100000000000005440000000001000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e0000014f020000000001012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d168220c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c0400483045022100ee9c22bd9db9fc8052eea4a0bfe2448eec7739ba8fa445292d81d181c87939240220409f1bfde401451519347d569ecfcfc9c70b07d4ec50bf229f6f74b17b3d6800014830450221008d6d347ec3a7dfe63c563146ba6acfd7c9392638eef97e864cc9f076ea98870202200337eea4d72e6dc38c3e482d86a5fe095037e8ce64c484668f64f17058987d180147522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae000000000100000001 \ No newline at end of file diff --git a/src/commonTest/resources/nonreg/v2/Negotiating_c8d15808/data.json b/src/commonTest/resources/nonreg/v2/Negotiating_c8d15808/data.json deleted file mode 100644 index 897fe83f2..000000000 --- a/src/commonTest/resources/nonreg/v2/Negotiating_c8d15808/data.json +++ /dev/null @@ -1,655 +0,0 @@ -{ - "type": "fr.acinq.lightning.channel.states.Negotiating", - "commitments": { - "params": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "channelConfig": [ - "funding_pubkey_based_channel_keypath" - ], - "channelFeatures": [ - "option_support_large_channel", - "option_static_remotekey", - "option_anchor_outputs", - "zero_reserve_channels", - "zero_conf_channels" - ], - "localParams": { - "nodeId": "037108815ff0128f7ed22640485c226d9ad64a9fd6d8b41b6623565aed6b34812c", - "fundingKeyPath": "m/385048399/1977025879/604622566/184658546/776346346/949304342'/277944247'/2049339775'/1'", - "dustLimit": 1100, - "maxHtlcValueInFlightMsat": 1500000000, - "htlcMinimum": 0, - "toSelfDelay": 144, - "maxAcceptedHtlcs": 100, - "isInitiator": true, - "defaultFinalScriptPubKey": "001405e0104aa726e34ff5cd3a6320d05c0862b5b01c", - "features": { - "activated": { - "initial_routing_sync": "Optional", - "option_data_loss_protect": "Optional", - "gossip_queries": "Optional", - "gossip_queries_ex": "Optional", - "var_onion_optin": "Mandatory", - "payment_secret": "Mandatory", - "basic_mpp": "Optional", - "option_support_large_channel": "Optional", - "option_static_remotekey": "Mandatory", - "option_anchor_outputs": "Mandatory", - "option_channel_type": "Mandatory", - "option_payment_metadata": "Optional", - "trampoline_payment_experimental": "Optional", - "wake_up_notification_provider": "Optional", - "pay_to_open_provider": "Optional", - "trusted_swap_in_provider": "Optional", - "channel_backup_provider": "Optional" - }, - "unknown": [ - ] - } - }, - "remoteParams": { - "nodeId": "0362b19a83930389b4468be40308efb3f352b23142ae25e6aba0465a8220f95b06", - "dustLimit": 1000, - "maxHtlcValueInFlightMsat": 1500000000, - "htlcMinimum": 1000, - "toSelfDelay": 144, - "maxAcceptedHtlcs": 100, - "revocationBasepoint": "03a42aef6d1c860caffa6c71a6f8ac2b16eec25bab0c3950cdb1fad7fb38a5f2a5", - "paymentBasepoint": "02508e1845b8bbe0773f6bf8f3f04f59a5896426765c7b6b23e6e466c95381182b", - "delayedPaymentBasepoint": "02d62233b7c33f8fd0911922461a651007f1de09d8c474029caa8f2c229c10de26", - "htlcBasepoint": "03d05c8245bdc12efd8b070b22b276e7db4254f4693e22b3f7c978c08e67b36236", - "features": { - "activated": { - "option_data_loss_protect": "Optional", - "initial_routing_sync": "Optional", - "gossip_queries": "Optional", - "var_onion_optin": "Mandatory", - "gossip_queries_ex": "Optional", - "option_static_remotekey": "Mandatory", - "payment_secret": "Mandatory", - "basic_mpp": "Optional", - "option_support_large_channel": "Optional", - "option_anchor_outputs": "Mandatory", - "option_channel_type": "Mandatory", - "option_payment_metadata": "Optional", - "wake_up_notification_client": "Optional", - "pay_to_open_client": "Optional", - "trusted_swap_in_client": "Optional", - "channel_backup_client": "Optional", - "trampoline_payment_experimental": "Optional" - }, - "unknown": [ - ] - } - }, - "channelFlags": 0 - }, - "changes": { - "localChanges": { - "proposed": [ - ], - "signed": [ - ], - "acked": [ - ] - }, - "remoteChanges": { - "proposed": [ - ], - "acked": [ - ], - "signed": [ - ] - }, - "localNextHtlcId": 0, - "remoteNextHtlcId": 0 - }, - "active": [ - { - "fundingTxIndex": 0, - "remoteFundingPubkey": "0385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa4", - "localFundingStatus": { - "status": "unconfirmed", - "txId": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f" - }, - "remoteFundingStatus": { - "status": "locked" - }, - "localCommit": { - "index": 0, - "spec": { - "htlcsIn": [ - ], - "htlcsOut": [ - ], - "feerate": 5000, - "toLocal": 800000000, - "toRemote": 200000000 - }, - "publishableTxs": { - "commitTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "020000000001012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000b77080044a0100000000000022002046672803839d10e21d43eafb532bc37cd21bd97dec7f9b50d45380cd1cce69654a01000000000000220020bbd7f17366848d8f624c28438128ce4dc8c72ea21deb0ccf25bee110920da032400d030000000000220020cb93e3adb8d213704e9a07ea2a6ce91dca51a9b76fcb6bef3cc9b5b7e10a7990781c0c00000000002200202f0860cd1fe361a1aaf5708f75b6511c92cd5a51bdaaccfbda77aead550d875104004730440220672323ca34b85c2a43e3e93ac8a642a8293b1483392f531736db975d05f3ad3c022019f7b5044cd2a230dc49484c219fd96485f98d21c6add317566f4b21816a2fb101483045022100956b481822da569bc75c1f7ab6ec34c0a1e14dd5b4701ea8473e5bfe6b6ad41702202b1a987850611c0f52cccbb6016c735a08572f61fe03616a186ca39a8b2e07970147522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452aede99dc20" - }, - "htlcTxsAndSigs": [ - ] - } - }, - "remoteCommit": { - "index": 0, - "spec": { - "htlcsIn": [ - ], - "htlcsOut": [ - ], - "feerate": 5000, - "toLocal": 200000000, - "toRemote": 800000000 - }, - "txid": "6498095b8d064f46673e7c0d919636e1dff0c0a76ed61dd96938a178253ea4cb", - "remotePerCommitmentPoint": "02365f9a5e4822956750faa46230f54e47d4b6ef9d58eb8c488d80a5efed938d5b" - }, - "nextRemoteCommit": null - } - ], - "inactive": [ - ], - "payments": { - }, - "remoteNextCommitInfo": { - "left": null, - "right": "03c57839fd412868a398bea05d01678a752661126a2d1357a0f7cb6f0c60311125" - }, - "remotePerCommitmentSecrets": "" - }, - "localShutdown": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "scriptPubKey": "001405e0104aa726e34ff5cd3a6320d05c0862b5b01c" - }, - "remoteShutdown": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "scriptPubKey": "001434947cfb2e8f6054ddf12daed4308cbe342580d1", - "tlvStream": { - "records": [ - { - "type": "fr.acinq.lightning.wire.ShutdownTlv.ChannelData", - "ecb": { - "data": "56ac7d2006dabb7b7e26a032ac384ce15362f230e007a713e45ee0a514aef433db46a55d4650585517be36dc68babddf369cbfa743e9ad976640545119c378548729fd5750f0772ae26e1ac80a288f3baa7ae2416e9ea796403fe0b2111a919370021aba83cc9c3abd6671ddb7e2c54eaa64701b86d5b70ac2a44f723e399c449ff1b9ccb8e20481ea1ab6b9a752b38601fb202f4cf960cfdf3c77c91829747fbff494ab3701148abfb09bdee3bffe1bc46d157ae16e9d701764532db299530a3679b6ecce62fab88a75a8524b1b7484faf08b9347e1e3e92623286b98a27f8236f9d94831c489c9b66846d2e65b4c75a2850bf30b3268a3122589a58223265e5d62df74cf77ab3e781c3c1612142810b30c5e45775c70e6f17b3829688d69b5ed8769bd70018bc19de67fce65240ed94f1179087e74ca49212edd8d735f015a077e5cf6328d426d69e31898c0aafafe6d21b5784bf337508ba33a13c88a34a2d04e9f48e0f3ce7ad704524b9360adbf70d91b7900ccd2a53ce4da6f7b66226c860936f5549c7065f572e9e6debcec7560d5f2ec49bd257cd23a0da2dab7b72cc3118ee72826c15cc033bced6d35187d955019d1988549be9712ce4561ca1247497a6e60b506cb7f21dea80205fc66d2e13382998538a5c0dae806d18b8fce515a7538a881c5a12f67bc11e838b1154901f4fc84eb3165477f4bdf02dcf3d8ab42ba2ade55ee22cdf07bacf2b561cf05ebd3f8eca283c451ec09f0a8cd7b3ecbb83d17157e9830bb3d85d7143ebab10306544820b3811e89b7ce013d96db368bd9eff243e575dc10b2e7c576b9df66ad6c7379e6dda3423bde90a564d9995ade0a72842816996bbdbfaae0946ed2747c3247904fafae4bbe792bbba66ca29b1f9b0179a4093bb363dd3abbc6478441528b28daf1797d2d8fd3f200f0a6fdb8bfd4dfb02506bb16d4db103531d6f13d9c46613d4f03b84be135e19c4ede30717613efc50d6f28b6a36b5e61839ccd7a36a0d8ad6e81691f0772cff88f0e800bb9539e71ea3f1a52f281a9ba7c469fa917dbc75d8b7dc9e702c6a70d5d46b453804771adb6bc8cf85476ac31657776e674b632358f1e49ac1a9a4934736830224a136d76be62cf925af87746be07ef128b11a06d798ac7780843d46a2a5d3dd12eac27ef1af0a12581ec423df8be05aa0473b7cc30e55cf77d7255d1b2f9d0223e3dea9912552aee6fc1c9d3266d69266d40c8b85730e1a4327c956a51e06705e8b3f47463ab4bac168253ae55583523ed4220d97908932efc57616b4977e2418f26eb1077a4320386abf788ff8456bf044f5b95821520f8985f734a97dbcd5ad21d66d1b870a73f5bba1c4f382d369a3c8ebff86ce0b7fa29cd589053f1fbdc1fc392ccac7d548f11326ccc22cf641b7f10afa5d79c1b2015b768bda455fe573bd15001259a9ef3a0c47e3e4937065a4712d2d8d49c989bd59e3d8c130913fef431d954fd34b09947d40dce38a6301602ef65bcd1d874ae23bde4436cd0c0c2d8c671f0f73b42ee20fe083de4ce2380b4a33568eee72b82e6bf157dcee288091f9ffcc0837ae75ab3aba9eb7e081a5e491239a19e778dca132b958ee845a8de97876721766507191e74dd6b5ed4c08ba9b9547525fc0b809c46a4a7dc529df6f9b33f27905f355043c31f4a32cf2d1f7086a6af0455fc424da920ec2906a7464823b9f8bab0d693c8ea8a55317df43e6c6bda79015814558da1fc2c92ed6c80863544788dac519f418349a7707d59a1dcd160ea4867a562dd04c780c954d3e43bff6c8186eb4b80359ed267e216c96b0ef3d57fd3d39a99cc7e034afd2d3f6c62cfcdea85eec1f2ef1f2fc5f272a6117034b6c8b5085a1d02892d942b952a17fef041d4082296a0fc800497b86760d89b7eaf03a90c5482fe5304fe81fd4bda06a8a333a03a819b3341ab9335f12dcdb8fbdb27c235d80ee0d41844c564f9c84de48c198064a9111d236e6c3e60f36e3c656216c191097f17b285fba088391f5b65a430e92eeaae792b243fe05c88887bc9d52480bc63628e5a1e4821a977e1411dd22d343aca4aebe1b9b6efd23197bb3701fcbbbab1d5f2f426b85601c5ff37d79377f41dd8ebd16af52ae50ed0b45d4db319b1d6789cd2b6c3fa2e1ba2abb2a00d1267e0fe7467aa2be5a76af028c15f9ce9f5edb31c1aea177795ee1ccee5b667bac787f6115659a264fd5be27cd77e4eab64c4ac30a57eec78bcf3b13a0119ea60a0e8953d2f955c10295a5b0ffe4e653042deed40473a143e6201a1f64052f0d6edaa5796a4956e477745b0e00805f4cf4e0e3300ce338d8f27e8bd6c3fb626222f3e09ce38ac076bb49726e31aa4e48372f3638e7ddb66451496387e4a8c9d0ed3268f368455c3a055e70edb94bcf7961a51c740c9e1de1cbbc70c189dd48c1208a86b0fc85264659597bcd3c0980c87146446d6d2edee022b91573f8f734d2d8e21b6b1b78873c39ec34dad9b90d9b6214c33dec5dc087c108c9c8a70de64b6e5cb794cc35f581af2416831968d0021ce6e7d56e4880c34481e99cc6ac41a36619fc0de2628196f4d6f4b10ac82ff810302bab14cd58b6c10143a758f93a4bc99893d6d0a6391c5a4cd9c90ca2ce6e8310d4293305548a618cd0a5d4477dbb7911ce5bf92fc8810d549cb440ff9d5607811ecc5a0e878b780c51814fda3826dc4f108f63ac9e2a74cc0a375a5be4c9eed9dc836dfd3761f966f58a6eb60ca6d8102d34d5640cab6c253b7fbb6a17e0eece493f2541dbb9c43b6ea618deecb816cc5af8ad9b1914d445d622656cbfe9e5e22aa341412fdfb0b59b6baee4c56a9fe1ae146e47e7d3aa3f9b2eec7492e6ec1d01eb9ecdf1c9488c3c8a02b5582e145256cc6df17bd3947e4528941e358a83bc32802a047d7c3564e8c8f4f3869a5d66a34421efdc67dde9cafc5fbe685be01d0c420f764d3a7f027225d9b3ac980a7b3af4536b7bf89abbce5d9a4474f461240097ec5d81e21d969a41065b3818b7936231d28f208b066c272641d011c2412e0ecff7115feeca6bf137068a0da8d88360e9741fd1c9147208355b0eb466dc00b48e1845868834dcdc21d2719eea5e0f40df5e04dbb45a87ef473212f0ffd2ea97f82487938a25893eb834ca6b9c27b1910c9e3a4fa57d7c453e25bb9a193d3b71df314f93f10b7ee2dbc0498e16dff70aa79cb61c2b22cf471014f4046f71358ed17082dd0a797c8e4a624bf79d774ef1892232c7f2fb8cb9958b3912d120e84adab1f4f9c943311212f9f006870741dd47d109fde5de7f3973aad517bafb3b83c9249c7283e5e8b977488068e6f7a90418b87824b55abb62e045d3605cfe8271339a0e6d5090629d33882c9339533ec4ae2436d6e0fd48e853c56d68744cec5b5acb0c3246c301d5dbc96db9f8bc38adb66fb9e5d8712f3f6761abaaea03a57a57a9dd8c4fdab4969770fd3f3afe8545e7f12152d01eada01133a0578391a2ff9a57d828dbfeb558cfba31dafdba1b629dd497352b8f92d630aa20ce9e95d416f5d65ce95efec6bc62fa3822127b19285e9a3420a48227bac6dcda6d3531ce57f401250cf581fa8bba6f1c23fc3269d6b01a347369225619a784f08f9a84b03a2b2d44874fe943712811555898f4812f4c9cb622dc2a9cd49996d086d6a7df33eb0436746ff3180d408e19aea960f4beb0ca12170549e874c23fdf27654fd870708bde5ff98f26d26defdfdf5d2dab2e29db10d53579a6913a1ea31c49d0bc6aaca7ec0babff6e5c251d72198adbd5b1192c33d756ecd4fe4b1e35a2d43dcd4a3ed292cb4a26b236d986d83cca36b4e31ed3d1cb1409b3dff0f437b2b3897300cb8de1672e6b878a7bfff9dd75e01e16b6bff56d06b392c0349cd85b99de6cfffdf9e93c3ecb2f688d3b2b7442dd257b0893572cfbf348b2f28989eba7b8579384884b0352a77207af3d5c18d9acb09f944e6881d9deb9a1a9248c4b9f74f341982122777e95da9667cd0f1f09dcad04de4899aa0cc6bd2ee428ef3a4224c37e911c202328262192ec8180d0cd8329e569caf9bfb515819872e65066433b92ec6ee289f278e8fde4eba02a6c09e695643ff3f439687dbb3a20e7cc4d99ccc54727bc19f831ff28efb29717036dbf78465ca8b63e2d1154d6629b4f4c576bd967f9a5cc554862728fd2a7bd7ac9c1f9b628b3542acf023013baf6a8002feb051e2d2ac8ca66c97d428026cea6e428aa72d96b7ef53bb185360a3ac0f079e9e9d11f51829262eb18b1682d48bfc5024e65fd7af0f94f5b940c5e7b2760ff841def1506855cf85e679cb904dcf829687aede7fb70840e9ad6d9b7ad7b27ffb6def8a840f40d11f794bde4bbced2b5b63fc2c263461ade7f02fee63a4e0907a7f1b44a0e3656c8e4ccc6f00731972e9b1337dbe72d70fe715b93ee4e106ca3c330356a5983e74dec3a5e75d20b5e5fad7e51f28ce38f966bf83a44bb83a6a9ec694a2d61d71f536f6bb3da3c787f2c763cc2045067d56d2600aa0f4f24bfaf43b37fb8fece78d91ec511fcce7680bbda8684cdb0e9a619cd9888321bbd3d60ebec5ce4787b9ce687ffcd136db1f2a2877143c7dcb17bcbbdc7c8b5e3850097e7a12691211b4e607361a4834bf6f8f73575c3009a0dc6f2fc257c23404fc293933e3b1c31d0975968da2d4e54ac082289ab76c725f38913d0480cb61c6bff80b3f30b25662a39459619417d820cd25b34265bea62809d9e52b57a7e1c604ee4390e39d6185f6391dbd46f514dd6af3978de827adf594da0f0d430a5f9e216a003f128533bf40377b5c0c5bcd391f77c9e3e9aed8994a514c21ab5e38ca0176c8427d742e66db449d5657a05266d96f4fa3f2adefcafed21bc955c9b26cffe1f98e3a17b002387c14eddd1cc3ddda603e1076669bd0d6eda1079c9fc976437cd999c37b655ae612587c74b7cd00ae658e54572818be38c62f9c2ac0c97cae81c4eddfe4940ba79a545e54b0cfb439b81336e7d8f191b5885d19138c3d57badcaec8a1320715304bccd54c7f04a0577a80f0c600a92719982844f27130cee8932577e5b237c8432fcbf80e0c1dc97e5ae31a9eb4027964465cbf531cc9ebe8fd1750d681bfb1590265801bf7c8bbb876b17daa008876961fc7db1a7e4d896075248d845035817e1aafa68ce8f4a6cb1f344d11056ecbe423f3df6b2c9d22db72f9cb35860c096d3c6a960012420b4133c6b567" - } - } - ] - } - }, - "closingTxProposed": [ - [ - { - "unsignedTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "02000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d15e320c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c00000000", - "toLocalIndex": 1 - }, - "localClosingSigned": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "feeSatoshis": 674, - "signature": "9fbce74a05823e5ff30227d6d96abf1adea0e2c3e225f19011d2c26fbc955b8758877c062bfe97f7a311988946421561dec3009292133c7b9c7153044c793949", - "tlvStream": { - "records": [ - { - "type": "fr.acinq.lightning.wire.ClosingSignedTlv.FeeRange", - "min": 337, - "max": 1348 - } - ] - } - } - }, - { - "unsignedTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "02000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d10e310c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c00000000", - "toLocalIndex": 1 - }, - "localClosingSigned": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "feeSatoshis": 1010, - "signature": "959c687c87ee014e988275260a28f5522b9aa7df58201780e8da0714c80466db75747a0cbe30ad56656ed9f7d05599fc959758ed23566b815565dc20177d366c", - "tlvStream": { - "records": [ - { - "type": "fr.acinq.lightning.wire.ClosingSignedTlv.FeeRange", - "min": 337, - "max": 1348 - } - ] - } - } - }, - { - "unsignedTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "02000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d114300c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c00000000", - "toLocalIndex": 1 - }, - "localClosingSigned": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "feeSatoshis": 1260, - "signature": "7ba4aab1322712d9ac5b12b0ead3c2386eab48e380fb0e93218de67de109f1d5552694f878c64a8b536e7be333bbec781fe2838845852db3905de3fcb46aa536", - "tlvStream": { - "records": [ - { - "type": "fr.acinq.lightning.wire.ClosingSignedTlv.FeeRange", - "min": 337, - "max": 1348 - } - ] - } - } - }, - { - "unsignedTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "02000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d11a2f0c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c00000000", - "toLocalIndex": 1 - }, - "localClosingSigned": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "feeSatoshis": 1510, - "signature": "12804a6c0c36c336baffe28a211042a1fc1cdd3c0626e06643a29a30d282b2b076487caa9a6e619ab141ffd6775bd4e1da32d55f87a548ea27421720a3e8ad08", - "tlvStream": { - "records": [ - { - "type": "fr.acinq.lightning.wire.ClosingSignedTlv.FeeRange", - "min": 337, - "max": 1348 - } - ] - } - } - }, - { - "unsignedTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "02000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d1202e0c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c00000000", - "toLocalIndex": 1 - }, - "localClosingSigned": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "feeSatoshis": 1760, - "signature": "4214aa761eaec84f0bc571ad5bd2a427ba9ce6fc363adcb3c4b81aa5ced969d92361859b2eb9557afab41ebe54dcd18d645781085e3aa534819e57d8bea9d2e2", - "tlvStream": { - "records": [ - { - "type": "fr.acinq.lightning.wire.ClosingSignedTlv.FeeRange", - "min": 337, - "max": 1348 - } - ] - } - } - }, - { - "unsignedTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "02000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d1262d0c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c00000000", - "toLocalIndex": 1 - }, - "localClosingSigned": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "feeSatoshis": 2010, - "signature": "a66e4ad93233f6add8965f12ecb66f7c06a3e7a8ee42f692bb50426a7a32d470323c560e5069cc1801f85ad13a3bf149601a1a4b86d5d82cfb934b75f4dd5757", - "tlvStream": { - "records": [ - { - "type": "fr.acinq.lightning.wire.ClosingSignedTlv.FeeRange", - "min": 337, - "max": 1348 - } - ] - } - } - }, - { - "unsignedTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "02000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d12c2c0c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c00000000", - "toLocalIndex": 1 - }, - "localClosingSigned": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "feeSatoshis": 2260, - "signature": "86c58c46963050df8fb7babb0dbbada4f4275c07089c9c7ac56a1b032b00bfd82244dc56d99ecff8f117e0b11bcf589a33f40c2248c7dd37eb84caa97e6000f5", - "tlvStream": { - "records": [ - { - "type": "fr.acinq.lightning.wire.ClosingSignedTlv.FeeRange", - "min": 337, - "max": 1348 - } - ] - } - } - }, - { - "unsignedTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "02000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d1322b0c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c00000000", - "toLocalIndex": 1 - }, - "localClosingSigned": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "feeSatoshis": 2510, - "signature": "6395a7e0db7cffd3d87b3edff6cee0d9fc0cd75a7d968b4ec4ff013bb27d368460e4e35277d0019d55dda79d7fab336ee1332452a406b273808c36ed3a7ea379", - "tlvStream": { - "records": [ - { - "type": "fr.acinq.lightning.wire.ClosingSignedTlv.FeeRange", - "min": 337, - "max": 1348 - } - ] - } - } - }, - { - "unsignedTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "02000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d1382a0c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c00000000", - "toLocalIndex": 1 - }, - "localClosingSigned": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "feeSatoshis": 2760, - "signature": "cc97e4cbd3048272c8da6e3abb8bfb0c00e0febbd91b7d73ca9be4769ac69a115b481bf55291214e5e479f5749eb183562dda84c57d292066522671462ac4f80", - "tlvStream": { - "records": [ - { - "type": "fr.acinq.lightning.wire.ClosingSignedTlv.FeeRange", - "min": 337, - "max": 1348 - } - ] - } - } - }, - { - "unsignedTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "02000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d13e290c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c00000000", - "toLocalIndex": 1 - }, - "localClosingSigned": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "feeSatoshis": 3010, - "signature": "7da842faca84a073d474dfac71b0a15052216c8b398b4609cac8d7fd336787c046507e39739109f4c69d40ba6dbe79f17d250d0a95defb1004f3c3c790491cd8", - "tlvStream": { - "records": [ - { - "type": "fr.acinq.lightning.wire.ClosingSignedTlv.FeeRange", - "min": 337, - "max": 1348 - } - ] - } - } - }, - { - "unsignedTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "02000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d144280c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c00000000", - "toLocalIndex": 1 - }, - "localClosingSigned": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "feeSatoshis": 3260, - "signature": "e0cab5a41fb2ac378593652d7c4b54b9662ca6bbe5b17ad1e87c7b206b4c1ee826200fae1897061ef33fe0f393e4b48fb3cf37b7922cf128fd69a277535f09d9", - "tlvStream": { - "records": [ - { - "type": "fr.acinq.lightning.wire.ClosingSignedTlv.FeeRange", - "min": 337, - "max": 1348 - } - ] - } - } - }, - { - "unsignedTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "02000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d14a270c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c00000000", - "toLocalIndex": 1 - }, - "localClosingSigned": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "feeSatoshis": 3510, - "signature": "c1a543b0bc4a8093d70d9e952b2e6a7d62ec8bb189297089109ab71f81d61f8024c79a176321c1402b41463c3eda28f2c544cbf6b8197e077eb4e20a5f9b7533", - "tlvStream": { - "records": [ - { - "type": "fr.acinq.lightning.wire.ClosingSignedTlv.FeeRange", - "min": 337, - "max": 1348 - } - ] - } - } - }, - { - "unsignedTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "02000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d150260c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c00000000", - "toLocalIndex": 1 - }, - "localClosingSigned": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "feeSatoshis": 3760, - "signature": "4279947219b647ca78f9f61028bec3c646e4045bbcd2f0a2aee2e14096a0843e7646e6a9f4be01aafe9093464d8db418ac9ec40f46951b9af8360137eda02dee", - "tlvStream": { - "records": [ - { - "type": "fr.acinq.lightning.wire.ClosingSignedTlv.FeeRange", - "min": 337, - "max": 1348 - } - ] - } - } - }, - { - "unsignedTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "02000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d156250c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c00000000", - "toLocalIndex": 1 - }, - "localClosingSigned": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "feeSatoshis": 4010, - "signature": "45e552dfea26356bfe073bda30d91bd009dd7bded18259bb484dab76736366656d7b5f387c4d7d6fa61390e14bedbe96f0f632b41160156932ed09647c29e3d9", - "tlvStream": { - "records": [ - { - "type": "fr.acinq.lightning.wire.ClosingSignedTlv.FeeRange", - "min": 337, - "max": 1348 - } - ] - } - } - }, - { - "unsignedTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "02000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d15c240c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c00000000", - "toLocalIndex": 1 - }, - "localClosingSigned": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "feeSatoshis": 4260, - "signature": "25662fe3ce073f2fec18372d52ef37c8bf42b462de18ca3589a7cd6044637f90174880f091d10052e8a8de8c64114f27403491c4484cebf7f2b9207417486d54", - "tlvStream": { - "records": [ - { - "type": "fr.acinq.lightning.wire.ClosingSignedTlv.FeeRange", - "min": 337, - "max": 1348 - } - ] - } - } - }, - { - "unsignedTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "02000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d162230c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c00000000", - "toLocalIndex": 1 - }, - "localClosingSigned": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "feeSatoshis": 4510, - "signature": "c6d02f7322fd5d333acbd3204b68dbaf8748e10c164b771b1c939dca5af948aa0767de9d5b1f528c388aa5ee21f9f2b0d9260a24604021356aabe272cd205053", - "tlvStream": { - "records": [ - { - "type": "fr.acinq.lightning.wire.ClosingSignedTlv.FeeRange", - "min": 337, - "max": 1348 - } - ] - } - } - } - ] - ], - "bestUnpublishedClosingTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "020000000001012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d168220c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c0400483045022100ee9c22bd9db9fc8052eea4a0bfe2448eec7739ba8fa445292d81d181c87939240220409f1bfde401451519347d569ecfcfc9c70b07d4ec50bf229f6f74b17b3d6800014830450221008d6d347ec3a7dfe63c563146ba6acfd7c9392638eef97e864cc9f076ea98870202200337eea4d72e6dc38c3e482d86a5fe095037e8ce64c484668f64f17058987d180147522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae00000000", - "toLocalIndex": 1 - }, - "closingFeerates": null -} \ No newline at end of file diff --git a/src/commonTest/resources/nonreg/v2/Negotiating_d9b4cd96/data.bin b/src/commonTest/resources/nonreg/v2/Negotiating_d9b4cd96/data.bin deleted file mode 100644 index 74d6653c7..000000000 --- a/src/commonTest/resources/nonreg/v2/Negotiating_d9b4cd96/data.bin +++ /dev/null @@ -1 +0,0 @@ -0000000200000e5f0000002f66722e6163696e712e6c696768746e696e672e73657269616c697a6174696f6e2e76322e4e65676f74696174696e670000002006226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f00000021037108815ff0128f7ed22640485c226d9ad64a9fd6d8b41b6623565aed6b34812c00061a800000000b426c6f636b486561646572000000500100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5494dffff7f2002000000000000000000271000000000000027100000000000002710000000040000000f000000210362b19a83930389b4468be40308efb3f352b23142ae25e6aba0465a8220f95b060000000900000000af70d6bd0000000021b1adae00000000e6a03a190000000024f606c1000000003878f51d0000000092f83b32000000006c9cf00200000000a4b8a485000000008000000000000000000003e80000000059682f000000000000004e2000000000000003e800000090000000640000000016001434947cfb2e8f6054ddf12daed4308cbe342580d1000000110000002d66722e6163696e712e6c696768746e696e672e466561747572652e496e697469616c526f7574696e6753796e63010000003066722e6163696e712e6c696768746e696e672e466561747572652e4f7074696f6e446174614c6f737350726f74656374010000002e66722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c52616e676551756572696573010000003666722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c52616e676551756572696573457874656e646564010000002e66722e6163696e712e6c696768746e696e672e466561747572652e5661726961626c654c656e6774684f6e696f6e000000002866722e6163696e712e6c696768746e696e672e466561747572652e5061796d656e74536563726574000000003066722e6163696e712e6c696768746e696e672e466561747572652e42617369634d756c7469506172745061796d656e74010000002066722e6163696e712e6c696768746e696e672e466561747572652e57756d626f010000002a66722e6163696e712e6c696768746e696e672e466561747572652e53746174696352656d6f74654b6579000000002866722e6163696e712e6c696768746e696e672e466561747572652e416e63686f724f757470757473000000002666722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c54797065000000002a66722e6163696e712e6c696768746e696e672e466561747572652e5061796d656e744d65746164617461010000003866722e6163696e712e6c696768746e696e672e466561747572652e4578706572696d656e74616c5472616d706f6c696e655061796d656e74010000003366722e6163696e712e6c696768746e696e672e466561747572652e57616b6555704e6f74696669636174696f6e436c69656e74010000002a66722e6163696e712e6c696768746e696e672e466561747572652e506179546f4f70656e436c69656e74010000002e66722e6163696e712e6c696768746e696e672e466561747572652e5472757374656453776170496e436c69656e74010000002e66722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c4261636b7570436c69656e74010000000000000021037108815ff0128f7ed22640485c226d9ad64a9fd6d8b41b6623565aed6b34812c000000000000044c0000000059682f000000000000002710000000000000000000000090000000640000002102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c00000021037d549bc475d9b2b0098e3b2f23282671646eab09b36e2f01099f39e376552864000000210368434fc548cb471f7ed8c94638433bfb07cceb97665c411450fdc23c60236409000000210399d61c09ee58f1cdc497a872f6b284cbaccd54f56bcbf7acf1f5595b577506cc000000210288fb5246c577f7ea28bc1b56f64d4c9f6c931b7075f7890bc6b4daff6253b5d6000000110000003066722e6163696e712e6c696768746e696e672e466561747572652e4f7074696f6e446174614c6f737350726f74656374010000002d66722e6163696e712e6c696768746e696e672e466561747572652e496e697469616c526f7574696e6753796e63010000002e66722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c52616e676551756572696573010000002e66722e6163696e712e6c696768746e696e672e466561747572652e5661726961626c654c656e6774684f6e696f6e000000003666722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c52616e676551756572696573457874656e646564010000002a66722e6163696e712e6c696768746e696e672e466561747572652e53746174696352656d6f74654b6579000000002866722e6163696e712e6c696768746e696e672e466561747572652e5061796d656e74536563726574000000003066722e6163696e712e6c696768746e696e672e466561747572652e42617369634d756c7469506172745061796d656e74010000002066722e6163696e712e6c696768746e696e672e466561747572652e57756d626f010000002866722e6163696e712e6c696768746e696e672e466561747572652e416e63686f724f757470757473000000002666722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c54797065000000002a66722e6163696e712e6c696768746e696e672e466561747572652e5061796d656e744d65746164617461010000003566722e6163696e712e6c696768746e696e672e466561747572652e57616b6555704e6f74696669636174696f6e50726f7669646572010000002c66722e6163696e712e6c696768746e696e672e466561747572652e506179546f4f70656e50726f7669646572010000003066722e6163696e712e6c696768746e696e672e466561747572652e5472757374656453776170496e50726f7669646572010000003066722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c4261636b757050726f7669646572010000003866722e6163696e712e6c696768746e696e672e466561747572652e4578706572696d656e74616c5472616d706f6c696e655061796d656e740100000000000000000000000000000000000000000000001388000000000bebc200000000002faf0800000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e000001bc020000000001012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000b77080044a0100000000000022002046672803839d10e21d43eafb532bc37cd21bd97dec7f9b50d45380cd1cce69654a01000000000000220020bbd7f17366848d8f624c28438128ce4dc8c72ea21deb0ccf25bee110920da032400d03000000000022002031dbc67ef6930d0825de6c23bd311eb93d40430d543c0555aa0f15b7aaab0cbc781c0c0000000000220020958bb43c9e6d1b985001c2f4dc38d286d7fde78bb04d7ec5a5ae44d8ebf0c40c040047304402201991b61ae8ef7bf6bd03f6f965552294e7941fce3fc91a024094cbd9b3464dd202206068ef64671e59b5825408e58462613a6ad0edfc7aa23853aea36187298c493901483045022100cca233f9a14605a7adab49f959c5b42260a55156282cbc802397fc934d5e537c02203504b82653044526706d76d3ddf0f083ea77a16f6cc13c93add344069a55cb940147522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452aede99dc20000000000000000000000000000000000000000000001388000000002faf0800000000000bebc2000000002051487720c64eaa73a972e2e240f5fe4b1cc1c46d9a76854a11c62ab969222a29000000210332dcde49bbcc222f9e793771bca07d28b08c2d6e12992ebe5398c20194f267220000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001000000210234ea3e3929ca115acc645d07c40eada7a98d86017614c3fa466d7e19760917e4000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000000000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd00000000000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000001976a9143a52c0fc59997d1e53009d607e3d93ca56b1014c88ac0000000000000000000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd00000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c0000000000000000000000010000000000 \ No newline at end of file diff --git a/src/commonTest/resources/nonreg/v2/Negotiating_d9b4cd96/data.json b/src/commonTest/resources/nonreg/v2/Negotiating_d9b4cd96/data.json deleted file mode 100644 index 76501b4ad..000000000 --- a/src/commonTest/resources/nonreg/v2/Negotiating_d9b4cd96/data.json +++ /dev/null @@ -1,186 +0,0 @@ -{ - "type": "fr.acinq.lightning.channel.states.Negotiating", - "commitments": { - "params": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "channelConfig": [ - "funding_pubkey_based_channel_keypath" - ], - "channelFeatures": [ - "option_support_large_channel", - "option_static_remotekey", - "option_anchor_outputs", - "zero_reserve_channels", - "zero_conf_channels" - ], - "localParams": { - "nodeId": "0362b19a83930389b4468be40308efb3f352b23142ae25e6aba0465a8220f95b06", - "fundingKeyPath": "m/795924157'/565292462/1721776665'/620103361/947451165/318257970'/1822224386/616080517'/0'", - "dustLimit": 1000, - "maxHtlcValueInFlightMsat": 1500000000, - "htlcMinimum": 1000, - "toSelfDelay": 144, - "maxAcceptedHtlcs": 100, - "isInitiator": false, - "defaultFinalScriptPubKey": "001434947cfb2e8f6054ddf12daed4308cbe342580d1", - "features": { - "activated": { - "initial_routing_sync": "Optional", - "option_data_loss_protect": "Optional", - "gossip_queries": "Optional", - "gossip_queries_ex": "Optional", - "var_onion_optin": "Mandatory", - "payment_secret": "Mandatory", - "basic_mpp": "Optional", - "option_support_large_channel": "Optional", - "option_static_remotekey": "Mandatory", - "option_anchor_outputs": "Mandatory", - "option_channel_type": "Mandatory", - "option_payment_metadata": "Optional", - "trampoline_payment_experimental": "Optional", - "wake_up_notification_client": "Optional", - "pay_to_open_client": "Optional", - "trusted_swap_in_client": "Optional", - "channel_backup_client": "Optional" - }, - "unknown": [ - ] - } - }, - "remoteParams": { - "nodeId": "037108815ff0128f7ed22640485c226d9ad64a9fd6d8b41b6623565aed6b34812c", - "dustLimit": 1100, - "maxHtlcValueInFlightMsat": 1500000000, - "htlcMinimum": 0, - "toSelfDelay": 144, - "maxAcceptedHtlcs": 100, - "revocationBasepoint": "037d549bc475d9b2b0098e3b2f23282671646eab09b36e2f01099f39e376552864", - "paymentBasepoint": "0368434fc548cb471f7ed8c94638433bfb07cceb97665c411450fdc23c60236409", - "delayedPaymentBasepoint": "0399d61c09ee58f1cdc497a872f6b284cbaccd54f56bcbf7acf1f5595b577506cc", - "htlcBasepoint": "0288fb5246c577f7ea28bc1b56f64d4c9f6c931b7075f7890bc6b4daff6253b5d6", - "features": { - "activated": { - "option_data_loss_protect": "Optional", - "initial_routing_sync": "Optional", - "gossip_queries": "Optional", - "var_onion_optin": "Mandatory", - "gossip_queries_ex": "Optional", - "option_static_remotekey": "Mandatory", - "payment_secret": "Mandatory", - "basic_mpp": "Optional", - "option_support_large_channel": "Optional", - "option_anchor_outputs": "Mandatory", - "option_channel_type": "Mandatory", - "option_payment_metadata": "Optional", - "wake_up_notification_provider": "Optional", - "pay_to_open_provider": "Optional", - "trusted_swap_in_provider": "Optional", - "channel_backup_provider": "Optional", - "trampoline_payment_experimental": "Optional" - }, - "unknown": [ - ] - } - }, - "channelFlags": 0 - }, - "changes": { - "localChanges": { - "proposed": [ - ], - "signed": [ - ], - "acked": [ - ] - }, - "remoteChanges": { - "proposed": [ - ], - "acked": [ - ], - "signed": [ - ] - }, - "localNextHtlcId": 0, - "remoteNextHtlcId": 0 - }, - "active": [ - { - "fundingTxIndex": 0, - "remoteFundingPubkey": "02b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c", - "localFundingStatus": { - "status": "unconfirmed", - "txId": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f" - }, - "remoteFundingStatus": { - "status": "locked" - }, - "localCommit": { - "index": 0, - "spec": { - "htlcsIn": [ - ], - "htlcsOut": [ - ], - "feerate": 5000, - "toLocal": 200000000, - "toRemote": 800000000 - }, - "publishableTxs": { - "commitTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "020000000001012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000b77080044a0100000000000022002046672803839d10e21d43eafb532bc37cd21bd97dec7f9b50d45380cd1cce69654a01000000000000220020bbd7f17366848d8f624c28438128ce4dc8c72ea21deb0ccf25bee110920da032400d03000000000022002031dbc67ef6930d0825de6c23bd311eb93d40430d543c0555aa0f15b7aaab0cbc781c0c0000000000220020958bb43c9e6d1b985001c2f4dc38d286d7fde78bb04d7ec5a5ae44d8ebf0c40c040047304402201991b61ae8ef7bf6bd03f6f965552294e7941fce3fc91a024094cbd9b3464dd202206068ef64671e59b5825408e58462613a6ad0edfc7aa23853aea36187298c493901483045022100cca233f9a14605a7adab49f959c5b42260a55156282cbc802397fc934d5e537c02203504b82653044526706d76d3ddf0f083ea77a16f6cc13c93add344069a55cb940147522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452aede99dc20" - }, - "htlcTxsAndSigs": [ - ] - } - }, - "remoteCommit": { - "index": 0, - "spec": { - "htlcsIn": [ - ], - "htlcsOut": [ - ], - "feerate": 5000, - "toLocal": 800000000, - "toRemote": 200000000 - }, - "txid": "51487720c64eaa73a972e2e240f5fe4b1cc1c46d9a76854a11c62ab969222a29", - "remotePerCommitmentPoint": "0332dcde49bbcc222f9e793771bca07d28b08c2d6e12992ebe5398c20194f26722" - }, - "nextRemoteCommit": null - } - ], - "inactive": [ - ], - "payments": { - }, - "remoteNextCommitInfo": { - "left": null, - "right": "0234ea3e3929ca115acc645d07c40eada7a98d86017614c3fa466d7e19760917e4" - }, - "remotePerCommitmentSecrets": "" - }, - "localShutdown": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "scriptPubKey": "76a9143a52c0fc59997d1e53009d607e3d93ca56b1014c88ac" - }, - "remoteShutdown": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "scriptPubKey": "001405e0104aa726e34ff5cd3a6320d05c0862b5b01c" - }, - "closingTxProposed": [ - [ - ] - ], - "bestUnpublishedClosingTx": null, - "closingFeerates": null -} \ No newline at end of file diff --git a/src/commonTest/resources/nonreg/v2/Negotiating_ee10091c/data.bin b/src/commonTest/resources/nonreg/v2/Negotiating_ee10091c/data.bin deleted file mode 100644 index a2be83bbe..000000000 --- a/src/commonTest/resources/nonreg/v2/Negotiating_ee10091c/data.bin +++ /dev/null @@ -1 +0,0 @@ -00000002000012760000002f66722e6163696e712e6c696768746e696e672e73657269616c697a6174696f6e2e76322e4e65676f74696174696e670000002006226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f00000021037108815ff0128f7ed22640485c226d9ad64a9fd6d8b41b6623565aed6b34812c00061a800000000b426c6f636b486561646572000000500100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5494dffff7f2002000000000000000000271000000000000027100000000000002710000000040000000f000000210362b19a83930389b4468be40308efb3f352b23142ae25e6aba0465a8220f95b060000000900000000af70d6bd0000000021b1adae00000000e6a03a190000000024f606c1000000003878f51d0000000092f83b32000000006c9cf00200000000a4b8a485000000008000000000000000000003e80000000059682f000000000000004e2000000000000003e800000090000000640000000016001434947cfb2e8f6054ddf12daed4308cbe342580d1000000110000002d66722e6163696e712e6c696768746e696e672e466561747572652e496e697469616c526f7574696e6753796e63010000003066722e6163696e712e6c696768746e696e672e466561747572652e4f7074696f6e446174614c6f737350726f74656374010000002e66722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c52616e676551756572696573010000003666722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c52616e676551756572696573457874656e646564010000002e66722e6163696e712e6c696768746e696e672e466561747572652e5661726961626c654c656e6774684f6e696f6e000000002866722e6163696e712e6c696768746e696e672e466561747572652e5061796d656e74536563726574000000003066722e6163696e712e6c696768746e696e672e466561747572652e42617369634d756c7469506172745061796d656e74010000002066722e6163696e712e6c696768746e696e672e466561747572652e57756d626f010000002a66722e6163696e712e6c696768746e696e672e466561747572652e53746174696352656d6f74654b6579000000002866722e6163696e712e6c696768746e696e672e466561747572652e416e63686f724f757470757473000000002666722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c54797065000000002a66722e6163696e712e6c696768746e696e672e466561747572652e5061796d656e744d65746164617461010000003866722e6163696e712e6c696768746e696e672e466561747572652e4578706572696d656e74616c5472616d706f6c696e655061796d656e74010000003366722e6163696e712e6c696768746e696e672e466561747572652e57616b6555704e6f74696669636174696f6e436c69656e74010000002a66722e6163696e712e6c696768746e696e672e466561747572652e506179546f4f70656e436c69656e74010000002e66722e6163696e712e6c696768746e696e672e466561747572652e5472757374656453776170496e436c69656e74010000002e66722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c4261636b7570436c69656e74010000000000000021037108815ff0128f7ed22640485c226d9ad64a9fd6d8b41b6623565aed6b34812c000000000000044c0000000059682f000000000000002710000000000000000000000090000000640000002102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c00000021037d549bc475d9b2b0098e3b2f23282671646eab09b36e2f01099f39e376552864000000210368434fc548cb471f7ed8c94638433bfb07cceb97665c411450fdc23c60236409000000210399d61c09ee58f1cdc497a872f6b284cbaccd54f56bcbf7acf1f5595b577506cc000000210288fb5246c577f7ea28bc1b56f64d4c9f6c931b7075f7890bc6b4daff6253b5d6000000110000003066722e6163696e712e6c696768746e696e672e466561747572652e4f7074696f6e446174614c6f737350726f74656374010000002d66722e6163696e712e6c696768746e696e672e466561747572652e496e697469616c526f7574696e6753796e63010000002e66722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c52616e676551756572696573010000002e66722e6163696e712e6c696768746e696e672e466561747572652e5661726961626c654c656e6774684f6e696f6e000000003666722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c52616e676551756572696573457874656e646564010000002a66722e6163696e712e6c696768746e696e672e466561747572652e53746174696352656d6f74654b6579000000002866722e6163696e712e6c696768746e696e672e466561747572652e5061796d656e74536563726574000000003066722e6163696e712e6c696768746e696e672e466561747572652e42617369634d756c7469506172745061796d656e74010000002066722e6163696e712e6c696768746e696e672e466561747572652e57756d626f010000002866722e6163696e712e6c696768746e696e672e466561747572652e416e63686f724f757470757473000000002666722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c54797065000000002a66722e6163696e712e6c696768746e696e672e466561747572652e5061796d656e744d65746164617461010000003566722e6163696e712e6c696768746e696e672e466561747572652e57616b6555704e6f74696669636174696f6e50726f7669646572010000002c66722e6163696e712e6c696768746e696e672e466561747572652e506179546f4f70656e50726f7669646572010000003066722e6163696e712e6c696768746e696e672e466561747572652e5472757374656453776170496e50726f7669646572010000003066722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c4261636b757050726f7669646572010000003866722e6163696e712e6c696768746e696e672e466561747572652e4578706572696d656e74616c5472616d706f6c696e655061796d656e740100000000000000000000000000000000000000000000001388000000000bebc200000000002faf0800000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e000001bc020000000001012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000b77080044a0100000000000022002046672803839d10e21d43eafb532bc37cd21bd97dec7f9b50d45380cd1cce69654a01000000000000220020bbd7f17366848d8f624c28438128ce4dc8c72ea21deb0ccf25bee110920da032400d03000000000022002031dbc67ef6930d0825de6c23bd311eb93d40430d543c0555aa0f15b7aaab0cbc781c0c0000000000220020958bb43c9e6d1b985001c2f4dc38d286d7fde78bb04d7ec5a5ae44d8ebf0c40c040047304402201991b61ae8ef7bf6bd03f6f965552294e7941fce3fc91a024094cbd9b3464dd202206068ef64671e59b5825408e58462613a6ad0edfc7aa23853aea36187298c493901483045022100cca233f9a14605a7adab49f959c5b42260a55156282cbc802397fc934d5e537c02203504b82653044526706d76d3ddf0f083ea77a16f6cc13c93add344069a55cb940147522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452aede99dc20000000000000000000000000000000000000000000001388000000002faf0800000000000bebc2000000002051487720c64eaa73a972e2e240f5fe4b1cc1c46d9a76854a11c62ab969222a29000000210332dcde49bbcc222f9e793771bca07d28b08c2d6e12992ebe5398c20194f267220000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001000000210234ea3e3929ca115acc645d07c40eada7a98d86017614c3fa466d7e19760917e4000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000000000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd00000000000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd00000016001434947cfb2e8f6054ddf12daed4308cbe342580d10000000000000000000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd00000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c00000000000000000000000100000001000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e0000007102000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d11a2d0c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c000000000100000000000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd00000000000007e600000040517e72591fed6c80b3bd8314cf4e44a3ca19a19882ab92d6238ab01e5fa76ab52435b680685bec0f3f04d2bd75bb4e137d1175c87987d99662450efc66b907c3000000010000003166722e6163696e712e6c696768746e696e672e776972652e436c6f73696e675369676e6564546c762e46656552616e6765000000000000054400000000000007e60000000001000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e0000014e020000000001012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d16b2e0c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c0400483045022100b2cc62e81ae67b7f67421055afda676fdf049cd8b5810afe7d13c4c0f63f724002206acf483e46ec6517a208d00851e19e964aab2de5290a5c599366701f4102a50e0147304402206dd03bb394e2058717cd89586906385e457a4ed3634af2960b3928f113e1e7de02205ac9c9322430c11240769a51b43cbaf203c7c04f199c3d0d457b21f387c21cdb0147522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae000000000100000000 \ No newline at end of file diff --git a/src/commonTest/resources/nonreg/v2/Negotiating_ee10091c/data.json b/src/commonTest/resources/nonreg/v2/Negotiating_ee10091c/data.json deleted file mode 100644 index 97299fe3d..000000000 --- a/src/commonTest/resources/nonreg/v2/Negotiating_ee10091c/data.json +++ /dev/null @@ -1,225 +0,0 @@ -{ - "type": "fr.acinq.lightning.channel.states.Negotiating", - "commitments": { - "params": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "channelConfig": [ - "funding_pubkey_based_channel_keypath" - ], - "channelFeatures": [ - "option_support_large_channel", - "option_static_remotekey", - "option_anchor_outputs", - "zero_reserve_channels", - "zero_conf_channels" - ], - "localParams": { - "nodeId": "0362b19a83930389b4468be40308efb3f352b23142ae25e6aba0465a8220f95b06", - "fundingKeyPath": "m/795924157'/565292462/1721776665'/620103361/947451165/318257970'/1822224386/616080517'/0'", - "dustLimit": 1000, - "maxHtlcValueInFlightMsat": 1500000000, - "htlcMinimum": 1000, - "toSelfDelay": 144, - "maxAcceptedHtlcs": 100, - "isInitiator": false, - "defaultFinalScriptPubKey": "001434947cfb2e8f6054ddf12daed4308cbe342580d1", - "features": { - "activated": { - "initial_routing_sync": "Optional", - "option_data_loss_protect": "Optional", - "gossip_queries": "Optional", - "gossip_queries_ex": "Optional", - "var_onion_optin": "Mandatory", - "payment_secret": "Mandatory", - "basic_mpp": "Optional", - "option_support_large_channel": "Optional", - "option_static_remotekey": "Mandatory", - "option_anchor_outputs": "Mandatory", - "option_channel_type": "Mandatory", - "option_payment_metadata": "Optional", - "trampoline_payment_experimental": "Optional", - "wake_up_notification_client": "Optional", - "pay_to_open_client": "Optional", - "trusted_swap_in_client": "Optional", - "channel_backup_client": "Optional" - }, - "unknown": [ - ] - } - }, - "remoteParams": { - "nodeId": "037108815ff0128f7ed22640485c226d9ad64a9fd6d8b41b6623565aed6b34812c", - "dustLimit": 1100, - "maxHtlcValueInFlightMsat": 1500000000, - "htlcMinimum": 0, - "toSelfDelay": 144, - "maxAcceptedHtlcs": 100, - "revocationBasepoint": "037d549bc475d9b2b0098e3b2f23282671646eab09b36e2f01099f39e376552864", - "paymentBasepoint": "0368434fc548cb471f7ed8c94638433bfb07cceb97665c411450fdc23c60236409", - "delayedPaymentBasepoint": "0399d61c09ee58f1cdc497a872f6b284cbaccd54f56bcbf7acf1f5595b577506cc", - "htlcBasepoint": "0288fb5246c577f7ea28bc1b56f64d4c9f6c931b7075f7890bc6b4daff6253b5d6", - "features": { - "activated": { - "option_data_loss_protect": "Optional", - "initial_routing_sync": "Optional", - "gossip_queries": "Optional", - "var_onion_optin": "Mandatory", - "gossip_queries_ex": "Optional", - "option_static_remotekey": "Mandatory", - "payment_secret": "Mandatory", - "basic_mpp": "Optional", - "option_support_large_channel": "Optional", - "option_anchor_outputs": "Mandatory", - "option_channel_type": "Mandatory", - "option_payment_metadata": "Optional", - "wake_up_notification_provider": "Optional", - "pay_to_open_provider": "Optional", - "trusted_swap_in_provider": "Optional", - "channel_backup_provider": "Optional", - "trampoline_payment_experimental": "Optional" - }, - "unknown": [ - ] - } - }, - "channelFlags": 0 - }, - "changes": { - "localChanges": { - "proposed": [ - ], - "signed": [ - ], - "acked": [ - ] - }, - "remoteChanges": { - "proposed": [ - ], - "acked": [ - ], - "signed": [ - ] - }, - "localNextHtlcId": 0, - "remoteNextHtlcId": 0 - }, - "active": [ - { - "fundingTxIndex": 0, - "remoteFundingPubkey": "02b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c", - "localFundingStatus": { - "status": "unconfirmed", - "txId": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f" - }, - "remoteFundingStatus": { - "status": "locked" - }, - "localCommit": { - "index": 0, - "spec": { - "htlcsIn": [ - ], - "htlcsOut": [ - ], - "feerate": 5000, - "toLocal": 200000000, - "toRemote": 800000000 - }, - "publishableTxs": { - "commitTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "020000000001012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000b77080044a0100000000000022002046672803839d10e21d43eafb532bc37cd21bd97dec7f9b50d45380cd1cce69654a01000000000000220020bbd7f17366848d8f624c28438128ce4dc8c72ea21deb0ccf25bee110920da032400d03000000000022002031dbc67ef6930d0825de6c23bd311eb93d40430d543c0555aa0f15b7aaab0cbc781c0c0000000000220020958bb43c9e6d1b985001c2f4dc38d286d7fde78bb04d7ec5a5ae44d8ebf0c40c040047304402201991b61ae8ef7bf6bd03f6f965552294e7941fce3fc91a024094cbd9b3464dd202206068ef64671e59b5825408e58462613a6ad0edfc7aa23853aea36187298c493901483045022100cca233f9a14605a7adab49f959c5b42260a55156282cbc802397fc934d5e537c02203504b82653044526706d76d3ddf0f083ea77a16f6cc13c93add344069a55cb940147522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452aede99dc20" - }, - "htlcTxsAndSigs": [ - ] - } - }, - "remoteCommit": { - "index": 0, - "spec": { - "htlcsIn": [ - ], - "htlcsOut": [ - ], - "feerate": 5000, - "toLocal": 800000000, - "toRemote": 200000000 - }, - "txid": "51487720c64eaa73a972e2e240f5fe4b1cc1c46d9a76854a11c62ab969222a29", - "remotePerCommitmentPoint": "0332dcde49bbcc222f9e793771bca07d28b08c2d6e12992ebe5398c20194f26722" - }, - "nextRemoteCommit": null - } - ], - "inactive": [ - ], - "payments": { - }, - "remoteNextCommitInfo": { - "left": null, - "right": "0234ea3e3929ca115acc645d07c40eada7a98d86017614c3fa466d7e19760917e4" - }, - "remotePerCommitmentSecrets": "" - }, - "localShutdown": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "scriptPubKey": "001434947cfb2e8f6054ddf12daed4308cbe342580d1" - }, - "remoteShutdown": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "scriptPubKey": "001405e0104aa726e34ff5cd3a6320d05c0862b5b01c" - }, - "closingTxProposed": [ - [ - { - "unsignedTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "02000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d11a2d0c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c00000000", - "toLocalIndex": 0 - }, - "localClosingSigned": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "feeSatoshis": 2022, - "signature": "517e72591fed6c80b3bd8314cf4e44a3ca19a19882ab92d6238ab01e5fa76ab52435b680685bec0f3f04d2bd75bb4e137d1175c87987d99662450efc66b907c3", - "tlvStream": { - "records": [ - { - "type": "fr.acinq.lightning.wire.ClosingSignedTlv.FeeRange", - "min": 1348, - "max": 2022 - } - ] - } - } - } - ] - ], - "bestUnpublishedClosingTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "020000000001012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d16b2e0c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c0400483045022100b2cc62e81ae67b7f67421055afda676fdf049cd8b5810afe7d13c4c0f63f724002206acf483e46ec6517a208d00851e19e964aab2de5290a5c599366701f4102a50e0147304402206dd03bb394e2058717cd89586906385e457a4ed3634af2960b3928f113e1e7de02205ac9c9322430c11240769a51b43cbaf203c7c04f199c3d0d457b21f387c21cdb0147522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae00000000", - "toLocalIndex": 0 - }, - "closingFeerates": null -} \ No newline at end of file diff --git a/src/commonTest/resources/nonreg/v2/Negotiating_f52b19b8/data.bin b/src/commonTest/resources/nonreg/v2/Negotiating_f52b19b8/data.bin deleted file mode 100644 index d633028f6..000000000 --- a/src/commonTest/resources/nonreg/v2/Negotiating_f52b19b8/data.bin +++ /dev/null @@ -1 +0,0 @@ -0000000200002e5e0000002f66722e6163696e712e6c696768746e696e672e73657269616c697a6174696f6e2e76322e4e65676f74696174696e670000002006226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f000000210362b19a83930389b4468be40308efb3f352b23142ae25e6aba0465a8220f95b0600061a800000000b426c6f636b486561646572000000500100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5494dffff7f2002000000000000000000271000000000000027100000000000002710000000040000000f00000021037108815ff0128f7ed22640485c226d9ad64a9fd6d8b41b6623565aed6b34812c000000090000000016f35f4f0000000075d70557000000002409cee6000000000b01aa72000000002e461aea00000000b8953c1600000000909117b700000000fa26717f0000000080000001000000000000044c0000000059682f000000000000002710000000000000000000000090000000640100000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c000000110000002d66722e6163696e712e6c696768746e696e672e466561747572652e496e697469616c526f7574696e6753796e63010000003066722e6163696e712e6c696768746e696e672e466561747572652e4f7074696f6e446174614c6f737350726f74656374010000002e66722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c52616e676551756572696573010000003666722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c52616e676551756572696573457874656e646564010000002e66722e6163696e712e6c696768746e696e672e466561747572652e5661726961626c654c656e6774684f6e696f6e000000002866722e6163696e712e6c696768746e696e672e466561747572652e5061796d656e74536563726574000000003066722e6163696e712e6c696768746e696e672e466561747572652e42617369634d756c7469506172745061796d656e74010000002066722e6163696e712e6c696768746e696e672e466561747572652e57756d626f010000002a66722e6163696e712e6c696768746e696e672e466561747572652e53746174696352656d6f74654b6579000000002866722e6163696e712e6c696768746e696e672e466561747572652e416e63686f724f757470757473000000002666722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c54797065000000002a66722e6163696e712e6c696768746e696e672e466561747572652e5061796d656e744d65746164617461010000003866722e6163696e712e6c696768746e696e672e466561747572652e4578706572696d656e74616c5472616d706f6c696e655061796d656e74010000003566722e6163696e712e6c696768746e696e672e466561747572652e57616b6555704e6f74696669636174696f6e50726f7669646572010000002c66722e6163696e712e6c696768746e696e672e466561747572652e506179546f4f70656e50726f7669646572010000003066722e6163696e712e6c696768746e696e672e466561747572652e5472757374656453776170496e50726f7669646572010000003066722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c4261636b757050726f76696465720100000000000000210362b19a83930389b4468be40308efb3f352b23142ae25e6aba0465a8220f95b0600000000000003e80000000059682f000000000000004e2000000000000003e80000009000000064000000210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa40000002103a42aef6d1c860caffa6c71a6f8ac2b16eec25bab0c3950cdb1fad7fb38a5f2a50000002102508e1845b8bbe0773f6bf8f3f04f59a5896426765c7b6b23e6e466c95381182b0000002102d62233b7c33f8fd0911922461a651007f1de09d8c474029caa8f2c229c10de260000002103d05c8245bdc12efd8b070b22b276e7db4254f4693e22b3f7c978c08e67b36236000000110000003066722e6163696e712e6c696768746e696e672e466561747572652e4f7074696f6e446174614c6f737350726f74656374010000002d66722e6163696e712e6c696768746e696e672e466561747572652e496e697469616c526f7574696e6753796e63010000002e66722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c52616e676551756572696573010000002e66722e6163696e712e6c696768746e696e672e466561747572652e5661726961626c654c656e6774684f6e696f6e000000003666722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c52616e676551756572696573457874656e646564010000002a66722e6163696e712e6c696768746e696e672e466561747572652e53746174696352656d6f74654b6579000000002866722e6163696e712e6c696768746e696e672e466561747572652e5061796d656e74536563726574000000003066722e6163696e712e6c696768746e696e672e466561747572652e42617369634d756c7469506172745061796d656e74010000002066722e6163696e712e6c696768746e696e672e466561747572652e57756d626f010000002866722e6163696e712e6c696768746e696e672e466561747572652e416e63686f724f757470757473000000002666722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c54797065000000002a66722e6163696e712e6c696768746e696e672e466561747572652e5061796d656e744d65746164617461010000003366722e6163696e712e6c696768746e696e672e466561747572652e57616b6555704e6f74696669636174696f6e436c69656e74010000002a66722e6163696e712e6c696768746e696e672e466561747572652e506179546f4f70656e436c69656e74010000002e66722e6163696e712e6c696768746e696e672e466561747572652e5472757374656453776170496e436c69656e74010000002e66722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c4261636b7570436c69656e74010000003866722e6163696e712e6c696768746e696e672e466561747572652e4578706572696d656e74616c5472616d706f6c696e655061796d656e740100000000000000000000000000000000000000000000001388000000002faf0800000000000bebc200000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e000001bc020000000001012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000b77080044a0100000000000022002046672803839d10e21d43eafb532bc37cd21bd97dec7f9b50d45380cd1cce69654a01000000000000220020bbd7f17366848d8f624c28438128ce4dc8c72ea21deb0ccf25bee110920da032400d030000000000220020cb93e3adb8d213704e9a07ea2a6ce91dca51a9b76fcb6bef3cc9b5b7e10a7990781c0c00000000002200202f0860cd1fe361a1aaf5708f75b6511c92cd5a51bdaaccfbda77aead550d875104004730440220672323ca34b85c2a43e3e93ac8a642a8293b1483392f531736db975d05f3ad3c022019f7b5044cd2a230dc49484c219fd96485f98d21c6add317566f4b21816a2fb101483045022100956b481822da569bc75c1f7ab6ec34c0a1e14dd5b4701ea8473e5bfe6b6ad41702202b1a987850611c0f52cccbb6016c735a08572f61fe03616a186ca39a8b2e07970147522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452aede99dc20000000000000000000000000000000000000000000001388000000000bebc200000000002faf0800000000206498095b8d064f46673e7c0d919636e1dff0c0a76ed61dd96938a178253ea4cb0000002102365f9a5e4822956750faa46230f54e47d4b6ef9d58eb8c488d80a5efed938d5b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100010000002103c57839fd412868a398bea05d01678a752661126a2d1357a0f7cb6f0c60311125000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000000000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd00000ee48c0ca0219d38704b18133d3e9c6f2fff5fcba2fa4d7ddca7cd38361c62d91123930e013d96e802c4ef5e6c9cb1f101aa956ff6fd3375a525dd9a1483c4e39135fc8d732b2109b7965a03f4acb1a4b0c3e9de40ec5d0b075f0b9a6d7ee71f6fba369ba60c5de117d04338216a29a4034ab7a3fe6b162d2fffd8d8ffb1a1e120aba163590a45add7b0cb61a56acd91fa206fadece0959b20d127e7b64ee0a2dfd945bcd9b31cade08fb9dc778e101f6de98b23d805c82415b48f72bad94058c651a9bf017a75c518d7cd8975e2ee114691aab5c05c5178273744408ecbdb20119eb638019cabb65baf2f379bdabeba39fab76c027b7ef802c5561cc9d80675621aef1cc1a60d27ede5b54c40a92e71ea7579376480583bd18be60875b4789f59197c4647eb0581a6b777d0e0cbef26166cd73a501a39133f9f7d529b8cd7a67356c9509f0d0254edb193434b72e34235adddec1bb43ad0605fe92651d3f68499a96e788aed0d641e15a166eb45c181d3a71f87bd92fbd3a309026534da87120a24c8b0a87ec13bd4eae6954085b8d1b3a0b1316f8602974a2949d0daf65b915ed77c78a67d78c49d1538a2365e50da0931237df3ea18613f3dedc1ed6d73686528b7fba8a84270a88d715879630e7bf2bcfcbc26e3d02ea691aa23f7cb9db872933aed347c86068f422111c22f2d91a509792304771274dd8c34dbd645bc319ef17ebacdc42dcba613105bab6e0f520869dcab50e7591fe803a4dc1301997af79983481b803b71800d3f552ea3401dfb93e9019c4e566d7112aab6169f05e0017f522776942a2b26114fa11969daf6a761933d1650a75f1d645943e85bb0be8338721bd43671c5e6d18052420dcbff9c28ed02888e8e5bb89bbd45f3d043887289ab36bc311621a62e5c874cc333e28cc275cc4242f4e524c0ddb9f5ea9199eedb0668f21048b11f486c5ba712d5edcbea80e85148e4a51a3a1c84842ed7db02b88c121d0426335183ee62e6a20ceb1040a658e769fc261e27eafed669d7c6bd8bb58111325a8e5c1faf44ed32ceb1791a8b1d2a482a6353beb4e7a4bded388408c1bbb72823e846a16a5e65612d412dbf9a0d6c21545fb965f3d43f4e16b9a1daa885433a4dbcb45cf25e5cf8e43bfadc4c6663061fee3894da75582ed83201a1e171271c638057a9c3d8faed7036c4f7e2a6bb45ab87f102803f4b9d0ebfe6342740c5082367dc5257652edb933f96a90113775e738bcd22e97730596f3d1631bf0ef05d96c8579f1f6a503631dc79c8238cdfd1e6ba4ebdbc1a6884f455f1048d66d275fa4deeff73bea7f6611e100f7e7ec94276fb85b8fb1f47cb08b2e09e97e744f64c0733e8f9e340f2e6e2d75adf7693692de5f4360aa5f666707db1488ad6be41312689ae6e8d6f7f1113c757f9aeb690a3545493c6a26b6f01926efd9da9747d444c11d60f3da935de3007c8bf7538e696663c8aa98b1b58881f666ba00d7c619747d385e59e3f5885d6a4d1ddc70df9ca2d6c871cb6143647a194bd4ada7baf8f3421faa74dd7e18ee66d57e9281f9235e749a09ccca9b15e0a5bcc2bc49ee8aa7d9b9321e173863d40e3625412f1d0bd115e9dc07fa3addc5e6df48e3464c09b06c2fc02929fafb6b848f17e0d0f234c27280412754f651763caaa55fbf90e911b2bb64a69b1d2c79b4430bbde2f07630e635f7937d827686bcb622f287049c607944af8a3aacceaf74a7d709fecd909d99722486654d097c63781ac283347ab4f37d8d9d15f5638ae3f2780930752a8d1c19f25b904e59837464680b57901d7d09dd029bc3d0201d0929616ba5e7c7d967618678885c05da4abb1df78cbf3def8a5c7c1497a78266a62670471da7eeb65c1127275b9f534e4162bd33f4d77036a0823b0f53fb33bb6ff41f419379e4b21723feaa0d627a693625af1b1030a5436bb487fc4b8f8dda4bf513a58d44637df3901751f006e560cd8e53bf46e1512b7c449a79638bb14624af9b1409bcf301d32d4dcbf9078f2efdf356af11cdcee29fff984134de2003898cb60117ada37c2c20c963bfd337cb2c9c70b78efa746b6137fe70140aae2c7cb30697e54a5baa2a5ab4188b7ac8f4910a53f195537965e5229a41511c0a02b046a2f7b92acb0dfea2c2ab34209c04f5b92296fc4214c2644536ccf9495a79da81a53688f86a2b070f727b39e0dfa1d379c4bbaebe0d9f0c907fa90cb43383dbb033bb859e4dcb43efbcc388f1a235eb40979ef295a3bc1099aa0cf9788f776fca622dd8589079d20fd2c265e3b4d6812588ad226dfb61efb00eac0536409cb9b51d46a838dc347b8c1b9c521204f3cf99157e892ccad0a046a6c8bffebb810ef374cd7bd31d390706d53f983ade51bc920c5fbe8625fed4b34304207964e8ad12bd78c4b4590ed4d224e7f8b366bf1af81e0000b9a2543ac84a57a64d04d8be82e7888974dc4bfdc64772402952f0e0b42d4857aa7081c54f93313c74b5a5abe10615086458815ed93d226a80528383d9336dc21f8d5d40ec40c1cd954be32d8a31c777a96eef4e36bd9acedaa1fe1d806a73623e31c19992c741018f876da5b88dc8c3fffa82363273cf10952444f53308d2e6f40f52cff30b68c7dc38b56763aef19c29bb742bdf5d7b60b59a7c50075a258c9a8ab3ebb04eb7080555b5a114fb9e7ce9760f819a72217fd52b27c7beabb14a2ab837e73dbe64e31fae6b1051bb50df8d7866d38de6b119eb37bc7036f8896c096efd3b453cb9658eb72431cecb54a9c487e52ee32416a08784fae535df25a2518244d19abb78e3cc8485b5c89123c0f1cb5eca8ad96c95c6539ea14440e5d9f299bd8bba6259481b7b0401b3b5b26d0e755c996da5f9668ddc76ab96c61f83233e24b3fa6b27114799f3ac0d17951883cb1cdad6ab72384a1f821d9ffffb728aa288d6aaacb93558bfba2ec59e67fc67ecf278eb11ac844894f67aa4bc4799da7bd39644096fe737b81d6adc69dbc06f4a153b5b6c3e57e544fec36deeffdc9e24a194a8e1abed5a361f5131c38d6e0cf05b86886a217283c865aca2919a6d46886ece53bd43cc5af069619fb12c812f92c007df3b504c66e7f10a593fdd8d3c4e6a8c743ced232732ad438a667df097bac7566de7fdc85225845545b189d85a83b18d4053f3c6fc2105fbba0e254c2a5c753b97d1791045630527672f82eadeaec0db03c3f880377de04e1b7cbf09fbf87c04def97cd8dee544581e877788f21b7567a955dfd7a06a816dc7ac11529400acb16abf4e7730f16c3312ac43a84b62e9aed266134ef2ee0db3bf2aedbc12f838eec6d0f1427defe77bdb650aa5398dd4989b94b9236a70e68d48c2e4f5bab36312fd1f1e4593cd9995878fd6a2b12515c0d41c9f0aeaac69fb77a013d8d4704ab4a173574d595edc90882c1bf947e9fdbe0ab1d680e3b4ec6e497cdd6a8e00e8dc9bca52066997d1c973ba27aadbe36876f1011dc11d6835acbbe5c7cfd6c3204b2a44dbf89b9715fd4797cf4200a4ca858705f624a1b48d75e166a1cb0c68e8dc0c994d69e199835e9f62f9b24167f28781f2f35ea1149f53bbda63bcb27b74f0e3e4704026e84e873306de2300488e9a182d2e85e46ac04b89c94277bc1f883a7047f62d117e45055bba398612091e9fcd4bbdd0d15e4b41c97898d9acdf904aa6cf144ef62ef7dd26f755c2fe353ed5eff1aef005ab99b7e355111a9ba5c5d03874914526e0356bc78f09543d6419e87be1df37d34393b12f87c676f49556a6ae5c91c194bbecf27936a91f3688a501c2ccb9a32fea57e195d3b0e0fd0b4640840400ec086678ee67ba0bd774de3c111979708409207e4d4bd1dce2321b77ccc71127be8318fe92e6ec730a47112bd069c9cad37361f693d07a90b0a37e5875938b06d6370d1f1c1c280bfd83fc5e2d0b803e467eacfd37c48ca37721193859cd499653f5dfd78c26e4b181e82b5005cac0e9bd55fb2850dd4c70cc1e3fe5c81167336f36839fce30f245061191282585ff911c9e4af395ad4cf77b6e4f17d389ae8fbd61a3a3a4e73ccae0716507afa7ac4d0f2349c3aa56f47b6aa78806d7c20b50e125ee329921ffe96f8123d3e4be8be89b2318b6e016c385728b7a02f7dbb14552e2863453c33e3854047e6d8f84fe9f56c9200962025182d418580a294a0d09e9740e187e3be88236f62542b56bf08f72a859ae8a809e78a90e86b9b2cde799f9cca6049d5f49e97365744bede14be8cf680175cca275444e37327ea04d624faed898e0fc7751f1ac7d6241d93472c2d6ee8925fedc9169539799701174a81d3d6e00a9ac9647286d08b6c982c6baf86810d1e9f91c581f0c755273009389019bcb68a7ffbb4f0bc7de1ec45004c93f1a04a8c4cb60490654f616250c14bb54e9fe1fa1ad866830451afe98559d3e0e85073c2950d181feeb935c6cb69962a644ba8736535c11e7a9efbc17e9669b1c232985e9c5eaad29618ad9f461f1438d8c35c691d3d3bf80642a11f57cbf19ec1a7e63b2289d7c0e178052b6b344267d99e018c3f724f44ac465097ddea64d35e36c78736cfe6488991c4469d25b132db3560744e418be6ef3452ab5a73f66205e1ba67944cf1a556e60b037fb9ec6579f8638be744e075e0fc99722bcfc40efaf603c00e16b714ada2b7390cf2e9867df6c5961d96cb63298037df5f20e69b3b4bd2d2a24f68c48e02538fc1b2723fff9b52f18012d2024c40bfefb202b6292065b2cafb67aa1539e9d8b96ca039cc08e232fbb44cb46d7ce5017b14cd7f4e4e1675c2bd0b8d74958ac3c1232134d91dd02d701eef4ab953237b548f289f7e9ff902e7b39c40226596037271dd3296865618fd62a0abe228adb4286217b6049d157bd3a91b8997730fb29f0b086c9a0cd56f7f0ad198eedf098c86371570db86a7e2e972d58c8baee2e9e7aa34534e3f11e210d21ab8bb9de9517910e67d24881c8d2a72baa26b440bcdba17aa1c0d3448e3b78c62ad09bdf8a686af48107386c8a2fe1e8b575f9be0780a642305e9e9147f93fbc71447780dda6bc865d3412e5aecf0e842603bf65f059c9a3c3515ed949152e68d386415aaad1e8048be59bef3e4bab26d9cdc15a81a84f51dad584db81558c2c12c0728b0a028ea4729b6f032585d45feae6bc12e237febab2bef1117c366380078d163de200e03fa31640e9e927737f2679c8104f74b7ac4d36e32bd4a7d84632a2cf95e161fb3b5fa81321d5afe02467f059d13f440a03592a3f2b2ee93f667e2ed66559ef53cd734bed10b16062d6581be18e4717cf8837443653a5ffe6da47a73883210b7129bd1543b745f5ada684a84003f8955ae9150126f22397d5e38c814899b67000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd00000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c0000000000000000000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000001976a9143a52c0fc59997d1e53009d607e3d93ca56b1014c88ac000000010000002f66722e6163696e712e6c696768746e696e672e776972652e53687574646f776e546c762e4368616e6e656c4461746100000ee48c0ca0219d38704b18133d3e9c6f2fff5fcba2fa4d7ddca7cd38361c62d91123930e013d96e802c4ef5e6c9cb1f101aa956ff6fd3375a525dd9a1483c4e39135fc8d732b2109b7965a03f4acb1a4b0c3e9de40ec5d0b075f0b9a6d7ee71f6fba369ba60c5de117d04338216a29a4034ab7a3fe6b162d2fffd8d8ffb1a1e120aba163590a45add7b0cb61a56acd91fa206fadece0959b20d127e7b64ee0a2dfd945bcd9b31cade08fb9dc778e101f6de98b23d805c82415b48f72bad94058c651a9bf017a75c518d7cd8975e2ee114691aab5c05c5178273744408ecbdb20119eb638019cabb65baf2f379bdabeba39fab76c027b7ef802c5561cc9d80675621aef1cc1a60d27ede5b54c40a92e71ea7579376480583bd18be60875b4789f59197c4647eb0581a6b777d0e0cbef26166cd73a501a39133f9f7d529b8cd7a67356c9509f0d0254edb193434b72e34235adddec1bb43ad0605fe92651d3f68499a96e788aed0d641e15a166eb45c181d3a71f87bd92fbd3a309026534da87120a24c8b0a87ec13bd4eae6954085b8d1b3a0b1316f8602974a2949d0daf65b915ed77c78a67d78c49d1538a2365e50da0931237df3ea18613f3dedc1ed6d73686528b7fba8a84270a88d715879630e7bf2bcfcbc26e3d02ea691aa23f7cb9db872933aed347c86068f422111c22f2d91a509792304771274dd8c34dbd645bc319ef17ebacdc42dcba613105bab6e0f520869dcab50e7591fe803a4dc1301997af79983481b803b71800d3f552ea3401dfb93e9019c4e566d7112aab6169f05e0017f522776942a2b26114fa11969daf6a761933d1650a75f1d645943e85bb0be8338721bd43671c5e6d18052420dcbff9c28ed02888e8e5bb89bbd45f3d043887289ab36bc311621a62e5c874cc333e28cc275cc4242f4e524c0ddb9f5ea9199eedb0668f21048b11f486c5ba712d5edcbea80e85148e4a51a3a1c84842ed7db02b88c121d0426335183ee62e6a20ceb1040a658e769fc261e27eafed669d7c6bd8bb58111325a8e5c1faf44ed32ceb1791a8b1d2a482a6353beb4e7a4bded388408c1bbb72823e846a16a5e65612d412dbf9a0d6c21545fb965f3d43f4e16b9a1daa885433a4dbcb45cf25e5cf8e43bfadc4c6663061fee3894da75582ed83201a1e171271c638057a9c3d8faed7036c4f7e2a6bb45ab87f102803f4b9d0ebfe6342740c5082367dc5257652edb933f96a90113775e738bcd22e97730596f3d1631bf0ef05d96c8579f1f6a503631dc79c8238cdfd1e6ba4ebdbc1a6884f455f1048d66d275fa4deeff73bea7f6611e100f7e7ec94276fb85b8fb1f47cb08b2e09e97e744f64c0733e8f9e340f2e6e2d75adf7693692de5f4360aa5f666707db1488ad6be41312689ae6e8d6f7f1113c757f9aeb690a3545493c6a26b6f01926efd9da9747d444c11d60f3da935de3007c8bf7538e696663c8aa98b1b58881f666ba00d7c619747d385e59e3f5885d6a4d1ddc70df9ca2d6c871cb6143647a194bd4ada7baf8f3421faa74dd7e18ee66d57e9281f9235e749a09ccca9b15e0a5bcc2bc49ee8aa7d9b9321e173863d40e3625412f1d0bd115e9dc07fa3addc5e6df48e3464c09b06c2fc02929fafb6b848f17e0d0f234c27280412754f651763caaa55fbf90e911b2bb64a69b1d2c79b4430bbde2f07630e635f7937d827686bcb622f287049c607944af8a3aacceaf74a7d709fecd909d99722486654d097c63781ac283347ab4f37d8d9d15f5638ae3f2780930752a8d1c19f25b904e59837464680b57901d7d09dd029bc3d0201d0929616ba5e7c7d967618678885c05da4abb1df78cbf3def8a5c7c1497a78266a62670471da7eeb65c1127275b9f534e4162bd33f4d77036a0823b0f53fb33bb6ff41f419379e4b21723feaa0d627a693625af1b1030a5436bb487fc4b8f8dda4bf513a58d44637df3901751f006e560cd8e53bf46e1512b7c449a79638bb14624af9b1409bcf301d32d4dcbf9078f2efdf356af11cdcee29fff984134de2003898cb60117ada37c2c20c963bfd337cb2c9c70b78efa746b6137fe70140aae2c7cb30697e54a5baa2a5ab4188b7ac8f4910a53f195537965e5229a41511c0a02b046a2f7b92acb0dfea2c2ab34209c04f5b92296fc4214c2644536ccf9495a79da81a53688f86a2b070f727b39e0dfa1d379c4bbaebe0d9f0c907fa90cb43383dbb033bb859e4dcb43efbcc388f1a235eb40979ef295a3bc1099aa0cf9788f776fca622dd8589079d20fd2c265e3b4d6812588ad226dfb61efb00eac0536409cb9b51d46a838dc347b8c1b9c521204f3cf99157e892ccad0a046a6c8bffebb810ef374cd7bd31d390706d53f983ade51bc920c5fbe8625fed4b34304207964e8ad12bd78c4b4590ed4d224e7f8b366bf1af81e0000b9a2543ac84a57a64d04d8be82e7888974dc4bfdc64772402952f0e0b42d4857aa7081c54f93313c74b5a5abe10615086458815ed93d226a80528383d9336dc21f8d5d40ec40c1cd954be32d8a31c777a96eef4e36bd9acedaa1fe1d806a73623e31c19992c741018f876da5b88dc8c3fffa82363273cf10952444f53308d2e6f40f52cff30b68c7dc38b56763aef19c29bb742bdf5d7b60b59a7c50075a258c9a8ab3ebb04eb7080555b5a114fb9e7ce9760f819a72217fd52b27c7beabb14a2ab837e73dbe64e31fae6b1051bb50df8d7866d38de6b119eb37bc7036f8896c096efd3b453cb9658eb72431cecb54a9c487e52ee32416a08784fae535df25a2518244d19abb78e3cc8485b5c89123c0f1cb5eca8ad96c95c6539ea14440e5d9f299bd8bba6259481b7b0401b3b5b26d0e755c996da5f9668ddc76ab96c61f83233e24b3fa6b27114799f3ac0d17951883cb1cdad6ab72384a1f821d9ffffb728aa288d6aaacb93558bfba2ec59e67fc67ecf278eb11ac844894f67aa4bc4799da7bd39644096fe737b81d6adc69dbc06f4a153b5b6c3e57e544fec36deeffdc9e24a194a8e1abed5a361f5131c38d6e0cf05b86886a217283c865aca2919a6d46886ece53bd43cc5af069619fb12c812f92c007df3b504c66e7f10a593fdd8d3c4e6a8c743ced232732ad438a667df097bac7566de7fdc85225845545b189d85a83b18d4053f3c6fc2105fbba0e254c2a5c753b97d1791045630527672f82eadeaec0db03c3f880377de04e1b7cbf09fbf87c04def97cd8dee544581e877788f21b7567a955dfd7a06a816dc7ac11529400acb16abf4e7730f16c3312ac43a84b62e9aed266134ef2ee0db3bf2aedbc12f838eec6d0f1427defe77bdb650aa5398dd4989b94b9236a70e68d48c2e4f5bab36312fd1f1e4593cd9995878fd6a2b12515c0d41c9f0aeaac69fb77a013d8d4704ab4a173574d595edc90882c1bf947e9fdbe0ab1d680e3b4ec6e497cdd6a8e00e8dc9bca52066997d1c973ba27aadbe36876f1011dc11d6835acbbe5c7cfd6c3204b2a44dbf89b9715fd4797cf4200a4ca858705f624a1b48d75e166a1cb0c68e8dc0c994d69e199835e9f62f9b24167f28781f2f35ea1149f53bbda63bcb27b74f0e3e4704026e84e873306de2300488e9a182d2e85e46ac04b89c94277bc1f883a7047f62d117e45055bba398612091e9fcd4bbdd0d15e4b41c97898d9acdf904aa6cf144ef62ef7dd26f755c2fe353ed5eff1aef005ab99b7e355111a9ba5c5d03874914526e0356bc78f09543d6419e87be1df37d34393b12f87c676f49556a6ae5c91c194bbecf27936a91f3688a501c2ccb9a32fea57e195d3b0e0fd0b4640840400ec086678ee67ba0bd774de3c111979708409207e4d4bd1dce2321b77ccc71127be8318fe92e6ec730a47112bd069c9cad37361f693d07a90b0a37e5875938b06d6370d1f1c1c280bfd83fc5e2d0b803e467eacfd37c48ca37721193859cd499653f5dfd78c26e4b181e82b5005cac0e9bd55fb2850dd4c70cc1e3fe5c81167336f36839fce30f245061191282585ff911c9e4af395ad4cf77b6e4f17d389ae8fbd61a3a3a4e73ccae0716507afa7ac4d0f2349c3aa56f47b6aa78806d7c20b50e125ee329921ffe96f8123d3e4be8be89b2318b6e016c385728b7a02f7dbb14552e2863453c33e3854047e6d8f84fe9f56c9200962025182d418580a294a0d09e9740e187e3be88236f62542b56bf08f72a859ae8a809e78a90e86b9b2cde799f9cca6049d5f49e97365744bede14be8cf680175cca275444e37327ea04d624faed898e0fc7751f1ac7d6241d93472c2d6ee8925fedc9169539799701174a81d3d6e00a9ac9647286d08b6c982c6baf86810d1e9f91c581f0c755273009389019bcb68a7ffbb4f0bc7de1ec45004c93f1a04a8c4cb60490654f616250c14bb54e9fe1fa1ad866830451afe98559d3e0e85073c2950d181feeb935c6cb69962a644ba8736535c11e7a9efbc17e9669b1c232985e9c5eaad29618ad9f461f1438d8c35c691d3d3bf80642a11f57cbf19ec1a7e63b2289d7c0e178052b6b344267d99e018c3f724f44ac465097ddea64d35e36c78736cfe6488991c4469d25b132db3560744e418be6ef3452ab5a73f66205e1ba67944cf1a556e60b037fb9ec6579f8638be744e075e0fc99722bcfc40efaf603c00e16b714ada2b7390cf2e9867df6c5961d96cb63298037df5f20e69b3b4bd2d2a24f68c48e02538fc1b2723fff9b52f18012d2024c40bfefb202b6292065b2cafb67aa1539e9d8b96ca039cc08e232fbb44cb46d7ce5017b14cd7f4e4e1675c2bd0b8d74958ac3c1232134d91dd02d701eef4ab953237b548f289f7e9ff902e7b39c40226596037271dd3296865618fd62a0abe228adb4286217b6049d157bd3a91b8997730fb29f0b086c9a0cd56f7f0ad198eedf098c86371570db86a7e2e972d58c8baee2e9e7aa34534e3f11e210d21ab8bb9de9517910e67d24881c8d2a72baa26b440bcdba17aa1c0d3448e3b78c62ad09bdf8a686af48107386c8a2fe1e8b575f9be0780a642305e9e9147f93fbc71447780dda6bc865d3412e5aecf0e842603bf65f059c9a3c3515ed949152e68d386415aaad1e8048be59bef3e4bab26d9cdc15a81a84f51dad584db81558c2c12c0728b0a028ea4729b6f032585d45feae6bc12e237febab2bef1117c366380078d163de200e03fa31640e9e927737f2679c8104f74b7ac4d36e32bd4a7d84632a2cf95e161fb3b5fa81321d5afe02467f059d13f440a03592a3f2b2ee93f667e2ed66559ef53cd734bed10b16062d6581be18e4717cf8837443653a5ffe6da47a73883210b7129bd1543b745f5ada684a84003f8955ae9150126f22397d5e38c814899b67000000000000000100000001000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e0000007402000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d0300000000001976a9143a52c0fc59997d1e53009d607e3d93ca56b1014c88ac341a0c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c000000000100000001000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000001acc00000040b9978e8ceff7e273183cee9ffc17676e8410e3ccf6922e99a0739fe9d176a5da19dbff7a5e3aa7aa1327eff9ff2ffd01dd92fa465fe65c6ea7b88cbd179213ea000000010000003166722e6163696e712e6c696768746e696e672e776972652e436c6f73696e675369676e6564546c762e46656552616e67650000000000000d6600000000000035980000000000 \ No newline at end of file diff --git a/src/commonTest/resources/nonreg/v2/Negotiating_f52b19b8/data.json b/src/commonTest/resources/nonreg/v2/Negotiating_f52b19b8/data.json deleted file mode 100644 index 9bc7d6500..000000000 --- a/src/commonTest/resources/nonreg/v2/Negotiating_f52b19b8/data.json +++ /dev/null @@ -1,227 +0,0 @@ -{ - "type": "fr.acinq.lightning.channel.states.Negotiating", - "commitments": { - "params": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "channelConfig": [ - "funding_pubkey_based_channel_keypath" - ], - "channelFeatures": [ - "option_support_large_channel", - "option_static_remotekey", - "option_anchor_outputs", - "zero_reserve_channels", - "zero_conf_channels" - ], - "localParams": { - "nodeId": "037108815ff0128f7ed22640485c226d9ad64a9fd6d8b41b6623565aed6b34812c", - "fundingKeyPath": "m/385048399/1977025879/604622566/184658546/776346346/949304342'/277944247'/2049339775'/1'", - "dustLimit": 1100, - "maxHtlcValueInFlightMsat": 1500000000, - "htlcMinimum": 0, - "toSelfDelay": 144, - "maxAcceptedHtlcs": 100, - "isInitiator": true, - "defaultFinalScriptPubKey": "001405e0104aa726e34ff5cd3a6320d05c0862b5b01c", - "features": { - "activated": { - "initial_routing_sync": "Optional", - "option_data_loss_protect": "Optional", - "gossip_queries": "Optional", - "gossip_queries_ex": "Optional", - "var_onion_optin": "Mandatory", - "payment_secret": "Mandatory", - "basic_mpp": "Optional", - "option_support_large_channel": "Optional", - "option_static_remotekey": "Mandatory", - "option_anchor_outputs": "Mandatory", - "option_channel_type": "Mandatory", - "option_payment_metadata": "Optional", - "trampoline_payment_experimental": "Optional", - "wake_up_notification_provider": "Optional", - "pay_to_open_provider": "Optional", - "trusted_swap_in_provider": "Optional", - "channel_backup_provider": "Optional" - }, - "unknown": [ - ] - } - }, - "remoteParams": { - "nodeId": "0362b19a83930389b4468be40308efb3f352b23142ae25e6aba0465a8220f95b06", - "dustLimit": 1000, - "maxHtlcValueInFlightMsat": 1500000000, - "htlcMinimum": 1000, - "toSelfDelay": 144, - "maxAcceptedHtlcs": 100, - "revocationBasepoint": "03a42aef6d1c860caffa6c71a6f8ac2b16eec25bab0c3950cdb1fad7fb38a5f2a5", - "paymentBasepoint": "02508e1845b8bbe0773f6bf8f3f04f59a5896426765c7b6b23e6e466c95381182b", - "delayedPaymentBasepoint": "02d62233b7c33f8fd0911922461a651007f1de09d8c474029caa8f2c229c10de26", - "htlcBasepoint": "03d05c8245bdc12efd8b070b22b276e7db4254f4693e22b3f7c978c08e67b36236", - "features": { - "activated": { - "option_data_loss_protect": "Optional", - "initial_routing_sync": "Optional", - "gossip_queries": "Optional", - "var_onion_optin": "Mandatory", - "gossip_queries_ex": "Optional", - "option_static_remotekey": "Mandatory", - "payment_secret": "Mandatory", - "basic_mpp": "Optional", - "option_support_large_channel": "Optional", - "option_anchor_outputs": "Mandatory", - "option_channel_type": "Mandatory", - "option_payment_metadata": "Optional", - "wake_up_notification_client": "Optional", - "pay_to_open_client": "Optional", - "trusted_swap_in_client": "Optional", - "channel_backup_client": "Optional", - "trampoline_payment_experimental": "Optional" - }, - "unknown": [ - ] - } - }, - "channelFlags": 0 - }, - "changes": { - "localChanges": { - "proposed": [ - ], - "signed": [ - ], - "acked": [ - ] - }, - "remoteChanges": { - "proposed": [ - ], - "acked": [ - ], - "signed": [ - ] - }, - "localNextHtlcId": 0, - "remoteNextHtlcId": 0 - }, - "active": [ - { - "fundingTxIndex": 0, - "remoteFundingPubkey": "0385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa4", - "localFundingStatus": { - "status": "unconfirmed", - "txId": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f" - }, - "remoteFundingStatus": { - "status": "locked" - }, - "localCommit": { - "index": 0, - "spec": { - "htlcsIn": [ - ], - "htlcsOut": [ - ], - "feerate": 5000, - "toLocal": 800000000, - "toRemote": 200000000 - }, - "publishableTxs": { - "commitTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "020000000001012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000b77080044a0100000000000022002046672803839d10e21d43eafb532bc37cd21bd97dec7f9b50d45380cd1cce69654a01000000000000220020bbd7f17366848d8f624c28438128ce4dc8c72ea21deb0ccf25bee110920da032400d030000000000220020cb93e3adb8d213704e9a07ea2a6ce91dca51a9b76fcb6bef3cc9b5b7e10a7990781c0c00000000002200202f0860cd1fe361a1aaf5708f75b6511c92cd5a51bdaaccfbda77aead550d875104004730440220672323ca34b85c2a43e3e93ac8a642a8293b1483392f531736db975d05f3ad3c022019f7b5044cd2a230dc49484c219fd96485f98d21c6add317566f4b21816a2fb101483045022100956b481822da569bc75c1f7ab6ec34c0a1e14dd5b4701ea8473e5bfe6b6ad41702202b1a987850611c0f52cccbb6016c735a08572f61fe03616a186ca39a8b2e07970147522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452aede99dc20" - }, - "htlcTxsAndSigs": [ - ] - } - }, - "remoteCommit": { - "index": 0, - "spec": { - "htlcsIn": [ - ], - "htlcsOut": [ - ], - "feerate": 5000, - "toLocal": 200000000, - "toRemote": 800000000 - }, - "txid": "6498095b8d064f46673e7c0d919636e1dff0c0a76ed61dd96938a178253ea4cb", - "remotePerCommitmentPoint": "02365f9a5e4822956750faa46230f54e47d4b6ef9d58eb8c488d80a5efed938d5b" - }, - "nextRemoteCommit": null - } - ], - "inactive": [ - ], - "payments": { - }, - "remoteNextCommitInfo": { - "left": null, - "right": "03c57839fd412868a398bea05d01678a752661126a2d1357a0f7cb6f0c60311125" - }, - "remotePerCommitmentSecrets": "", - "remoteChannelData": { - "data": "8c0ca0219d38704b18133d3e9c6f2fff5fcba2fa4d7ddca7cd38361c62d91123930e013d96e802c4ef5e6c9cb1f101aa956ff6fd3375a525dd9a1483c4e39135fc8d732b2109b7965a03f4acb1a4b0c3e9de40ec5d0b075f0b9a6d7ee71f6fba369ba60c5de117d04338216a29a4034ab7a3fe6b162d2fffd8d8ffb1a1e120aba163590a45add7b0cb61a56acd91fa206fadece0959b20d127e7b64ee0a2dfd945bcd9b31cade08fb9dc778e101f6de98b23d805c82415b48f72bad94058c651a9bf017a75c518d7cd8975e2ee114691aab5c05c5178273744408ecbdb20119eb638019cabb65baf2f379bdabeba39fab76c027b7ef802c5561cc9d80675621aef1cc1a60d27ede5b54c40a92e71ea7579376480583bd18be60875b4789f59197c4647eb0581a6b777d0e0cbef26166cd73a501a39133f9f7d529b8cd7a67356c9509f0d0254edb193434b72e34235adddec1bb43ad0605fe92651d3f68499a96e788aed0d641e15a166eb45c181d3a71f87bd92fbd3a309026534da87120a24c8b0a87ec13bd4eae6954085b8d1b3a0b1316f8602974a2949d0daf65b915ed77c78a67d78c49d1538a2365e50da0931237df3ea18613f3dedc1ed6d73686528b7fba8a84270a88d715879630e7bf2bcfcbc26e3d02ea691aa23f7cb9db872933aed347c86068f422111c22f2d91a509792304771274dd8c34dbd645bc319ef17ebacdc42dcba613105bab6e0f520869dcab50e7591fe803a4dc1301997af79983481b803b71800d3f552ea3401dfb93e9019c4e566d7112aab6169f05e0017f522776942a2b26114fa11969daf6a761933d1650a75f1d645943e85bb0be8338721bd43671c5e6d18052420dcbff9c28ed02888e8e5bb89bbd45f3d043887289ab36bc311621a62e5c874cc333e28cc275cc4242f4e524c0ddb9f5ea9199eedb0668f21048b11f486c5ba712d5edcbea80e85148e4a51a3a1c84842ed7db02b88c121d0426335183ee62e6a20ceb1040a658e769fc261e27eafed669d7c6bd8bb58111325a8e5c1faf44ed32ceb1791a8b1d2a482a6353beb4e7a4bded388408c1bbb72823e846a16a5e65612d412dbf9a0d6c21545fb965f3d43f4e16b9a1daa885433a4dbcb45cf25e5cf8e43bfadc4c6663061fee3894da75582ed83201a1e171271c638057a9c3d8faed7036c4f7e2a6bb45ab87f102803f4b9d0ebfe6342740c5082367dc5257652edb933f96a90113775e738bcd22e97730596f3d1631bf0ef05d96c8579f1f6a503631dc79c8238cdfd1e6ba4ebdbc1a6884f455f1048d66d275fa4deeff73bea7f6611e100f7e7ec94276fb85b8fb1f47cb08b2e09e97e744f64c0733e8f9e340f2e6e2d75adf7693692de5f4360aa5f666707db1488ad6be41312689ae6e8d6f7f1113c757f9aeb690a3545493c6a26b6f01926efd9da9747d444c11d60f3da935de3007c8bf7538e696663c8aa98b1b58881f666ba00d7c619747d385e59e3f5885d6a4d1ddc70df9ca2d6c871cb6143647a194bd4ada7baf8f3421faa74dd7e18ee66d57e9281f9235e749a09ccca9b15e0a5bcc2bc49ee8aa7d9b9321e173863d40e3625412f1d0bd115e9dc07fa3addc5e6df48e3464c09b06c2fc02929fafb6b848f17e0d0f234c27280412754f651763caaa55fbf90e911b2bb64a69b1d2c79b4430bbde2f07630e635f7937d827686bcb622f287049c607944af8a3aacceaf74a7d709fecd909d99722486654d097c63781ac283347ab4f37d8d9d15f5638ae3f2780930752a8d1c19f25b904e59837464680b57901d7d09dd029bc3d0201d0929616ba5e7c7d967618678885c05da4abb1df78cbf3def8a5c7c1497a78266a62670471da7eeb65c1127275b9f534e4162bd33f4d77036a0823b0f53fb33bb6ff41f419379e4b21723feaa0d627a693625af1b1030a5436bb487fc4b8f8dda4bf513a58d44637df3901751f006e560cd8e53bf46e1512b7c449a79638bb14624af9b1409bcf301d32d4dcbf9078f2efdf356af11cdcee29fff984134de2003898cb60117ada37c2c20c963bfd337cb2c9c70b78efa746b6137fe70140aae2c7cb30697e54a5baa2a5ab4188b7ac8f4910a53f195537965e5229a41511c0a02b046a2f7b92acb0dfea2c2ab34209c04f5b92296fc4214c2644536ccf9495a79da81a53688f86a2b070f727b39e0dfa1d379c4bbaebe0d9f0c907fa90cb43383dbb033bb859e4dcb43efbcc388f1a235eb40979ef295a3bc1099aa0cf9788f776fca622dd8589079d20fd2c265e3b4d6812588ad226dfb61efb00eac0536409cb9b51d46a838dc347b8c1b9c521204f3cf99157e892ccad0a046a6c8bffebb810ef374cd7bd31d390706d53f983ade51bc920c5fbe8625fed4b34304207964e8ad12bd78c4b4590ed4d224e7f8b366bf1af81e0000b9a2543ac84a57a64d04d8be82e7888974dc4bfdc64772402952f0e0b42d4857aa7081c54f93313c74b5a5abe10615086458815ed93d226a80528383d9336dc21f8d5d40ec40c1cd954be32d8a31c777a96eef4e36bd9acedaa1fe1d806a73623e31c19992c741018f876da5b88dc8c3fffa82363273cf10952444f53308d2e6f40f52cff30b68c7dc38b56763aef19c29bb742bdf5d7b60b59a7c50075a258c9a8ab3ebb04eb7080555b5a114fb9e7ce9760f819a72217fd52b27c7beabb14a2ab837e73dbe64e31fae6b1051bb50df8d7866d38de6b119eb37bc7036f8896c096efd3b453cb9658eb72431cecb54a9c487e52ee32416a08784fae535df25a2518244d19abb78e3cc8485b5c89123c0f1cb5eca8ad96c95c6539ea14440e5d9f299bd8bba6259481b7b0401b3b5b26d0e755c996da5f9668ddc76ab96c61f83233e24b3fa6b27114799f3ac0d17951883cb1cdad6ab72384a1f821d9ffffb728aa288d6aaacb93558bfba2ec59e67fc67ecf278eb11ac844894f67aa4bc4799da7bd39644096fe737b81d6adc69dbc06f4a153b5b6c3e57e544fec36deeffdc9e24a194a8e1abed5a361f5131c38d6e0cf05b86886a217283c865aca2919a6d46886ece53bd43cc5af069619fb12c812f92c007df3b504c66e7f10a593fdd8d3c4e6a8c743ced232732ad438a667df097bac7566de7fdc85225845545b189d85a83b18d4053f3c6fc2105fbba0e254c2a5c753b97d1791045630527672f82eadeaec0db03c3f880377de04e1b7cbf09fbf87c04def97cd8dee544581e877788f21b7567a955dfd7a06a816dc7ac11529400acb16abf4e7730f16c3312ac43a84b62e9aed266134ef2ee0db3bf2aedbc12f838eec6d0f1427defe77bdb650aa5398dd4989b94b9236a70e68d48c2e4f5bab36312fd1f1e4593cd9995878fd6a2b12515c0d41c9f0aeaac69fb77a013d8d4704ab4a173574d595edc90882c1bf947e9fdbe0ab1d680e3b4ec6e497cdd6a8e00e8dc9bca52066997d1c973ba27aadbe36876f1011dc11d6835acbbe5c7cfd6c3204b2a44dbf89b9715fd4797cf4200a4ca858705f624a1b48d75e166a1cb0c68e8dc0c994d69e199835e9f62f9b24167f28781f2f35ea1149f53bbda63bcb27b74f0e3e4704026e84e873306de2300488e9a182d2e85e46ac04b89c94277bc1f883a7047f62d117e45055bba398612091e9fcd4bbdd0d15e4b41c97898d9acdf904aa6cf144ef62ef7dd26f755c2fe353ed5eff1aef005ab99b7e355111a9ba5c5d03874914526e0356bc78f09543d6419e87be1df37d34393b12f87c676f49556a6ae5c91c194bbecf27936a91f3688a501c2ccb9a32fea57e195d3b0e0fd0b4640840400ec086678ee67ba0bd774de3c111979708409207e4d4bd1dce2321b77ccc71127be8318fe92e6ec730a47112bd069c9cad37361f693d07a90b0a37e5875938b06d6370d1f1c1c280bfd83fc5e2d0b803e467eacfd37c48ca37721193859cd499653f5dfd78c26e4b181e82b5005cac0e9bd55fb2850dd4c70cc1e3fe5c81167336f36839fce30f245061191282585ff911c9e4af395ad4cf77b6e4f17d389ae8fbd61a3a3a4e73ccae0716507afa7ac4d0f2349c3aa56f47b6aa78806d7c20b50e125ee329921ffe96f8123d3e4be8be89b2318b6e016c385728b7a02f7dbb14552e2863453c33e3854047e6d8f84fe9f56c9200962025182d418580a294a0d09e9740e187e3be88236f62542b56bf08f72a859ae8a809e78a90e86b9b2cde799f9cca6049d5f49e97365744bede14be8cf680175cca275444e37327ea04d624faed898e0fc7751f1ac7d6241d93472c2d6ee8925fedc9169539799701174a81d3d6e00a9ac9647286d08b6c982c6baf86810d1e9f91c581f0c755273009389019bcb68a7ffbb4f0bc7de1ec45004c93f1a04a8c4cb60490654f616250c14bb54e9fe1fa1ad866830451afe98559d3e0e85073c2950d181feeb935c6cb69962a644ba8736535c11e7a9efbc17e9669b1c232985e9c5eaad29618ad9f461f1438d8c35c691d3d3bf80642a11f57cbf19ec1a7e63b2289d7c0e178052b6b344267d99e018c3f724f44ac465097ddea64d35e36c78736cfe6488991c4469d25b132db3560744e418be6ef3452ab5a73f66205e1ba67944cf1a556e60b037fb9ec6579f8638be744e075e0fc99722bcfc40efaf603c00e16b714ada2b7390cf2e9867df6c5961d96cb63298037df5f20e69b3b4bd2d2a24f68c48e02538fc1b2723fff9b52f18012d2024c40bfefb202b6292065b2cafb67aa1539e9d8b96ca039cc08e232fbb44cb46d7ce5017b14cd7f4e4e1675c2bd0b8d74958ac3c1232134d91dd02d701eef4ab953237b548f289f7e9ff902e7b39c40226596037271dd3296865618fd62a0abe228adb4286217b6049d157bd3a91b8997730fb29f0b086c9a0cd56f7f0ad198eedf098c86371570db86a7e2e972d58c8baee2e9e7aa34534e3f11e210d21ab8bb9de9517910e67d24881c8d2a72baa26b440bcdba17aa1c0d3448e3b78c62ad09bdf8a686af48107386c8a2fe1e8b575f9be0780a642305e9e9147f93fbc71447780dda6bc865d3412e5aecf0e842603bf65f059c9a3c3515ed949152e68d386415aaad1e8048be59bef3e4bab26d9cdc15a81a84f51dad584db81558c2c12c0728b0a028ea4729b6f032585d45feae6bc12e237febab2bef1117c366380078d163de200e03fa31640e9e927737f2679c8104f74b7ac4d36e32bd4a7d84632a2cf95e161fb3b5fa81321d5afe02467f059d13f440a03592a3f2b2ee93f667e2ed66559ef53cd734bed10b16062d6581be18e4717cf8837443653a5ffe6da47a73883210b7129bd1543b745f5ada684a84003f8955ae9150126f22397d5e38c814899b67" - } - }, - "localShutdown": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "scriptPubKey": "001405e0104aa726e34ff5cd3a6320d05c0862b5b01c" - }, - "remoteShutdown": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "scriptPubKey": "76a9143a52c0fc59997d1e53009d607e3d93ca56b1014c88ac", - "tlvStream": { - "records": [ - { - "type": "fr.acinq.lightning.wire.ShutdownTlv.ChannelData", - "ecb": { - "data": "8c0ca0219d38704b18133d3e9c6f2fff5fcba2fa4d7ddca7cd38361c62d91123930e013d96e802c4ef5e6c9cb1f101aa956ff6fd3375a525dd9a1483c4e39135fc8d732b2109b7965a03f4acb1a4b0c3e9de40ec5d0b075f0b9a6d7ee71f6fba369ba60c5de117d04338216a29a4034ab7a3fe6b162d2fffd8d8ffb1a1e120aba163590a45add7b0cb61a56acd91fa206fadece0959b20d127e7b64ee0a2dfd945bcd9b31cade08fb9dc778e101f6de98b23d805c82415b48f72bad94058c651a9bf017a75c518d7cd8975e2ee114691aab5c05c5178273744408ecbdb20119eb638019cabb65baf2f379bdabeba39fab76c027b7ef802c5561cc9d80675621aef1cc1a60d27ede5b54c40a92e71ea7579376480583bd18be60875b4789f59197c4647eb0581a6b777d0e0cbef26166cd73a501a39133f9f7d529b8cd7a67356c9509f0d0254edb193434b72e34235adddec1bb43ad0605fe92651d3f68499a96e788aed0d641e15a166eb45c181d3a71f87bd92fbd3a309026534da87120a24c8b0a87ec13bd4eae6954085b8d1b3a0b1316f8602974a2949d0daf65b915ed77c78a67d78c49d1538a2365e50da0931237df3ea18613f3dedc1ed6d73686528b7fba8a84270a88d715879630e7bf2bcfcbc26e3d02ea691aa23f7cb9db872933aed347c86068f422111c22f2d91a509792304771274dd8c34dbd645bc319ef17ebacdc42dcba613105bab6e0f520869dcab50e7591fe803a4dc1301997af79983481b803b71800d3f552ea3401dfb93e9019c4e566d7112aab6169f05e0017f522776942a2b26114fa11969daf6a761933d1650a75f1d645943e85bb0be8338721bd43671c5e6d18052420dcbff9c28ed02888e8e5bb89bbd45f3d043887289ab36bc311621a62e5c874cc333e28cc275cc4242f4e524c0ddb9f5ea9199eedb0668f21048b11f486c5ba712d5edcbea80e85148e4a51a3a1c84842ed7db02b88c121d0426335183ee62e6a20ceb1040a658e769fc261e27eafed669d7c6bd8bb58111325a8e5c1faf44ed32ceb1791a8b1d2a482a6353beb4e7a4bded388408c1bbb72823e846a16a5e65612d412dbf9a0d6c21545fb965f3d43f4e16b9a1daa885433a4dbcb45cf25e5cf8e43bfadc4c6663061fee3894da75582ed83201a1e171271c638057a9c3d8faed7036c4f7e2a6bb45ab87f102803f4b9d0ebfe6342740c5082367dc5257652edb933f96a90113775e738bcd22e97730596f3d1631bf0ef05d96c8579f1f6a503631dc79c8238cdfd1e6ba4ebdbc1a6884f455f1048d66d275fa4deeff73bea7f6611e100f7e7ec94276fb85b8fb1f47cb08b2e09e97e744f64c0733e8f9e340f2e6e2d75adf7693692de5f4360aa5f666707db1488ad6be41312689ae6e8d6f7f1113c757f9aeb690a3545493c6a26b6f01926efd9da9747d444c11d60f3da935de3007c8bf7538e696663c8aa98b1b58881f666ba00d7c619747d385e59e3f5885d6a4d1ddc70df9ca2d6c871cb6143647a194bd4ada7baf8f3421faa74dd7e18ee66d57e9281f9235e749a09ccca9b15e0a5bcc2bc49ee8aa7d9b9321e173863d40e3625412f1d0bd115e9dc07fa3addc5e6df48e3464c09b06c2fc02929fafb6b848f17e0d0f234c27280412754f651763caaa55fbf90e911b2bb64a69b1d2c79b4430bbde2f07630e635f7937d827686bcb622f287049c607944af8a3aacceaf74a7d709fecd909d99722486654d097c63781ac283347ab4f37d8d9d15f5638ae3f2780930752a8d1c19f25b904e59837464680b57901d7d09dd029bc3d0201d0929616ba5e7c7d967618678885c05da4abb1df78cbf3def8a5c7c1497a78266a62670471da7eeb65c1127275b9f534e4162bd33f4d77036a0823b0f53fb33bb6ff41f419379e4b21723feaa0d627a693625af1b1030a5436bb487fc4b8f8dda4bf513a58d44637df3901751f006e560cd8e53bf46e1512b7c449a79638bb14624af9b1409bcf301d32d4dcbf9078f2efdf356af11cdcee29fff984134de2003898cb60117ada37c2c20c963bfd337cb2c9c70b78efa746b6137fe70140aae2c7cb30697e54a5baa2a5ab4188b7ac8f4910a53f195537965e5229a41511c0a02b046a2f7b92acb0dfea2c2ab34209c04f5b92296fc4214c2644536ccf9495a79da81a53688f86a2b070f727b39e0dfa1d379c4bbaebe0d9f0c907fa90cb43383dbb033bb859e4dcb43efbcc388f1a235eb40979ef295a3bc1099aa0cf9788f776fca622dd8589079d20fd2c265e3b4d6812588ad226dfb61efb00eac0536409cb9b51d46a838dc347b8c1b9c521204f3cf99157e892ccad0a046a6c8bffebb810ef374cd7bd31d390706d53f983ade51bc920c5fbe8625fed4b34304207964e8ad12bd78c4b4590ed4d224e7f8b366bf1af81e0000b9a2543ac84a57a64d04d8be82e7888974dc4bfdc64772402952f0e0b42d4857aa7081c54f93313c74b5a5abe10615086458815ed93d226a80528383d9336dc21f8d5d40ec40c1cd954be32d8a31c777a96eef4e36bd9acedaa1fe1d806a73623e31c19992c741018f876da5b88dc8c3fffa82363273cf10952444f53308d2e6f40f52cff30b68c7dc38b56763aef19c29bb742bdf5d7b60b59a7c50075a258c9a8ab3ebb04eb7080555b5a114fb9e7ce9760f819a72217fd52b27c7beabb14a2ab837e73dbe64e31fae6b1051bb50df8d7866d38de6b119eb37bc7036f8896c096efd3b453cb9658eb72431cecb54a9c487e52ee32416a08784fae535df25a2518244d19abb78e3cc8485b5c89123c0f1cb5eca8ad96c95c6539ea14440e5d9f299bd8bba6259481b7b0401b3b5b26d0e755c996da5f9668ddc76ab96c61f83233e24b3fa6b27114799f3ac0d17951883cb1cdad6ab72384a1f821d9ffffb728aa288d6aaacb93558bfba2ec59e67fc67ecf278eb11ac844894f67aa4bc4799da7bd39644096fe737b81d6adc69dbc06f4a153b5b6c3e57e544fec36deeffdc9e24a194a8e1abed5a361f5131c38d6e0cf05b86886a217283c865aca2919a6d46886ece53bd43cc5af069619fb12c812f92c007df3b504c66e7f10a593fdd8d3c4e6a8c743ced232732ad438a667df097bac7566de7fdc85225845545b189d85a83b18d4053f3c6fc2105fbba0e254c2a5c753b97d1791045630527672f82eadeaec0db03c3f880377de04e1b7cbf09fbf87c04def97cd8dee544581e877788f21b7567a955dfd7a06a816dc7ac11529400acb16abf4e7730f16c3312ac43a84b62e9aed266134ef2ee0db3bf2aedbc12f838eec6d0f1427defe77bdb650aa5398dd4989b94b9236a70e68d48c2e4f5bab36312fd1f1e4593cd9995878fd6a2b12515c0d41c9f0aeaac69fb77a013d8d4704ab4a173574d595edc90882c1bf947e9fdbe0ab1d680e3b4ec6e497cdd6a8e00e8dc9bca52066997d1c973ba27aadbe36876f1011dc11d6835acbbe5c7cfd6c3204b2a44dbf89b9715fd4797cf4200a4ca858705f624a1b48d75e166a1cb0c68e8dc0c994d69e199835e9f62f9b24167f28781f2f35ea1149f53bbda63bcb27b74f0e3e4704026e84e873306de2300488e9a182d2e85e46ac04b89c94277bc1f883a7047f62d117e45055bba398612091e9fcd4bbdd0d15e4b41c97898d9acdf904aa6cf144ef62ef7dd26f755c2fe353ed5eff1aef005ab99b7e355111a9ba5c5d03874914526e0356bc78f09543d6419e87be1df37d34393b12f87c676f49556a6ae5c91c194bbecf27936a91f3688a501c2ccb9a32fea57e195d3b0e0fd0b4640840400ec086678ee67ba0bd774de3c111979708409207e4d4bd1dce2321b77ccc71127be8318fe92e6ec730a47112bd069c9cad37361f693d07a90b0a37e5875938b06d6370d1f1c1c280bfd83fc5e2d0b803e467eacfd37c48ca37721193859cd499653f5dfd78c26e4b181e82b5005cac0e9bd55fb2850dd4c70cc1e3fe5c81167336f36839fce30f245061191282585ff911c9e4af395ad4cf77b6e4f17d389ae8fbd61a3a3a4e73ccae0716507afa7ac4d0f2349c3aa56f47b6aa78806d7c20b50e125ee329921ffe96f8123d3e4be8be89b2318b6e016c385728b7a02f7dbb14552e2863453c33e3854047e6d8f84fe9f56c9200962025182d418580a294a0d09e9740e187e3be88236f62542b56bf08f72a859ae8a809e78a90e86b9b2cde799f9cca6049d5f49e97365744bede14be8cf680175cca275444e37327ea04d624faed898e0fc7751f1ac7d6241d93472c2d6ee8925fedc9169539799701174a81d3d6e00a9ac9647286d08b6c982c6baf86810d1e9f91c581f0c755273009389019bcb68a7ffbb4f0bc7de1ec45004c93f1a04a8c4cb60490654f616250c14bb54e9fe1fa1ad866830451afe98559d3e0e85073c2950d181feeb935c6cb69962a644ba8736535c11e7a9efbc17e9669b1c232985e9c5eaad29618ad9f461f1438d8c35c691d3d3bf80642a11f57cbf19ec1a7e63b2289d7c0e178052b6b344267d99e018c3f724f44ac465097ddea64d35e36c78736cfe6488991c4469d25b132db3560744e418be6ef3452ab5a73f66205e1ba67944cf1a556e60b037fb9ec6579f8638be744e075e0fc99722bcfc40efaf603c00e16b714ada2b7390cf2e9867df6c5961d96cb63298037df5f20e69b3b4bd2d2a24f68c48e02538fc1b2723fff9b52f18012d2024c40bfefb202b6292065b2cafb67aa1539e9d8b96ca039cc08e232fbb44cb46d7ce5017b14cd7f4e4e1675c2bd0b8d74958ac3c1232134d91dd02d701eef4ab953237b548f289f7e9ff902e7b39c40226596037271dd3296865618fd62a0abe228adb4286217b6049d157bd3a91b8997730fb29f0b086c9a0cd56f7f0ad198eedf098c86371570db86a7e2e972d58c8baee2e9e7aa34534e3f11e210d21ab8bb9de9517910e67d24881c8d2a72baa26b440bcdba17aa1c0d3448e3b78c62ad09bdf8a686af48107386c8a2fe1e8b575f9be0780a642305e9e9147f93fbc71447780dda6bc865d3412e5aecf0e842603bf65f059c9a3c3515ed949152e68d386415aaad1e8048be59bef3e4bab26d9cdc15a81a84f51dad584db81558c2c12c0728b0a028ea4729b6f032585d45feae6bc12e237febab2bef1117c366380078d163de200e03fa31640e9e927737f2679c8104f74b7ac4d36e32bd4a7d84632a2cf95e161fb3b5fa81321d5afe02467f059d13f440a03592a3f2b2ee93f667e2ed66559ef53cd734bed10b16062d6581be18e4717cf8837443653a5ffe6da47a73883210b7129bd1543b745f5ada684a84003f8955ae9150126f22397d5e38c814899b67" - } - } - ] - } - }, - "closingTxProposed": [ - [ - { - "unsignedTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "02000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d0300000000001976a9143a52c0fc59997d1e53009d607e3d93ca56b1014c88ac341a0c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c00000000", - "toLocalIndex": 1 - }, - "localClosingSigned": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "feeSatoshis": 6860, - "signature": "b9978e8ceff7e273183cee9ffc17676e8410e3ccf6922e99a0739fe9d176a5da19dbff7a5e3aa7aa1327eff9ff2ffd01dd92fa465fe65c6ea7b88cbd179213ea", - "tlvStream": { - "records": [ - { - "type": "fr.acinq.lightning.wire.ClosingSignedTlv.FeeRange", - "min": 3430, - "max": 13720 - } - ] - } - } - } - ] - ], - "bestUnpublishedClosingTx": null, - "closingFeerates": null -} \ No newline at end of file diff --git a/src/commonTest/resources/nonreg/v2/Normal_748a735b/data.json b/src/commonTest/resources/nonreg/v2/Normal_748a735b/data.json index 1972b21d2..f5ac0a631 100644 --- a/src/commonTest/resources/nonreg/v2/Normal_748a735b/data.json +++ b/src/commonTest/resources/nonreg/v2/Normal_748a735b/data.json @@ -185,7 +185,7 @@ "remoteChannelUpdate": null, "localShutdown": null, "remoteShutdown": null, - "closingFeerates": null, + "closingFeerate": null, "spliceStatus": "None", "liquidityLeases": [ ] diff --git a/src/commonTest/resources/nonreg/v2/Normal_e2253ddd/data.json b/src/commonTest/resources/nonreg/v2/Normal_e2253ddd/data.json index f5e6d6451..1225abcde 100644 --- a/src/commonTest/resources/nonreg/v2/Normal_e2253ddd/data.json +++ b/src/commonTest/resources/nonreg/v2/Normal_e2253ddd/data.json @@ -360,7 +360,7 @@ "remoteChannelUpdate": null, "localShutdown": null, "remoteShutdown": null, - "closingFeerates": null, + "closingFeerate": null, "spliceStatus": "None", "liquidityLeases": [ ] diff --git a/src/commonTest/resources/nonreg/v2/Normal_ff248f8d/data.json b/src/commonTest/resources/nonreg/v2/Normal_ff248f8d/data.json index 85e46b5a8..db0bbd7e1 100644 --- a/src/commonTest/resources/nonreg/v2/Normal_ff248f8d/data.json +++ b/src/commonTest/resources/nonreg/v2/Normal_ff248f8d/data.json @@ -198,7 +198,7 @@ }, "localShutdown": null, "remoteShutdown": null, - "closingFeerates": null, + "closingFeerate": null, "spliceStatus": "None", "liquidityLeases": [ ] diff --git a/src/commonTest/resources/nonreg/v2/Normal_ff4a71b6/data.json b/src/commonTest/resources/nonreg/v2/Normal_ff4a71b6/data.json index fdf1580ff..f453e74c0 100644 --- a/src/commonTest/resources/nonreg/v2/Normal_ff4a71b6/data.json +++ b/src/commonTest/resources/nonreg/v2/Normal_ff4a71b6/data.json @@ -368,7 +368,7 @@ "remoteChannelUpdate": null, "localShutdown": null, "remoteShutdown": null, - "closingFeerates": null, + "closingFeerate": null, "spliceStatus": "None", "liquidityLeases": [ ] diff --git a/src/commonTest/resources/nonreg/v2/Normal_ffd9f5db/data.json b/src/commonTest/resources/nonreg/v2/Normal_ffd9f5db/data.json index 77e09eece..284af9d3e 100644 --- a/src/commonTest/resources/nonreg/v2/Normal_ffd9f5db/data.json +++ b/src/commonTest/resources/nonreg/v2/Normal_ffd9f5db/data.json @@ -217,7 +217,7 @@ "remoteChannelUpdate": null, "localShutdown": null, "remoteShutdown": null, - "closingFeerates": null, + "closingFeerate": null, "spliceStatus": "None", "liquidityLeases": [ ] diff --git a/src/commonTest/resources/nonreg/v2/ShuttingDown_c321b947/data.json b/src/commonTest/resources/nonreg/v2/ShuttingDown_c321b947/data.json index e3c2516d7..d738635bb 100644 --- a/src/commonTest/resources/nonreg/v2/ShuttingDown_c321b947/data.json +++ b/src/commonTest/resources/nonreg/v2/ShuttingDown_c321b947/data.json @@ -258,5 +258,5 @@ ] } }, - "closingFeerates": null + "closingFeerate": null } \ No newline at end of file diff --git a/src/commonTest/resources/nonreg/v2/ShuttingDown_f89ecd50/data.json b/src/commonTest/resources/nonreg/v2/ShuttingDown_f89ecd50/data.json index fc47ec79b..7eb207936 100644 --- a/src/commonTest/resources/nonreg/v2/ShuttingDown_f89ecd50/data.json +++ b/src/commonTest/resources/nonreg/v2/ShuttingDown_f89ecd50/data.json @@ -283,5 +283,5 @@ "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", "scriptPubKey": "001405e0104aa726e34ff5cd3a6320d05c0862b5b01c" }, - "closingFeerates": null + "closingFeerate": null } \ No newline at end of file diff --git a/src/commonTest/resources/nonreg/v3/Negotiating_da44c6e2/data.bin b/src/commonTest/resources/nonreg/v3/Negotiating_da44c6e2/data.bin deleted file mode 100644 index 603fff4c3..000000000 --- a/src/commonTest/resources/nonreg/v3/Negotiating_da44c6e2/data.bin +++ /dev/null @@ -1 +0,0 @@ -00000003000025310000002f66722e6163696e712e6c696768746e696e672e73657269616c697a6174696f6e2e76332e4e65676f74696174696e670000002006226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f000000210362b19a83930389b4468be40308efb3f352b23142ae25e6aba0465a8220f95b0600061a800000000b426c6f636b486561646572000000500100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5494dffff7f200200000000000000000003e800000000000003e800000000000003e800000001010000000314100000000021037108815ff0128f7ed22640485c226d9ad64a9fd6d8b41b6623565aed6b34812c000000090000000016f35f4f0000000075d70557000000002409cee6000000000b01aa72000000002e461aea00000000b8953c1600000000909117b700000000fa26717f0000000080000001000000000000044c0000000059682f000000000000002710000000000000000000000090000000640100000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c000000110000002d66722e6163696e712e6c696768746e696e672e466561747572652e496e697469616c526f7574696e6753796e63010000003066722e6163696e712e6c696768746e696e672e466561747572652e4f7074696f6e446174614c6f737350726f74656374010000002e66722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c52616e676551756572696573010000003666722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c52616e676551756572696573457874656e646564010000002e66722e6163696e712e6c696768746e696e672e466561747572652e5661726961626c654c656e6774684f6e696f6e000000002866722e6163696e712e6c696768746e696e672e466561747572652e5061796d656e74536563726574000000003066722e6163696e712e6c696768746e696e672e466561747572652e42617369634d756c7469506172745061796d656e74010000002066722e6163696e712e6c696768746e696e672e466561747572652e57756d626f010000002a66722e6163696e712e6c696768746e696e672e466561747572652e53746174696352656d6f74654b6579000000002866722e6163696e712e6c696768746e696e672e466561747572652e416e63686f724f757470757473000000002666722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c54797065000000002a66722e6163696e712e6c696768746e696e672e466561747572652e5061796d656e744d65746164617461010000003866722e6163696e712e6c696768746e696e672e466561747572652e4578706572696d656e74616c5472616d706f6c696e655061796d656e74010000003566722e6163696e712e6c696768746e696e672e466561747572652e57616b6555704e6f74696669636174696f6e50726f7669646572010000002c66722e6163696e712e6c696768746e696e672e466561747572652e506179546f4f70656e50726f7669646572010000003066722e6163696e712e6c696768746e696e672e466561747572652e5472757374656453776170496e50726f7669646572010000003066722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c4261636b757050726f76696465720100000000000000210362b19a83930389b4468be40308efb3f352b23142ae25e6aba0465a8220f95b0600000000000003e80000000059682f000000000000004e2000000000000003e80000009000000064000000210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa40000002103a42aef6d1c860caffa6c71a6f8ac2b16eec25bab0c3950cdb1fad7fb38a5f2a50000002102508e1845b8bbe0773f6bf8f3f04f59a5896426765c7b6b23e6e466c95381182b0000002102d62233b7c33f8fd0911922461a651007f1de09d8c474029caa8f2c229c10de260000002103d05c8245bdc12efd8b070b22b276e7db4254f4693e22b3f7c978c08e67b36236000000110000003066722e6163696e712e6c696768746e696e672e466561747572652e4f7074696f6e446174614c6f737350726f74656374010000002d66722e6163696e712e6c696768746e696e672e466561747572652e496e697469616c526f7574696e6753796e63010000002e66722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c52616e676551756572696573010000002e66722e6163696e712e6c696768746e696e672e466561747572652e5661726961626c654c656e6774684f6e696f6e000000003666722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c52616e676551756572696573457874656e646564010000002a66722e6163696e712e6c696768746e696e672e466561747572652e53746174696352656d6f74654b6579000000002866722e6163696e712e6c696768746e696e672e466561747572652e5061796d656e74536563726574000000003066722e6163696e712e6c696768746e696e672e466561747572652e42617369634d756c7469506172745061796d656e74010000002066722e6163696e712e6c696768746e696e672e466561747572652e57756d626f010000002866722e6163696e712e6c696768746e696e672e466561747572652e416e63686f724f757470757473000000002666722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c54797065000000002a66722e6163696e712e6c696768746e696e672e466561747572652e5061796d656e744d65746164617461010000003366722e6163696e712e6c696768746e696e672e466561747572652e57616b6555704e6f74696669636174696f6e436c69656e74010000002a66722e6163696e712e6c696768746e696e672e466561747572652e506179546f4f70656e436c69656e74010000002e66722e6163696e712e6c696768746e696e672e466561747572652e5472757374656453776170496e436c69656e74010000002e66722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c4261636b7570436c69656e74010000003866722e6163696e712e6c696768746e696e672e466561747572652e4578706572696d656e74616c5472616d706f6c696e655061796d656e740100000000000000000000000000000000000000000000001388000000002faf0800000000000bebc200000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e000001bc020000000001012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000b77080044a0100000000000022002046672803839d10e21d43eafb532bc37cd21bd97dec7f9b50d45380cd1cce69654a01000000000000220020bbd7f17366848d8f624c28438128ce4dc8c72ea21deb0ccf25bee110920da032400d030000000000220020cb93e3adb8d213704e9a07ea2a6ce91dca51a9b76fcb6bef3cc9b5b7e10a7990781c0c00000000002200202f0860cd1fe361a1aaf5708f75b6511c92cd5a51bdaaccfbda77aead550d875104004730440220672323ca34b85c2a43e3e93ac8a642a8293b1483392f531736db975d05f3ad3c022019f7b5044cd2a230dc49484c219fd96485f98d21c6add317566f4b21816a2fb101483045022100956b481822da569bc75c1f7ab6ec34c0a1e14dd5b4701ea8473e5bfe6b6ad41702202b1a987850611c0f52cccbb6016c735a08572f61fe03616a186ca39a8b2e07970147522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452aede99dc20000000000000000000000000000000000000000000001388000000000bebc200000000002faf0800000000206498095b8d064f46673e7c0d919636e1dff0c0a76ed61dd96938a178253ea4cb0000002102365f9a5e4822956750faa46230f54e47d4b6ef9d58eb8c488d80a5efed938d5b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100010000002103c57839fd412868a398bea05d01678a752661126a2d1357a0f7cb6f0c60311125000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000000000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd00000000000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd00000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c0000000000000000000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd00000016001434947cfb2e8f6054ddf12daed4308cbe342580d1000000010000002f66722e6163696e712e6c696768746e696e672e776972652e53687574646f776e546c762e4368616e6e656c4461746100000e8556ac7d2006dabb7b7e26a032ac384ce15362f230e007a713e45ee0a514aef433db46a55d4650585517be36dc68babddf369cbfa743e9ad976640545119c378548729fd5750f0772ae26e1ac80a288f3baa7ae2416e9ea796403fe0b2111a919370021aba83cc9c3abd6671ddb7e2c54eaa64701b86d5b70ac2a44f723e399c449ff1b9ccb8e20481ea1ab6b9a752b38601fb202f4cf960cfdf3c77c91829747fbff494ab3701148abfb09bdee3bffe1bc46d157ae16e9d701764532db299530a3679b6ecce62fab88a75a8524b1b7484faf08b9347e1e3e92623286b98a27f8236f9d94831c489c9b66846d2e65b4c75a2850bf30b3268a3122589a58223265e5d62df74cf77ab3e781c3c1612142810b30c5e45775c70e6f17b3829688d69b5ed8769bd70018bc19de67fce65240ed94f1179087e74ca49212edd8d735f015a077e5cf6328d426d69e31898c0aafafe6d21b5784bf337508ba33a13c88a34a2d04e9f48e0f3ce7ad704524b9360adbf70d91b7900ccd2a53ce4da6f7b66226c860936f5549c7065f572e9e6debcec7560d5f2ec49bd257cd23a0da2dab7b72cc3118ee72826c15cc033bced6d35187d955019d1988549be9712ce4561ca1247497a6e60b506cb7f21dea80205fc66d2e13382998538a5c0dae806d18b8fce515a7538a881c5a12f67bc11e838b1154901f4fc84eb3165477f4bdf02dcf3d8ab42ba2ade55ee22cdf07bacf2b561cf05ebd3f8eca283c451ec09f0a8cd7b3ecbb83d17157e9830bb3d85d7143ebab10306544820b3811e89b7ce013d96db368bd9eff243e575dc10b2e7c576b9df66ad6c7379e6dda3423bde90a564d9995ade0a72842816996bbdbfaae0946ed2747c3247904fafae4bbe792bbba66ca29b1f9b0179a4093bb363dd3abbc6478441528b28daf1797d2d8fd3f200f0a6fdb8bfd4dfb02506bb16d4db103531d6f13d9c46613d4f03b84be135e19c4ede30717613efc50d6f28b6a36b5e61839ccd7a36a0d8ad6e81691f0772cff88f0e800bb9539e71ea3f1a52f281a9ba7c469fa917dbc75d8b7dc9e702c6a70d5d46b453804771adb6bc8cf85476ac31657776e674b632358f1e49ac1a9a4934736830224a136d76be62cf925af87746be07ef128b11a06d798ac7780843d46a2a5d3dd12eac27ef1af0a12581ec423df8be05aa0473b7cc30e55cf77d7255d1b2f9d0223e3dea9912552aee6fc1c9d3266d69266d40c8b85730e1a4327c956a51e06705e8b3f47463ab4bac168253ae55583523ed4220d97908932efc57616b4977e2418f26eb1077a4320386abf788ff8456bf044f5b95821520f8985f734a97dbcd5ad21d66d1b870a73f5bba1c4f382d369a3c8ebff86ce0b7fa29cd589053f1fbdc1fc392ccac7d548f11326ccc22cf641b7f10afa5d79c1b2015b768bda455fe573bd15001259a9ef3a0c47e3e4937065a4712d2d8d49c989bd59e3d8c130913fef431d954fd34b09947d40dce38a6301602ef65bcd1d874ae23bde4436cd0c0c2d8c671f0f73b42ee20fe083de4ce2380b4a33568eee72b82e6bf157dcee288091f9ffcc0837ae75ab3aba9eb7e081a5e491239a19e778dca132b958ee845a8de97876721766507191e74dd6b5ed4c08ba9b9547525fc0b809c46a4a7dc529df6f9b33f27905f355043c31f4a32cf2d1f7086a6af0455fc424da920ec2906a7464823b9f8bab0d693c8ea8a55317df43e6c6bda79015814558da1fc2c92ed6c80863544788dac519f418349a7707d59a1dcd160ea4867a562dd04c780c954d3e43bff6c8186eb4b80359ed267e216c96b0ef3d57fd3d39a99cc7e034afd2d3f6c62cfcdea85eec1f2ef1f2fc5f272a6117034b6c8b5085a1d02892d942b952a17fef041d4082296a0fc800497b86760d89b7eaf03a90c5482fe5304fe81fd4bda06a8a333a03a819b3341ab9335f12dcdb8fbdb27c235d80ee0d41844c564f9c84de48c198064a9111d236e6c3e60f36e3c656216c191097f17b285fba088391f5b65a430e92eeaae792b243fe05c88887bc9d52480bc63628e5a1e4821a977e1411dd22d343aca4aebe1b9b6efd23197bb3701fcbbbab1d5f2f426b85601c5ff37d79377f41dd8ebd16af52ae50ed0b45d4db319b1d6789cd2b6c3fa2e1ba2abb2a00d1267e0fe7467aa2be5a76af028c15f9ce9f5edb31c1aea177795ee1ccee5b667bac787f6115659a264fd5be27cd77e4eab64c4ac30a57eec78bcf3b13a0119ea60a0e8953d2f955c10295a5b0ffe4e653042deed40473a143e6201a1f64052f0d6edaa5796a4956e477745b0e00805f4cf4e0e3300ce338d8f27e8bd6c3fb626222f3e09ce38ac076bb49726e31aa4e48372f3638e7ddb66451496387e4a8c9d0ed3268f368455c3a055e70edb94bcf7961a51c740c9e1de1cbbc70c189dd48c1208a86b0fc85264659597bcd3c0980c87146446d6d2edee022b91573f8f734d2d8e21b6b1b78873c39ec34dad9b90d9b6214c33dec5dc087c108c9c8a70de64b6e5cb794cc35f581af2416831968d0021ce6e7d56e4880c34481e99cc6ac41a36619fc0de2628196f4d6f4b10ac82ff810302bab14cd58b6c10143a758f93a4bc99893d6d0a6391c5a4cd9c90ca2ce6e8310d4293305548a618cd0a5d4477dbb7911ce5bf92fc8810d549cb440ff9d5607811ecc5a0e878b780c51814fda3826dc4f108f63ac9e2a74cc0a375a5be4c9eed9dc836dfd3761f966f58a6eb60ca6d8102d34d5640cab6c253b7fbb6a17e0eece493f2541dbb9c43b6ea618deecb816cc5af8ad9b1914d445d622656cbfe9e5e22aa341412fdfb0b59b6baee4c56a9fe1ae146e47e7d3aa3f9b2eec7492e6ec1d01eb9ecdf1c9488c3c8a02b5582e145256cc6df17bd3947e4528941e358a83bc32802a047d7c3564e8c8f4f3869a5d66a34421efdc67dde9cafc5fbe685be01d0c420f764d3a7f027225d9b3ac980a7b3af4536b7bf89abbce5d9a4474f461240097ec5d81e21d969a41065b3818b7936231d28f208b066c272641d011c2412e0ecff7115feeca6bf137068a0da8d88360e9741fd1c9147208355b0eb466dc00b48e1845868834dcdc21d2719eea5e0f40df5e04dbb45a87ef473212f0ffd2ea97f82487938a25893eb834ca6b9c27b1910c9e3a4fa57d7c453e25bb9a193d3b71df314f93f10b7ee2dbc0498e16dff70aa79cb61c2b22cf471014f4046f71358ed17082dd0a797c8e4a624bf79d774ef1892232c7f2fb8cb9958b3912d120e84adab1f4f9c943311212f9f006870741dd47d109fde5de7f3973aad517bafb3b83c9249c7283e5e8b977488068e6f7a90418b87824b55abb62e045d3605cfe8271339a0e6d5090629d33882c9339533ec4ae2436d6e0fd48e853c56d68744cec5b5acb0c3246c301d5dbc96db9f8bc38adb66fb9e5d8712f3f6761abaaea03a57a57a9dd8c4fdab4969770fd3f3afe8545e7f12152d01eada01133a0578391a2ff9a57d828dbfeb558cfba31dafdba1b629dd497352b8f92d630aa20ce9e95d416f5d65ce95efec6bc62fa3822127b19285e9a3420a48227bac6dcda6d3531ce57f401250cf581fa8bba6f1c23fc3269d6b01a347369225619a784f08f9a84b03a2b2d44874fe943712811555898f4812f4c9cb622dc2a9cd49996d086d6a7df33eb0436746ff3180d408e19aea960f4beb0ca12170549e874c23fdf27654fd870708bde5ff98f26d26defdfdf5d2dab2e29db10d53579a6913a1ea31c49d0bc6aaca7ec0babff6e5c251d72198adbd5b1192c33d756ecd4fe4b1e35a2d43dcd4a3ed292cb4a26b236d986d83cca36b4e31ed3d1cb1409b3dff0f437b2b3897300cb8de1672e6b878a7bfff9dd75e01e16b6bff56d06b392c0349cd85b99de6cfffdf9e93c3ecb2f688d3b2b7442dd257b0893572cfbf348b2f28989eba7b8579384884b0352a77207af3d5c18d9acb09f944e6881d9deb9a1a9248c4b9f74f341982122777e95da9667cd0f1f09dcad04de4899aa0cc6bd2ee428ef3a4224c37e911c202328262192ec8180d0cd8329e569caf9bfb515819872e65066433b92ec6ee289f278e8fde4eba02a6c09e695643ff3f439687dbb3a20e7cc4d99ccc54727bc19f831ff28efb29717036dbf78465ca8b63e2d1154d6629b4f4c576bd967f9a5cc554862728fd2a7bd7ac9c1f9b628b3542acf023013baf6a8002feb051e2d2ac8ca66c97d428026cea6e428aa72d96b7ef53bb185360a3ac0f079e9e9d11f51829262eb18b1682d48bfc5024e65fd7af0f94f5b940c5e7b2760ff841def1506855cf85e679cb904dcf829687aede7fb70840e9ad6d9b7ad7b27ffb6def8a840f40d11f794bde4bbced2b5b63fc2c263461ade7f02fee63a4e0907a7f1b44a0e3656c8e4ccc6f00731972e9b1337dbe72d70fe715b93ee4e106ca3c330356a5983e74dec3a5e75d20b5e5fad7e51f28ce38f966bf83a44bb83a6a9ec694a2d61d71f536f6bb3da3c787f2c763cc2045067d56d2600aa0f4f24bfaf43b37fb8fece78d91ec511fcce7680bbda8684cdb0e9a619cd9888321bbd3d60ebec5ce4787b9ce687ffcd136db1f2a2877143c7dcb17bcbbdc7c8b5e3850097e7a12691211b4e607361a4834bf6f8f73575c3009a0dc6f2fc257c23404fc293933e3b1c31d0975968da2d4e54ac082289ab76c725f38913d0480cb61c6bff80b3f30b25662a39459619417d820cd25b34265bea62809d9e52b57a7e1c604ee4390e39d6185f6391dbd46f514dd6af3978de827adf594da0f0d430a5f9e216a003f128533bf40377b5c0c5bcd391f77c9e3e9aed8994a514c21ab5e38ca0176c8427d742e66db449d5657a05266d96f4fa3f2adefcafed21bc955c9b26cffe1f98e3a17b002387c14eddd1cc3ddda603e1076669bd0d6eda1079c9fc976437cd999c37b655ae612587c74b7cd00ae658e54572818be38c62f9c2ac0c97cae81c4eddfe4940ba79a545e54b0cfb439b81336e7d8f191b5885d19138c3d57badcaec8a1320715304bccd54c7f04a0577a80f0c600a92719982844f27130cee8932577e5b237c8432fcbf80e0c1dc97e5ae31a9eb4027964465cbf531cc9ebe8fd1750d681bfb1590265801bf7c8bbb876b17daa008876961fc7db1a7e4d896075248d845035817e1aafa68ce8f4a6cb1f344d11056ecbe423f3df6b2c9d22db72f9cb35860c096d3c6a960012420b4133c6b567000000000000000100000003000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e0000007102000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d15e320c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c000000000100000001000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd00000000000002a2000000409fbce74a05823e5ff30227d6d96abf1adea0e2c3e225f19011d2c26fbc955b8758877c062bfe97f7a311988946421561dec3009292133c7b9c7153044c793949000000010000003166722e6163696e712e6c696768746e696e672e776972652e436c6f73696e675369676e6564546c762e46656552616e67650000000000000151000000000000054400000000000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e0000007102000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d1ce2e0c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c000000000100000001000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000063200000040006a1e2e00b0f2bbf61c20a9d1346e5df613344a59a26fcdaceb4d5a68a54e277ce25a9832c56e6a65372a1ee96cf559c2a6dd92d7cb7648dc12a81d8e177701000000010000003166722e6163696e712e6c696768746e696e672e776972652e436c6f73696e675369676e6564546c762e46656552616e67650000000000000151000000000000054400000000000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e0000007102000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d1002e0c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c000000000100000001000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000070000000040690cdadcf5f89b49a2509571bb563934c054aaf7d5ba1a05db8293f98b20d13f4d5ee294430a44238dc55e2d535a537683fa26df4f4d314d3515ee223df6d512000000010000003166722e6163696e712e6c696768746e696e672e776972652e436c6f73696e675369676e6564546c762e46656552616e6765000000000000015100000000000005440000000001000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e0000014e020000000001012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d1302d0c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c04004730440220375de514cc4965caf75b10029df0efffd804aa7c912964a7e8f53544b4bf4182022068d1bc35cf91d9576ae9c658c47e33443665402dad89ef00b231032d58ebc01d0148304502210096286d2f0bf1327c074f643c483d7bb96bfaa8b37b1b6235f72cf21d9094efaf02204ef0813a42b6b76e221f0bac47d11806d3a61db74ed5136ba8144c25d1fcc85d0147522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae00000000010000000100 \ No newline at end of file diff --git a/src/commonTest/resources/nonreg/v3/Negotiating_da44c6e2/data.json b/src/commonTest/resources/nonreg/v3/Negotiating_da44c6e2/data.json deleted file mode 100644 index 1a0f84e64..000000000 --- a/src/commonTest/resources/nonreg/v3/Negotiating_da44c6e2/data.json +++ /dev/null @@ -1,289 +0,0 @@ -{ - "type": "fr.acinq.lightning.channel.states.Negotiating", - "commitments": { - "params": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "channelConfig": [ - "funding_pubkey_based_channel_keypath" - ], - "channelFeatures": [ - "option_static_remotekey", - "option_support_large_channel", - "option_anchor_outputs" - ], - "localParams": { - "nodeId": "037108815ff0128f7ed22640485c226d9ad64a9fd6d8b41b6623565aed6b34812c", - "fundingKeyPath": "m/385048399/1977025879/604622566/184658546/776346346/949304342'/277944247'/2049339775'/1'", - "dustLimit": 1100, - "maxHtlcValueInFlightMsat": 1500000000, - "htlcMinimum": 0, - "toSelfDelay": 144, - "maxAcceptedHtlcs": 100, - "isInitiator": true, - "defaultFinalScriptPubKey": "001405e0104aa726e34ff5cd3a6320d05c0862b5b01c", - "features": { - "activated": { - "initial_routing_sync": "Optional", - "option_data_loss_protect": "Optional", - "gossip_queries": "Optional", - "gossip_queries_ex": "Optional", - "var_onion_optin": "Mandatory", - "payment_secret": "Mandatory", - "basic_mpp": "Optional", - "option_support_large_channel": "Optional", - "option_static_remotekey": "Mandatory", - "option_anchor_outputs": "Mandatory", - "option_channel_type": "Mandatory", - "option_payment_metadata": "Optional", - "trampoline_payment_experimental": "Optional", - "wake_up_notification_provider": "Optional", - "pay_to_open_provider": "Optional", - "trusted_swap_in_provider": "Optional", - "channel_backup_provider": "Optional" - }, - "unknown": [ - ] - } - }, - "remoteParams": { - "nodeId": "0362b19a83930389b4468be40308efb3f352b23142ae25e6aba0465a8220f95b06", - "dustLimit": 1000, - "maxHtlcValueInFlightMsat": 1500000000, - "htlcMinimum": 1000, - "toSelfDelay": 144, - "maxAcceptedHtlcs": 100, - "revocationBasepoint": "03a42aef6d1c860caffa6c71a6f8ac2b16eec25bab0c3950cdb1fad7fb38a5f2a5", - "paymentBasepoint": "02508e1845b8bbe0773f6bf8f3f04f59a5896426765c7b6b23e6e466c95381182b", - "delayedPaymentBasepoint": "02d62233b7c33f8fd0911922461a651007f1de09d8c474029caa8f2c229c10de26", - "htlcBasepoint": "03d05c8245bdc12efd8b070b22b276e7db4254f4693e22b3f7c978c08e67b36236", - "features": { - "activated": { - "option_data_loss_protect": "Optional", - "initial_routing_sync": "Optional", - "gossip_queries": "Optional", - "var_onion_optin": "Mandatory", - "gossip_queries_ex": "Optional", - "option_static_remotekey": "Mandatory", - "payment_secret": "Mandatory", - "basic_mpp": "Optional", - "option_support_large_channel": "Optional", - "option_anchor_outputs": "Mandatory", - "option_channel_type": "Mandatory", - "option_payment_metadata": "Optional", - "wake_up_notification_client": "Optional", - "pay_to_open_client": "Optional", - "trusted_swap_in_client": "Optional", - "channel_backup_client": "Optional", - "trampoline_payment_experimental": "Optional" - }, - "unknown": [ - ] - } - }, - "channelFlags": 0 - }, - "changes": { - "localChanges": { - "proposed": [ - ], - "signed": [ - ], - "acked": [ - ] - }, - "remoteChanges": { - "proposed": [ - ], - "acked": [ - ], - "signed": [ - ] - }, - "localNextHtlcId": 0, - "remoteNextHtlcId": 0 - }, - "active": [ - { - "fundingTxIndex": 0, - "remoteFundingPubkey": "0385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa4", - "localFundingStatus": { - "status": "unconfirmed", - "txId": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f" - }, - "remoteFundingStatus": { - "status": "locked" - }, - "localCommit": { - "index": 0, - "spec": { - "htlcsIn": [ - ], - "htlcsOut": [ - ], - "feerate": 5000, - "toLocal": 800000000, - "toRemote": 200000000 - }, - "publishableTxs": { - "commitTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "020000000001012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000b77080044a0100000000000022002046672803839d10e21d43eafb532bc37cd21bd97dec7f9b50d45380cd1cce69654a01000000000000220020bbd7f17366848d8f624c28438128ce4dc8c72ea21deb0ccf25bee110920da032400d030000000000220020cb93e3adb8d213704e9a07ea2a6ce91dca51a9b76fcb6bef3cc9b5b7e10a7990781c0c00000000002200202f0860cd1fe361a1aaf5708f75b6511c92cd5a51bdaaccfbda77aead550d875104004730440220672323ca34b85c2a43e3e93ac8a642a8293b1483392f531736db975d05f3ad3c022019f7b5044cd2a230dc49484c219fd96485f98d21c6add317566f4b21816a2fb101483045022100956b481822da569bc75c1f7ab6ec34c0a1e14dd5b4701ea8473e5bfe6b6ad41702202b1a987850611c0f52cccbb6016c735a08572f61fe03616a186ca39a8b2e07970147522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452aede99dc20" - }, - "htlcTxsAndSigs": [ - ] - } - }, - "remoteCommit": { - "index": 0, - "spec": { - "htlcsIn": [ - ], - "htlcsOut": [ - ], - "feerate": 5000, - "toLocal": 200000000, - "toRemote": 800000000 - }, - "txid": "6498095b8d064f46673e7c0d919636e1dff0c0a76ed61dd96938a178253ea4cb", - "remotePerCommitmentPoint": "02365f9a5e4822956750faa46230f54e47d4b6ef9d58eb8c488d80a5efed938d5b" - }, - "nextRemoteCommit": null - } - ], - "inactive": [ - ], - "payments": { - }, - "remoteNextCommitInfo": { - "left": null, - "right": "03c57839fd412868a398bea05d01678a752661126a2d1357a0f7cb6f0c60311125" - }, - "remotePerCommitmentSecrets": "" - }, - "localShutdown": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "scriptPubKey": "001405e0104aa726e34ff5cd3a6320d05c0862b5b01c" - }, - "remoteShutdown": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "scriptPubKey": "001434947cfb2e8f6054ddf12daed4308cbe342580d1", - "tlvStream": { - "records": [ - { - "type": "fr.acinq.lightning.wire.ShutdownTlv.ChannelData", - "ecb": { - "data": "56ac7d2006dabb7b7e26a032ac384ce15362f230e007a713e45ee0a514aef433db46a55d4650585517be36dc68babddf369cbfa743e9ad976640545119c378548729fd5750f0772ae26e1ac80a288f3baa7ae2416e9ea796403fe0b2111a919370021aba83cc9c3abd6671ddb7e2c54eaa64701b86d5b70ac2a44f723e399c449ff1b9ccb8e20481ea1ab6b9a752b38601fb202f4cf960cfdf3c77c91829747fbff494ab3701148abfb09bdee3bffe1bc46d157ae16e9d701764532db299530a3679b6ecce62fab88a75a8524b1b7484faf08b9347e1e3e92623286b98a27f8236f9d94831c489c9b66846d2e65b4c75a2850bf30b3268a3122589a58223265e5d62df74cf77ab3e781c3c1612142810b30c5e45775c70e6f17b3829688d69b5ed8769bd70018bc19de67fce65240ed94f1179087e74ca49212edd8d735f015a077e5cf6328d426d69e31898c0aafafe6d21b5784bf337508ba33a13c88a34a2d04e9f48e0f3ce7ad704524b9360adbf70d91b7900ccd2a53ce4da6f7b66226c860936f5549c7065f572e9e6debcec7560d5f2ec49bd257cd23a0da2dab7b72cc3118ee72826c15cc033bced6d35187d955019d1988549be9712ce4561ca1247497a6e60b506cb7f21dea80205fc66d2e13382998538a5c0dae806d18b8fce515a7538a881c5a12f67bc11e838b1154901f4fc84eb3165477f4bdf02dcf3d8ab42ba2ade55ee22cdf07bacf2b561cf05ebd3f8eca283c451ec09f0a8cd7b3ecbb83d17157e9830bb3d85d7143ebab10306544820b3811e89b7ce013d96db368bd9eff243e575dc10b2e7c576b9df66ad6c7379e6dda3423bde90a564d9995ade0a72842816996bbdbfaae0946ed2747c3247904fafae4bbe792bbba66ca29b1f9b0179a4093bb363dd3abbc6478441528b28daf1797d2d8fd3f200f0a6fdb8bfd4dfb02506bb16d4db103531d6f13d9c46613d4f03b84be135e19c4ede30717613efc50d6f28b6a36b5e61839ccd7a36a0d8ad6e81691f0772cff88f0e800bb9539e71ea3f1a52f281a9ba7c469fa917dbc75d8b7dc9e702c6a70d5d46b453804771adb6bc8cf85476ac31657776e674b632358f1e49ac1a9a4934736830224a136d76be62cf925af87746be07ef128b11a06d798ac7780843d46a2a5d3dd12eac27ef1af0a12581ec423df8be05aa0473b7cc30e55cf77d7255d1b2f9d0223e3dea9912552aee6fc1c9d3266d69266d40c8b85730e1a4327c956a51e06705e8b3f47463ab4bac168253ae55583523ed4220d97908932efc57616b4977e2418f26eb1077a4320386abf788ff8456bf044f5b95821520f8985f734a97dbcd5ad21d66d1b870a73f5bba1c4f382d369a3c8ebff86ce0b7fa29cd589053f1fbdc1fc392ccac7d548f11326ccc22cf641b7f10afa5d79c1b2015b768bda455fe573bd15001259a9ef3a0c47e3e4937065a4712d2d8d49c989bd59e3d8c130913fef431d954fd34b09947d40dce38a6301602ef65bcd1d874ae23bde4436cd0c0c2d8c671f0f73b42ee20fe083de4ce2380b4a33568eee72b82e6bf157dcee288091f9ffcc0837ae75ab3aba9eb7e081a5e491239a19e778dca132b958ee845a8de97876721766507191e74dd6b5ed4c08ba9b9547525fc0b809c46a4a7dc529df6f9b33f27905f355043c31f4a32cf2d1f7086a6af0455fc424da920ec2906a7464823b9f8bab0d693c8ea8a55317df43e6c6bda79015814558da1fc2c92ed6c80863544788dac519f418349a7707d59a1dcd160ea4867a562dd04c780c954d3e43bff6c8186eb4b80359ed267e216c96b0ef3d57fd3d39a99cc7e034afd2d3f6c62cfcdea85eec1f2ef1f2fc5f272a6117034b6c8b5085a1d02892d942b952a17fef041d4082296a0fc800497b86760d89b7eaf03a90c5482fe5304fe81fd4bda06a8a333a03a819b3341ab9335f12dcdb8fbdb27c235d80ee0d41844c564f9c84de48c198064a9111d236e6c3e60f36e3c656216c191097f17b285fba088391f5b65a430e92eeaae792b243fe05c88887bc9d52480bc63628e5a1e4821a977e1411dd22d343aca4aebe1b9b6efd23197bb3701fcbbbab1d5f2f426b85601c5ff37d79377f41dd8ebd16af52ae50ed0b45d4db319b1d6789cd2b6c3fa2e1ba2abb2a00d1267e0fe7467aa2be5a76af028c15f9ce9f5edb31c1aea177795ee1ccee5b667bac787f6115659a264fd5be27cd77e4eab64c4ac30a57eec78bcf3b13a0119ea60a0e8953d2f955c10295a5b0ffe4e653042deed40473a143e6201a1f64052f0d6edaa5796a4956e477745b0e00805f4cf4e0e3300ce338d8f27e8bd6c3fb626222f3e09ce38ac076bb49726e31aa4e48372f3638e7ddb66451496387e4a8c9d0ed3268f368455c3a055e70edb94bcf7961a51c740c9e1de1cbbc70c189dd48c1208a86b0fc85264659597bcd3c0980c87146446d6d2edee022b91573f8f734d2d8e21b6b1b78873c39ec34dad9b90d9b6214c33dec5dc087c108c9c8a70de64b6e5cb794cc35f581af2416831968d0021ce6e7d56e4880c34481e99cc6ac41a36619fc0de2628196f4d6f4b10ac82ff810302bab14cd58b6c10143a758f93a4bc99893d6d0a6391c5a4cd9c90ca2ce6e8310d4293305548a618cd0a5d4477dbb7911ce5bf92fc8810d549cb440ff9d5607811ecc5a0e878b780c51814fda3826dc4f108f63ac9e2a74cc0a375a5be4c9eed9dc836dfd3761f966f58a6eb60ca6d8102d34d5640cab6c253b7fbb6a17e0eece493f2541dbb9c43b6ea618deecb816cc5af8ad9b1914d445d622656cbfe9e5e22aa341412fdfb0b59b6baee4c56a9fe1ae146e47e7d3aa3f9b2eec7492e6ec1d01eb9ecdf1c9488c3c8a02b5582e145256cc6df17bd3947e4528941e358a83bc32802a047d7c3564e8c8f4f3869a5d66a34421efdc67dde9cafc5fbe685be01d0c420f764d3a7f027225d9b3ac980a7b3af4536b7bf89abbce5d9a4474f461240097ec5d81e21d969a41065b3818b7936231d28f208b066c272641d011c2412e0ecff7115feeca6bf137068a0da8d88360e9741fd1c9147208355b0eb466dc00b48e1845868834dcdc21d2719eea5e0f40df5e04dbb45a87ef473212f0ffd2ea97f82487938a25893eb834ca6b9c27b1910c9e3a4fa57d7c453e25bb9a193d3b71df314f93f10b7ee2dbc0498e16dff70aa79cb61c2b22cf471014f4046f71358ed17082dd0a797c8e4a624bf79d774ef1892232c7f2fb8cb9958b3912d120e84adab1f4f9c943311212f9f006870741dd47d109fde5de7f3973aad517bafb3b83c9249c7283e5e8b977488068e6f7a90418b87824b55abb62e045d3605cfe8271339a0e6d5090629d33882c9339533ec4ae2436d6e0fd48e853c56d68744cec5b5acb0c3246c301d5dbc96db9f8bc38adb66fb9e5d8712f3f6761abaaea03a57a57a9dd8c4fdab4969770fd3f3afe8545e7f12152d01eada01133a0578391a2ff9a57d828dbfeb558cfba31dafdba1b629dd497352b8f92d630aa20ce9e95d416f5d65ce95efec6bc62fa3822127b19285e9a3420a48227bac6dcda6d3531ce57f401250cf581fa8bba6f1c23fc3269d6b01a347369225619a784f08f9a84b03a2b2d44874fe943712811555898f4812f4c9cb622dc2a9cd49996d086d6a7df33eb0436746ff3180d408e19aea960f4beb0ca12170549e874c23fdf27654fd870708bde5ff98f26d26defdfdf5d2dab2e29db10d53579a6913a1ea31c49d0bc6aaca7ec0babff6e5c251d72198adbd5b1192c33d756ecd4fe4b1e35a2d43dcd4a3ed292cb4a26b236d986d83cca36b4e31ed3d1cb1409b3dff0f437b2b3897300cb8de1672e6b878a7bfff9dd75e01e16b6bff56d06b392c0349cd85b99de6cfffdf9e93c3ecb2f688d3b2b7442dd257b0893572cfbf348b2f28989eba7b8579384884b0352a77207af3d5c18d9acb09f944e6881d9deb9a1a9248c4b9f74f341982122777e95da9667cd0f1f09dcad04de4899aa0cc6bd2ee428ef3a4224c37e911c202328262192ec8180d0cd8329e569caf9bfb515819872e65066433b92ec6ee289f278e8fde4eba02a6c09e695643ff3f439687dbb3a20e7cc4d99ccc54727bc19f831ff28efb29717036dbf78465ca8b63e2d1154d6629b4f4c576bd967f9a5cc554862728fd2a7bd7ac9c1f9b628b3542acf023013baf6a8002feb051e2d2ac8ca66c97d428026cea6e428aa72d96b7ef53bb185360a3ac0f079e9e9d11f51829262eb18b1682d48bfc5024e65fd7af0f94f5b940c5e7b2760ff841def1506855cf85e679cb904dcf829687aede7fb70840e9ad6d9b7ad7b27ffb6def8a840f40d11f794bde4bbced2b5b63fc2c263461ade7f02fee63a4e0907a7f1b44a0e3656c8e4ccc6f00731972e9b1337dbe72d70fe715b93ee4e106ca3c330356a5983e74dec3a5e75d20b5e5fad7e51f28ce38f966bf83a44bb83a6a9ec694a2d61d71f536f6bb3da3c787f2c763cc2045067d56d2600aa0f4f24bfaf43b37fb8fece78d91ec511fcce7680bbda8684cdb0e9a619cd9888321bbd3d60ebec5ce4787b9ce687ffcd136db1f2a2877143c7dcb17bcbbdc7c8b5e3850097e7a12691211b4e607361a4834bf6f8f73575c3009a0dc6f2fc257c23404fc293933e3b1c31d0975968da2d4e54ac082289ab76c725f38913d0480cb61c6bff80b3f30b25662a39459619417d820cd25b34265bea62809d9e52b57a7e1c604ee4390e39d6185f6391dbd46f514dd6af3978de827adf594da0f0d430a5f9e216a003f128533bf40377b5c0c5bcd391f77c9e3e9aed8994a514c21ab5e38ca0176c8427d742e66db449d5657a05266d96f4fa3f2adefcafed21bc955c9b26cffe1f98e3a17b002387c14eddd1cc3ddda603e1076669bd0d6eda1079c9fc976437cd999c37b655ae612587c74b7cd00ae658e54572818be38c62f9c2ac0c97cae81c4eddfe4940ba79a545e54b0cfb439b81336e7d8f191b5885d19138c3d57badcaec8a1320715304bccd54c7f04a0577a80f0c600a92719982844f27130cee8932577e5b237c8432fcbf80e0c1dc97e5ae31a9eb4027964465cbf531cc9ebe8fd1750d681bfb1590265801bf7c8bbb876b17daa008876961fc7db1a7e4d896075248d845035817e1aafa68ce8f4a6cb1f344d11056ecbe423f3df6b2c9d22db72f9cb35860c096d3c6a960012420b4133c6b567" - } - } - ] - } - }, - "closingTxProposed": [ - [ - { - "unsignedTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "02000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d15e320c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c00000000", - "toLocalIndex": 1 - }, - "localClosingSigned": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "feeSatoshis": 674, - "signature": "9fbce74a05823e5ff30227d6d96abf1adea0e2c3e225f19011d2c26fbc955b8758877c062bfe97f7a311988946421561dec3009292133c7b9c7153044c793949", - "tlvStream": { - "records": [ - { - "type": "fr.acinq.lightning.wire.ClosingSignedTlv.FeeRange", - "min": 337, - "max": 1348 - } - ] - } - } - }, - { - "unsignedTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "02000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d1ce2e0c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c00000000", - "toLocalIndex": 1 - }, - "localClosingSigned": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "feeSatoshis": 1586, - "signature": "006a1e2e00b0f2bbf61c20a9d1346e5df613344a59a26fcdaceb4d5a68a54e277ce25a9832c56e6a65372a1ee96cf559c2a6dd92d7cb7648dc12a81d8e177701", - "tlvStream": { - "records": [ - { - "type": "fr.acinq.lightning.wire.ClosingSignedTlv.FeeRange", - "min": 337, - "max": 1348 - } - ] - } - } - }, - { - "unsignedTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "02000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d1002e0c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c00000000", - "toLocalIndex": 1 - }, - "localClosingSigned": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "feeSatoshis": 1792, - "signature": "690cdadcf5f89b49a2509571bb563934c054aaf7d5ba1a05db8293f98b20d13f4d5ee294430a44238dc55e2d535a537683fa26df4f4d314d3515ee223df6d512", - "tlvStream": { - "records": [ - { - "type": "fr.acinq.lightning.wire.ClosingSignedTlv.FeeRange", - "min": 337, - "max": 1348 - } - ] - } - } - } - ] - ], - "bestUnpublishedClosingTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "020000000001012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d1302d0c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c04004730440220375de514cc4965caf75b10029df0efffd804aa7c912964a7e8f53544b4bf4182022068d1bc35cf91d9576ae9c658c47e33443665402dad89ef00b231032d58ebc01d0148304502210096286d2f0bf1327c074f643c483d7bb96bfaa8b37b1b6235f72cf21d9094efaf02204ef0813a42b6b76e221f0bac47d11806d3a61db74ed5136ba8144c25d1fcc85d0147522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae00000000", - "toLocalIndex": 1 - }, - "closingFeerates": null -} \ No newline at end of file diff --git a/src/commonTest/resources/nonreg/v3/Negotiating_dabbed55/data.bin b/src/commonTest/resources/nonreg/v3/Negotiating_dabbed55/data.bin deleted file mode 100644 index eedfb58da..000000000 --- a/src/commonTest/resources/nonreg/v3/Negotiating_dabbed55/data.bin +++ /dev/null @@ -1 +0,0 @@ -0000000300002d250000002f66722e6163696e712e6c696768746e696e672e73657269616c697a6174696f6e2e76332e4e65676f74696174696e670000002006226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f000000210362b19a83930389b4468be40308efb3f352b23142ae25e6aba0465a8220f95b0600061a800000000b426c6f636b486561646572000000500100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5494dffff7f200200000000000000000003e800000000000003e800000000000003e800000001010000000314100000000021037108815ff0128f7ed22640485c226d9ad64a9fd6d8b41b6623565aed6b34812c000000090000000016f35f4f0000000075d70557000000002409cee6000000000b01aa72000000002e461aea00000000b8953c1600000000909117b700000000fa26717f0000000080000001000000000000044c0000000059682f000000000000002710000000000000000000000090000000640100000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c000000110000002d66722e6163696e712e6c696768746e696e672e466561747572652e496e697469616c526f7574696e6753796e63010000003066722e6163696e712e6c696768746e696e672e466561747572652e4f7074696f6e446174614c6f737350726f74656374010000002e66722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c52616e676551756572696573010000003666722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c52616e676551756572696573457874656e646564010000002e66722e6163696e712e6c696768746e696e672e466561747572652e5661726961626c654c656e6774684f6e696f6e000000002866722e6163696e712e6c696768746e696e672e466561747572652e5061796d656e74536563726574000000003066722e6163696e712e6c696768746e696e672e466561747572652e42617369634d756c7469506172745061796d656e74010000002066722e6163696e712e6c696768746e696e672e466561747572652e57756d626f010000002a66722e6163696e712e6c696768746e696e672e466561747572652e53746174696352656d6f74654b6579000000002866722e6163696e712e6c696768746e696e672e466561747572652e416e63686f724f757470757473000000002666722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c54797065000000002a66722e6163696e712e6c696768746e696e672e466561747572652e5061796d656e744d65746164617461010000003866722e6163696e712e6c696768746e696e672e466561747572652e4578706572696d656e74616c5472616d706f6c696e655061796d656e74010000003566722e6163696e712e6c696768746e696e672e466561747572652e57616b6555704e6f74696669636174696f6e50726f7669646572010000002c66722e6163696e712e6c696768746e696e672e466561747572652e506179546f4f70656e50726f7669646572010000003066722e6163696e712e6c696768746e696e672e466561747572652e5472757374656453776170496e50726f7669646572010000003066722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c4261636b757050726f76696465720100000000000000210362b19a83930389b4468be40308efb3f352b23142ae25e6aba0465a8220f95b0600000000000003e80000000059682f000000000000004e2000000000000003e80000009000000064000000210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa40000002103a42aef6d1c860caffa6c71a6f8ac2b16eec25bab0c3950cdb1fad7fb38a5f2a50000002102508e1845b8bbe0773f6bf8f3f04f59a5896426765c7b6b23e6e466c95381182b0000002102d62233b7c33f8fd0911922461a651007f1de09d8c474029caa8f2c229c10de260000002103d05c8245bdc12efd8b070b22b276e7db4254f4693e22b3f7c978c08e67b36236000000110000003066722e6163696e712e6c696768746e696e672e466561747572652e4f7074696f6e446174614c6f737350726f74656374010000002d66722e6163696e712e6c696768746e696e672e466561747572652e496e697469616c526f7574696e6753796e63010000002e66722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c52616e676551756572696573010000002e66722e6163696e712e6c696768746e696e672e466561747572652e5661726961626c654c656e6774684f6e696f6e000000003666722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c52616e676551756572696573457874656e646564010000002a66722e6163696e712e6c696768746e696e672e466561747572652e53746174696352656d6f74654b6579000000002866722e6163696e712e6c696768746e696e672e466561747572652e5061796d656e74536563726574000000003066722e6163696e712e6c696768746e696e672e466561747572652e42617369634d756c7469506172745061796d656e74010000002066722e6163696e712e6c696768746e696e672e466561747572652e57756d626f010000002866722e6163696e712e6c696768746e696e672e466561747572652e416e63686f724f757470757473000000002666722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c54797065000000002a66722e6163696e712e6c696768746e696e672e466561747572652e5061796d656e744d65746164617461010000003366722e6163696e712e6c696768746e696e672e466561747572652e57616b6555704e6f74696669636174696f6e436c69656e74010000002a66722e6163696e712e6c696768746e696e672e466561747572652e506179546f4f70656e436c69656e74010000002e66722e6163696e712e6c696768746e696e672e466561747572652e5472757374656453776170496e436c69656e74010000002e66722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c4261636b7570436c69656e74010000003866722e6163696e712e6c696768746e696e672e466561747572652e4578706572696d656e74616c5472616d706f6c696e655061796d656e740100000000000000000000000000000000000000000000001388000000002faf0800000000000bebc200000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e000001bc020000000001012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000b77080044a0100000000000022002046672803839d10e21d43eafb532bc37cd21bd97dec7f9b50d45380cd1cce69654a01000000000000220020bbd7f17366848d8f624c28438128ce4dc8c72ea21deb0ccf25bee110920da032400d030000000000220020cb93e3adb8d213704e9a07ea2a6ce91dca51a9b76fcb6bef3cc9b5b7e10a7990781c0c00000000002200202f0860cd1fe361a1aaf5708f75b6511c92cd5a51bdaaccfbda77aead550d875104004730440220672323ca34b85c2a43e3e93ac8a642a8293b1483392f531736db975d05f3ad3c022019f7b5044cd2a230dc49484c219fd96485f98d21c6add317566f4b21816a2fb101483045022100956b481822da569bc75c1f7ab6ec34c0a1e14dd5b4701ea8473e5bfe6b6ad41702202b1a987850611c0f52cccbb6016c735a08572f61fe03616a186ca39a8b2e07970147522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452aede99dc20000000000000000000000000000000000000000000001388000000000bebc200000000002faf0800000000206498095b8d064f46673e7c0d919636e1dff0c0a76ed61dd96938a178253ea4cb0000002102365f9a5e4822956750faa46230f54e47d4b6ef9d58eb8c488d80a5efed938d5b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100010000002103c57839fd412868a398bea05d01678a752661126a2d1357a0f7cb6f0c60311125000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000000000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd00000000000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd00000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c0000000000000000000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd00000016001434947cfb2e8f6054ddf12daed4308cbe342580d1000000010000002f66722e6163696e712e6c696768746e696e672e776972652e53687574646f776e546c762e4368616e6e656c4461746100000e8556ac7d2006dabb7b7e26a032ac384ce15362f230e007a713e45ee0a514aef433db46a55d4650585517be36dc68babddf369cbfa743e9ad976640545119c378548729fd5750f0772ae26e1ac80a288f3baa7ae2416e9ea796403fe0b2111a919370021aba83cc9c3abd6671ddb7e2c54eaa64701b86d5b70ac2a44f723e399c449ff1b9ccb8e20481ea1ab6b9a752b38601fb202f4cf960cfdf3c77c91829747fbff494ab3701148abfb09bdee3bffe1bc46d157ae16e9d701764532db299530a3679b6ecce62fab88a75a8524b1b7484faf08b9347e1e3e92623286b98a27f8236f9d94831c489c9b66846d2e65b4c75a2850bf30b3268a3122589a58223265e5d62df74cf77ab3e781c3c1612142810b30c5e45775c70e6f17b3829688d69b5ed8769bd70018bc19de67fce65240ed94f1179087e74ca49212edd8d735f015a077e5cf6328d426d69e31898c0aafafe6d21b5784bf337508ba33a13c88a34a2d04e9f48e0f3ce7ad704524b9360adbf70d91b7900ccd2a53ce4da6f7b66226c860936f5549c7065f572e9e6debcec7560d5f2ec49bd257cd23a0da2dab7b72cc3118ee72826c15cc033bced6d35187d955019d1988549be9712ce4561ca1247497a6e60b506cb7f21dea80205fc66d2e13382998538a5c0dae806d18b8fce515a7538a881c5a12f67bc11e838b1154901f4fc84eb3165477f4bdf02dcf3d8ab42ba2ade55ee22cdf07bacf2b561cf05ebd3f8eca283c451ec09f0a8cd7b3ecbb83d17157e9830bb3d85d7143ebab10306544820b3811e89b7ce013d96db368bd9eff243e575dc10b2e7c576b9df66ad6c7379e6dda3423bde90a564d9995ade0a72842816996bbdbfaae0946ed2747c3247904fafae4bbe792bbba66ca29b1f9b0179a4093bb363dd3abbc6478441528b28daf1797d2d8fd3f200f0a6fdb8bfd4dfb02506bb16d4db103531d6f13d9c46613d4f03b84be135e19c4ede30717613efc50d6f28b6a36b5e61839ccd7a36a0d8ad6e81691f0772cff88f0e800bb9539e71ea3f1a52f281a9ba7c469fa917dbc75d8b7dc9e702c6a70d5d46b453804771adb6bc8cf85476ac31657776e674b632358f1e49ac1a9a4934736830224a136d76be62cf925af87746be07ef128b11a06d798ac7780843d46a2a5d3dd12eac27ef1af0a12581ec423df8be05aa0473b7cc30e55cf77d7255d1b2f9d0223e3dea9912552aee6fc1c9d3266d69266d40c8b85730e1a4327c956a51e06705e8b3f47463ab4bac168253ae55583523ed4220d97908932efc57616b4977e2418f26eb1077a4320386abf788ff8456bf044f5b95821520f8985f734a97dbcd5ad21d66d1b870a73f5bba1c4f382d369a3c8ebff86ce0b7fa29cd589053f1fbdc1fc392ccac7d548f11326ccc22cf641b7f10afa5d79c1b2015b768bda455fe573bd15001259a9ef3a0c47e3e4937065a4712d2d8d49c989bd59e3d8c130913fef431d954fd34b09947d40dce38a6301602ef65bcd1d874ae23bde4436cd0c0c2d8c671f0f73b42ee20fe083de4ce2380b4a33568eee72b82e6bf157dcee288091f9ffcc0837ae75ab3aba9eb7e081a5e491239a19e778dca132b958ee845a8de97876721766507191e74dd6b5ed4c08ba9b9547525fc0b809c46a4a7dc529df6f9b33f27905f355043c31f4a32cf2d1f7086a6af0455fc424da920ec2906a7464823b9f8bab0d693c8ea8a55317df43e6c6bda79015814558da1fc2c92ed6c80863544788dac519f418349a7707d59a1dcd160ea4867a562dd04c780c954d3e43bff6c8186eb4b80359ed267e216c96b0ef3d57fd3d39a99cc7e034afd2d3f6c62cfcdea85eec1f2ef1f2fc5f272a6117034b6c8b5085a1d02892d942b952a17fef041d4082296a0fc800497b86760d89b7eaf03a90c5482fe5304fe81fd4bda06a8a333a03a819b3341ab9335f12dcdb8fbdb27c235d80ee0d41844c564f9c84de48c198064a9111d236e6c3e60f36e3c656216c191097f17b285fba088391f5b65a430e92eeaae792b243fe05c88887bc9d52480bc63628e5a1e4821a977e1411dd22d343aca4aebe1b9b6efd23197bb3701fcbbbab1d5f2f426b85601c5ff37d79377f41dd8ebd16af52ae50ed0b45d4db319b1d6789cd2b6c3fa2e1ba2abb2a00d1267e0fe7467aa2be5a76af028c15f9ce9f5edb31c1aea177795ee1ccee5b667bac787f6115659a264fd5be27cd77e4eab64c4ac30a57eec78bcf3b13a0119ea60a0e8953d2f955c10295a5b0ffe4e653042deed40473a143e6201a1f64052f0d6edaa5796a4956e477745b0e00805f4cf4e0e3300ce338d8f27e8bd6c3fb626222f3e09ce38ac076bb49726e31aa4e48372f3638e7ddb66451496387e4a8c9d0ed3268f368455c3a055e70edb94bcf7961a51c740c9e1de1cbbc70c189dd48c1208a86b0fc85264659597bcd3c0980c87146446d6d2edee022b91573f8f734d2d8e21b6b1b78873c39ec34dad9b90d9b6214c33dec5dc087c108c9c8a70de64b6e5cb794cc35f581af2416831968d0021ce6e7d56e4880c34481e99cc6ac41a36619fc0de2628196f4d6f4b10ac82ff810302bab14cd58b6c10143a758f93a4bc99893d6d0a6391c5a4cd9c90ca2ce6e8310d4293305548a618cd0a5d4477dbb7911ce5bf92fc8810d549cb440ff9d5607811ecc5a0e878b780c51814fda3826dc4f108f63ac9e2a74cc0a375a5be4c9eed9dc836dfd3761f966f58a6eb60ca6d8102d34d5640cab6c253b7fbb6a17e0eece493f2541dbb9c43b6ea618deecb816cc5af8ad9b1914d445d622656cbfe9e5e22aa341412fdfb0b59b6baee4c56a9fe1ae146e47e7d3aa3f9b2eec7492e6ec1d01eb9ecdf1c9488c3c8a02b5582e145256cc6df17bd3947e4528941e358a83bc32802a047d7c3564e8c8f4f3869a5d66a34421efdc67dde9cafc5fbe685be01d0c420f764d3a7f027225d9b3ac980a7b3af4536b7bf89abbce5d9a4474f461240097ec5d81e21d969a41065b3818b7936231d28f208b066c272641d011c2412e0ecff7115feeca6bf137068a0da8d88360e9741fd1c9147208355b0eb466dc00b48e1845868834dcdc21d2719eea5e0f40df5e04dbb45a87ef473212f0ffd2ea97f82487938a25893eb834ca6b9c27b1910c9e3a4fa57d7c453e25bb9a193d3b71df314f93f10b7ee2dbc0498e16dff70aa79cb61c2b22cf471014f4046f71358ed17082dd0a797c8e4a624bf79d774ef1892232c7f2fb8cb9958b3912d120e84adab1f4f9c943311212f9f006870741dd47d109fde5de7f3973aad517bafb3b83c9249c7283e5e8b977488068e6f7a90418b87824b55abb62e045d3605cfe8271339a0e6d5090629d33882c9339533ec4ae2436d6e0fd48e853c56d68744cec5b5acb0c3246c301d5dbc96db9f8bc38adb66fb9e5d8712f3f6761abaaea03a57a57a9dd8c4fdab4969770fd3f3afe8545e7f12152d01eada01133a0578391a2ff9a57d828dbfeb558cfba31dafdba1b629dd497352b8f92d630aa20ce9e95d416f5d65ce95efec6bc62fa3822127b19285e9a3420a48227bac6dcda6d3531ce57f401250cf581fa8bba6f1c23fc3269d6b01a347369225619a784f08f9a84b03a2b2d44874fe943712811555898f4812f4c9cb622dc2a9cd49996d086d6a7df33eb0436746ff3180d408e19aea960f4beb0ca12170549e874c23fdf27654fd870708bde5ff98f26d26defdfdf5d2dab2e29db10d53579a6913a1ea31c49d0bc6aaca7ec0babff6e5c251d72198adbd5b1192c33d756ecd4fe4b1e35a2d43dcd4a3ed292cb4a26b236d986d83cca36b4e31ed3d1cb1409b3dff0f437b2b3897300cb8de1672e6b878a7bfff9dd75e01e16b6bff56d06b392c0349cd85b99de6cfffdf9e93c3ecb2f688d3b2b7442dd257b0893572cfbf348b2f28989eba7b8579384884b0352a77207af3d5c18d9acb09f944e6881d9deb9a1a9248c4b9f74f341982122777e95da9667cd0f1f09dcad04de4899aa0cc6bd2ee428ef3a4224c37e911c202328262192ec8180d0cd8329e569caf9bfb515819872e65066433b92ec6ee289f278e8fde4eba02a6c09e695643ff3f439687dbb3a20e7cc4d99ccc54727bc19f831ff28efb29717036dbf78465ca8b63e2d1154d6629b4f4c576bd967f9a5cc554862728fd2a7bd7ac9c1f9b628b3542acf023013baf6a8002feb051e2d2ac8ca66c97d428026cea6e428aa72d96b7ef53bb185360a3ac0f079e9e9d11f51829262eb18b1682d48bfc5024e65fd7af0f94f5b940c5e7b2760ff841def1506855cf85e679cb904dcf829687aede7fb70840e9ad6d9b7ad7b27ffb6def8a840f40d11f794bde4bbced2b5b63fc2c263461ade7f02fee63a4e0907a7f1b44a0e3656c8e4ccc6f00731972e9b1337dbe72d70fe715b93ee4e106ca3c330356a5983e74dec3a5e75d20b5e5fad7e51f28ce38f966bf83a44bb83a6a9ec694a2d61d71f536f6bb3da3c787f2c763cc2045067d56d2600aa0f4f24bfaf43b37fb8fece78d91ec511fcce7680bbda8684cdb0e9a619cd9888321bbd3d60ebec5ce4787b9ce687ffcd136db1f2a2877143c7dcb17bcbbdc7c8b5e3850097e7a12691211b4e607361a4834bf6f8f73575c3009a0dc6f2fc257c23404fc293933e3b1c31d0975968da2d4e54ac082289ab76c725f38913d0480cb61c6bff80b3f30b25662a39459619417d820cd25b34265bea62809d9e52b57a7e1c604ee4390e39d6185f6391dbd46f514dd6af3978de827adf594da0f0d430a5f9e216a003f128533bf40377b5c0c5bcd391f77c9e3e9aed8994a514c21ab5e38ca0176c8427d742e66db449d5657a05266d96f4fa3f2adefcafed21bc955c9b26cffe1f98e3a17b002387c14eddd1cc3ddda603e1076669bd0d6eda1079c9fc976437cd999c37b655ae612587c74b7cd00ae658e54572818be38c62f9c2ac0c97cae81c4eddfe4940ba79a545e54b0cfb439b81336e7d8f191b5885d19138c3d57badcaec8a1320715304bccd54c7f04a0577a80f0c600a92719982844f27130cee8932577e5b237c8432fcbf80e0c1dc97e5ae31a9eb4027964465cbf531cc9ebe8fd1750d681bfb1590265801bf7c8bbb876b17daa008876961fc7db1a7e4d896075248d845035817e1aafa68ce8f4a6cb1f344d11056ecbe423f3df6b2c9d22db72f9cb35860c096d3c6a960012420b4133c6b567000000000000000100000007000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e0000007102000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d15e320c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c000000000100000001000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd00000000000002a2000000409fbce74a05823e5ff30227d6d96abf1adea0e2c3e225f19011d2c26fbc955b8758877c062bfe97f7a311988946421561dec3009292133c7b9c7153044c793949000000010000003166722e6163696e712e6c696768746e696e672e776972652e436c6f73696e675369676e6564546c762e46656552616e67650000000000000151000000000000054400000000000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e0000007102000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d10e310c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c000000000100000001000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd00000000000003f200000040959c687c87ee014e988275260a28f5522b9aa7df58201780e8da0714c80466db75747a0cbe30ad56656ed9f7d05599fc959758ed23566b815565dc20177d366c000000010000003166722e6163696e712e6c696768746e696e672e776972652e436c6f73696e675369676e6564546c762e46656552616e67650000000000000151000000000000054400000000000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e0000007102000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d114300c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c000000000100000001000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd00000000000004ec000000407ba4aab1322712d9ac5b12b0ead3c2386eab48e380fb0e93218de67de109f1d5552694f878c64a8b536e7be333bbec781fe2838845852db3905de3fcb46aa536000000010000003166722e6163696e712e6c696768746e696e672e776972652e436c6f73696e675369676e6564546c762e46656552616e67650000000000000151000000000000054400000000000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e0000007102000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d11a2f0c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c000000000100000001000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd00000000000005e60000004012804a6c0c36c336baffe28a211042a1fc1cdd3c0626e06643a29a30d282b2b076487caa9a6e619ab141ffd6775bd4e1da32d55f87a548ea27421720a3e8ad08000000010000003166722e6163696e712e6c696768746e696e672e776972652e436c6f73696e675369676e6564546c762e46656552616e67650000000000000151000000000000054400000000000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e0000007102000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d1202e0c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c000000000100000001000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd00000000000006e0000000404214aa761eaec84f0bc571ad5bd2a427ba9ce6fc363adcb3c4b81aa5ced969d92361859b2eb9557afab41ebe54dcd18d645781085e3aa534819e57d8bea9d2e2000000010000003166722e6163696e712e6c696768746e696e672e776972652e436c6f73696e675369676e6564546c762e46656552616e67650000000000000151000000000000054400000000000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e0000007102000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d1262d0c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c000000000100000001000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd00000000000007da00000040a66e4ad93233f6add8965f12ecb66f7c06a3e7a8ee42f692bb50426a7a32d470323c560e5069cc1801f85ad13a3bf149601a1a4b86d5d82cfb934b75f4dd5757000000010000003166722e6163696e712e6c696768746e696e672e776972652e436c6f73696e675369676e6564546c762e46656552616e67650000000000000151000000000000054400000000000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e0000007102000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d12c2c0c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c000000000100000001000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd00000000000008d40000004086c58c46963050df8fb7babb0dbbada4f4275c07089c9c7ac56a1b032b00bfd82244dc56d99ecff8f117e0b11bcf589a33f40c2248c7dd37eb84caa97e6000f5000000010000003166722e6163696e712e6c696768746e696e672e776972652e436c6f73696e675369676e6564546c762e46656552616e6765000000000000015100000000000005440000000001000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e0000014e020000000001012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d1322b0c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c040047304402206395a7e0db7cffd3d87b3edff6cee0d9fc0cd75a7d968b4ec4ff013bb27d3684022060e4e35277d0019d55dda79d7fab336ee1332452a406b273808c36ed3a7ea37901483045022100d1a0d9307bd4fbb4561de2392e27d1c42dcd1da524cdea0144444e338f9e0f440220546af31b1a48bfcaf8b0f8a98f8ab7618c4c850c5226b976288bfed1e15516030147522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae00000000010000000100 \ No newline at end of file diff --git a/src/commonTest/resources/nonreg/v3/Negotiating_dabbed55/data.json b/src/commonTest/resources/nonreg/v3/Negotiating_dabbed55/data.json deleted file mode 100644 index 4c122a653..000000000 --- a/src/commonTest/resources/nonreg/v3/Negotiating_dabbed55/data.json +++ /dev/null @@ -1,401 +0,0 @@ -{ - "type": "fr.acinq.lightning.channel.states.Negotiating", - "commitments": { - "params": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "channelConfig": [ - "funding_pubkey_based_channel_keypath" - ], - "channelFeatures": [ - "option_static_remotekey", - "option_support_large_channel", - "option_anchor_outputs" - ], - "localParams": { - "nodeId": "037108815ff0128f7ed22640485c226d9ad64a9fd6d8b41b6623565aed6b34812c", - "fundingKeyPath": "m/385048399/1977025879/604622566/184658546/776346346/949304342'/277944247'/2049339775'/1'", - "dustLimit": 1100, - "maxHtlcValueInFlightMsat": 1500000000, - "htlcMinimum": 0, - "toSelfDelay": 144, - "maxAcceptedHtlcs": 100, - "isInitiator": true, - "defaultFinalScriptPubKey": "001405e0104aa726e34ff5cd3a6320d05c0862b5b01c", - "features": { - "activated": { - "initial_routing_sync": "Optional", - "option_data_loss_protect": "Optional", - "gossip_queries": "Optional", - "gossip_queries_ex": "Optional", - "var_onion_optin": "Mandatory", - "payment_secret": "Mandatory", - "basic_mpp": "Optional", - "option_support_large_channel": "Optional", - "option_static_remotekey": "Mandatory", - "option_anchor_outputs": "Mandatory", - "option_channel_type": "Mandatory", - "option_payment_metadata": "Optional", - "trampoline_payment_experimental": "Optional", - "wake_up_notification_provider": "Optional", - "pay_to_open_provider": "Optional", - "trusted_swap_in_provider": "Optional", - "channel_backup_provider": "Optional" - }, - "unknown": [ - ] - } - }, - "remoteParams": { - "nodeId": "0362b19a83930389b4468be40308efb3f352b23142ae25e6aba0465a8220f95b06", - "dustLimit": 1000, - "maxHtlcValueInFlightMsat": 1500000000, - "htlcMinimum": 1000, - "toSelfDelay": 144, - "maxAcceptedHtlcs": 100, - "revocationBasepoint": "03a42aef6d1c860caffa6c71a6f8ac2b16eec25bab0c3950cdb1fad7fb38a5f2a5", - "paymentBasepoint": "02508e1845b8bbe0773f6bf8f3f04f59a5896426765c7b6b23e6e466c95381182b", - "delayedPaymentBasepoint": "02d62233b7c33f8fd0911922461a651007f1de09d8c474029caa8f2c229c10de26", - "htlcBasepoint": "03d05c8245bdc12efd8b070b22b276e7db4254f4693e22b3f7c978c08e67b36236", - "features": { - "activated": { - "option_data_loss_protect": "Optional", - "initial_routing_sync": "Optional", - "gossip_queries": "Optional", - "var_onion_optin": "Mandatory", - "gossip_queries_ex": "Optional", - "option_static_remotekey": "Mandatory", - "payment_secret": "Mandatory", - "basic_mpp": "Optional", - "option_support_large_channel": "Optional", - "option_anchor_outputs": "Mandatory", - "option_channel_type": "Mandatory", - "option_payment_metadata": "Optional", - "wake_up_notification_client": "Optional", - "pay_to_open_client": "Optional", - "trusted_swap_in_client": "Optional", - "channel_backup_client": "Optional", - "trampoline_payment_experimental": "Optional" - }, - "unknown": [ - ] - } - }, - "channelFlags": 0 - }, - "changes": { - "localChanges": { - "proposed": [ - ], - "signed": [ - ], - "acked": [ - ] - }, - "remoteChanges": { - "proposed": [ - ], - "acked": [ - ], - "signed": [ - ] - }, - "localNextHtlcId": 0, - "remoteNextHtlcId": 0 - }, - "active": [ - { - "fundingTxIndex": 0, - "remoteFundingPubkey": "0385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa4", - "localFundingStatus": { - "status": "unconfirmed", - "txId": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f" - }, - "remoteFundingStatus": { - "status": "locked" - }, - "localCommit": { - "index": 0, - "spec": { - "htlcsIn": [ - ], - "htlcsOut": [ - ], - "feerate": 5000, - "toLocal": 800000000, - "toRemote": 200000000 - }, - "publishableTxs": { - "commitTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "020000000001012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000b77080044a0100000000000022002046672803839d10e21d43eafb532bc37cd21bd97dec7f9b50d45380cd1cce69654a01000000000000220020bbd7f17366848d8f624c28438128ce4dc8c72ea21deb0ccf25bee110920da032400d030000000000220020cb93e3adb8d213704e9a07ea2a6ce91dca51a9b76fcb6bef3cc9b5b7e10a7990781c0c00000000002200202f0860cd1fe361a1aaf5708f75b6511c92cd5a51bdaaccfbda77aead550d875104004730440220672323ca34b85c2a43e3e93ac8a642a8293b1483392f531736db975d05f3ad3c022019f7b5044cd2a230dc49484c219fd96485f98d21c6add317566f4b21816a2fb101483045022100956b481822da569bc75c1f7ab6ec34c0a1e14dd5b4701ea8473e5bfe6b6ad41702202b1a987850611c0f52cccbb6016c735a08572f61fe03616a186ca39a8b2e07970147522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452aede99dc20" - }, - "htlcTxsAndSigs": [ - ] - } - }, - "remoteCommit": { - "index": 0, - "spec": { - "htlcsIn": [ - ], - "htlcsOut": [ - ], - "feerate": 5000, - "toLocal": 200000000, - "toRemote": 800000000 - }, - "txid": "6498095b8d064f46673e7c0d919636e1dff0c0a76ed61dd96938a178253ea4cb", - "remotePerCommitmentPoint": "02365f9a5e4822956750faa46230f54e47d4b6ef9d58eb8c488d80a5efed938d5b" - }, - "nextRemoteCommit": null - } - ], - "inactive": [ - ], - "payments": { - }, - "remoteNextCommitInfo": { - "left": null, - "right": "03c57839fd412868a398bea05d01678a752661126a2d1357a0f7cb6f0c60311125" - }, - "remotePerCommitmentSecrets": "" - }, - "localShutdown": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "scriptPubKey": "001405e0104aa726e34ff5cd3a6320d05c0862b5b01c" - }, - "remoteShutdown": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "scriptPubKey": "001434947cfb2e8f6054ddf12daed4308cbe342580d1", - "tlvStream": { - "records": [ - { - "type": "fr.acinq.lightning.wire.ShutdownTlv.ChannelData", - "ecb": { - "data": "56ac7d2006dabb7b7e26a032ac384ce15362f230e007a713e45ee0a514aef433db46a55d4650585517be36dc68babddf369cbfa743e9ad976640545119c378548729fd5750f0772ae26e1ac80a288f3baa7ae2416e9ea796403fe0b2111a919370021aba83cc9c3abd6671ddb7e2c54eaa64701b86d5b70ac2a44f723e399c449ff1b9ccb8e20481ea1ab6b9a752b38601fb202f4cf960cfdf3c77c91829747fbff494ab3701148abfb09bdee3bffe1bc46d157ae16e9d701764532db299530a3679b6ecce62fab88a75a8524b1b7484faf08b9347e1e3e92623286b98a27f8236f9d94831c489c9b66846d2e65b4c75a2850bf30b3268a3122589a58223265e5d62df74cf77ab3e781c3c1612142810b30c5e45775c70e6f17b3829688d69b5ed8769bd70018bc19de67fce65240ed94f1179087e74ca49212edd8d735f015a077e5cf6328d426d69e31898c0aafafe6d21b5784bf337508ba33a13c88a34a2d04e9f48e0f3ce7ad704524b9360adbf70d91b7900ccd2a53ce4da6f7b66226c860936f5549c7065f572e9e6debcec7560d5f2ec49bd257cd23a0da2dab7b72cc3118ee72826c15cc033bced6d35187d955019d1988549be9712ce4561ca1247497a6e60b506cb7f21dea80205fc66d2e13382998538a5c0dae806d18b8fce515a7538a881c5a12f67bc11e838b1154901f4fc84eb3165477f4bdf02dcf3d8ab42ba2ade55ee22cdf07bacf2b561cf05ebd3f8eca283c451ec09f0a8cd7b3ecbb83d17157e9830bb3d85d7143ebab10306544820b3811e89b7ce013d96db368bd9eff243e575dc10b2e7c576b9df66ad6c7379e6dda3423bde90a564d9995ade0a72842816996bbdbfaae0946ed2747c3247904fafae4bbe792bbba66ca29b1f9b0179a4093bb363dd3abbc6478441528b28daf1797d2d8fd3f200f0a6fdb8bfd4dfb02506bb16d4db103531d6f13d9c46613d4f03b84be135e19c4ede30717613efc50d6f28b6a36b5e61839ccd7a36a0d8ad6e81691f0772cff88f0e800bb9539e71ea3f1a52f281a9ba7c469fa917dbc75d8b7dc9e702c6a70d5d46b453804771adb6bc8cf85476ac31657776e674b632358f1e49ac1a9a4934736830224a136d76be62cf925af87746be07ef128b11a06d798ac7780843d46a2a5d3dd12eac27ef1af0a12581ec423df8be05aa0473b7cc30e55cf77d7255d1b2f9d0223e3dea9912552aee6fc1c9d3266d69266d40c8b85730e1a4327c956a51e06705e8b3f47463ab4bac168253ae55583523ed4220d97908932efc57616b4977e2418f26eb1077a4320386abf788ff8456bf044f5b95821520f8985f734a97dbcd5ad21d66d1b870a73f5bba1c4f382d369a3c8ebff86ce0b7fa29cd589053f1fbdc1fc392ccac7d548f11326ccc22cf641b7f10afa5d79c1b2015b768bda455fe573bd15001259a9ef3a0c47e3e4937065a4712d2d8d49c989bd59e3d8c130913fef431d954fd34b09947d40dce38a6301602ef65bcd1d874ae23bde4436cd0c0c2d8c671f0f73b42ee20fe083de4ce2380b4a33568eee72b82e6bf157dcee288091f9ffcc0837ae75ab3aba9eb7e081a5e491239a19e778dca132b958ee845a8de97876721766507191e74dd6b5ed4c08ba9b9547525fc0b809c46a4a7dc529df6f9b33f27905f355043c31f4a32cf2d1f7086a6af0455fc424da920ec2906a7464823b9f8bab0d693c8ea8a55317df43e6c6bda79015814558da1fc2c92ed6c80863544788dac519f418349a7707d59a1dcd160ea4867a562dd04c780c954d3e43bff6c8186eb4b80359ed267e216c96b0ef3d57fd3d39a99cc7e034afd2d3f6c62cfcdea85eec1f2ef1f2fc5f272a6117034b6c8b5085a1d02892d942b952a17fef041d4082296a0fc800497b86760d89b7eaf03a90c5482fe5304fe81fd4bda06a8a333a03a819b3341ab9335f12dcdb8fbdb27c235d80ee0d41844c564f9c84de48c198064a9111d236e6c3e60f36e3c656216c191097f17b285fba088391f5b65a430e92eeaae792b243fe05c88887bc9d52480bc63628e5a1e4821a977e1411dd22d343aca4aebe1b9b6efd23197bb3701fcbbbab1d5f2f426b85601c5ff37d79377f41dd8ebd16af52ae50ed0b45d4db319b1d6789cd2b6c3fa2e1ba2abb2a00d1267e0fe7467aa2be5a76af028c15f9ce9f5edb31c1aea177795ee1ccee5b667bac787f6115659a264fd5be27cd77e4eab64c4ac30a57eec78bcf3b13a0119ea60a0e8953d2f955c10295a5b0ffe4e653042deed40473a143e6201a1f64052f0d6edaa5796a4956e477745b0e00805f4cf4e0e3300ce338d8f27e8bd6c3fb626222f3e09ce38ac076bb49726e31aa4e48372f3638e7ddb66451496387e4a8c9d0ed3268f368455c3a055e70edb94bcf7961a51c740c9e1de1cbbc70c189dd48c1208a86b0fc85264659597bcd3c0980c87146446d6d2edee022b91573f8f734d2d8e21b6b1b78873c39ec34dad9b90d9b6214c33dec5dc087c108c9c8a70de64b6e5cb794cc35f581af2416831968d0021ce6e7d56e4880c34481e99cc6ac41a36619fc0de2628196f4d6f4b10ac82ff810302bab14cd58b6c10143a758f93a4bc99893d6d0a6391c5a4cd9c90ca2ce6e8310d4293305548a618cd0a5d4477dbb7911ce5bf92fc8810d549cb440ff9d5607811ecc5a0e878b780c51814fda3826dc4f108f63ac9e2a74cc0a375a5be4c9eed9dc836dfd3761f966f58a6eb60ca6d8102d34d5640cab6c253b7fbb6a17e0eece493f2541dbb9c43b6ea618deecb816cc5af8ad9b1914d445d622656cbfe9e5e22aa341412fdfb0b59b6baee4c56a9fe1ae146e47e7d3aa3f9b2eec7492e6ec1d01eb9ecdf1c9488c3c8a02b5582e145256cc6df17bd3947e4528941e358a83bc32802a047d7c3564e8c8f4f3869a5d66a34421efdc67dde9cafc5fbe685be01d0c420f764d3a7f027225d9b3ac980a7b3af4536b7bf89abbce5d9a4474f461240097ec5d81e21d969a41065b3818b7936231d28f208b066c272641d011c2412e0ecff7115feeca6bf137068a0da8d88360e9741fd1c9147208355b0eb466dc00b48e1845868834dcdc21d2719eea5e0f40df5e04dbb45a87ef473212f0ffd2ea97f82487938a25893eb834ca6b9c27b1910c9e3a4fa57d7c453e25bb9a193d3b71df314f93f10b7ee2dbc0498e16dff70aa79cb61c2b22cf471014f4046f71358ed17082dd0a797c8e4a624bf79d774ef1892232c7f2fb8cb9958b3912d120e84adab1f4f9c943311212f9f006870741dd47d109fde5de7f3973aad517bafb3b83c9249c7283e5e8b977488068e6f7a90418b87824b55abb62e045d3605cfe8271339a0e6d5090629d33882c9339533ec4ae2436d6e0fd48e853c56d68744cec5b5acb0c3246c301d5dbc96db9f8bc38adb66fb9e5d8712f3f6761abaaea03a57a57a9dd8c4fdab4969770fd3f3afe8545e7f12152d01eada01133a0578391a2ff9a57d828dbfeb558cfba31dafdba1b629dd497352b8f92d630aa20ce9e95d416f5d65ce95efec6bc62fa3822127b19285e9a3420a48227bac6dcda6d3531ce57f401250cf581fa8bba6f1c23fc3269d6b01a347369225619a784f08f9a84b03a2b2d44874fe943712811555898f4812f4c9cb622dc2a9cd49996d086d6a7df33eb0436746ff3180d408e19aea960f4beb0ca12170549e874c23fdf27654fd870708bde5ff98f26d26defdfdf5d2dab2e29db10d53579a6913a1ea31c49d0bc6aaca7ec0babff6e5c251d72198adbd5b1192c33d756ecd4fe4b1e35a2d43dcd4a3ed292cb4a26b236d986d83cca36b4e31ed3d1cb1409b3dff0f437b2b3897300cb8de1672e6b878a7bfff9dd75e01e16b6bff56d06b392c0349cd85b99de6cfffdf9e93c3ecb2f688d3b2b7442dd257b0893572cfbf348b2f28989eba7b8579384884b0352a77207af3d5c18d9acb09f944e6881d9deb9a1a9248c4b9f74f341982122777e95da9667cd0f1f09dcad04de4899aa0cc6bd2ee428ef3a4224c37e911c202328262192ec8180d0cd8329e569caf9bfb515819872e65066433b92ec6ee289f278e8fde4eba02a6c09e695643ff3f439687dbb3a20e7cc4d99ccc54727bc19f831ff28efb29717036dbf78465ca8b63e2d1154d6629b4f4c576bd967f9a5cc554862728fd2a7bd7ac9c1f9b628b3542acf023013baf6a8002feb051e2d2ac8ca66c97d428026cea6e428aa72d96b7ef53bb185360a3ac0f079e9e9d11f51829262eb18b1682d48bfc5024e65fd7af0f94f5b940c5e7b2760ff841def1506855cf85e679cb904dcf829687aede7fb70840e9ad6d9b7ad7b27ffb6def8a840f40d11f794bde4bbced2b5b63fc2c263461ade7f02fee63a4e0907a7f1b44a0e3656c8e4ccc6f00731972e9b1337dbe72d70fe715b93ee4e106ca3c330356a5983e74dec3a5e75d20b5e5fad7e51f28ce38f966bf83a44bb83a6a9ec694a2d61d71f536f6bb3da3c787f2c763cc2045067d56d2600aa0f4f24bfaf43b37fb8fece78d91ec511fcce7680bbda8684cdb0e9a619cd9888321bbd3d60ebec5ce4787b9ce687ffcd136db1f2a2877143c7dcb17bcbbdc7c8b5e3850097e7a12691211b4e607361a4834bf6f8f73575c3009a0dc6f2fc257c23404fc293933e3b1c31d0975968da2d4e54ac082289ab76c725f38913d0480cb61c6bff80b3f30b25662a39459619417d820cd25b34265bea62809d9e52b57a7e1c604ee4390e39d6185f6391dbd46f514dd6af3978de827adf594da0f0d430a5f9e216a003f128533bf40377b5c0c5bcd391f77c9e3e9aed8994a514c21ab5e38ca0176c8427d742e66db449d5657a05266d96f4fa3f2adefcafed21bc955c9b26cffe1f98e3a17b002387c14eddd1cc3ddda603e1076669bd0d6eda1079c9fc976437cd999c37b655ae612587c74b7cd00ae658e54572818be38c62f9c2ac0c97cae81c4eddfe4940ba79a545e54b0cfb439b81336e7d8f191b5885d19138c3d57badcaec8a1320715304bccd54c7f04a0577a80f0c600a92719982844f27130cee8932577e5b237c8432fcbf80e0c1dc97e5ae31a9eb4027964465cbf531cc9ebe8fd1750d681bfb1590265801bf7c8bbb876b17daa008876961fc7db1a7e4d896075248d845035817e1aafa68ce8f4a6cb1f344d11056ecbe423f3df6b2c9d22db72f9cb35860c096d3c6a960012420b4133c6b567" - } - } - ] - } - }, - "closingTxProposed": [ - [ - { - "unsignedTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "02000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d15e320c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c00000000", - "toLocalIndex": 1 - }, - "localClosingSigned": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "feeSatoshis": 674, - "signature": "9fbce74a05823e5ff30227d6d96abf1adea0e2c3e225f19011d2c26fbc955b8758877c062bfe97f7a311988946421561dec3009292133c7b9c7153044c793949", - "tlvStream": { - "records": [ - { - "type": "fr.acinq.lightning.wire.ClosingSignedTlv.FeeRange", - "min": 337, - "max": 1348 - } - ] - } - } - }, - { - "unsignedTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "02000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d10e310c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c00000000", - "toLocalIndex": 1 - }, - "localClosingSigned": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "feeSatoshis": 1010, - "signature": "959c687c87ee014e988275260a28f5522b9aa7df58201780e8da0714c80466db75747a0cbe30ad56656ed9f7d05599fc959758ed23566b815565dc20177d366c", - "tlvStream": { - "records": [ - { - "type": "fr.acinq.lightning.wire.ClosingSignedTlv.FeeRange", - "min": 337, - "max": 1348 - } - ] - } - } - }, - { - "unsignedTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "02000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d114300c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c00000000", - "toLocalIndex": 1 - }, - "localClosingSigned": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "feeSatoshis": 1260, - "signature": "7ba4aab1322712d9ac5b12b0ead3c2386eab48e380fb0e93218de67de109f1d5552694f878c64a8b536e7be333bbec781fe2838845852db3905de3fcb46aa536", - "tlvStream": { - "records": [ - { - "type": "fr.acinq.lightning.wire.ClosingSignedTlv.FeeRange", - "min": 337, - "max": 1348 - } - ] - } - } - }, - { - "unsignedTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "02000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d11a2f0c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c00000000", - "toLocalIndex": 1 - }, - "localClosingSigned": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "feeSatoshis": 1510, - "signature": "12804a6c0c36c336baffe28a211042a1fc1cdd3c0626e06643a29a30d282b2b076487caa9a6e619ab141ffd6775bd4e1da32d55f87a548ea27421720a3e8ad08", - "tlvStream": { - "records": [ - { - "type": "fr.acinq.lightning.wire.ClosingSignedTlv.FeeRange", - "min": 337, - "max": 1348 - } - ] - } - } - }, - { - "unsignedTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "02000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d1202e0c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c00000000", - "toLocalIndex": 1 - }, - "localClosingSigned": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "feeSatoshis": 1760, - "signature": "4214aa761eaec84f0bc571ad5bd2a427ba9ce6fc363adcb3c4b81aa5ced969d92361859b2eb9557afab41ebe54dcd18d645781085e3aa534819e57d8bea9d2e2", - "tlvStream": { - "records": [ - { - "type": "fr.acinq.lightning.wire.ClosingSignedTlv.FeeRange", - "min": 337, - "max": 1348 - } - ] - } - } - }, - { - "unsignedTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "02000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d1262d0c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c00000000", - "toLocalIndex": 1 - }, - "localClosingSigned": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "feeSatoshis": 2010, - "signature": "a66e4ad93233f6add8965f12ecb66f7c06a3e7a8ee42f692bb50426a7a32d470323c560e5069cc1801f85ad13a3bf149601a1a4b86d5d82cfb934b75f4dd5757", - "tlvStream": { - "records": [ - { - "type": "fr.acinq.lightning.wire.ClosingSignedTlv.FeeRange", - "min": 337, - "max": 1348 - } - ] - } - } - }, - { - "unsignedTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "02000000012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d12c2c0c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c00000000", - "toLocalIndex": 1 - }, - "localClosingSigned": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "feeSatoshis": 2260, - "signature": "86c58c46963050df8fb7babb0dbbada4f4275c07089c9c7ac56a1b032b00bfd82244dc56d99ecff8f117e0b11bcf589a33f40c2248c7dd37eb84caa97e6000f5", - "tlvStream": { - "records": [ - { - "type": "fr.acinq.lightning.wire.ClosingSignedTlv.FeeRange", - "min": 337, - "max": 1348 - } - ] - } - } - } - ] - ], - "bestUnpublishedClosingTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "020000000001012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000000ffffffff02400d03000000000016001434947cfb2e8f6054ddf12daed4308cbe342580d1322b0c000000000016001405e0104aa726e34ff5cd3a6320d05c0862b5b01c040047304402206395a7e0db7cffd3d87b3edff6cee0d9fc0cd75a7d968b4ec4ff013bb27d3684022060e4e35277d0019d55dda79d7fab336ee1332452a406b273808c36ed3a7ea37901483045022100d1a0d9307bd4fbb4561de2392e27d1c42dcd1da524cdea0144444e338f9e0f440220546af31b1a48bfcaf8b0f8a98f8ab7618c4c850c5226b976288bfed1e15516030147522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae00000000", - "toLocalIndex": 1 - }, - "closingFeerates": null -} \ No newline at end of file diff --git a/src/commonTest/resources/nonreg/v3/Negotiating_fadb50c1/data.bin b/src/commonTest/resources/nonreg/v3/Negotiating_fadb50c1/data.bin deleted file mode 100644 index 8ae59db22..000000000 --- a/src/commonTest/resources/nonreg/v3/Negotiating_fadb50c1/data.bin +++ /dev/null @@ -1 +0,0 @@ -0000000300000eb40000002f66722e6163696e712e6c696768746e696e672e73657269616c697a6174696f6e2e76332e4e65676f74696174696e670000002006226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f00000021037108815ff0128f7ed22640485c226d9ad64a9fd6d8b41b6623565aed6b34812c00061a800000000b426c6f636b486561646572000000500100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5494dffff7f2002000000000000000000271000000000000027100000000000002710000000010100000003141000000000210362b19a83930389b4468be40308efb3f352b23142ae25e6aba0465a8220f95b060000000900000000af70d6bd0000000021b1adae00000000e6a03a190000000024f606c1000000003878f51d0000000092f83b32000000006c9cf00200000000a4b8a485000000008000000000000000000003e80000000059682f000000000000004e2000000000000003e800000090000000640000000016001434947cfb2e8f6054ddf12daed4308cbe342580d1000000120000002d66722e6163696e712e6c696768746e696e672e466561747572652e496e697469616c526f7574696e6753796e63010000003066722e6163696e712e6c696768746e696e672e466561747572652e4f7074696f6e446174614c6f737350726f74656374010000002e66722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c52616e676551756572696573010000003666722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c52616e676551756572696573457874656e646564010000002e66722e6163696e712e6c696768746e696e672e466561747572652e5661726961626c654c656e6774684f6e696f6e000000002866722e6163696e712e6c696768746e696e672e466561747572652e5061796d656e74536563726574000000003066722e6163696e712e6c696768746e696e672e466561747572652e42617369634d756c7469506172745061796d656e74010000002066722e6163696e712e6c696768746e696e672e466561747572652e57756d626f010000002a66722e6163696e712e6c696768746e696e672e466561747572652e53746174696352656d6f74654b6579000000002866722e6163696e712e6c696768746e696e672e466561747572652e416e63686f724f757470757473000000002666722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c54797065000000002a66722e6163696e712e6c696768746e696e672e466561747572652e5061796d656e744d65746164617461010000003866722e6163696e712e6c696768746e696e672e466561747572652e4578706572696d656e74616c5472616d706f6c696e655061796d656e74010000003366722e6163696e712e6c696768746e696e672e466561747572652e57616b6555704e6f74696669636174696f6e436c69656e74010000002a66722e6163696e712e6c696768746e696e672e466561747572652e506179546f4f70656e436c69656e74010000002e66722e6163696e712e6c696768746e696e672e466561747572652e5472757374656453776170496e436c69656e74010000002e66722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c4261636b7570436c69656e74010000002c66722e6163696e712e6c696768746e696e672e466561747572652e53687574646f776e416e79536567776974010000000000000021037108815ff0128f7ed22640485c226d9ad64a9fd6d8b41b6623565aed6b34812c000000000000044c0000000059682f000000000000002710000000000000000000000090000000640000002102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c00000021037d549bc475d9b2b0098e3b2f23282671646eab09b36e2f01099f39e376552864000000210368434fc548cb471f7ed8c94638433bfb07cceb97665c411450fdc23c60236409000000210399d61c09ee58f1cdc497a872f6b284cbaccd54f56bcbf7acf1f5595b577506cc000000210288fb5246c577f7ea28bc1b56f64d4c9f6c931b7075f7890bc6b4daff6253b5d6000000120000003066722e6163696e712e6c696768746e696e672e466561747572652e4f7074696f6e446174614c6f737350726f74656374010000002d66722e6163696e712e6c696768746e696e672e466561747572652e496e697469616c526f7574696e6753796e63010000002e66722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c52616e676551756572696573010000002e66722e6163696e712e6c696768746e696e672e466561747572652e5661726961626c654c656e6774684f6e696f6e000000003666722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c52616e676551756572696573457874656e646564010000002a66722e6163696e712e6c696768746e696e672e466561747572652e53746174696352656d6f74654b6579000000002866722e6163696e712e6c696768746e696e672e466561747572652e5061796d656e74536563726574000000003066722e6163696e712e6c696768746e696e672e466561747572652e42617369634d756c7469506172745061796d656e74010000002066722e6163696e712e6c696768746e696e672e466561747572652e57756d626f010000002866722e6163696e712e6c696768746e696e672e466561747572652e416e63686f724f757470757473000000002c66722e6163696e712e6c696768746e696e672e466561747572652e53687574646f776e416e79536567776974010000002666722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c54797065000000002a66722e6163696e712e6c696768746e696e672e466561747572652e5061796d656e744d65746164617461010000003566722e6163696e712e6c696768746e696e672e466561747572652e57616b6555704e6f74696669636174696f6e50726f7669646572010000002c66722e6163696e712e6c696768746e696e672e466561747572652e506179546f4f70656e50726f7669646572010000003066722e6163696e712e6c696768746e696e672e466561747572652e5472757374656453776170496e50726f7669646572010000003066722e6163696e712e6c696768746e696e672e466561747572652e4368616e6e656c4261636b757050726f7669646572010000003866722e6163696e712e6c696768746e696e672e466561747572652e4578706572696d656e74616c5472616d706f6c696e655061796d656e740100000000000000000000000000000000000000000000001388000000000bebc200000000002faf0800000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000b5472616e73616374696f6e000001bc020000000001012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000b77080044a0100000000000022002046672803839d10e21d43eafb532bc37cd21bd97dec7f9b50d45380cd1cce69654a01000000000000220020bbd7f17366848d8f624c28438128ce4dc8c72ea21deb0ccf25bee110920da032400d03000000000022002031dbc67ef6930d0825de6c23bd311eb93d40430d543c0555aa0f15b7aaab0cbc781c0c0000000000220020958bb43c9e6d1b985001c2f4dc38d286d7fde78bb04d7ec5a5ae44d8ebf0c40c040047304402201991b61ae8ef7bf6bd03f6f965552294e7941fce3fc91a024094cbd9b3464dd202206068ef64671e59b5825408e58462613a6ad0edfc7aa23853aea36187298c493901483045022100cca233f9a14605a7adab49f959c5b42260a55156282cbc802397fc934d5e537c02203504b82653044526706d76d3ddf0f083ea77a16f6cc13c93add344069a55cb940147522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452aede99dc20000000000000000000000000000000000000000000001388000000002faf0800000000000bebc2000000002051487720c64eaa73a972e2e240f5fe4b1cc1c46d9a76854a11c62ab969222a29000000210332dcde49bbcc222f9e793771bca07d28b08c2d6e12992ebe5398c20194f267220000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001000000210234ea3e3929ca115acc645d07c40eada7a98d86017614c3fa466d7e19760917e4000000084f7574506f696e74000000242f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000000554784f75740000002b40420f00000000002200204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b800000047522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae0000000000000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd00000000000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd00000016001434947cfb2e8f6054ddf12daed4308cbe342580d10000000000000000000000202f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd0000000751050102030405000000000000000000000001000000000000 \ No newline at end of file diff --git a/src/commonTest/resources/nonreg/v3/Negotiating_fadb50c1/data.json b/src/commonTest/resources/nonreg/v3/Negotiating_fadb50c1/data.json deleted file mode 100644 index 152463972..000000000 --- a/src/commonTest/resources/nonreg/v3/Negotiating_fadb50c1/data.json +++ /dev/null @@ -1,186 +0,0 @@ -{ - "type": "fr.acinq.lightning.channel.states.Negotiating", - "commitments": { - "params": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "channelConfig": [ - "funding_pubkey_based_channel_keypath" - ], - "channelFeatures": [ - "option_static_remotekey", - "option_support_large_channel", - "option_anchor_outputs" - ], - "localParams": { - "nodeId": "0362b19a83930389b4468be40308efb3f352b23142ae25e6aba0465a8220f95b06", - "fundingKeyPath": "m/795924157'/565292462/1721776665'/620103361/947451165/318257970'/1822224386/616080517'/0'", - "dustLimit": 1000, - "maxHtlcValueInFlightMsat": 1500000000, - "htlcMinimum": 1000, - "toSelfDelay": 144, - "maxAcceptedHtlcs": 100, - "isInitiator": false, - "defaultFinalScriptPubKey": "001434947cfb2e8f6054ddf12daed4308cbe342580d1", - "features": { - "activated": { - "initial_routing_sync": "Optional", - "option_data_loss_protect": "Optional", - "gossip_queries": "Optional", - "gossip_queries_ex": "Optional", - "var_onion_optin": "Mandatory", - "payment_secret": "Mandatory", - "basic_mpp": "Optional", - "option_support_large_channel": "Optional", - "option_static_remotekey": "Mandatory", - "option_anchor_outputs": "Mandatory", - "option_channel_type": "Mandatory", - "option_payment_metadata": "Optional", - "trampoline_payment_experimental": "Optional", - "wake_up_notification_client": "Optional", - "pay_to_open_client": "Optional", - "trusted_swap_in_client": "Optional", - "channel_backup_client": "Optional", - "option_shutdown_anysegwit": "Optional" - }, - "unknown": [ - ] - } - }, - "remoteParams": { - "nodeId": "037108815ff0128f7ed22640485c226d9ad64a9fd6d8b41b6623565aed6b34812c", - "dustLimit": 1100, - "maxHtlcValueInFlightMsat": 1500000000, - "htlcMinimum": 0, - "toSelfDelay": 144, - "maxAcceptedHtlcs": 100, - "revocationBasepoint": "037d549bc475d9b2b0098e3b2f23282671646eab09b36e2f01099f39e376552864", - "paymentBasepoint": "0368434fc548cb471f7ed8c94638433bfb07cceb97665c411450fdc23c60236409", - "delayedPaymentBasepoint": "0399d61c09ee58f1cdc497a872f6b284cbaccd54f56bcbf7acf1f5595b577506cc", - "htlcBasepoint": "0288fb5246c577f7ea28bc1b56f64d4c9f6c931b7075f7890bc6b4daff6253b5d6", - "features": { - "activated": { - "option_data_loss_protect": "Optional", - "initial_routing_sync": "Optional", - "gossip_queries": "Optional", - "var_onion_optin": "Mandatory", - "gossip_queries_ex": "Optional", - "option_static_remotekey": "Mandatory", - "payment_secret": "Mandatory", - "basic_mpp": "Optional", - "option_support_large_channel": "Optional", - "option_anchor_outputs": "Mandatory", - "option_shutdown_anysegwit": "Optional", - "option_channel_type": "Mandatory", - "option_payment_metadata": "Optional", - "wake_up_notification_provider": "Optional", - "pay_to_open_provider": "Optional", - "trusted_swap_in_provider": "Optional", - "channel_backup_provider": "Optional", - "trampoline_payment_experimental": "Optional" - }, - "unknown": [ - ] - } - }, - "channelFlags": 0 - }, - "changes": { - "localChanges": { - "proposed": [ - ], - "signed": [ - ], - "acked": [ - ] - }, - "remoteChanges": { - "proposed": [ - ], - "acked": [ - ], - "signed": [ - ] - }, - "localNextHtlcId": 0, - "remoteNextHtlcId": 0 - }, - "active": [ - { - "fundingTxIndex": 0, - "remoteFundingPubkey": "02b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c", - "localFundingStatus": { - "status": "unconfirmed", - "txId": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f" - }, - "remoteFundingStatus": { - "status": "locked" - }, - "localCommit": { - "index": 0, - "spec": { - "htlcsIn": [ - ], - "htlcsOut": [ - ], - "feerate": 5000, - "toLocal": 200000000, - "toRemote": 800000000 - }, - "publishableTxs": { - "commitTx": { - "input": { - "outPoint": "bdcd274e9bc89c621b30596e344389d28c3a92f820ef5a680ebfcb615b827c2f:0", - "txOut": { - "amount": 1000000, - "publicKeyScript": "00204ba42b50e089764e60e9e0c76c57e41d252d6beb976332f14a7b255bbb5322b8" - }, - "redeemScript": "522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452ae" - }, - "tx": "020000000001012f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd000000000000b77080044a0100000000000022002046672803839d10e21d43eafb532bc37cd21bd97dec7f9b50d45380cd1cce69654a01000000000000220020bbd7f17366848d8f624c28438128ce4dc8c72ea21deb0ccf25bee110920da032400d03000000000022002031dbc67ef6930d0825de6c23bd311eb93d40430d543c0555aa0f15b7aaab0cbc781c0c0000000000220020958bb43c9e6d1b985001c2f4dc38d286d7fde78bb04d7ec5a5ae44d8ebf0c40c040047304402201991b61ae8ef7bf6bd03f6f965552294e7941fce3fc91a024094cbd9b3464dd202206068ef64671e59b5825408e58462613a6ad0edfc7aa23853aea36187298c493901483045022100cca233f9a14605a7adab49f959c5b42260a55156282cbc802397fc934d5e537c02203504b82653044526706d76d3ddf0f083ea77a16f6cc13c93add344069a55cb940147522102b6eaf304d966a6df90f3b3df7af7be6b1625854bbc096cb8b3507b2a37c2bf9c210385cfd7d8850e4cb8fcbed57310911218e5d5e1fd34f92ef5d9db14d56418caa452aede99dc20" - }, - "htlcTxsAndSigs": [ - ] - } - }, - "remoteCommit": { - "index": 0, - "spec": { - "htlcsIn": [ - ], - "htlcsOut": [ - ], - "feerate": 5000, - "toLocal": 800000000, - "toRemote": 200000000 - }, - "txid": "51487720c64eaa73a972e2e240f5fe4b1cc1c46d9a76854a11c62ab969222a29", - "remotePerCommitmentPoint": "0332dcde49bbcc222f9e793771bca07d28b08c2d6e12992ebe5398c20194f26722" - }, - "nextRemoteCommit": null - } - ], - "inactive": [ - ], - "payments": { - }, - "remoteNextCommitInfo": { - "left": null, - "right": "0234ea3e3929ca115acc645d07c40eada7a98d86017614c3fa466d7e19760917e4" - }, - "remotePerCommitmentSecrets": "" - }, - "localShutdown": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "scriptPubKey": "001434947cfb2e8f6054ddf12daed4308cbe342580d1" - }, - "remoteShutdown": { - "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", - "scriptPubKey": "51050102030405" - }, - "closingTxProposed": [ - [ - ] - ], - "bestUnpublishedClosingTx": null, - "closingFeerates": null -} \ No newline at end of file diff --git a/src/commonTest/resources/nonreg/v3/Normal_fd10d3cc/data.json b/src/commonTest/resources/nonreg/v3/Normal_fd10d3cc/data.json index 60ae64d06..86a3b9288 100644 --- a/src/commonTest/resources/nonreg/v3/Normal_fd10d3cc/data.json +++ b/src/commonTest/resources/nonreg/v3/Normal_fd10d3cc/data.json @@ -258,7 +258,7 @@ "scriptPubKey": "001405e0104aa726e34ff5cd3a6320d05c0862b5b01c" }, "remoteShutdown": null, - "closingFeerates": null, + "closingFeerate": null, "spliceStatus": "None", "liquidityLeases": [ ] diff --git a/src/commonTest/resources/nonreg/v3/Normal_fe897b64/data.json b/src/commonTest/resources/nonreg/v3/Normal_fe897b64/data.json index 4add406ad..594d9840d 100644 --- a/src/commonTest/resources/nonreg/v3/Normal_fe897b64/data.json +++ b/src/commonTest/resources/nonreg/v3/Normal_fe897b64/data.json @@ -229,7 +229,7 @@ "remoteChannelUpdate": null, "localShutdown": null, "remoteShutdown": null, - "closingFeerates": null, + "closingFeerate": null, "spliceStatus": "None", "liquidityLeases": [ ] diff --git a/src/commonTest/resources/nonreg/v3/Normal_ff248f8d/data.json b/src/commonTest/resources/nonreg/v3/Normal_ff248f8d/data.json index 4ab6752e6..232d846e4 100644 --- a/src/commonTest/resources/nonreg/v3/Normal_ff248f8d/data.json +++ b/src/commonTest/resources/nonreg/v3/Normal_ff248f8d/data.json @@ -196,7 +196,7 @@ }, "localShutdown": null, "remoteShutdown": null, - "closingFeerates": null, + "closingFeerate": null, "spliceStatus": "None", "liquidityLeases": [ ] diff --git a/src/commonTest/resources/nonreg/v3/Normal_ff4a71b6/data.json b/src/commonTest/resources/nonreg/v3/Normal_ff4a71b6/data.json index 43df4d86f..e906fb983 100644 --- a/src/commonTest/resources/nonreg/v3/Normal_ff4a71b6/data.json +++ b/src/commonTest/resources/nonreg/v3/Normal_ff4a71b6/data.json @@ -366,7 +366,7 @@ "remoteChannelUpdate": null, "localShutdown": null, "remoteShutdown": null, - "closingFeerates": null, + "closingFeerate": null, "spliceStatus": "None", "liquidityLeases": [ ] diff --git a/src/commonTest/resources/nonreg/v3/ShuttingDown_ef41a1a5/data.json b/src/commonTest/resources/nonreg/v3/ShuttingDown_ef41a1a5/data.json index 37bfaadfc..f07b90c11 100644 --- a/src/commonTest/resources/nonreg/v3/ShuttingDown_ef41a1a5/data.json +++ b/src/commonTest/resources/nonreg/v3/ShuttingDown_ef41a1a5/data.json @@ -281,5 +281,5 @@ "channelId": "2f7c825b61cbbf0e685aef20f8923a8cd28943346e59301b629cc89b4e27cdbd", "scriptPubKey": "001405e0104aa726e34ff5cd3a6320d05c0862b5b01c" }, - "closingFeerates": null + "closingFeerate": null } \ No newline at end of file diff --git a/src/commonTest/resources/nonreg/v3/ShuttingDown_ef7081a1/data.json b/src/commonTest/resources/nonreg/v3/ShuttingDown_ef7081a1/data.json index 4eccd551b..ea687b83d 100644 --- a/src/commonTest/resources/nonreg/v3/ShuttingDown_ef7081a1/data.json +++ b/src/commonTest/resources/nonreg/v3/ShuttingDown_ef7081a1/data.json @@ -273,5 +273,5 @@ ] } }, - "closingFeerates": null + "closingFeerate": null } \ No newline at end of file