Skip to content

Commit

Permalink
Remove reserve check if splice contribution is positive (#2771)
Browse files Browse the repository at this point in the history
If remote has a positive contribution, we do not check their
post-splice reserve level, because they are improving their
situation, even if they stay below the requirement. Note that if
local splices-in some funds in the same operation, remote
post-splice reserve may actually be worse than before, but that's
not their fault.
  • Loading branch information
pm47 committed Nov 3, 2023
1 parent 830335f commit 35e318e
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2690,7 +2690,7 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
spliceOut = cmd.spliceOutputs,
targetFeerate = targetFeerate)
val commitTxFees = Transactions.commitTxTotalCost(d.commitments.params.remoteParams.dustLimit, parentCommitment.remoteCommit.spec, d.commitments.params.commitmentFormat)
if (parentCommitment.localCommit.spec.toLocal + fundingContribution < parentCommitment.localChannelReserve(d.commitments.params).max(commitTxFees)) {
if (fundingContribution < 0.sat && parentCommitment.localCommit.spec.toLocal + fundingContribution < parentCommitment.localChannelReserve(d.commitments.params).max(commitTxFees)) {
log.warning(s"cannot do splice: insufficient funds (commitTxFees=$commitTxFees reserve=${parentCommitment.localChannelReserve(d.commitments.params)})")
Left(InvalidSpliceRequest(d.channelId))
} else if (cmd.spliceOut_opt.map(_.scriptPubKey).exists(!MutualClose.isValidFinalScriptPubkey(_, allowAnySegwit = true))) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -660,11 +660,17 @@ private class InteractiveTxBuilder(replyTo: ActorRef[InteractiveTxBuilder.Respon
}

val sharedInput_opt = fundingParams.sharedInput_opt.map(_ => {
val remoteReserve = channelParams.remoteChannelReserveForCapacity(fundingParams.fundingAmount, isSplice = true)
// We ignore the reserve requirement if we are splicing funds into the channel, which increases the size of the reserve.
if (sharedOutput.remoteAmount < remoteReserve && remoteOutputs.nonEmpty && localInputs.isEmpty) {
log.warn("invalid interactive tx: peer takes too much funds out and falls below the channel reserve ({} < {})", sharedOutput.remoteAmount, remoteReserve)
return Left(InvalidCompleteInteractiveTx(fundingParams.channelId))
if (fundingParams.remoteContribution >= 0.sat) {
// If remote has a positive contribution, we do not check their post-splice reserve level, because they are improving
// their situation, even if they stay below the requirement. Note that if local splices-in some funds in the same
// operation, remote post-splice reserve may actually be worse than before, but that's not their fault.
} else {
// If remote removes funds from the channel, it must meet reserve requirements post-splice
val remoteReserve = channelParams.remoteChannelReserveForCapacity(fundingParams.fundingAmount, isSplice = true)
if (sharedOutput.remoteAmount < remoteReserve) {
log.warn("invalid interactive tx: peer takes too much funds out and falls below the channel reserve ({} < {})", sharedOutput.remoteAmount, remoteReserve)
return Left(InvalidCompleteInteractiveTx(fundingParams.channelId))
}
}
if (sharedInputs.length > 1) {
log.warn("invalid interactive tx: shared input included multiple times")
Expand Down

0 comments on commit 35e318e

Please sign in to comment.