diff --git a/src/commonMain/kotlin/fr/acinq/lightning/channel/InteractiveTx.kt b/src/commonMain/kotlin/fr/acinq/lightning/channel/InteractiveTx.kt index 5ee837ce2..44261068e 100644 --- a/src/commonMain/kotlin/fr/acinq/lightning/channel/InteractiveTx.kt +++ b/src/commonMain/kotlin/fr/acinq/lightning/channel/InteractiveTx.kt @@ -205,7 +205,8 @@ data class FundingContributions(val inputs: List, v ): Either { walletInputs.forEach { (tx, txOutput) -> if (tx.txOut.size <= txOutput) return Either.Left(FundingContributionFailure.InputOutOfBounds(tx.txid, txOutput)) - if (tx.txOut[txOutput].amount < params.dustLimit) return Either.Left(FundingContributionFailure.InputBelowDust(tx.txid, txOutput, tx.txOut[txOutput].amount, params.dustLimit)) + val dustLimit = Transactions.dustLimit(tx.txOut[txOutput].publicKeyScript) + if (tx.txOut[txOutput].amount < dustLimit) return Either.Left(FundingContributionFailure.InputBelowDust(tx.txid, txOutput, tx.txOut[txOutput].amount, dustLimit)) if (Transaction.write(tx.stripInputWitnesses()).size > 65_000) return Either.Left(FundingContributionFailure.InputTxTooLarge(tx)) } val previousFundingAmount = sharedUtxo?.second?.fundingAmount ?: 0.sat @@ -775,11 +776,11 @@ data class InteractiveTxSigningSession( val signedLocalCommitTx = Transactions.addSigs(localCommit.value.commitTx, fundingKey.publicKey(), fundingParams.remoteFundingPubkey, localSigOfLocalTx, remoteCommitSig.signature) when (Transactions.checkSpendable(signedLocalCommitTx)) { is Try.Failure -> { - logger.info { "interactiveTxSession=$this"} - logger.info { "channelParams=$channelParams"} - logger.info { "fundingKey=${fundingKey.publicKey()}"} - logger.info { "localSigOfLocalTx=$localSigOfLocalTx"} - logger.info { "signedLocalCommitTx=$signedLocalCommitTx"} + logger.info { "interactiveTxSession=$this" } + logger.info { "channelParams=$channelParams" } + logger.info { "fundingKey=${fundingKey.publicKey()}" } + logger.info { "localSigOfLocalTx=$localSigOfLocalTx" } + logger.info { "signedLocalCommitTx=$signedLocalCommitTx" } Pair(this, InteractiveTxSigningSessionAction.AbortFundingAttempt(InvalidCommitmentSignature(fundingParams.channelId, signedLocalCommitTx.tx.txid))) } is Try.Success -> { diff --git a/src/commonMain/kotlin/fr/acinq/lightning/transactions/Transactions.kt b/src/commonMain/kotlin/fr/acinq/lightning/transactions/Transactions.kt index 72dcf951c..016d8a42b 100644 --- a/src/commonMain/kotlin/fr/acinq/lightning/transactions/Transactions.kt +++ b/src/commonMain/kotlin/fr/acinq/lightning/transactions/Transactions.kt @@ -181,6 +181,21 @@ object Transactions { */ fun fee2rate(fee: Satoshi, weight: Int): FeeratePerKw = FeeratePerKw((fee * 1000L) / weight.toLong()) + /** As defined in https://github.com/lightning/bolts/blob/master/03-transactions.md#dust-limits */ + fun dustLimit(scriptPubKey: ByteVector): Satoshi { + return runTrying { + val script = Script.parse(scriptPubKey) + when { + Script.isPay2pkh(script) -> 546.sat + Script.isPay2sh(script) -> 540.sat + Script.isPay2wpkh(script) -> 294.sat + Script.isPay2wsh(script) -> 330.sat + Script.isNativeWitnessScript(script) -> 354.sat + else -> 546.sat + } + }.getOrElse { 546.sat } + } + /** Offered HTLCs below this amount will be trimmed. */ fun offeredHtlcTrimThreshold(dustLimit: Satoshi, spec: CommitmentSpec): Satoshi = dustLimit + weight2fee(spec.feerate, Commitments.HTLC_TIMEOUT_WEIGHT) diff --git a/src/commonTest/kotlin/fr/acinq/lightning/channel/InteractiveTxTestsCommon.kt b/src/commonTest/kotlin/fr/acinq/lightning/channel/InteractiveTxTestsCommon.kt index bd04b820e..345f379d5 100644 --- a/src/commonTest/kotlin/fr/acinq/lightning/channel/InteractiveTxTestsCommon.kt +++ b/src/commonTest/kotlin/fr/acinq/lightning/channel/InteractiveTxTestsCommon.kt @@ -635,7 +635,7 @@ class InteractiveTxTestsCommon : LightningTestSuite() { val pubKey = privKey.publicKey() val fundingParams = InteractiveTxParams(randomBytes32(), true, 150_000.sat, 50_000.sat, pubKey, 0, 660.sat, FeeratePerKw(2500.sat)) run { - val previousTx = Transaction(2, listOf(), listOf(TxOut(650.sat, Script.pay2wpkh(pubKey))), 0) + val previousTx = Transaction(2, listOf(), listOf(TxOut(293.sat, Script.pay2wpkh(pubKey))), 0) val result = FundingContributions.create(channelKeys, swapInKeys, fundingParams, listOf(WalletState.Utxo(previousTx, 0, 0))).left assertNotNull(result) assertIs(result)