mirror of
https://github.com/ACINQ/eclair.git
synced 2024-11-19 01:43:22 +01:00
Add detailed error message when splice feerate is incorrect (#2920)
This can be helpful when troubleshooting cross-compatibility issues. Replaces #2911.
This commit is contained in:
parent
13d4c9f06c
commit
96d0c9a35b
@ -83,6 +83,7 @@ case class UnexpectedFundingSignatures (override val channelId: Byte
|
|||||||
case class InvalidFundingFeerate (override val channelId: ByteVector32, targetFeerate: FeeratePerKw, actualFeerate: FeeratePerKw) extends ChannelException(channelId, s"invalid funding feerate: target=$targetFeerate actual=$actualFeerate")
|
case class InvalidFundingFeerate (override val channelId: ByteVector32, targetFeerate: FeeratePerKw, actualFeerate: FeeratePerKw) extends ChannelException(channelId, s"invalid funding feerate: target=$targetFeerate actual=$actualFeerate")
|
||||||
case class InvalidFundingSignature (override val channelId: ByteVector32, txId_opt: Option[TxId]) extends ChannelException(channelId, s"invalid funding signature: txId=${txId_opt.map(_.toString()).getOrElse("n/a")}")
|
case class InvalidFundingSignature (override val channelId: ByteVector32, txId_opt: Option[TxId]) extends ChannelException(channelId, s"invalid funding signature: txId=${txId_opt.map(_.toString()).getOrElse("n/a")}")
|
||||||
case class InvalidRbfFeerate (override val channelId: ByteVector32, proposed: FeeratePerKw, expected: FeeratePerKw) extends ChannelException(channelId, s"invalid rbf attempt: the feerate must be at least $expected, you proposed $proposed")
|
case class InvalidRbfFeerate (override val channelId: ByteVector32, proposed: FeeratePerKw, expected: FeeratePerKw) extends ChannelException(channelId, s"invalid rbf attempt: the feerate must be at least $expected, you proposed $proposed")
|
||||||
|
case class InvalidSpliceFeerate (override val channelId: ByteVector32, proposed: FeeratePerKw, expected: FeeratePerKw) extends ChannelException(channelId, s"invalid splice request: the feerate must be at least $expected, you proposed $proposed")
|
||||||
case class InvalidSpliceRequest (override val channelId: ByteVector32) extends ChannelException(channelId, "invalid splice request")
|
case class InvalidSpliceRequest (override val channelId: ByteVector32) extends ChannelException(channelId, "invalid splice request")
|
||||||
case class InvalidRbfAlreadyInProgress (override val channelId: ByteVector32) extends ChannelException(channelId, "invalid rbf attempt: the current rbf attempt must be completed or aborted first")
|
case class InvalidRbfAlreadyInProgress (override val channelId: ByteVector32) extends ChannelException(channelId, "invalid rbf attempt: the current rbf attempt must be completed or aborted first")
|
||||||
case class InvalidSpliceAlreadyInProgress (override val channelId: ByteVector32) extends ChannelException(channelId, "invalid splice attempt: the current splice attempt must be completed or aborted first")
|
case class InvalidSpliceAlreadyInProgress (override val channelId: ByteVector32) extends ChannelException(channelId, "invalid splice attempt: the current splice attempt must be completed or aborted first")
|
||||||
|
@ -986,8 +986,8 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
|
|||||||
log.info("rejecting splice request: channel not quiescent")
|
log.info("rejecting splice request: channel not quiescent")
|
||||||
stay() using d.copy(spliceStatus = SpliceStatus.SpliceAborted) sending TxAbort(d.channelId, InvalidSpliceNotQuiescent(d.channelId).getMessage)
|
stay() using d.copy(spliceStatus = SpliceStatus.SpliceAborted) sending TxAbort(d.channelId, InvalidSpliceNotQuiescent(d.channelId).getMessage)
|
||||||
} else if (msg.feerate < nodeParams.currentBitcoinCoreFeerates.minimum) {
|
} else if (msg.feerate < nodeParams.currentBitcoinCoreFeerates.minimum) {
|
||||||
log.info("rejecting splice request: feerate too low")
|
log.info("rejecting splice request: feerate too low ({} < {})", msg.feerate, nodeParams.currentBitcoinCoreFeerates.minimum)
|
||||||
stay() using d.copy(spliceStatus = SpliceStatus.SpliceAborted) sending TxAbort(d.channelId, InvalidSpliceRequest(d.channelId).getMessage)
|
stay() using d.copy(spliceStatus = SpliceStatus.SpliceAborted) sending TxAbort(d.channelId, InvalidSpliceFeerate(d.channelId, msg.feerate, nodeParams.currentBitcoinCoreFeerates.minimum).getMessage)
|
||||||
} else if (d.commitments.active.count(_.fundingTxIndex == d.commitments.latest.fundingTxIndex) > 1) {
|
} else if (d.commitments.active.count(_.fundingTxIndex == d.commitments.latest.fundingTxIndex) > 1) {
|
||||||
val previousTxs = d.commitments.active.filter(_.fundingTxIndex == d.commitments.latest.fundingTxIndex).map(_.fundingTxId)
|
val previousTxs = d.commitments.active.filter(_.fundingTxIndex == d.commitments.latest.fundingTxIndex).map(_.fundingTxId)
|
||||||
log.info("rejecting splice request: the previous splice has unconfirmed rbf attempts (txIds={})", previousTxs.mkString(", "))
|
log.info("rejecting splice request: the previous splice has unconfirmed rbf attempts (txIds={})", previousTxs.mkString(", "))
|
||||||
|
@ -795,7 +795,7 @@ private class InteractiveTxBuilder(replyTo: ActorRef[InteractiveTxBuilder.Respon
|
|||||||
val nextFeerate = Transactions.fee2rate(sharedTx.fees, tx.weight())
|
val nextFeerate = Transactions.fee2rate(sharedTx.fees, tx.weight())
|
||||||
if (nextFeerate <= previousFeerate) {
|
if (nextFeerate <= previousFeerate) {
|
||||||
log.warn("invalid interactive tx: next feerate isn't greater than previous feerate (previous={}, next={})", previousFeerate, nextFeerate)
|
log.warn("invalid interactive tx: next feerate isn't greater than previous feerate (previous={}, next={})", previousFeerate, nextFeerate)
|
||||||
return Left(InvalidCompleteInteractiveTx(fundingParams.channelId))
|
return Left(InvalidRbfFeerate(fundingParams.channelId, nextFeerate, previousFeerate))
|
||||||
}
|
}
|
||||||
case None =>
|
case None =>
|
||||||
val feeWithoutWitness = Transactions.weight2fee(fundingParams.targetFeerate, tx.weight())
|
val feeWithoutWitness = Transactions.weight2fee(fundingParams.targetFeerate, tx.weight())
|
||||||
@ -811,7 +811,7 @@ private class InteractiveTxBuilder(replyTo: ActorRef[InteractiveTxBuilder.Respon
|
|||||||
}
|
}
|
||||||
if (sharedTx.fees < minimumFee) {
|
if (sharedTx.fees < minimumFee) {
|
||||||
log.warn("invalid interactive tx: below the target feerate (target={}, actual={})", fundingParams.targetFeerate, Transactions.fee2rate(sharedTx.fees, tx.weight()))
|
log.warn("invalid interactive tx: below the target feerate (target={}, actual={})", fundingParams.targetFeerate, Transactions.fee2rate(sharedTx.fees, tx.weight()))
|
||||||
return Left(InvalidCompleteInteractiveTx(fundingParams.channelId))
|
return Left(InvalidSpliceFeerate(fundingParams.channelId, Transactions.fee2rate(sharedTx.fees, tx.weight()), fundingParams.targetFeerate))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2669,7 +2669,7 @@ class InteractiveTxBuilderSpec extends TestKitBaseClass with AnyFunSuiteLike wit
|
|||||||
probe.expectMsgType[SendMessage]
|
probe.expectMsgType[SendMessage]
|
||||||
// Alice --- tx_complete --> Bob
|
// Alice --- tx_complete --> Bob
|
||||||
bob ! ReceiveMessage(TxComplete(params.channelId))
|
bob ! ReceiveMessage(TxComplete(params.channelId))
|
||||||
assert(probe.expectMsgType[RemoteFailure].cause == InvalidCompleteInteractiveTx(params.channelId))
|
assert(probe.expectMsgType[RemoteFailure].cause.isInstanceOf[InvalidSpliceFeerate])
|
||||||
}
|
}
|
||||||
|
|
||||||
test("previous attempts not double-spent") {
|
test("previous attempts not double-spent") {
|
||||||
|
Loading…
Reference in New Issue
Block a user