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

Improve channel state tests #1709

Merged
merged 4 commits into from
Feb 26, 2021
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 @@ -98,29 +98,37 @@ trait StateTestsHelperMethods extends TestKitBase {
}

def reachNormal(setup: SetupFixture, tags: Set[String] = Set.empty): Unit = {
import com.softwaremill.quicklens._
import setup._
val channelVersion = List(
ChannelVersion.STANDARD,
if (tags.contains(StateTestsTags.AnchorOutputs)) ChannelVersion.ANCHOR_OUTPUTS else ChannelVersion.ZEROES,
if (tags.contains(StateTestsTags.StaticRemoteKey)) ChannelVersion.STATIC_REMOTEKEY else ChannelVersion.ZEROES,
).reduce(_ | _)
pm47 marked this conversation as resolved.
Show resolved Hide resolved

val channelFlags = if (tags.contains(StateTestsTags.ChannelsPublic)) ChannelFlags.AnnounceChannel else ChannelFlags.Empty
val pushMsat = if (tags.contains(StateTestsTags.NoPushMsat)) 0.msat else TestConstants.pushMsat
val (aliceParams, bobParams, channelVersion) = if (tags.contains(StateTestsTags.AnchorOutputs)) {
val features = Features(Set(ActivatedFeature(Features.StaticRemoteKey, FeatureSupport.Mandatory), ActivatedFeature(Features.AnchorOutputs, FeatureSupport.Optional)))
(Alice.channelParams.copy(features = features), Bob.channelParams.copy(features = features), ChannelVersion.ANCHOR_OUTPUTS)
} else if (tags.contains(StateTestsTags.StaticRemoteKey)) {
val features = Features(Set(ActivatedFeature(Features.StaticRemoteKey, FeatureSupport.Optional)))
val aliceParams = Alice.channelParams.copy(features = features, walletStaticPaymentBasepoint = Some(Helpers.getWalletPaymentBasepoint(wallet)))
val bobParams = Bob.channelParams.copy(features = features, walletStaticPaymentBasepoint = Some(Helpers.getWalletPaymentBasepoint(wallet)))
(aliceParams, bobParams, ChannelVersion.STATIC_REMOTEKEY)
} else {
(Alice.channelParams, Bob.channelParams, ChannelVersion.STANDARD)
}
val aliceParams = Alice.channelParams
.modify(_.features.activated).usingIf(channelVersion.hasStaticRemotekey)(_ ++ Set(ActivatedFeature(Features.StaticRemoteKey, FeatureSupport.Optional)))
.modify(_.features.activated).usingIf(channelVersion.hasAnchorOutputs)(_ ++ Set(ActivatedFeature(Features.StaticRemoteKey, FeatureSupport.Mandatory), ActivatedFeature(Features.AnchorOutputs, FeatureSupport.Optional)))
.modify(_.walletStaticPaymentBasepoint).setToIf(channelVersion.paysDirectlyToWallet)(Some(Helpers.getWalletPaymentBasepoint(wallet)))
val bobParams = Bob.channelParams
.modify(_.features.activated).usingIf(channelVersion.hasStaticRemotekey)(_ ++ Set(ActivatedFeature(Features.StaticRemoteKey, FeatureSupport.Optional)))
.modify(_.features.activated).usingIf(channelVersion.hasAnchorOutputs)(_ ++ Set(ActivatedFeature(Features.StaticRemoteKey, FeatureSupport.Mandatory), ActivatedFeature(Features.AnchorOutputs, FeatureSupport.Optional)))
.modify(_.walletStaticPaymentBasepoint).setToIf(channelVersion.paysDirectlyToWallet)(Some(Helpers.getWalletPaymentBasepoint(wallet)))
val initialFeeratePerKw = if (tags.contains(StateTestsTags.AnchorOutputs)) {
FeeEstimator.AnchorOutputMaxCommitFeerate
} else {
TestConstants.feeratePerKw
}
val (fundingSatoshis, pushMsat) = if (tags.contains(StateTestsTags.NoPushMsat)) {
(TestConstants.fundingSatoshis, 0.msat)
} else {
(TestConstants.fundingSatoshis, TestConstants.pushMsat)
}

val aliceInit = Init(aliceParams.features)
val bobInit = Init(bobParams.features)
alice ! INPUT_INIT_FUNDER(ByteVector32.Zeroes, TestConstants.fundingSatoshis, pushMsat, initialFeeratePerKw, TestConstants.feeratePerKw, None, aliceParams, alice2bob.ref, bobInit, channelFlags, channelVersion)
alice ! INPUT_INIT_FUNDER(ByteVector32.Zeroes, fundingSatoshis, pushMsat, initialFeeratePerKw, TestConstants.feeratePerKw, None, aliceParams, alice2bob.ref, bobInit, channelFlags, channelVersion)
bob ! INPUT_INIT_FUNDEE(ByteVector32.Zeroes, bobParams, bob2alice.ref, aliceInit, channelVersion)
alice2bob.expectMsgType[OpenChannel]
alice2bob.forward(bob)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,16 @@ package fr.acinq.eclair.channel.states.b

import akka.actor.ActorRef
import akka.testkit.{TestFSMRef, TestProbe}
import fr.acinq.bitcoin.{ByteVector32, SatoshiLong}
import fr.acinq.bitcoin.{Btc, ByteVector32, SatoshiLong}
import fr.acinq.eclair.FeatureSupport.Optional
import fr.acinq.eclair.Features.Wumbo
import fr.acinq.eclair.TestConstants.{Alice, Bob}
import fr.acinq.eclair.blockchain._
import fr.acinq.eclair.channel._
import fr.acinq.eclair.channel.states.StateTestsBase
import fr.acinq.eclair.transactions.Transactions
import fr.acinq.eclair.wire._
import fr.acinq.eclair.{TestConstants, TestKitBaseClass, ToMilliSatoshiConversion}
import fr.acinq.eclair.{ActivatedFeature, Features, TestConstants, TestKitBaseClass, ToMilliSatoshiConversion}
import org.scalatest.funsuite.FixtureAnyFunSuiteLike
import org.scalatest.{Outcome, Tag}

Expand All @@ -40,18 +42,32 @@ class WaitForFundingCreatedStateSpec extends TestKitBaseClass with FixtureAnyFun
case class FixtureParam(bob: TestFSMRef[State, Data, Channel], alice2bob: TestProbe, bob2alice: TestProbe, bob2blockchain: TestProbe)

override def withFixture(test: OneArgTest): Outcome = {
val setup = init()
import setup._
import com.softwaremill.quicklens._
val aliceNodeParams = Alice.nodeParams
.modify(_.maxFundingSatoshis).setToIf(test.tags.contains("wumbo"))(Btc(100))
val aliceParams = Alice.channelParams
.modify(_.features).setToIf(test.tags.contains("wumbo"))(Features(Set(ActivatedFeature(Wumbo, Optional))))
val bobNodeParams = Bob.nodeParams
.modify(_.maxFundingSatoshis).setToIf(test.tags.contains("wumbo"))(Btc(100))
val bobParams = Bob.channelParams
.modify(_.features).setToIf(test.tags.contains("wumbo"))(Features(Set(ActivatedFeature(Wumbo, Optional))))

val (fundingSatoshis, pushMsat) = if (test.tags.contains("funder_below_reserve")) {
(1000100 sat, (1000000 sat).toMilliSatoshi) // toLocal = 100 satoshis
} else if (test.tags.contains("wumbo")) {
(Btc(5).toSatoshi, TestConstants.pushMsat)
} else {
(TestConstants.fundingSatoshis, TestConstants.pushMsat)
}
val aliceInit = Init(Alice.channelParams.features)
val bobInit = Init(Bob.channelParams.features)

val setup = init(aliceNodeParams, bobNodeParams)

import setup._
val aliceInit = Init(aliceParams.features)
val bobInit = Init(bobParams.features)
within(30 seconds) {
alice ! INPUT_INIT_FUNDER(ByteVector32.Zeroes, fundingSatoshis, pushMsat, TestConstants.feeratePerKw, TestConstants.feeratePerKw, None, Alice.channelParams, alice2bob.ref, bobInit, ChannelFlags.Empty, ChannelVersion.STANDARD)
bob ! INPUT_INIT_FUNDEE(ByteVector32.Zeroes, Bob.channelParams, bob2alice.ref, aliceInit, ChannelVersion.STANDARD)
alice ! INPUT_INIT_FUNDER(ByteVector32.Zeroes, fundingSatoshis, pushMsat, TestConstants.feeratePerKw, TestConstants.feeratePerKw, None, aliceParams, alice2bob.ref, bobInit, ChannelFlags.Empty, ChannelVersion.STANDARD)
bob ! INPUT_INIT_FUNDEE(ByteVector32.Zeroes, bobParams, bob2alice.ref, aliceInit, ChannelVersion.STANDARD)
alice2bob.expectMsgType[OpenChannel]
alice2bob.forward(bob)
bob2alice.expectMsgType[AcceptChannel]
Expand All @@ -68,7 +84,20 @@ class WaitForFundingCreatedStateSpec extends TestKitBaseClass with FixtureAnyFun
awaitCond(bob.stateName == WAIT_FOR_FUNDING_CONFIRMED)
bob2alice.expectMsgType[FundingSigned]
bob2blockchain.expectMsgType[WatchSpent]
bob2blockchain.expectMsgType[WatchConfirmed]
val watchConfirmed = bob2blockchain.expectMsgType[WatchConfirmed]
assert(watchConfirmed.minDepth === Alice.nodeParams.minDepthBlocks)
}

test("recv FundingCreated (wumbo)", Tag("wumbo")) { f =>
import f._
alice2bob.expectMsgType[FundingCreated]
alice2bob.forward(bob)
awaitCond(bob.stateName == WAIT_FOR_FUNDING_CONFIRMED)
bob2alice.expectMsgType[FundingSigned]
bob2blockchain.expectMsgType[WatchSpent]
val watchConfirmed = bob2blockchain.expectMsgType[WatchConfirmed]
// when we are fundee, we use a higher min depth for wumbo channels
assert(watchConfirmed.minDepth > Bob.nodeParams.minDepthBlocks)
}

test("recv FundingCreated (funder can't pay fees)", Tag("funder_below_reserve")) { f =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,17 @@
package fr.acinq.eclair.channel.states.b

import akka.testkit.{TestFSMRef, TestProbe}
import fr.acinq.bitcoin.{ByteVector32, ByteVector64}
import fr.acinq.bitcoin.{Btc, ByteVector32, ByteVector64}
import fr.acinq.eclair.FeatureSupport.Optional
import fr.acinq.eclair.Features.Wumbo
import fr.acinq.eclair.TestConstants.{Alice, Bob}
import fr.acinq.eclair.blockchain._
import fr.acinq.eclair.channel.Channel.TickChannelOpenTimeout
import fr.acinq.eclair.channel._
import fr.acinq.eclair.channel.states.StateTestsBase
import fr.acinq.eclair.wire.{AcceptChannel, Error, FundingCreated, FundingSigned, Init, OpenChannel}
import fr.acinq.eclair.{TestConstants, TestKitBaseClass}
import org.scalatest.Outcome
import fr.acinq.eclair.{ActivatedFeature, Features, TestConstants, TestKitBaseClass}
import org.scalatest.{Outcome, Tag}
import org.scalatest.funsuite.FixtureAnyFunSuiteLike

import scala.concurrent.duration._
Expand All @@ -39,13 +41,30 @@ class WaitForFundingSignedStateSpec extends TestKitBaseClass with FixtureAnyFunS
case class FixtureParam(alice: TestFSMRef[State, Data, Channel], alice2bob: TestProbe, bob2alice: TestProbe, alice2blockchain: TestProbe)

override def withFixture(test: OneArgTest): Outcome = {
val setup = init()
import com.softwaremill.quicklens._
val aliceNodeParams = Alice.nodeParams
.modify(_.maxFundingSatoshis).setToIf(test.tags.contains("wumbo"))(Btc(100))
val aliceParams = Alice.channelParams
.modify(_.features).setToIf(test.tags.contains("wumbo"))(Features(Set(ActivatedFeature(Wumbo, Optional))))
val bobNodeParams = Bob.nodeParams
.modify(_.maxFundingSatoshis).setToIf(test.tags.contains("wumbo"))(Btc(100))
val bobParams = Bob.channelParams
.modify(_.features).setToIf(test.tags.contains("wumbo"))(Features(Set(ActivatedFeature(Wumbo, Optional))))

val (fundingSatoshis, pushMsat) = if (test.tags.contains("wumbo")) {
(Btc(5).toSatoshi, TestConstants.pushMsat)
} else {
(TestConstants.fundingSatoshis, TestConstants.pushMsat)
}

val setup = init(aliceNodeParams, bobNodeParams)

import setup._
val aliceInit = Init(Alice.channelParams.features)
val bobInit = Init(Bob.channelParams.features)
val aliceInit = Init(aliceParams.features)
val bobInit = Init(bobParams.features)
within(30 seconds) {
alice ! INPUT_INIT_FUNDER(ByteVector32.Zeroes, TestConstants.fundingSatoshis, TestConstants.pushMsat, TestConstants.feeratePerKw, TestConstants.feeratePerKw, None, Alice.channelParams, alice2bob.ref, bobInit, ChannelFlags.Empty, ChannelVersion.STANDARD)
bob ! INPUT_INIT_FUNDEE(ByteVector32.Zeroes, Bob.channelParams, bob2alice.ref, aliceInit, ChannelVersion.STANDARD)
alice ! INPUT_INIT_FUNDER(ByteVector32.Zeroes, fundingSatoshis, pushMsat, TestConstants.feeratePerKw, TestConstants.feeratePerKw, None, aliceParams, alice2bob.ref, bobInit, ChannelFlags.Empty, ChannelVersion.STANDARD)
bob ! INPUT_INIT_FUNDEE(ByteVector32.Zeroes, bobParams, bob2alice.ref, aliceInit, ChannelVersion.STANDARD)
alice2bob.expectMsgType[OpenChannel]
alice2bob.forward(bob)
bob2alice.expectMsgType[AcceptChannel]
Expand All @@ -63,7 +82,20 @@ class WaitForFundingSignedStateSpec extends TestKitBaseClass with FixtureAnyFunS
bob2alice.forward(alice)
awaitCond(alice.stateName == WAIT_FOR_FUNDING_CONFIRMED)
alice2blockchain.expectMsgType[WatchSpent]
alice2blockchain.expectMsgType[WatchConfirmed]
val watchConfirmed = alice2blockchain.expectMsgType[WatchConfirmed]
// when we are funder, we keep our regular min depth even for wumbo channels
assert(watchConfirmed.minDepth === Alice.nodeParams.minDepthBlocks)
}

test("recv FundingSigned with valid signature (wumbo)", Tag("wumbo")) { f =>
import f._
bob2alice.expectMsgType[FundingSigned]
bob2alice.forward(alice)
awaitCond(alice.stateName == WAIT_FOR_FUNDING_CONFIRMED)
alice2blockchain.expectMsgType[WatchSpent]
val watchConfirmed = alice2blockchain.expectMsgType[WatchConfirmed]

assert(watchConfirmed.minDepth === Alice.nodeParams.minDepthBlocks)
}

test("recv FundingSigned with invalid signature") { f =>
Expand Down