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

Make ChannelContext.process a suspend function #653

Merged
merged 1 commit into from
May 31, 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
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import fr.acinq.lightning.channel.ChannelCommand
* Channel has been aborted before it was funded (because we did not receive a FundingCreated or FundingSigned message for example)
*/
data object Aborted : ChannelState() {
override fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
override suspend fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
return Pair(this@Aborted, listOf())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ sealed class ChannelState {
* @param cmd input event (for example, a message was received, a command was sent by the GUI/API, etc)
* @return a (new state, list of actions) pair
*/
abstract fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>>
abstract suspend fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>>

fun ChannelContext.process(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
suspend fun ChannelContext.process(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
return try {
processInternal(cmd)
.let { (newState, actions) -> Pair(newState, newState.run { maybeAddBackupToMessages(actions) }) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ data class Closed(val state: Closing) : ChannelStateWithCommitments() {
return this.copy(state = state.updateCommitments(input) as Closing)
}

override fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
override suspend fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
return Pair(this@Closed, listOf())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ data class Closing(

override fun updateCommitments(input: Commitments): ChannelStateWithCommitments = this.copy(commitments = input)

override fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
override suspend fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
return when (cmd) {
is ChannelCommand.WatchReceived -> {
val watch = cmd.watch
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ data class LegacyWaitForFundingConfirmed(
) : ChannelStateWithCommitments() {
override fun updateCommitments(input: Commitments): ChannelStateWithCommitments = this.copy(commitments = input)

override fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
override suspend fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
return when (cmd) {
is ChannelCommand.MessageReceived -> when (cmd.message) {
is ChannelReady -> Pair([email protected](deferred = cmd.message), listOf())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ data class LegacyWaitForFundingLocked(
) : ChannelStateWithCommitments() {
override fun updateCommitments(input: Commitments): ChannelStateWithCommitments = this.copy(commitments = input)

override fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
override suspend fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
return when (cmd) {
is ChannelCommand.MessageReceived -> when (cmd.message) {
is ChannelReady -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ data class Negotiating(

override fun updateCommitments(input: Commitments): ChannelStateWithCommitments = this.copy(commitments = input)

override fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
override suspend fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
return when (cmd) {
is ChannelCommand.MessageReceived -> when (cmd.message) {
is ClosingSigned -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ data class Normal(

override fun updateCommitments(input: Commitments): ChannelStateWithCommitments = this.copy(commitments = input)

override fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
override suspend fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
val forbiddenPreSplice = cmd is ChannelCommand.ForbiddenDuringQuiescence && spliceStatus is QuiescenceNegotiation
val forbiddenDuringSplice = cmd is ChannelCommand.ForbiddenDuringSplice && spliceStatus is QuiescentSpliceStatus
if (forbiddenPreSplice || forbiddenDuringSplice) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ data class Offline(val state: PersistedChannelState) : ChannelState() {

val channelId = state.channelId

override fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
override suspend fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
return when (cmd) {
is ChannelCommand.Connected -> {
when (state) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ data class ShuttingDown(
) : ChannelStateWithCommitments() {
override fun updateCommitments(input: Commitments): ChannelStateWithCommitments = this.copy(commitments = input)

override fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
override suspend fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
return when (cmd) {
is ChannelCommand.MessageReceived -> {
when (cmd.message) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ data class Syncing(val state: PersistedChannelState, val channelReestablishSent:
is ChannelStateWithCommitments -> state.commitments.params.localParams.channelKeys(keyManager)
}

override fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
override suspend fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
return when (cmd) {
is ChannelCommand.MessageReceived -> when (cmd.message) {
is ChannelReestablish -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ data class WaitForAcceptChannel(
) : ChannelState() {
val temporaryChannelId: ByteVector32 get() = lastSent.temporaryChannelId

override fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
override suspend fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
return when (cmd) {
is ChannelCommand.MessageReceived -> when (cmd.message) {
is AcceptDualFundedChannel -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ data class WaitForChannelReady(
) : ChannelStateWithCommitments() {
override fun updateCommitments(input: Commitments): ChannelStateWithCommitments = this.copy(commitments = input)

override fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
override suspend fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
return when (cmd) {
is ChannelCommand.MessageReceived -> when (cmd.message) {
is TxSignatures -> when (commitments.latest.localFundingStatus) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ data class WaitForFundingConfirmed(

override fun updateCommitments(input: Commitments): ChannelStateWithCommitments = this.copy(commitments = input)

override fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
override suspend fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
return when (cmd) {
is ChannelCommand.MessageReceived -> when (cmd.message) {
is TxSignatures -> when (latestFundingTx.sharedTx) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ data class WaitForFundingCreated(
) : ChannelState() {
val channelId: ByteVector32 = interactiveTxSession.fundingParams.channelId

override fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
override suspend fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
return when (cmd) {
is ChannelCommand.MessageReceived -> when (cmd.message) {
is InteractiveTxConstructionMessage -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ data class WaitForFundingSigned(
) : PersistedChannelState() {
override val channelId: ByteVector32 = channelParams.channelId

override fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
override suspend fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
return when (cmd) {
is ChannelCommand.MessageReceived -> when (cmd.message) {
is CommitSig -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import fr.acinq.lightning.wire.OpenDualFundedChannel
import fr.acinq.lightning.wire.TlvStream

data object WaitForInit : ChannelState() {
override fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
override suspend fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
return when (cmd) {
is ChannelCommand.Init.NonInitiator -> {
val nextState = WaitForOpenChannel(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ data class WaitForOpenChannel(
val channelConfig: ChannelConfig,
val remoteInit: Init
) : ChannelState() {
override fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
override suspend fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
return when (cmd) {
is ChannelCommand.MessageReceived -> when (cmd.message) {
is OpenDualFundedChannel -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ data class WaitForRemotePublishFutureCommitment(
) : ChannelStateWithCommitments() {
override fun updateCommitments(input: Commitments): ChannelStateWithCommitments = this.copy(commitments = input)

override fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
override suspend fun ChannelContext.processInternal(cmd: ChannelCommand): Pair<ChannelState, List<ChannelAction>> {
return when {
cmd is ChannelCommand.WatchReceived && cmd.watch is WatchEventSpent && cmd.watch.event is BITCOIN_FUNDING_SPENT -> handlePotentialForceClose(cmd.watch)
cmd is ChannelCommand.Disconnected -> Pair(Offline(this@WaitForRemotePublishFutureCommitment), listOf())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import fr.acinq.lightning.channel.states.*
import fr.acinq.lightning.crypto.KeyManager
import fr.acinq.lightning.db.ChannelClosingType
import fr.acinq.lightning.json.JsonSerializers
import fr.acinq.lightning.logging.*
import fr.acinq.lightning.logging.MDCLogger
import fr.acinq.lightning.logging.mdc
import fr.acinq.lightning.payment.OutgoingPaymentPacket
import fr.acinq.lightning.router.ChannelHop
import fr.acinq.lightning.serialization.Serialization
Expand All @@ -20,6 +21,7 @@ import fr.acinq.lightning.tests.utils.testLoggerFactory
import fr.acinq.lightning.transactions.Transactions
import fr.acinq.lightning.utils.*
import fr.acinq.lightning.wire.*
import kotlinx.coroutines.runBlocking
import kotlinx.serialization.encodeToString
import kotlin.test.*

Expand Down Expand Up @@ -89,14 +91,15 @@ data class LNChannel<out S : ChannelState>(
}
}

fun process(cmd: ChannelCommand): Pair<LNChannel<ChannelState>, List<ChannelAction>> =
fun process(cmd: ChannelCommand): Pair<LNChannel<ChannelState>, List<ChannelAction>> = runBlocking {
state
.run { ctx.copy(logger = ctx.logger.copy(staticMdc = state.mdc())).process(cmd) }
.let { (newState, actions) ->
checkSerialization(actions)
JsonSerializers.json.encodeToString(newState)
LNChannel(ctx, newState) to actions
}
}

/** same as [process] but with the added assumption that we stay in the same state */
fun processSameState(event: ChannelCommand): Pair<LNChannel<S>, List<ChannelAction>> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import kotlinx.coroutines.withTimeout
import kotlin.time.Duration
import kotlin.time.Duration.Companion.seconds

/**
* This defers to kotlin's [kotlinx.coroutines.runBlocking] on all platforms except iOS which needs custom code.
*/
expect fun runSuspendBlocking(block: suspend CoroutineScope.() -> Unit)

fun runSuspendTest(timeout: Duration = 30.seconds, test: suspend CoroutineScope.() -> Unit) {
Expand Down
Loading