Skip to content

Commit

Permalink
Reject unreasonably low splice feerate (#2657)
Browse files Browse the repository at this point in the history
We let the initiator pick the feerate, but it must at least meet some
sanity requirements.
  • Loading branch information
pm47 authored May 12, 2023
1 parent 55a985a commit fa985da
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -827,9 +827,15 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
case Event(msg: SpliceInit, d: DATA_NORMAL) =>
d.spliceStatus match {
case SpliceStatus.NoSplice =>
if (d.commitments.isIdle) {
if (!d.commitments.isIdle) {
log.info("rejecting splice request: channel not idle")
stay() using d.copy(spliceStatus = SpliceStatus.SpliceAborted) sending TxAbort(d.channelId, InvalidSpliceRequest(d.channelId).getMessage)
} else if (msg.feerate < nodeParams.onChainFeeConf.feeEstimator.getMempoolMinFeeratePerKw()) {
log.info("rejecting splice request: feerate too low")
stay() using d.copy(spliceStatus = SpliceStatus.SpliceAborted) sending TxAbort(d.channelId, InvalidSpliceRequest(d.channelId).getMessage)
} else {
log.info(s"accepting splice with remote.in.amount=${msg.fundingContribution} remote.in.push=${msg.pushAmount}")
val parentCommitment = d.commitments.latest.commitment
val parentCommitment = d.commitments.latest.commitment
val spliceAck = SpliceAck(d.channelId,
fundingContribution = 0.sat, // only remote contributes to the splice
fundingPubKey = keyManager.fundingPublicKey(d.commitments.params.localParams.fundingKeyPath, parentCommitment.fundingTxIndex + 1).publicKey,
Expand Down Expand Up @@ -858,9 +864,6 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
))
txBuilder ! InteractiveTxBuilder.Start(self)
stay() using d.copy(spliceStatus = SpliceStatus.SpliceInProgress(cmd_opt = None, splice = txBuilder, remoteCommitSig = None)) sending spliceAck
} else {
log.info("rejecting splice request, channel not idle or not compatible")
stay() using d.copy(spliceStatus = SpliceStatus.SpliceAborted) sending TxAbort(d.channelId, InvalidSpliceRequest(d.channelId).getMessage)
}
case SpliceStatus.SpliceAborted =>
log.info("rejecting splice attempt: our previous tx_abort was not acked")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import akka.testkit.{TestFSMRef, TestProbe}
import fr.acinq.bitcoin.scalacompat.{ByteVector32, SatoshiLong, Transaction}
import fr.acinq.eclair._
import fr.acinq.eclair.blockchain.bitcoind.ZmqWatcher._
import fr.acinq.eclair.blockchain.fee.FeeratePerKw
import fr.acinq.eclair.channel.Helpers.Closing.{LocalClose, RemoteClose, RevokedClose}
import fr.acinq.eclair.channel.LocalFundingStatus.DualFundedUnconfirmedFundingTx
import fr.acinq.eclair.channel._
Expand Down Expand Up @@ -169,6 +170,18 @@ class NormalSplicesStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLik
sender.expectMsgType[RES_FAILURE[_, _]]
}

test("recv CMD_SPLICE (splice-in, feerate too low)") { f =>
import f._

val sender = TestProbe()
val cmd = CMD_SPLICE(sender.ref, spliceIn_opt = Some(SpliceIn(500_000 sat)), spliceOut_opt = None)
alice ! cmd
// we tweak the feerate
val spliceInit = alice2bob.expectMsgType[SpliceInit].copy(feerate = FeeratePerKw(100.sat))
alice2bob.forward(bob, spliceInit)
bob2alice.expectMsgType[TxAbort]
}

test("recv CMD_SPLICE (splice-in + splice-out)") { f =>
import f._

Expand Down

0 comments on commit fa985da

Please sign in to comment.