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

Follow-ups to #649 and #660 #704

Merged
merged 4 commits into from
Sep 27, 2024
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
12 changes: 5 additions & 7 deletions src/commonMain/kotlin/fr/acinq/lightning/NodeEvents.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ import fr.acinq.lightning.channel.states.ChannelStateWithCommitments
import fr.acinq.lightning.channel.states.Normal
import fr.acinq.lightning.channel.states.WaitForFundingCreated
import fr.acinq.lightning.db.IncomingPayment
import fr.acinq.lightning.db.OutgoingPayment
import fr.acinq.lightning.utils.sum
import fr.acinq.lightning.wire.Init
import fr.acinq.lightning.wire.LiquidityAds

sealed interface NodeEvents

Expand All @@ -35,13 +37,8 @@ sealed interface ChannelEvents : NodeEvents {
}

sealed interface LiquidityEvents : NodeEvents {
/** Amount of liquidity purchased, before fees are paid. */
val amount: MilliSatoshi
val fee: MilliSatoshi
val source: Source

enum class Source { OnChainWallet, OffChainPayment }
data class Rejected(override val amount: MilliSatoshi, override val fee: MilliSatoshi, override val source: Source, val reason: Reason) : LiquidityEvents {
data class Rejected(val amount: MilliSatoshi, val fee: MilliSatoshi, val source: Source, val reason: Reason) : LiquidityEvents {
sealed class Reason {
data object PolicySetToDisabled : Reason()
sealed class TooExpensive : Reason() {
Expand All @@ -54,7 +51,7 @@ sealed interface LiquidityEvents : NodeEvents {
data class TooManyParts(val parts: Int) : Reason()
}
}
data class Accepted(override val amount: MilliSatoshi, override val fee: MilliSatoshi, override val source: Source) : LiquidityEvents
data class Purchased(val purchase: LiquidityAds.Purchase) : LiquidityEvents
}

/** This is useful on iOS to ask the OS for time to finish some sensitive tasks. */
Expand All @@ -77,4 +74,5 @@ sealed interface PaymentEvents : NodeEvents {
val amount: MilliSatoshi = receivedWith.map { it.amountReceived }.sum()
val fees: MilliSatoshi = receivedWith.map { it.fees }.sum()
}
data class PaymentSent(val payment: OutgoingPayment) : PaymentEvents
}
1 change: 1 addition & 0 deletions src/commonMain/kotlin/fr/acinq/lightning/NodeParams.kt
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ data class NodeParams(
Feature.ChannelBackupClient to FeatureSupport.Optional,
Feature.ExperimentalSplice to FeatureSupport.Optional,
Feature.OnTheFlyFunding to FeatureSupport.Optional,
Feature.FundingFeeCredit to FeatureSupport.Optional,
),
dustLimit = 546.sat,
maxRemoteDustLimit = 600.sat,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -913,13 +913,11 @@ data class Normal(
// and what we refunded the remote peer for some of their inputs and outputs via the lease.
val miningFees = action.fundingTx.sharedTx.tx.localFees.truncateToSatoshi() + purchase.fees.miningFee
add(ChannelAction.Storage.StoreOutgoingPayment.ViaInboundLiquidityRequest(txId = action.fundingTx.txId, miningFees = miningFees, purchase = purchase))
add(ChannelAction.EmitEvent(LiquidityEvents.Purchased(purchase)))
}
origins.filterIsInstance<Origin.OnChainWallet>().forEach { origin ->
add(ChannelAction.EmitEvent(SwapInEvents.Accepted(origin.inputs, origin.amountBeforeFees.truncateToSatoshi(), origin.fees)))
}
addAll(origins.map { origin ->
when (origin) {
is Origin.OffChainPayment -> ChannelAction.EmitEvent(LiquidityEvents.Accepted(liquidityPurchase?.amount?.toMilliSatoshi() ?: 0.msat, origin.fees.total.toMilliSatoshi(), LiquidityEvents.Source.OffChainPayment))
is Origin.OnChainWallet -> ChannelAction.EmitEvent(SwapInEvents.Accepted(origin.inputs, origin.amountBeforeFees.truncateToSatoshi(), origin.fees))
}
})
if (staticParams.useZeroConf) {
logger.info { "channel is using 0-conf, sending splice_locked right away" }
val spliceLocked = SpliceLocked(channelId, action.fundingTx.txId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,13 +136,11 @@ data class WaitForFundingSigned(
// and what we refunded the remote peer for some of their inputs and outputs via the lease.
val miningFees = action.fundingTx.sharedTx.tx.localFees.truncateToSatoshi() + purchase.fees.miningFee
add(ChannelAction.Storage.StoreOutgoingPayment.ViaInboundLiquidityRequest(txId = action.fundingTx.txId, miningFees = miningFees, purchase = purchase))
add(ChannelAction.EmitEvent(LiquidityEvents.Purchased(purchase)))
}
}
channelOrigin?.let {
when (it) {
is Origin.OffChainPayment -> add(ChannelAction.EmitEvent(LiquidityEvents.Accepted(liquidityPurchase?.amount?.toMilliSatoshi() ?: 0.msat, it.fees.total.toMilliSatoshi(), LiquidityEvents.Source.OffChainPayment)))
is Origin.OnChainWallet -> add(ChannelAction.EmitEvent(SwapInEvents.Accepted(it.inputs, it.amountBeforeFees.truncateToSatoshi(), it.fees)))
}
listOfNotNull(channelOrigin).filterIsInstance<Origin.OnChainWallet>().forEach { origin ->
add(ChannelAction.EmitEvent(SwapInEvents.Accepted(origin.inputs, origin.amountBeforeFees.truncateToSatoshi(), origin.fees)))
}
}
return if (staticParams.useZeroConf) {
Expand Down
3 changes: 2 additions & 1 deletion src/commonMain/kotlin/fr/acinq/lightning/db/PaymentsDb.kt
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,8 @@ data class InboundLiquidityOutgoingPayment(
override val confirmedAt: Long?,
override val lockedAt: Long?,
) : OnChainOutgoingPayment() {
override val fees: MilliSatoshi = (miningFees + purchase.fees.serviceFee).toMilliSatoshi()
val serviceFees: Satoshi = purchase.fees.serviceFee
override val fees: MilliSatoshi = (miningFees + serviceFees).toMilliSatoshi()
override val amount: MilliSatoshi = fees
override val completedAt: Long? = lockedAt
val fundingFee: LiquidityAds.FundingFee = LiquidityAds.FundingFee(purchase.fees.total.toMilliSatoshi(), txId)
Expand Down
1 change: 1 addition & 0 deletions src/commonMain/kotlin/fr/acinq/lightning/io/Peer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -910,6 +910,7 @@ class Peer(
)
}
}
nodeParams._nodeEvents.emit(PaymentEvents.PaymentSent(payment))
db.payments.addOutgoingPayment(payment)
}
is ChannelAction.Storage.SetLocked -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class WaitForFundingSignedTestsCommon : LightningTestSuite() {
val (alice, _, _, commitSigBob) = init(aliceFundingAmount = 0.sat, alicePushAmount = 0.msat, bobPushAmount = 50_000_000.msat, channelOrigin = channelOrigin)
val (alice1, actionsAlice1) = alice.process(ChannelCommand.MessageReceived(commitSigBob))
assertIs<WaitForFundingConfirmed>(alice1.state)
assertEquals(actionsAlice1.size, 6)
assertEquals(5, actionsAlice1.size)
actionsAlice1.hasOutgoingMessage<TxSignatures>()
actionsAlice1.has<ChannelAction.Storage.StoreState>()
actionsAlice1.find<ChannelAction.Storage.StoreIncomingPayment.ViaNewChannel>().also {
Expand All @@ -110,7 +110,6 @@ class WaitForFundingSignedTestsCommon : LightningTestSuite() {
actionsAlice1.hasWatch<WatchConfirmed>()
val events = actionsAlice1.filterIsInstance<ChannelAction.EmitEvent>().map { it.event }
assertTrue(events.any { it is ChannelEvents.Created })
assertTrue(events.any { it is LiquidityEvents.Accepted })
}

@Test
Expand Down Expand Up @@ -194,7 +193,7 @@ class WaitForFundingSignedTestsCommon : LightningTestSuite() {
assertTrue(actionsAlice1.isEmpty())
val (alice2, actionsAlice2) = alice1.process(ChannelCommand.MessageReceived(txSigsBob))
assertIs<WaitForFundingConfirmed>(alice2.state)
assertEquals(7, actionsAlice2.size)
assertEquals(8, actionsAlice2.size)
assertTrue(actionsAlice2.hasOutgoingMessage<TxSignatures>().channelData.isEmpty())
actionsAlice2.has<ChannelAction.Storage.StoreState>()
val watchConfirmedAlice = actionsAlice2.findWatch<WatchConfirmed>()
Expand Down