Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ignore commit_sig for aborted splice #2709

Merged
merged 1 commit into from
Jul 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,9 @@ class Channel(val nodeParams: NodeParams, val wallet: OnChainChannelFunder with
case s: SpliceStatus.SpliceInProgress =>
log.debug("received their commit_sig, deferring message")
stay() using d.copy(spliceStatus = s.copy(remoteCommitSig = Some(commit)))
case SpliceStatus.SpliceAborted =>
log.warning("received commit_sig after sending tx_abort, they probably sent it before receiving our tx_abort, ignoring...")
stay()
case SpliceStatus.SpliceWaitingForSigs(signingSession) =>
signingSession.receiveCommitSig(nodeParams, d.commitments.params, commit) match {
case Left(f) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,54 @@ class NormalSplicesStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLik
awaitCond(bob.stateData.asInstanceOf[DATA_NORMAL].spliceStatus == SpliceStatus.NoSplice)
}

test("recv TxAbort (after CommitSig)") { f =>
import f._

val sender = TestProbe()
alice ! CMD_SPLICE(sender.ref, spliceIn_opt = Some(SpliceIn(50_000 sat)), spliceOut_opt = None)
alice2bob.expectMsgType[SpliceInit]
alice2bob.forward(bob)
bob2alice.expectMsgType[SpliceAck]
bob2alice.forward(alice)
alice2bob.expectMsgType[TxAddInput]
alice2bob.forward(bob)
bob2alice.expectMsgType[TxComplete]
bob2alice.forward(alice)
alice2bob.expectMsgType[TxAddInput]
alice2bob.forward(bob)
bob2alice.expectMsgType[TxComplete]
bob2alice.forward(alice)
val output1 = alice2bob.expectMsgType[TxAddOutput]
alice2bob.forward(bob)
bob2alice.expectMsgType[TxComplete]
bob2alice.forward(alice)
alice2bob.expectMsgType[TxAddOutput]
// We forward a duplicate of the first output, which will make bob abort after receiving tx_complete.
alice2bob.forward(bob, output1.copy(serialId = UInt64(100)))
bob2alice.expectMsgType[TxComplete]
bob2alice.forward(alice)
alice2bob.expectMsgType[TxComplete]
alice2bob.forward(bob)
val commitSigAlice = alice2bob.expectMsgType[CommitSig]
val txAbortBob = bob2alice.expectMsgType[TxAbort]
sender.expectMsgType[RES_SPLICE]

// Bob ignores Alice's commit_sig.
alice2bob.forward(bob, commitSigAlice)
bob2alice.expectNoMessage(100 millis)
bob2blockchain.expectNoMessage(100 millis)

// Alice acks Bob's tx_abort.
bob2alice.forward(alice, txAbortBob)
alice2bob.expectMsgType[TxAbort]
alice2bob.forward(bob)

awaitCond(alice.stateData.asInstanceOf[DATA_NORMAL].spliceStatus == SpliceStatus.NoSplice)
awaitCond(bob.stateData.asInstanceOf[DATA_NORMAL].spliceStatus == SpliceStatus.NoSplice)
assert(alice.stateData.asInstanceOf[DATA_NORMAL].commitments.active.size == 1)
assert(bob.stateData.asInstanceOf[DATA_NORMAL].commitments.active.size == 1)
}

test("recv WatchFundingConfirmedTriggered on splice tx", Tag(NoMaxHtlcValueInFlight)) { f =>
import f._

Expand Down Expand Up @@ -1370,15 +1418,23 @@ class NormalSplicesStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLik
bob.stop()

alice2blockchain.expectNoMessage(100 millis)
bob2blockchain.expectNoMessage(100 millis)

val alice2 = TestFSMRef(new Channel(aliceNodeParams, wallet, bobNodeParams.nodeId, alice2blockchain.ref, TestProbe().ref, FakeTxPublisherFactory(alice2blockchain)), alicePeer)
alice2 ! INPUT_RESTORED(aliceData)

alice2blockchain.expectMsgType[SetChannelId]
alice2blockchain.expectWatchFundingConfirmed(fundingTx2.txid)
alice2blockchain.expectWatchFundingConfirmed(fundingTx1.txid)
alice2blockchain.expectWatchFundingSpent(fundingTx0.txid)
alice2blockchain.expectNoMessage(100 millis)

val bob2 = TestFSMRef(new Channel(bobNodeParams, wallet, aliceNodeParams.nodeId, bob2blockchain.ref, TestProbe().ref, FakeTxPublisherFactory(bob2blockchain)), bobPeer)
bob2 ! INPUT_RESTORED(bobData)
bob2blockchain.expectMsgType[SetChannelId]
bob2blockchain.expectWatchFundingConfirmed(fundingTx2.txid)
bob2blockchain.expectWatchFundingConfirmed(fundingTx1.txid)
bob2blockchain.expectWatchFundingSpent(fundingTx0.txid)
bob2blockchain.expectNoMessage(100 millis)
}

test("put back watches after restart (inactive)", Tag(ChannelStateTestsTags.ZeroConf), Tag(ChannelStateTestsTags.AnchorOutputsZeroFeeHtlcTxs)) { f =>
Expand Down Expand Up @@ -1421,15 +1477,23 @@ class NormalSplicesStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLik
bob.stop()

alice2blockchain.expectNoMessage(100 millis)
bob2blockchain.expectNoMessage(100 millis)

val alice2 = TestFSMRef(new Channel(aliceNodeParams, wallet, bobNodeParams.nodeId, alice2blockchain.ref, TestProbe().ref, FakeTxPublisherFactory(alice2blockchain)), alicePeer)
alice2 ! INPUT_RESTORED(aliceData)

alice2blockchain.expectMsgType[SetChannelId]
alice2blockchain.expectWatchPublished(fundingTx2.txid)
alice2blockchain.expectWatchFundingConfirmed(fundingTx1.txid)
alice2blockchain.expectWatchFundingSpent(fundingTx0.txid)
alice2blockchain.expectNoMessage(100 millis)

val bob2 = TestFSMRef(new Channel(bobNodeParams, wallet, aliceNodeParams.nodeId, bob2blockchain.ref, TestProbe().ref, FakeTxPublisherFactory(bob2blockchain)), bobPeer)
bob2 ! INPUT_RESTORED(bobData)
bob2blockchain.expectMsgType[SetChannelId]
bob2blockchain.expectWatchPublished(fundingTx2.txid)
bob2blockchain.expectWatchFundingConfirmed(fundingTx1.txid)
bob2blockchain.expectWatchFundingSpent(fundingTx0.txid)
bob2blockchain.expectNoMessage(100 millis)
}

}