Skip to content

Commit 597f027

Browse files
authored
Store HTLC info in shutdown state (#226)
We need to keep track of pending HTLCs before we go to the negotiating phase.
1 parent 758e43a commit 597f027

File tree

2 files changed

+26
-4
lines changed

2 files changed

+26
-4
lines changed

src/commonMain/kotlin/fr/acinq/eclair/channel/Channel.kt

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1786,7 +1786,7 @@ data class Normal(
17861786
logger.info { "c:$channelId adding paymentHash=${it.paymentHash} cltvExpiry=${it.cltvExpiry} to htlcs db for commitNumber=$nextCommitNumber" }
17871787
ChannelAction.Storage.HtlcInfo(channelId, nextCommitNumber, it.paymentHash, it.cltvExpiry)
17881788
}
1789-
val nextState = this.copy(commitments = result.value.first)
1789+
val nextState = this.copy(commitments = commitments1)
17901790
val actions = listOf(
17911791
ChannelAction.Storage.StoreHtlcInfos(htlcInfos),
17921792
ChannelAction.Storage.StoreState(nextState),
@@ -2195,8 +2195,21 @@ data class ShuttingDown(
21952195
is Either.Left -> handleCommandError(event.command, result.value)
21962196
is Either.Right -> {
21972197
val commitments1 = result.value.first
2198+
val nextRemoteCommit = commitments1.remoteNextCommitInfo.left!!.nextRemoteCommit
2199+
val nextCommitNumber = nextRemoteCommit.index
2200+
// we persist htlc data in order to be able to claim htlc outputs in case a revoked tx is published by our
2201+
// counterparty, so only htlcs above remote's dust_limit matter
2202+
val trimmedHtlcs = Transactions.trimOfferedHtlcs(commitments.remoteParams.dustLimit, nextRemoteCommit.spec) + Transactions.trimReceivedHtlcs(commitments.remoteParams.dustLimit, nextRemoteCommit.spec)
2203+
val htlcInfos = trimmedHtlcs.map { it.add }.map {
2204+
logger.info { "c:$channelId adding paymentHash=${it.paymentHash} cltvExpiry=${it.cltvExpiry} to htlcs db for commitNumber=$nextCommitNumber" }
2205+
ChannelAction.Storage.HtlcInfo(channelId, nextCommitNumber, it.paymentHash, it.cltvExpiry)
2206+
}
21982207
val nextState = this.copy(commitments = commitments1)
2199-
val actions = listOf(ChannelAction.Storage.StoreState(nextState), ChannelAction.Message.Send(result.value.second))
2208+
val actions = listOf(
2209+
ChannelAction.Storage.StoreHtlcInfos(htlcInfos),
2210+
ChannelAction.Storage.StoreState(nextState),
2211+
ChannelAction.Message.Send(result.value.second)
2212+
)
22002213
Pair(nextState, actions)
22012214
}
22022215
}

src/commonTest/kotlin/fr/acinq/eclair/channel/states/ShutdownTestsCommon.kt

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package fr.acinq.eclair.channel.states
22

33
import fr.acinq.bitcoin.*
4+
import fr.acinq.bitcoin.Crypto.sha256
45
import fr.acinq.eclair.CltvExpiry
56
import fr.acinq.eclair.Eclair.randomBytes32
67
import fr.acinq.eclair.Eclair.randomKey
@@ -21,6 +22,7 @@ import fr.acinq.eclair.tests.utils.EclairTestSuite
2122
import fr.acinq.eclair.utils.Either
2223
import fr.acinq.eclair.utils.UUID
2324
import fr.acinq.eclair.utils.msat
25+
import fr.acinq.eclair.utils.toByteVector32
2426
import fr.acinq.eclair.wire.*
2527
import kotlin.test.*
2628

@@ -186,8 +188,15 @@ class ShutdownTestsCommon : EclairTestSuite() {
186188
val fulfill = actions1.findOutgoingMessage<UpdateFulfillHtlc>()
187189
val (alice1, _) = alice.processEx(ChannelEvent.MessageReceived(fulfill))
188190
val (_, alice2) = signAndRevack(bob1, alice1)
189-
val (alice3, _) = alice2.processEx(ChannelEvent.ExecuteCommand(CMD_SIGN))
190-
assertTrue { alice3 is ShuttingDown && alice3.commitments.remoteNextCommitInfo.isLeft }
191+
val (alice3, actions3) = alice2.processEx(ChannelEvent.ExecuteCommand(CMD_SIGN))
192+
assertTrue(alice3 is ShuttingDown)
193+
assertTrue(alice3.commitments.remoteNextCommitInfo.isLeft)
194+
actions3.hasOutgoingMessage<CommitSig>()
195+
actions3.has<ChannelAction.Storage.StoreState>()
196+
// we still have 1 HTLC in the commit tx
197+
val htlcInfos = actions3.find<ChannelAction.Storage.StoreHtlcInfos>()
198+
assertEquals(htlcInfos.htlcs.size, 1)
199+
assertEquals(htlcInfos.htlcs.first().paymentHash, r2.sha256())
191200
}
192201

193202
@Test

0 commit comments

Comments
 (0)