Skip to content
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 @@ -21,7 +21,7 @@ import fr.acinq.bitcoin.scalacompat.{ByteVector32, ByteVector64, Satoshi, Transa
import fr.acinq.eclair.blockchain.fee.FeeratePerKw
import fr.acinq.eclair.channel.{ChannelFlags, RealScidStatus, ShortIds}
import fr.acinq.eclair.crypto.Mac32
import fr.acinq.eclair.{BlockHeight, CltvExpiry, CltvExpiryDelta, UnspecifiedShortChannelId, Alias, MilliSatoshi, RealShortChannelId, ShortChannelId, TimestampSecond, UInt64, channel}
import fr.acinq.eclair.{Alias, BlockHeight, CltvExpiry, CltvExpiryDelta, MilliSatoshi, RealShortChannelId, ShortChannelId, TimestampSecond, UInt64, UnspecifiedShortChannelId}
import org.apache.commons.codec.binary.Base32
import scodec.bits.{BitVector, ByteVector}
import scodec.codecs._
Expand Down Expand Up @@ -138,8 +138,8 @@ object CommonCodecs {

val realShortChannelIdStatus: Codec[RealScidStatus] = discriminated[RealScidStatus].by(uint8)
.typecase(0, provide(RealScidStatus.Unknown))
.typecase(1, realshortchannelid.as[channel.RealScidStatus.Temporary])
.typecase(2, realshortchannelid.as[channel.RealScidStatus.Final])
.typecase(1, realshortchannelid.as[RealScidStatus.Temporary])
.typecase(2, realshortchannelid.as[RealScidStatus.Final])

val shortids: Codec[ShortIds] = (
("real" | realShortChannelIdStatus) ::
Expand Down
8 changes: 8 additions & 0 deletions eclair-core/src/test/scala/fr/acinq/eclair/TestUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@ import fr.acinq.eclair.channel.fsm.Channel
import fr.acinq.eclair.io.Peer
import fr.acinq.eclair.wire.protocol.LightningMessage
import org.scalatest.concurrent.Eventually.eventually
import org.scalatest.concurrent.PatienceConfiguration

import java.io.File
import java.net.ServerSocket
import java.nio.file.Files
import java.util.UUID
import scala.concurrent.duration.{DurationInt, FiniteDuration}

object TestUtils {

Expand Down Expand Up @@ -104,7 +106,13 @@ object TestUtils {
eventStream.publish(DummyEvent())
assert(listener.msgAvailable)
}
}

def waitFor(duration: FiniteDuration): Unit = {
val now = TimestampMilli.now()
eventually(PatienceConfiguration.Timeout(duration * 2), PatienceConfiguration.Interval(50 millis)) {
assert(TimestampMilli.now() - now > duration)
}
Comment on lines +111 to +115
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure this actually achieves something? The calling thread will still be blocked right?

Copy link
Copy Markdown
Member Author

@t-bast t-bast Jun 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No it shouldn't, this should be using a spin lock (or something equivalent) and should release the thread after each test (so that other tests can run on that thread between checks), whereas Thread.sleep blocks the thread for the whole duration for everyone.

I haven't actually verified this, but it was the behavior on .NET and the JVM is highly similar, so I expect this to be true.

Copy link
Copy Markdown
Member Author

@t-bast t-bast Jun 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the doc of eventually, it attempts the check then sleeps (I assume with Thread.sleep) for the interval duration, then rinse & repeat. So it's not as good as I hoped, but it's still better than Thread.sleep, because instead of blocking the thread for the whole duration, we block it for smaller chunks, which regularly gives the opportunity for the task scheduler to run something else on this thread.

Copy link
Copy Markdown
Member

@pm47 pm47 Jun 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but I think this saves thread time for the additional thread that executes whatever code is inside the eventually. The caller thread still has to wait. Maybe I'm completely wrong.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there is an additional thread that executes the code in the eventually, I believe that most of the time it will just be executed by the caller thread (especially since it doesn't contain a future)?

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -213,11 +213,11 @@ class RestoreSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with Chan
.modify(_.relayParams.privateChannelFees.feeBase).setTo(765 msat),
Alice.nodeParams
.modify(_.relayParams.privateChannelFees.feeProportionalMillionths).setTo(2345),
// Alice.nodeParams
// .modify(_.channelConf.expiryDelta).setTo(CltvExpiryDelta(147)),
// Alice.nodeParams
// .modify(_.relayParams.privateChannelFees.feeProportionalMillionths).setTo(2345)
// .modify(_.channelConf.expiryDelta).setTo(CltvExpiryDelta(147)),
Alice.nodeParams
.modify(_.channelConf.expiryDelta).setTo(CltvExpiryDelta(147)),
Alice.nodeParams
.modify(_.relayParams.privateChannelFees.feeProportionalMillionths).setTo(2345)
.modify(_.channelConf.expiryDelta).setTo(CltvExpiryDelta(147)),
Comment on lines +216 to +220
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops

) foreach { newConfig =>

val newAlice: TestFSMRef[ChannelState, ChannelData, Channel] = TestFSMRef(new Channel(newConfig, wallet, Bob.nodeParams.nodeId, alice2blockchain.ref, alice2relayer.ref, FakeTxPublisherFactory(alice2blockchain)), alicePeer.ref)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,17 @@ class WaitForChannelReadyStateSpec extends TestKitBaseClass with FixtureAnyFunSu
import f._
// we have a real scid at this stage, because this isn't a zero-conf channel
assert(alice.stateData.asInstanceOf[DATA_WAIT_FOR_CHANNEL_READY].shortIds.real.isInstanceOf[RealScidStatus.Temporary])
assert(bob.stateData.asInstanceOf[DATA_WAIT_FOR_CHANNEL_READY].shortIds.real.isInstanceOf[RealScidStatus.Temporary])
val channelReady = bob2alice.expectMsgType[ChannelReady]
bob2alice.forward(alice)
val initialChannelUpdate = alice.stateData.asInstanceOf[DATA_NORMAL].channelUpdate
val initialChannelUpdate = alice2bob.expectMsgType[ChannelUpdate]
assert(initialChannelUpdate == alice.stateData.asInstanceOf[DATA_NORMAL].channelUpdate)
// we have a real scid, but the channel is not announced so alice uses bob's alias
assert(initialChannelUpdate.shortChannelId == channelReady.alias_opt.get)
assert(initialChannelUpdate.feeBaseMsat == relayFees.feeBase)
assert(initialChannelUpdate.feeProportionalMillionths == relayFees.feeProportionalMillionths)
bob2alice.expectNoMessage(200 millis)
alice2blockchain.expectMsgType[WatchFundingDeeplyBuried]
bob2alice.expectNoMessage(100 millis)
awaitCond(alice.stateName == NORMAL)
}

Expand All @@ -110,34 +113,40 @@ class WaitForChannelReadyStateSpec extends TestKitBaseClass with FixtureAnyFunSu
val channelReady = bob2alice.expectMsgType[ChannelReady]
val channelReadyNoAlias = channelReady.modify(_.tlvStream.records).using(_.filterNot(_.isInstanceOf[ChannelReadyTlv.ShortChannelIdTlv]))
bob2alice.forward(alice, channelReadyNoAlias)
val initialChannelUpdate = alice.stateData.asInstanceOf[DATA_NORMAL].channelUpdate
val initialChannelUpdate = alice2bob.expectMsgType[ChannelUpdate]
assert(initialChannelUpdate == alice.stateData.asInstanceOf[DATA_NORMAL].channelUpdate)
// the channel is not announced but bob didn't send an alias so we use the real scid
assert(initialChannelUpdate.shortChannelId == realScid)
assert(initialChannelUpdate.feeBaseMsat == relayFees.feeBase)
assert(initialChannelUpdate.feeProportionalMillionths == relayFees.feeProportionalMillionths)
bob2alice.expectNoMessage(200 millis)
alice2blockchain.expectMsgType[WatchFundingDeeplyBuried]
bob2alice.expectNoMessage(100 millis)
awaitCond(alice.stateName == NORMAL)
}

test("recv ChannelReady (zero-conf)", Tag(ChannelStateTestsTags.AnchorOutputsZeroFeeHtlcTxs), Tag(ChannelStateTestsTags.ZeroConf)) { f =>
import f._
// zero-conf channel: we don't have a real scid
assert(alice.stateData.asInstanceOf[DATA_WAIT_FOR_CHANNEL_READY].shortIds.real == RealScidStatus.Unknown)
assert(bob.stateData.asInstanceOf[DATA_WAIT_FOR_CHANNEL_READY].shortIds.real == RealScidStatus.Unknown)
val channelReady = bob2alice.expectMsgType[ChannelReady]
bob2alice.forward(alice)
val initialChannelUpdate = alice.stateData.asInstanceOf[DATA_NORMAL].channelUpdate
val initialChannelUpdate = alice2bob.expectMsgType[ChannelUpdate]
assert(initialChannelUpdate == alice.stateData.asInstanceOf[DATA_NORMAL].channelUpdate)
// the channel is not announced so alice uses bob's alias (we have a no real scid anyway)
assert(initialChannelUpdate.shortChannelId == channelReady.alias_opt.get)
assert(initialChannelUpdate.feeBaseMsat == relayFees.feeBase)
assert(initialChannelUpdate.feeProportionalMillionths == relayFees.feeProportionalMillionths)
bob2alice.expectNoMessage(200 millis)
alice2blockchain.expectMsgType[WatchFundingDeeplyBuried]
bob2alice.expectNoMessage(100 millis)
awaitCond(alice.stateName == NORMAL)
}

test("recv ChannelReady (zero-conf, no alias)", Tag(ChannelStateTestsTags.AnchorOutputsZeroFeeHtlcTxs), Tag(ChannelStateTestsTags.ZeroConf)) { f =>
import f._
// zero-conf channel: we don't have a real scid
assert(alice.stateData.asInstanceOf[DATA_WAIT_FOR_CHANNEL_READY].shortIds.real == RealScidStatus.Unknown)
assert(bob.stateData.asInstanceOf[DATA_WAIT_FOR_CHANNEL_READY].shortIds.real == RealScidStatus.Unknown)
val channelReady = bob2alice.expectMsgType[ChannelReady]
val channelReadyNoAlias = channelReady.modify(_.tlvStream.records).using(_.filterNot(_.isInstanceOf[ChannelReadyTlv.ShortChannelIdTlv]))
bob2alice.forward(alice, channelReadyNoAlias)
Expand All @@ -153,29 +162,36 @@ class WaitForChannelReadyStateSpec extends TestKitBaseClass with FixtureAnyFunSu
// we have a real scid at this stage, because this isn't a zero-conf channel
assert(alice.stateData.asInstanceOf[DATA_WAIT_FOR_CHANNEL_READY].shortIds.real.isInstanceOf[RealScidStatus.Temporary])
assert(alice.stateData.asInstanceOf[DATA_WAIT_FOR_CHANNEL_READY].commitments.channelFlags.announceChannel)
assert(bob.stateData.asInstanceOf[DATA_WAIT_FOR_CHANNEL_READY].shortIds.real.isInstanceOf[RealScidStatus.Temporary])
assert(bob.stateData.asInstanceOf[DATA_WAIT_FOR_CHANNEL_READY].commitments.channelFlags.announceChannel)
val channelReady = bob2alice.expectMsgType[ChannelReady]
bob2alice.forward(alice)
val initialChannelUpdate = alice.stateData.asInstanceOf[DATA_NORMAL].channelUpdate
val initialChannelUpdate = alice2bob.expectMsgType[ChannelUpdate]
assert(initialChannelUpdate == alice.stateData.asInstanceOf[DATA_NORMAL].channelUpdate)
// we have a real scid, but it is not the final one (less than 6 confirmations) so alice uses bob's alias
assert(initialChannelUpdate.shortChannelId == channelReady.alias_opt.get)
assert(initialChannelUpdate.feeBaseMsat == relayFees.feeBase)
assert(initialChannelUpdate.feeProportionalMillionths == relayFees.feeProportionalMillionths)
bob2alice.expectNoMessage(200 millis)
alice2blockchain.expectMsgType[WatchFundingDeeplyBuried]
bob2alice.expectNoMessage(100 millis)
awaitCond(alice.stateName == NORMAL)
}

test("recv ChannelReady (public, zero-conf)", Tag(ChannelStateTestsTags.ChannelsPublic), Tag(ChannelStateTestsTags.AnchorOutputsZeroFeeHtlcTxs), Tag(ChannelStateTestsTags.ZeroConf)) { f =>
import f._
// zero-conf channel: we don't have a real scid
assert(alice.stateData.asInstanceOf[DATA_WAIT_FOR_CHANNEL_READY].shortIds.real == RealScidStatus.Unknown)
assert(bob.stateData.asInstanceOf[DATA_WAIT_FOR_CHANNEL_READY].shortIds.real == RealScidStatus.Unknown)
val channelReady = bob2alice.expectMsgType[ChannelReady]
bob2alice.forward(alice)
val initialChannelUpdate = alice.stateData.asInstanceOf[DATA_NORMAL].channelUpdate
val initialChannelUpdate = alice2bob.expectMsgType[ChannelUpdate]
assert(initialChannelUpdate == alice.stateData.asInstanceOf[DATA_NORMAL].channelUpdate)
// the channel is not announced, so alice uses bob's alias (we have a no real scid anyway)
assert(initialChannelUpdate.shortChannelId == channelReady.alias_opt.get)
assert(initialChannelUpdate.feeBaseMsat == relayFees.feeBase)
assert(initialChannelUpdate.feeProportionalMillionths == relayFees.feeProportionalMillionths)
bob2alice.expectNoMessage(200 millis)
alice2blockchain.expectMsgType[WatchFundingDeeplyBuried]
bob2alice.expectNoMessage(100 millis)
awaitCond(alice.stateName == NORMAL)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3403,23 +3403,25 @@ class NormalStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with
test("recv WatchFundingDeeplyBuriedTriggered (public channel)", Tag(ChannelStateTestsTags.ChannelsPublic)) { f =>
import f._
val realShortChannelId = alice.stateData.asInstanceOf[DATA_NORMAL].shortIds.real.asInstanceOf[RealScidStatus.Temporary].realScid
val bobAlias = bob.stateData.asInstanceOf[DATA_NORMAL].shortIds.localAlias
// existing funding tx coordinates
val TxCoordinates(blockHeight, txIndex, _) = ShortChannelId.coordinates(realShortChannelId)
alice ! WatchFundingDeeplyBuriedTriggered(blockHeight, txIndex, null)
val annSigs = alice2bob.expectMsgType[AnnouncementSignatures]
assert(annSigs.shortChannelId == realShortChannelId)
// alice updates her internal state
awaitCond(alice.stateData.asInstanceOf[DATA_NORMAL].shortIds.real == RealScidStatus.Final(realShortChannelId))
// public channel: we prefer the real scid alias and it hasn't changed, so we don't send a new channel_update
alice2bob.expectNoMessage(1 second)
// we don't re-publish the same channel_update if there was no change
channelUpdateListener.expectNoMessage(1 second)
// public channel: alice will update the channel update to use the real scid when she receives her peer's announcement_signatures
alice2bob.expectNoMessage(100 millis)
channelUpdateListener.expectNoMessage(100 millis)
assert(alice.stateData.asInstanceOf[DATA_NORMAL].channelUpdate.shortChannelId == bobAlias)
}

test("recv WatchFundingDeeplyBuriedTriggered (public channel, zero-conf)", Tag(ChannelStateTestsTags.ChannelsPublic), Tag(ChannelStateTestsTags.AnchorOutputsZeroFeeHtlcTxs), Tag(ChannelStateTestsTags.ZeroConf)) { f =>
import f._
// in zero-conf channel we don't have a real short channel id when going to NORMAL state
assert(alice.stateData.asInstanceOf[DATA_NORMAL].shortIds.real == RealScidStatus.Unknown)
val bobAlias = bob.stateData.asInstanceOf[DATA_NORMAL].shortIds.localAlias
// funding tx coordinates (unknown before)
val (blockHeight, txIndex) = (BlockHeight(400000), 42)
alice ! WatchFundingDeeplyBuriedTriggered(blockHeight, txIndex, null)
Expand All @@ -3428,13 +3430,16 @@ class NormalStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with
assert(annSigs.shortChannelId == realShortChannelId)
// alice updates her internal state
awaitCond(alice.stateData.asInstanceOf[DATA_NORMAL].shortIds.real == RealScidStatus.Final(realShortChannelId))
// we don't send out a new channel_update with the real scid just yet, we wait for the peer's announcement_signatures
channelUpdateListener.expectNoMessage(1 second)
// public channel: alice will update the channel update to use the real scid when she receives her peer's announcement_signatures
alice2bob.expectNoMessage(100 millis)
channelUpdateListener.expectNoMessage(100 millis)
assert(alice.stateData.asInstanceOf[DATA_NORMAL].channelUpdate.shortChannelId == bobAlias)
}

test("recv WatchFundingDeeplyBuriedTriggered (public channel, short channel id changed)", Tag(ChannelStateTestsTags.ChannelsPublic)) { f =>
import f._
val realShortChannelId = alice.stateData.asInstanceOf[DATA_NORMAL].shortIds.real.asInstanceOf[RealScidStatus.Temporary].realScid
val bobAlias = bob.stateData.asInstanceOf[DATA_NORMAL].shortIds.localAlias
// existing funding tx coordinates
val TxCoordinates(blockHeight, txIndex, _) = ShortChannelId.coordinates(realShortChannelId)
// new funding tx coordinates (there was a reorg)
Expand All @@ -3445,22 +3450,25 @@ class NormalStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with
assert(annSigs.shortChannelId == newRealShortChannelId)
// update data with real short channel id
awaitCond(alice.stateData.asInstanceOf[DATA_NORMAL].shortIds.real == RealScidStatus.Final(newRealShortChannelId))
// we don't send out a new channel_update with the real scid just yet, we wait for the peer's announcement_signatures
channelUpdateListener.expectNoMessage(1 second)
// public channel: alice will update the channel update to use the real scid when she receives her peer's announcement_signatures
alice2bob.expectNoMessage(100 millis)
channelUpdateListener.expectNoMessage(100 millis)
assert(alice.stateData.asInstanceOf[DATA_NORMAL].channelUpdate.shortChannelId == bobAlias)
}

test("recv WatchFundingDeeplyBuriedTriggered (private channel)") { f =>
import f._
val realShortChannelId = alice.stateData.asInstanceOf[DATA_NORMAL].shortIds.real.asInstanceOf[RealScidStatus.Temporary].realScid
val bobAlias = bob.stateData.asInstanceOf[DATA_NORMAL].shortIds.localAlias
// existing funding tx coordinates
val TxCoordinates(blockHeight, txIndex, _) = ShortChannelId.coordinates(realShortChannelId)
alice ! WatchFundingDeeplyBuriedTriggered(blockHeight, txIndex, null)
// update data with real short channel id
awaitCond(alice.stateData.asInstanceOf[DATA_NORMAL].shortIds.real == RealScidStatus.Final(realShortChannelId))
// private channel: we prefer the remote alias, so there is no change in the channel_update, and we don't send a new one
alice2bob.expectNoMessage()
// we don't re-publish the same channel_update if there was no change
channelUpdateListener.expectNoMessage(1 second)
alice2bob.expectNoMessage(100 millis)
channelUpdateListener.expectNoMessage(100 millis)
assert(alice.stateData.asInstanceOf[DATA_NORMAL].channelUpdate.shortChannelId == bobAlias)
}

test("recv WatchFundingDeeplyBuriedTriggered (private channel, zero-conf)", Tag(ChannelStateTestsTags.AnchorOutputsZeroFeeHtlcTxs), Tag(ChannelStateTestsTags.ZeroConf)) { f =>
Expand All @@ -3470,21 +3478,23 @@ class NormalStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with
alice.underlying.system.eventStream.subscribe(listener.ref, classOf[TransactionConfirmed])
// zero-conf channel: the funding tx isn't confirmed
assert(alice.stateData.asInstanceOf[DATA_NORMAL].shortIds.real == RealScidStatus.Unknown)
val bobAlias = bob.stateData.asInstanceOf[DATA_NORMAL].shortIds.localAlias
alice ! WatchFundingDeeplyBuriedTriggered(BlockHeight(42000), 42, null)
val realShortChannelId = RealShortChannelId(BlockHeight(42000), 42, 0)
// update data with real short channel id
awaitCond(alice.stateData.asInstanceOf[DATA_NORMAL].shortIds.real == RealScidStatus.Final(realShortChannelId))
// private channel: we prefer the remote alias, so there is no change in the channel_update, and we don't send a new one
alice2bob.expectNoMessage()
alice2bob.expectNoMessage(100 millis)
channelUpdateListener.expectNoMessage(100 millis)
assert(alice.stateData.asInstanceOf[DATA_NORMAL].channelUpdate.shortChannelId == bobAlias)
// this is the first time we know the funding tx has been confirmed
listener.expectMsgType[TransactionConfirmed]
// we don't re-publish the same channel_update if there was no change
channelUpdateListener.expectNoMessage(1 second)
}

test("recv WatchFundingDeeplyBuriedTriggered (private channel, short channel id changed)") { f =>
import f._
val realShortChannelId = alice.stateData.asInstanceOf[DATA_NORMAL].shortIds.real.asInstanceOf[RealScidStatus.Temporary].realScid
val bobAlias = bob.stateData.asInstanceOf[DATA_NORMAL].shortIds.localAlias
// existing funding tx coordinates
val TxCoordinates(blockHeight, txIndex, _) = ShortChannelId.coordinates(realShortChannelId)
// new funding tx coordinates (there was a reorg)
Expand All @@ -3494,9 +3504,9 @@ class NormalStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with
// update data with real short channel id
awaitCond(alice.stateData.asInstanceOf[DATA_NORMAL].shortIds.real == RealScidStatus.Final(newRealShortChannelId))
// private channel: we prefer the remote alias, so there is no change in the channel_update, and we don't send a new one
alice2bob.expectNoMessage()
// we don't re-publish the same channel_update if there was no change
channelUpdateListener.expectNoMessage(1 second)
alice2bob.expectNoMessage(100 millis)
channelUpdateListener.expectNoMessage(100 millis)
assert(alice.stateData.asInstanceOf[DATA_NORMAL].channelUpdate.shortChannelId == bobAlias)
}

test("recv AnnouncementSignatures", Tag(ChannelStateTestsTags.ChannelsPublic)) { f =>
Expand All @@ -3513,7 +3523,7 @@ class NormalStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with
import initialState.commitments.{localParams, remoteParams}
val channelAnn = Announcements.makeChannelAnnouncement(Alice.nodeParams.chainHash, annSigsA.shortChannelId, Alice.nodeParams.nodeId, remoteParams.nodeId, Alice.channelKeyManager.fundingPublicKey(localParams.fundingKeyPath).publicKey, remoteParams.fundingPubKey, annSigsA.nodeSignature, annSigsB.nodeSignature, annSigsA.bitcoinSignature, annSigsB.bitcoinSignature)
// actual test starts here
bob2alice.forward(alice)
bob2alice.forward(alice, annSigsB)
Comment thread
pm47 marked this conversation as resolved.
awaitAssert {
val normal = alice.stateData.asInstanceOf[DATA_NORMAL]
assert(normal.shortIds.real == RealScidStatus.Final(annSigsA.shortChannelId) && normal.channelAnnouncement.contains(channelAnn) && normal.channelUpdate.shortChannelId == annSigsA.shortChannelId)
Expand Down
Loading