1
0
Fork 0
mirror of https://github.com/ACINQ/eclair.git synced 2025-02-23 22:46:44 +01:00

Delegate client creation to a specialized actor (#1400)

This allows decoupling the reconnection task from the actual client
creation.

Also improved tests.

Co-Authored-By: Bastien Teinturier <31281497+t-bast@users.noreply.github.com>
This commit is contained in:
Pierre-Marie Padiou 2020-04-30 18:10:55 +02:00 committed by GitHub
parent a18d3a76a2
commit 32f15c85eb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
55 changed files with 370 additions and 255 deletions

View file

@ -42,7 +42,7 @@ import fr.acinq.eclair.blockchain.{EclairWallet, _}
import fr.acinq.eclair.channel.Register
import fr.acinq.eclair.crypto.LocalKeyManager
import fr.acinq.eclair.db.{BackupHandler, Databases}
import fr.acinq.eclair.io.{Server, Switchboard}
import fr.acinq.eclair.io.{ClientSpawner, Server, Switchboard}
import fr.acinq.eclair.payment.Auditor
import fr.acinq.eclair.payment.receive.PaymentHandler
import fr.acinq.eclair.payment.relay.{CommandBuffer, Relayer}
@ -120,6 +120,7 @@ class Setup(datadir: File,
val feeEstimator = new FeeEstimator {
// @formatter:off
override def getFeeratePerKb(target: Int): Long = feeratesPerKB.get().feePerBlock(target)
override def getFeeratePerKw(target: Int): Long = feeratesPerKw.get().feePerBlock(target)
// @formatter:on
}
@ -295,7 +296,8 @@ class Setup(datadir: File,
// Before initializing the switchboard (which re-connects us to the network) and the user-facing parts of the system,
// we want to make sure the handler for post-restart broken HTLCs has finished initializing.
_ <- postRestartCleanUpInitialized.future
switchboard = system.actorOf(SimpleSupervisor.props(Switchboard.props(nodeParams, router, watcher, relayer, wallet), "switchboard", SupervisorStrategy.Resume))
switchboard = system.actorOf(SimpleSupervisor.props(Switchboard.props(nodeParams, watcher, relayer, wallet), "switchboard", SupervisorStrategy.Resume))
clientSpawner = system.actorOf(SimpleSupervisor.props(ClientSpawner.props(nodeParams, switchboard, router), "client-spawner", SupervisorStrategy.Restart))
server = system.actorOf(SimpleSupervisor.props(Server.props(nodeParams, switchboard, router, serverBindingAddress, Some(tcpBound)), "server", SupervisorStrategy.Restart))
paymentInitiator = system.actorOf(SimpleSupervisor.props(PaymentInitiator.props(nodeParams, router, relayer, register), "payment-initiator", SupervisorStrategy.Restart))
_ = for (i <- 0 until config.getInt("autoprobe-count")) yield system.actorOf(SimpleSupervisor.props(Autoprobe.props(nodeParams, router, paymentInitiator), s"payment-autoprobe-$i", SupervisorStrategy.Restart))

View file

@ -101,6 +101,9 @@ class ZMQActor(address: String, connected: Option[Promise[Done]] = None) extends
}
}
override def postStop(): Unit = {
ctx.close()
}
}
object ZMQActor {

View file

@ -32,9 +32,9 @@ import fr.acinq.eclair.{Logs, NodeParams}
import scala.concurrent.duration._
/**
* Created by PM on 27/10/2015.
*
*/
* Created by PM on 27/10/2015.
*
*/
class Client(nodeParams: NodeParams, switchboard: ActorRef, router: ActorRef, remoteAddress: InetSocketAddress, remoteNodeId: PublicKey, origin_opt: Option[ActorRef]) extends Actor with DiagnosticActorLogging {
import context.system

View file

@ -0,0 +1,44 @@
/*
* Copyright 2020 ACINQ SAS
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package fr.acinq.eclair.io
import java.net.InetSocketAddress
import akka.actor.{Actor, ActorLogging, ActorRef, Props}
import fr.acinq.bitcoin.Crypto.PublicKey
import fr.acinq.eclair.NodeParams
class ClientSpawner(nodeParams: NodeParams, switchboard: ActorRef, router: ActorRef) extends Actor with ActorLogging {
context.system.eventStream.subscribe(self, classOf[ClientSpawner.ConnectionRequest])
override def receive: Receive = {
case req: ClientSpawner.ConnectionRequest =>
log.info("initiating new connection to nodeId={} origin={}", req.remoteNodeId, sender)
context.actorOf(Client.props(nodeParams, switchboard, router, req.address, req.remoteNodeId, origin_opt = Some(req.origin)))
}
}
object ClientSpawner {
def props(nodeParams: NodeParams, switchboard: ActorRef, router: ActorRef): Props = Props(new ClientSpawner(nodeParams, switchboard, router))
case class ConnectionRequest(address: InetSocketAddress,
remoteNodeId: PublicKey,
origin: ActorRef)
}

View file

@ -31,12 +31,12 @@ object NodeURI {
val DEFAULT_PORT = 9735
/**
* Extracts the PublicKey and InetAddress from a string URI (format pubkey@host:port). Port is optional, default is 9735.
*
* @param uri uri of a node, as a String
* @throws IllegalArgumentException if the uri is not valid and can not be read
* @return a NodeURI
*/
* Extracts the PublicKey and InetAddress from a string URI (format pubkey@host:port). Port is optional, default is 9735.
*
* @param uri uri of a node, as a String
* @throws IllegalArgumentException if the uri is not valid and can not be read
* @return a NodeURI
*/
@throws[IllegalArgumentException]
def parse(uri: String): NodeURI = {
uri.split("@") match {

View file

@ -44,15 +44,10 @@ import scodec.bits.ByteVector
*
* Created by PM on 26/08/2016.
*/
class Peer(val nodeParams: NodeParams, remoteNodeId: PublicKey, switchboard: ActorRef, router: ActorRef, watcher: ActorRef, relayer: ActorRef, wallet: EclairWallet) extends FSMDiagnosticActorLogging[Peer.State, Peer.Data] {
class Peer(val nodeParams: NodeParams, remoteNodeId: PublicKey, watcher: ActorRef, relayer: ActorRef, wallet: EclairWallet) extends FSMDiagnosticActorLogging[Peer.State, Peer.Data] {
import Peer._
val reconnectionTask: ActorRef = context.actorOf(ReconnectionTask.props(nodeParams, remoteNodeId, switchboard, router), "reconnection-task")
// we register the reconnection task to our transitions ourselves; if we let the child actor register itself, there is
// a race condition and it may miss the first transition
listeners.add(reconnectionTask)
startWith(INSTANTIATING, Nothing)
when(INSTANTIATING) {
@ -119,34 +114,34 @@ class Peer(val nodeParams: NodeParams, remoteNodeId: PublicKey, switchboard: Act
d.peerConnection ! PoisonPill
stay
case Event(err: wire.Error, d: ConnectedData) =>
// error messages are a bit special because they can contain either temporaryChannelId or channelId (see BOLT 1)
d.channels.get(FinalChannelId(err.channelId)).orElse(d.channels.get(TemporaryChannelId(err.channelId))) match {
case Some(channel) => channel forward err
case None => () // let's not create a ping-pong of error messages here
}
stay
case Event(err: wire.Error, d: ConnectedData) =>
// error messages are a bit special because they can contain either temporaryChannelId or channelId (see BOLT 1)
d.channels.get(FinalChannelId(err.channelId)).orElse(d.channels.get(TemporaryChannelId(err.channelId))) match {
case Some(channel) => channel forward err
case None => () // let's not create a ping-pong of error messages here
}
stay
case Event(c: Peer.OpenChannel, d: ConnectedData) =>
if (c.fundingSatoshis >= Channel.MAX_FUNDING && !Features.hasFeature(nodeParams.features, Wumbo)) {
sender ! Status.Failure(new RuntimeException(s"fundingSatoshis=${c.fundingSatoshis} is too big, you must enable large channels support in 'eclair.features' to use funding above ${Channel.MAX_FUNDING} (see eclair.conf)"))
stay
} else if (c.fundingSatoshis >= Channel.MAX_FUNDING && !Features.hasFeature(d.remoteInit.features, Wumbo)) {
sender ! Status.Failure(new RuntimeException(s"fundingSatoshis=${c.fundingSatoshis} is too big, the remote peer doesn't support wumbo"))
stay
} else if (c.fundingSatoshis > nodeParams.maxFundingSatoshis) {
sender ! Status.Failure(new RuntimeException(s"fundingSatoshis=${c.fundingSatoshis} is too big for the current settings, increase 'eclair.max-funding-satoshis' (see eclair.conf)"))
stay
} else {
val (channel, localParams) = createNewChannel(nodeParams, funder = true, c.fundingSatoshis, origin_opt = Some(sender))
c.timeout_opt.map(openTimeout => context.system.scheduler.scheduleOnce(openTimeout.duration, channel, Channel.TickChannelOpenTimeout)(context.dispatcher))
val temporaryChannelId = randomBytes32
val channelFeeratePerKw = nodeParams.onChainFeeConf.feeEstimator.getFeeratePerKw(target = nodeParams.onChainFeeConf.feeTargets.commitmentBlockTarget)
val fundingTxFeeratePerKw = c.fundingTxFeeratePerKw_opt.getOrElse(nodeParams.onChainFeeConf.feeEstimator.getFeeratePerKw(target = nodeParams.onChainFeeConf.feeTargets.fundingBlockTarget))
log.info(s"requesting a new channel with fundingSatoshis=${c.fundingSatoshis}, pushMsat=${c.pushMsat} and fundingFeeratePerByte=${c.fundingTxFeeratePerKw_opt} temporaryChannelId=$temporaryChannelId localParams=$localParams")
channel ! INPUT_INIT_FUNDER(temporaryChannelId, c.fundingSatoshis, c.pushMsat, channelFeeratePerKw, fundingTxFeeratePerKw, localParams, d.peerConnection, d.remoteInit, c.channelFlags.getOrElse(nodeParams.channelFlags), ChannelVersion.STANDARD)
stay using d.copy(channels = d.channels + (TemporaryChannelId(temporaryChannelId) -> channel))
}
case Event(c: Peer.OpenChannel, d: ConnectedData) =>
if (c.fundingSatoshis >= Channel.MAX_FUNDING && !Features.hasFeature(nodeParams.features, Wumbo)) {
sender ! Status.Failure(new RuntimeException(s"fundingSatoshis=${c.fundingSatoshis} is too big, you must enable large channels support in 'eclair.features' to use funding above ${Channel.MAX_FUNDING} (see eclair.conf)"))
stay
} else if (c.fundingSatoshis >= Channel.MAX_FUNDING && !Features.hasFeature(d.remoteInit.features, Wumbo)) {
sender ! Status.Failure(new RuntimeException(s"fundingSatoshis=${c.fundingSatoshis} is too big, the remote peer doesn't support wumbo"))
stay
} else if (c.fundingSatoshis > nodeParams.maxFundingSatoshis) {
sender ! Status.Failure(new RuntimeException(s"fundingSatoshis=${c.fundingSatoshis} is too big for the current settings, increase 'eclair.max-funding-satoshis' (see eclair.conf)"))
stay
} else {
val (channel, localParams) = createNewChannel(nodeParams, funder = true, c.fundingSatoshis, origin_opt = Some(sender))
c.timeout_opt.map(openTimeout => context.system.scheduler.scheduleOnce(openTimeout.duration, channel, Channel.TickChannelOpenTimeout)(context.dispatcher))
val temporaryChannelId = randomBytes32
val channelFeeratePerKw = nodeParams.onChainFeeConf.feeEstimator.getFeeratePerKw(target = nodeParams.onChainFeeConf.feeTargets.commitmentBlockTarget)
val fundingTxFeeratePerKw = c.fundingTxFeeratePerKw_opt.getOrElse(nodeParams.onChainFeeConf.feeEstimator.getFeeratePerKw(target = nodeParams.onChainFeeConf.feeTargets.fundingBlockTarget))
log.info(s"requesting a new channel with fundingSatoshis=${c.fundingSatoshis}, pushMsat=${c.pushMsat} and fundingFeeratePerByte=${c.fundingTxFeeratePerKw_opt} temporaryChannelId=$temporaryChannelId localParams=$localParams")
channel ! INPUT_INIT_FUNDER(temporaryChannelId, c.fundingSatoshis, c.pushMsat, channelFeeratePerKw, fundingTxFeeratePerKw, localParams, d.peerConnection, d.remoteInit, c.channelFlags.getOrElse(nodeParams.channelFlags), ChannelVersion.STANDARD)
stay using d.copy(channels = d.channels + (TemporaryChannelId(temporaryChannelId) -> channel))
}
case Event(msg: wire.OpenChannel, d: ConnectedData) =>
d.channels.get(TemporaryChannelId(msg.temporaryChannelId)) match {
@ -162,12 +157,12 @@ class Peer(val nodeParams: NodeParams, remoteNodeId: PublicKey, switchboard: Act
stay
}
case Event(msg: wire.HasChannelId, d: ConnectedData) =>
d.channels.get(FinalChannelId(msg.channelId)) match {
case Some(channel) => channel forward msg
case None => replyUnknownChannel(d.peerConnection, msg.channelId)
}
stay
case Event(msg: wire.HasChannelId, d: ConnectedData) =>
d.channels.get(FinalChannelId(msg.channelId)) match {
case Some(channel) => channel forward msg
case None => replyUnknownChannel(d.peerConnection, msg.channelId)
}
stay
case Event(msg: wire.HasTemporaryChannelId, d: ConnectedData) =>
d.channels.get(TemporaryChannelId(msg.temporaryChannelId)) match {
@ -239,6 +234,12 @@ class Peer(val nodeParams: NodeParams, remoteNodeId: PublicKey, switchboard: Act
case Event(_: Channel.OutgoingMessage, _) => stay // we got disconnected or reconnected and this message was for the previous connection
}
private val reconnectionTask = context.actorOf(ReconnectionTask.props(nodeParams, remoteNodeId), "reconnection-task")
onTransition {
case _ -> (DISCONNECTED | CONNECTED) => reconnectionTask ! Peer.Transition(stateData, nextStateData)
}
onTransition {
case _ -> CONNECTED =>
Metrics.PeersConnected.withoutTags().increment()
@ -329,7 +330,7 @@ object Peer {
val UNKNOWN_CHANNEL_MESSAGE: ByteVector = ByteVector.view("unknown channel".getBytes())
// @formatter:on
def props(nodeParams: NodeParams, remoteNodeId: PublicKey, switchboard: ActorRef, router: ActorRef, watcher: ActorRef, relayer: ActorRef, wallet: EclairWallet): Props = Props(new Peer(nodeParams, remoteNodeId, switchboard: ActorRef, router, watcher, relayer, wallet))
def props(nodeParams: NodeParams, remoteNodeId: PublicKey, watcher: ActorRef, relayer: ActorRef, wallet: EclairWallet): Props = Props(new Peer(nodeParams, remoteNodeId, watcher, relayer: ActorRef, wallet))
// @formatter:off
@ -372,6 +373,8 @@ object Peer {
case class PeerRoutingMessage(peerConnection: ActorRef, remoteNodeId: PublicKey, message: RoutingMessage)
case class Transition(previousData: Peer.Data, nextData: Peer.Data)
// @formatter:on
def makeChannelParams(nodeParams: NodeParams, defaultFinalScriptPubKey: ByteVector, isFunder: Boolean, fundingAmount: Satoshi): LocalParams = {

View file

@ -32,7 +32,6 @@ import fr.acinq.eclair.{wire, _}
import scodec.Attempt
import scodec.bits.{BitVector, ByteVector}
import scala.compat.Platform
import scala.concurrent.duration._
import scala.util.Random
@ -259,6 +258,7 @@ class PeerConnection(nodeParams: NodeParams, switchboard: ActorRef, router: Acto
case Event(DelayedRebroadcast(rebroadcast), d: ConnectedData) =>
val thisRemote = RemoteGossip(self, d.remoteNodeId)
/**
* Send and count in a single iteration
*/

View file

@ -18,7 +18,7 @@ package fr.acinq.eclair.io
import java.net.InetSocketAddress
import akka.actor.{ActorRef, FSM, Props, Terminated}
import akka.actor.{ActorRef, Props, Status}
import akka.event.Logging.MDC
import com.google.common.net.HostAndPort
import fr.acinq.bitcoin.Crypto.PublicKey
@ -27,7 +27,6 @@ import fr.acinq.eclair.db.{NetworkDb, PeersDb}
import fr.acinq.eclair.io.Monitoring.Metrics
import fr.acinq.eclair.{FSMDiagnosticActorLogging, Logs, NodeParams}
import scala.compat.Platform
import scala.concurrent.duration.{FiniteDuration, _}
import scala.util.Random
@ -44,19 +43,19 @@ import scala.util.Random
* - concurrent incoming/outgoing connections and risk of reconnection loops
* - etc.
*/
class ReconnectionTask(nodeParams: NodeParams, remoteNodeId: PublicKey, switchboard: ActorRef, router: ActorRef) extends FSMDiagnosticActorLogging[ReconnectionTask.State, ReconnectionTask.Data] {
class ReconnectionTask(nodeParams: NodeParams, remoteNodeId: PublicKey) extends FSMDiagnosticActorLogging[ReconnectionTask.State, ReconnectionTask.Data] {
import ReconnectionTask._
startWith(IDLE, IdleData(Nothing))
when(CONNECTING) {
case Event(Terminated(actor), d: ConnectingData) if actor == d.connection =>
case Event(Status.Failure(_: Client.ConnectionFailed), d: ConnectingData) =>
log.info(s"connection failed, next reconnection in ${d.nextReconnectionDelay.toSeconds} seconds")
setReconnectTimer(d.nextReconnectionDelay)
goto(WAITING) using WaitingData(nextReconnectionDelay(d.nextReconnectionDelay, nodeParams.maxReconnectInterval))
case Event(FSM.Transition(_, Peer.DISCONNECTED, Peer.CONNECTED), d) =>
case Event(Peer.Transition(_, _: Peer.ConnectedData), d) =>
log.info("peer is connected")
goto(IDLE) using IdleData(d)
}
@ -66,29 +65,25 @@ class ReconnectionTask(nodeParams: NodeParams, remoteNodeId: PublicKey, switchbo
// we query the db every time because it may have been updated in the meantime (e.g. with network announcements)
getPeerAddressFromDb(nodeParams.db.peers, nodeParams.db.network, remoteNodeId) match {
case Some(address) =>
val connection = connect(address, origin_opt = None)
goto(CONNECTING) using ConnectingData(connection, address, d.nextReconnectionDelay)
connect(address, origin = self)
goto(CONNECTING) using ConnectingData(address, d.nextReconnectionDelay)
case None =>
// we don't have an address for that peer, nothing to do
goto(IDLE) using IdleData(d)
}
case Event(FSM.Transition(_, Peer.DISCONNECTED, Peer.CONNECTED), d) =>
case Event(Peer.Transition(_, _: Peer.ConnectedData), d) =>
log.info("peer is connected")
cancelTimer(RECONNECT_TIMER)
goto(IDLE) using IdleData(d)
}
when(IDLE) {
case Event(FSM.Transition(_, Peer.INSTANTIATING | Peer.CONNECTED, Peer.DISCONNECTED), d: IdleData) =>
if (nodeParams.autoReconnect) {
val (initialDelay, firstNextReconnectionDelay) = d.previousData match {
case Nothing =>
// The random initialDelay adds a minimum delay, which is important for a first connection to a new peer which advertises
// a public address. Right after the peer and this reconnection actor will be created, there will be a race between
// this automated connection task that uses data from network db, and the Peer.Connect command that may use the same
// address or a different one. This delay will cause the automated connection task to lose the race and prevent
// unnecessary parallel connections
case Event(Peer.Transition(previousPeerData, nextPeerData: Peer.DisconnectedData), d: IdleData) =>
if (nodeParams.autoReconnect && nextPeerData.channels.nonEmpty) { // we only reconnect if there are existing channels
val (initialDelay, firstNextReconnectionDelay) = (previousPeerData, d.previousData) match {
case (Peer.Nothing, _) =>
// When restarting, we add some randomization before the first reconnection attempt to avoid herd effect
val initialDelay = randomizeDelay(nodeParams.initialRandomReconnectDelay)
// When restarting, we will ~immediately reconnect, but then:
// - we don't want all the subsequent reconnection attempts to be synchronized (herd effect)
@ -97,7 +92,7 @@ class ReconnectionTask(nodeParams: NodeParams, remoteNodeId: PublicKey, switchbo
// That's why we set the next reconnection delay to a random value between MAX_RECONNECT_INTERVAL/2 and MAX_RECONNECT_INTERVAL.
val firstNextReconnectionDelay = nodeParams.maxReconnectInterval.minus(Random.nextInt(nodeParams.maxReconnectInterval.toSeconds.toInt / 2).seconds)
(initialDelay, firstNextReconnectionDelay)
case cd: ConnectingData if System.currentTimeMillis.milliseconds - d.since < 30.seconds =>
case (_, cd: ConnectingData) if System.currentTimeMillis.milliseconds - d.since < 30.seconds =>
log.info("peer is disconnected (shortly after connection was established)")
// If our latest successful connection attempt was less than 30 seconds ago, we pick up the exponential
// back-off retry delay where we left it. The goal is to address cases where the reconnection is successful,
@ -120,18 +115,14 @@ class ReconnectionTask(nodeParams: NodeParams, remoteNodeId: PublicKey, switchbo
stay
}
case Event(FSM.Transition(_, Peer.DISCONNECTED, Peer.CONNECTED), _) =>
case Event(Peer.Transition(_, _: Peer.ConnectedData), _) =>
log.info("peer is connected")
stay
}
whenUnhandled {
case Event(_: Terminated, _) => stay
case Event(TickReconnect, _) => stay
case Event(FSM.Transition(_, Peer.INSTANTIATING, Peer.INSTANTIATING), _) => stay // instantiation transition
case Event(Peer.Connect(_, hostAndPort_opt), _) =>
// manual connection requests happen completely independently of the automated reconnection process;
// we initiate a connection but don't modify our state.
@ -139,7 +130,7 @@ class ReconnectionTask(nodeParams: NodeParams, remoteNodeId: PublicKey, switchbo
hostAndPort_opt
.map(hostAndPort2InetSocketAddress)
.orElse(getPeerAddressFromDb(nodeParams.db.peers, nodeParams.db.network, remoteNodeId)) match {
case Some(address) => connect(address, Some(sender))
case Some(address) => connect(address, origin = sender)
case None => sender ! "no address found"
}
stay
@ -147,12 +138,10 @@ class ReconnectionTask(nodeParams: NodeParams, remoteNodeId: PublicKey, switchbo
private def setReconnectTimer(delay: FiniteDuration): Unit = setTimer(RECONNECT_TIMER, TickReconnect, delay, repeat = false)
private def connect(address: InetSocketAddress, origin_opt: Option[ActorRef]): ActorRef = {
private def connect(address: InetSocketAddress, origin: ActorRef): Unit = {
log.info(s"connecting to $address")
val connection = context.actorOf(Client.props(nodeParams, switchboard, router, address, remoteNodeId, origin_opt = origin_opt))
context.watch(connection)
context.system.eventStream.publish(ClientSpawner.ConnectionRequest(address, remoteNodeId, origin))
Metrics.ReconnectionsAttempts.withoutTags().increment()
connection
}
override def mdc(currentMessage: Any): MDC = {
@ -163,7 +152,7 @@ class ReconnectionTask(nodeParams: NodeParams, remoteNodeId: PublicKey, switchbo
object ReconnectionTask {
def props(nodeParams: NodeParams, remoteNodeId: PublicKey, switchboard: ActorRef, router: ActorRef): Props = Props(new ReconnectionTask(nodeParams, remoteNodeId, switchboard, router))
def props(nodeParams: NodeParams, remoteNodeId: PublicKey): Props = Props(new ReconnectionTask(nodeParams, remoteNodeId))
val RECONNECT_TIMER = "reconnect"
@ -181,7 +170,7 @@ object ReconnectionTask {
sealed trait Data
case object Nothing extends Data
case class IdleData(previousData: Data, since: FiniteDuration = System.currentTimeMillis.milliseconds) extends Data
case class ConnectingData(connection: ActorRef, to: InetSocketAddress, nextReconnectionDelay: FiniteDuration) extends Data
case class ConnectingData(to: InetSocketAddress, nextReconnectionDelay: FiniteDuration) extends Data
case class WaitingData(nextReconnectionDelay: FiniteDuration) extends Data
// @formatter:on

View file

@ -27,7 +27,7 @@ import fr.acinq.eclair.channel._
* Ties network connections to peers.
* Created by PM on 14/02/2017.
*/
class Switchboard(nodeParams: NodeParams, router: ActorRef, watcher: ActorRef, relayer: ActorRef, wallet: EclairWallet) extends Actor with ActorLogging {
class Switchboard(nodeParams: NodeParams, watcher: ActorRef, relayer: ActorRef, wallet: EclairWallet) extends Actor with ActorLogging {
import Switchboard._
@ -89,7 +89,7 @@ class Switchboard(nodeParams: NodeParams, router: ActorRef, watcher: ActorRef, r
def getPeer(remoteNodeId: PublicKey): Option[ActorRef] = context.child(peerActorName(remoteNodeId))
def createPeer(remoteNodeId: PublicKey): ActorRef = context.actorOf(
Peer.props(nodeParams, remoteNodeId, self, router, watcher, relayer, wallet),
Peer.props(nodeParams, remoteNodeId, watcher, relayer, wallet),
name = peerActorName(remoteNodeId))
def createOrGetPeer(remoteNodeId: PublicKey, offlineChannels: Set[HasCommitments]): ActorRef = {
@ -111,7 +111,7 @@ class Switchboard(nodeParams: NodeParams, router: ActorRef, watcher: ActorRef, r
object Switchboard {
def props(nodeParams: NodeParams, router: ActorRef, watcher: ActorRef, relayer: ActorRef, wallet: EclairWallet) = Props(new Switchboard(nodeParams, router, watcher, relayer, wallet))
def props(nodeParams: NodeParams, watcher: ActorRef, relayer: ActorRef, wallet: EclairWallet) = Props(new Switchboard(nodeParams, watcher, relayer, wallet))
def peerActorName(remoteNodeId: PublicKey): String = s"peer-$remoteNodeId"

View file

@ -46,7 +46,7 @@ import scala.concurrent.Await
import scala.concurrent.duration._
import scala.util.Success
class EclairImplSpec extends TestKit(ActorSystem("test")) with FixtureAnyFunSuiteLike with IdiomaticMockito with ParallelTestExecution {
class EclairImplSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with IdiomaticMockito with ParallelTestExecution {
implicit val timeout: Timeout = Timeout(30 seconds)
case class FixtureParam(register: TestProbe, router: TestProbe, paymentInitiator: TestProbe, switchboard: TestProbe, paymentHandler: TestProbe, kit: Kit)

View file

@ -16,29 +16,17 @@
package fr.acinq.eclair
import akka.actor.{ActorNotFound, ActorSystem, PoisonPill}
import akka.actor.ActorSystem
import akka.testkit.TestKit
import org.scalatest.funsuite.FixtureAnyFunSuiteLike
import org.scalatest.{BeforeAndAfterAll, BeforeAndAfterEach}
import scala.concurrent.Await
import org.scalatest.{BeforeAndAfterAll, TestSuite}
/**
* This base class kills all actor between each tests.
* Created by PM on 06/09/2016.
*/
abstract class TestkitBaseClass extends TestKit(ActorSystem("test")) with FixtureAnyFunSuiteLike with BeforeAndAfterEach with BeforeAndAfterAll {
override def afterEach() {
system.actorSelection(system / "*") ! PoisonPill
intercept[ActorNotFound] {
import scala.concurrent.duration._
Await.result(system.actorSelection(system / "*").resolveOne(42 days), 42 days)
}
}
abstract class TestKitBaseClass extends TestKit(ActorSystem("test")) with TestSuite with BeforeAndAfterAll {
override def afterAll {
TestKit.shutdownActorSystem(system)
}
}

View file

@ -16,10 +16,9 @@
package fr.acinq.eclair.blockchain.bitcoind
import akka.actor.ActorSystem
import akka.actor.Status.Failure
import akka.pattern.pipe
import akka.testkit.{TestKit, TestProbe}
import akka.testkit.TestProbe
import com.typesafe.config.ConfigFactory
import fr.acinq.bitcoin.{Block, ByteVector32, MilliBtc, OutPoint, Satoshi, Script, Transaction, TxIn, TxOut}
import fr.acinq.eclair.blockchain._
@ -27,7 +26,7 @@ import fr.acinq.eclair.blockchain.bitcoind.BitcoinCoreWallet.FundTransactionResp
import fr.acinq.eclair.blockchain.bitcoind.BitcoindService.BitcoinReq
import fr.acinq.eclair.blockchain.bitcoind.rpc.{BasicBitcoinJsonRPCClient, JsonRPCError}
import fr.acinq.eclair.transactions.Scripts
import fr.acinq.eclair.{LongToBtcAmount, addressToPublicKeyScript, randomKey}
import fr.acinq.eclair.{LongToBtcAmount, TestKitBaseClass, addressToPublicKeyScript, randomKey}
import grizzled.slf4j.Logging
import org.json4s.DefaultFormats
import org.json4s.JsonAST.{JString, _}
@ -41,7 +40,7 @@ import scala.jdk.CollectionConverters._
import scala.util.{Random, Try}
class BitcoinCoreWalletSpec extends TestKit(ActorSystem("test")) with BitcoindService with AnyFunSuiteLike with BeforeAndAfterAll with Logging {
class BitcoinCoreWalletSpec extends TestKitBaseClass with BitcoindService with AnyFunSuiteLike with BeforeAndAfterAll with Logging {
val commonConfig = ConfigFactory.parseMap(Map(
"eclair.chain" -> "regtest",

View file

@ -16,12 +16,12 @@
package fr.acinq.eclair.blockchain.bitcoind
import akka.actor.ActorSystem
import akka.actor.Status.Failure
import akka.pattern.pipe
import akka.testkit.{TestKit, TestProbe}
import akka.testkit.TestProbe
import com.typesafe.config.ConfigFactory
import fr.acinq.bitcoin.Transaction
import fr.acinq.eclair.TestKitBaseClass
import fr.acinq.eclair.blockchain.bitcoind.BitcoindService.BitcoinReq
import fr.acinq.eclair.blockchain.bitcoind.rpc.{BasicBitcoinJsonRPCClient, ExtendedBitcoinClient}
import grizzled.slf4j.Logging
@ -33,7 +33,7 @@ import org.scalatest.funsuite.AnyFunSuiteLike
import scala.concurrent.ExecutionContext.Implicits.global
import scala.jdk.CollectionConverters._
class ExtendedBitcoinClientSpec extends TestKit(ActorSystem("test")) with BitcoindService with AnyFunSuiteLike with BeforeAndAfterAll with Logging {
class ExtendedBitcoinClientSpec extends TestKitBaseClass with BitcoindService with AnyFunSuiteLike with BeforeAndAfterAll with Logging {
val commonConfig = ConfigFactory.parseMap(Map(
"eclair.chain" -> "regtest",

View file

@ -19,7 +19,7 @@ package fr.acinq.eclair.blockchain.bitcoind
import java.util.concurrent.atomic.AtomicLong
import akka.Done
import akka.actor.{ActorRef, ActorSystem, Props}
import akka.actor.{ActorRef, Props}
import akka.testkit.{TestKit, TestProbe}
import fr.acinq.bitcoin.{OutPoint, Script}
import fr.acinq.eclair.blockchain.WatcherSpec._
@ -29,7 +29,7 @@ import fr.acinq.eclair.blockchain.bitcoind.ZmqWatcher._
import fr.acinq.eclair.blockchain.bitcoind.rpc.ExtendedBitcoinClient
import fr.acinq.eclair.blockchain.bitcoind.zmq.ZMQActor
import fr.acinq.eclair.channel.{BITCOIN_FUNDING_DEPTHOK, BITCOIN_FUNDING_SPENT}
import fr.acinq.eclair.randomBytes32
import fr.acinq.eclair.{TestKitBaseClass, randomBytes32}
import grizzled.slf4j.Logging
import org.json4s.JsonAST.JValue
import org.scalatest.BeforeAndAfterAll
@ -38,7 +38,7 @@ import org.scalatest.funsuite.AnyFunSuiteLike
import scala.concurrent.Promise
import scala.concurrent.duration._
class ZmqWatcherSpec extends TestKit(ActorSystem("test")) with AnyFunSuiteLike with BitcoindService with BeforeAndAfterAll with Logging {
class ZmqWatcherSpec extends TestKitBaseClass with AnyFunSuiteLike with BitcoindService with BeforeAndAfterAll with Logging {
var zmqBlock: ActorRef = _
var zmqTx: ActorRef = _

View file

@ -19,12 +19,12 @@ package fr.acinq.eclair.blockchain.electrum
import java.net.InetSocketAddress
import java.util.concurrent.atomic.AtomicLong
import akka.actor.{ActorRef, ActorSystem, Props}
import akka.testkit.{TestKit, TestProbe}
import akka.actor.{ActorRef, Props}
import akka.testkit.TestProbe
import fr.acinq.bitcoin.{ByteVector32, Crypto, Transaction}
import fr.acinq.eclair.TestKitBaseClass
import fr.acinq.eclair.blockchain.electrum.ElectrumClient._
import grizzled.slf4j.Logging
import org.scalatest.BeforeAndAfterAll
import org.scalatest.funsuite.AnyFunSuiteLike
import scodec.bits._
@ -32,7 +32,7 @@ import scala.concurrent.duration._
import scala.util.Random
class ElectrumClientPoolSpec extends TestKit(ActorSystem("test")) with AnyFunSuiteLike with Logging with BeforeAndAfterAll {
class ElectrumClientPoolSpec extends TestKitBaseClass with AnyFunSuiteLike with Logging {
var pool: ActorRef = _
val probe = TestProbe()
// this is tx #2690 of block #500000
@ -49,10 +49,6 @@ class ElectrumClientPoolSpec extends TestKit(ActorSystem("test")) with AnyFunSui
import concurrent.ExecutionContext.Implicits.global
override protected def afterAll(): Unit = {
TestKit.shutdownActorSystem(system)
}
test("pick a random, unused server address") {
val usedAddresses = Random.shuffle(serverAddresses.toSeq).take(serverAddresses.size / 2).map(_.adress).toSet
for (_ <- 1 to 10) {

View file

@ -18,18 +18,18 @@ package fr.acinq.eclair.blockchain.electrum
import java.net.InetSocketAddress
import akka.actor.{ActorRef, ActorSystem, Props}
import akka.testkit.{TestKit, TestProbe}
import akka.actor.{ActorRef, Props}
import akka.testkit.TestProbe
import fr.acinq.bitcoin.{ByteVector32, Crypto, Transaction}
import fr.acinq.eclair.TestKitBaseClass
import grizzled.slf4j.Logging
import org.scalatest.BeforeAndAfterAll
import org.scalatest.funsuite.AnyFunSuiteLike
import scodec.bits._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
class ElectrumClientSpec extends TestKit(ActorSystem("test")) with AnyFunSuiteLike with Logging with BeforeAndAfterAll {
class ElectrumClientSpec extends TestKitBaseClass with AnyFunSuiteLike with Logging {
import ElectrumClient._
@ -59,10 +59,6 @@ class ElectrumClientSpec extends TestKit(ActorSystem("test")) with AnyFunSuiteLi
client = system.actorOf(Props(new ElectrumClient(new InetSocketAddress("electrum.acinq.co", 50002), SSL.STRICT)), "electrum-client")
}
override protected def afterAll(): Unit = {
TestKit.shutdownActorSystem(system)
}
test("connect to an electrumx mainnet server") {
probe.send(client, AddStatusListener(probe.ref))
probe.expectMsgType[ElectrumReady](15 seconds)

View file

@ -19,24 +19,24 @@ package fr.acinq.eclair.blockchain.electrum
import java.net.InetSocketAddress
import java.sql.DriverManager
import akka.actor.{ActorRef, ActorSystem, Terminated}
import akka.actor.{ActorRef, Terminated}
import akka.testkit
import akka.testkit.{TestActor, TestFSMRef, TestKit, TestProbe}
import akka.testkit.{TestActor, TestFSMRef, TestProbe}
import fr.acinq.bitcoin.Crypto.PublicKey
import fr.acinq.bitcoin.DeterministicWallet.derivePrivateKey
import fr.acinq.bitcoin.{Block, BlockHeader, ByteVector32, Crypto, DeterministicWallet, MnemonicCode, OutPoint, Satoshi, Script, Transaction, TxIn, TxOut}
import fr.acinq.eclair.LongToBtcAmount
import fr.acinq.eclair.blockchain.bitcoind.rpc.Error
import fr.acinq.eclair.blockchain.electrum.ElectrumClient._
import fr.acinq.eclair.blockchain.electrum.ElectrumWallet._
import fr.acinq.eclair.blockchain.electrum.db.sqlite.SqliteWalletDb
import fr.acinq.eclair.{LongToBtcAmount, TestKitBaseClass}
import org.scalatest.funsuite.AnyFunSuiteLike
import scodec.bits.ByteVector
import scala.annotation.tailrec
import scala.concurrent.duration._
class ElectrumWalletSimulatedClientSpec extends TestKit(ActorSystem("test")) with AnyFunSuiteLike {
class ElectrumWalletSimulatedClientSpec extends TestKitBaseClass with AnyFunSuiteLike {
import ElectrumWalletSimulatedClientSpec._

View file

@ -20,11 +20,10 @@ import java.net.InetSocketAddress
import java.sql.DriverManager
import java.util.concurrent.atomic.AtomicLong
import akka.actor.{ActorRef, ActorSystem, Props}
import akka.actor.{ActorRef, Props}
import akka.testkit.{TestKit, TestProbe}
import com.whisk.docker.DockerReadyChecker
import fr.acinq.bitcoin.{Block, Btc, ByteVector32, DeterministicWallet, MnemonicCode, OutPoint, Satoshi, Script, ScriptFlags, ScriptWitness, SigVersion, Transaction, TxIn, TxOut}
import fr.acinq.eclair.LongToBtcAmount
import fr.acinq.eclair.blockchain.bitcoind.BitcoinCoreWallet.{FundTransactionResponse, SignTransactionResponse}
import fr.acinq.eclair.blockchain.bitcoind.BitcoindService.BitcoinReq
import fr.acinq.eclair.blockchain.bitcoind.{BitcoinCoreWallet, BitcoindService}
@ -32,6 +31,7 @@ import fr.acinq.eclair.blockchain.electrum.ElectrumClient.{BroadcastTransaction,
import fr.acinq.eclair.blockchain.electrum.ElectrumClientPool.ElectrumServerAddress
import fr.acinq.eclair.blockchain.electrum.db.sqlite.SqliteWalletDb
import fr.acinq.eclair.transactions.{Scripts, Transactions}
import fr.acinq.eclair.{LongToBtcAmount, TestKitBaseClass}
import fr.acinq.{bitcoin, eclair}
import grizzled.slf4j.Logging
import org.json4s.JsonAST.{JDecimal, JString, JValue}
@ -42,7 +42,7 @@ import scodec.bits.ByteVector
import scala.concurrent.Await
import scala.concurrent.duration._
class ElectrumWalletSpec extends TestKit(ActorSystem("test")) with AnyFunSuiteLike with BitcoindService with ElectrumxService with BeforeAndAfterAll with Logging {
class ElectrumWalletSpec extends TestKitBaseClass with AnyFunSuiteLike with BitcoindService with ElectrumxService with BeforeAndAfterAll with Logging {
import ElectrumWallet._

View file

@ -19,7 +19,7 @@ package fr.acinq.eclair.blockchain.electrum
import java.net.InetSocketAddress
import java.util.concurrent.atomic.AtomicLong
import akka.actor.{ActorSystem, Props}
import akka.actor.Props
import akka.testkit.{TestKit, TestProbe}
import fr.acinq.bitcoin.{ByteVector32, OutPoint, SIGHASH_ALL, Script, ScriptFlags, ScriptWitness, SigVersion, Transaction, TxIn, TxOut}
import fr.acinq.eclair.blockchain.WatcherSpec._
@ -29,7 +29,7 @@ import fr.acinq.eclair.blockchain.bitcoind.BitcoindService.BitcoinReq
import fr.acinq.eclair.blockchain.electrum.ElectrumClient.SSL
import fr.acinq.eclair.blockchain.electrum.ElectrumClientPool.ElectrumServerAddress
import fr.acinq.eclair.channel.{BITCOIN_FUNDING_DEPTHOK, BITCOIN_FUNDING_SPENT}
import fr.acinq.eclair.{LongToBtcAmount, randomBytes32}
import fr.acinq.eclair.{LongToBtcAmount, TestKitBaseClass, randomBytes32}
import grizzled.slf4j.Logging
import org.json4s.JsonAST.JValue
import org.scalatest.BeforeAndAfterAll
@ -38,7 +38,7 @@ import scodec.bits._
import scala.concurrent.duration._
class ElectrumWatcherSpec extends TestKit(ActorSystem("test")) with AnyFunSuiteLike with BitcoindService with ElectrumxService with BeforeAndAfterAll with Logging {
class ElectrumWatcherSpec extends TestKitBaseClass with AnyFunSuiteLike with BitcoindService with ElectrumxService with BeforeAndAfterAll with Logging {
override def beforeAll(): Unit = {
logger.info("starting bitcoind")

View file

@ -16,12 +16,12 @@
package fr.acinq.eclair.blockchain.fee
import akka.actor.ActorSystem
import akka.actor.Status.Failure
import akka.pattern.pipe
import akka.testkit.{TestKit, TestProbe}
import akka.testkit.TestProbe
import com.typesafe.config.ConfigFactory
import fr.acinq.bitcoin._
import fr.acinq.eclair.TestKitBaseClass
import fr.acinq.eclair.blockchain.bitcoind.BitcoindService
import fr.acinq.eclair.blockchain.bitcoind.rpc.BasicBitcoinJsonRPCClient
import grizzled.slf4j.Logging
@ -36,7 +36,7 @@ import scala.jdk.CollectionConverters._
import scala.util.Random
class BitcoinCoreFeeProviderSpec extends TestKit(ActorSystem("test")) with BitcoindService with AnyFunSuiteLike with BeforeAndAfterAll with Logging {
class BitcoinCoreFeeProviderSpec extends TestKitBaseClass with BitcoindService with AnyFunSuiteLike with BeforeAndAfterAll with Logging {
val commonConfig = ConfigFactory.parseMap(Map(
"eclair.chain" -> "regtest",

View file

@ -84,7 +84,7 @@ class BitgoFeeProviderSpec extends AnyFunSuite {
implicit val system = ActorSystem("test")
implicit val ec = system.dispatcher
implicit val sttp = OkHttpFutureBackend()
implicit val timeout = Timeout(1 second)
implicit val timeout = Timeout(30 second)
val bitgo = new BitgoFeeProvider(Block.LivenetGenesisBlock.hash, 1 millisecond)
val e = intercept[Exception] {
Await.result(bitgo.getFeerates, timeout.duration)

View file

@ -28,14 +28,15 @@ import fr.acinq.eclair.payment.relay.Origin.Local
import fr.acinq.eclair.transactions.CommitmentSpec
import fr.acinq.eclair.transactions.Transactions.CommitTx
import fr.acinq.eclair.wire.{IncorrectOrUnknownPaymentDetails, UpdateAddHtlc}
import fr.acinq.eclair.{TestkitBaseClass, _}
import fr.acinq.eclair.{TestKitBaseClass, _}
import org.scalatest.funsuite.FixtureAnyFunSuiteLike
import org.scalatest.{Outcome, Tag}
import scodec.bits.ByteVector
import scala.concurrent.duration._
import scala.util.{Failure, Random, Success}
class CommitmentsSpec extends TestkitBaseClass with StateTestsHelperMethods {
class CommitmentsSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with StateTestsHelperMethods {
type FixtureParam = SetupFixture

View file

@ -35,6 +35,7 @@ import fr.acinq.eclair.router.Router.ChannelHop
import fr.acinq.eclair.wire.Onion.FinalLegacyPayload
import fr.acinq.eclair.wire._
import grizzled.slf4j.Logging
import org.scalatest.funsuite.FixtureAnyFunSuiteLike
import org.scalatest.{Outcome, Tag}
import scala.collection.immutable.Nil
@ -45,7 +46,7 @@ import scala.util.Random
* Created by PM on 05/07/2016.
*/
class FuzzySpec extends TestkitBaseClass with StateTestsHelperMethods with Logging {
class FuzzySpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with StateTestsHelperMethods with Logging {
case class FixtureParam(alice: TestFSMRef[State, Data, Channel], bob: TestFSMRef[State, Data, Channel], pipe: ActorRef, relayerA: ActorRef, relayerB: ActorRef, paymentHandlerA: ActorRef, paymentHandlerB: ActorRef)

View file

@ -10,12 +10,13 @@ import fr.acinq.eclair.crypto.{Generators, KeyManager}
import fr.acinq.eclair.transactions.Scripts
import fr.acinq.eclair.transactions.Transactions.{ClaimP2WPKHOutputTx, InputInfo}
import fr.acinq.eclair.wire.{ChannelReestablish, CommitSig, Error, Init, RevokeAndAck}
import fr.acinq.eclair.{TestConstants, TestkitBaseClass, _}
import fr.acinq.eclair.{TestConstants, TestKitBaseClass, _}
import org.scalatest.Outcome
import org.scalatest.funsuite.FixtureAnyFunSuiteLike
import scala.concurrent.duration._
class RecoverySpec extends TestkitBaseClass with StateTestsHelperMethods {
class RecoverySpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with StateTestsHelperMethods {
type FixtureParam = SetupFixture

View file

@ -24,7 +24,8 @@ import fr.acinq.eclair.channel.Channel.TickChannelOpenTimeout
import fr.acinq.eclair.channel.states.StateTestsHelperMethods
import fr.acinq.eclair.channel.{WAIT_FOR_FUNDING_INTERNAL, _}
import fr.acinq.eclair.wire.{AcceptChannel, ChannelTlv, Error, Init, OpenChannel, TlvStream}
import fr.acinq.eclair.{CltvExpiryDelta, LongToBtcAmount, TestConstants, TestkitBaseClass}
import fr.acinq.eclair.{CltvExpiryDelta, LongToBtcAmount, TestConstants, TestKitBaseClass}
import org.scalatest.funsuite.FixtureAnyFunSuiteLike
import org.scalatest.{Outcome, Tag}
import scodec.bits.{ByteVector, HexStringSyntax}
@ -35,7 +36,7 @@ import scala.concurrent.{Future, Promise}
* Created by PM on 05/07/2016.
*/
class WaitForAcceptChannelStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
class WaitForAcceptChannelStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with StateTestsHelperMethods {
case class FixtureParam(alice: TestFSMRef[State, Data, Channel], alice2bob: TestProbe, bob2alice: TestProbe, alice2blockchain: TestProbe)

View file

@ -21,9 +21,9 @@ import fr.acinq.bitcoin.{Block, Btc, ByteVector32}
import fr.acinq.eclair.TestConstants.{Alice, Bob}
import fr.acinq.eclair.channel._
import fr.acinq.eclair.channel.states.StateTestsHelperMethods
import fr.acinq.eclair.wire.{ChannelTlv, Error, Init, OpenChannel, TlvStream}
import fr.acinq.eclair.wire.{AcceptChannel, Error, Init, OpenChannel}
import fr.acinq.eclair.{CltvExpiryDelta, LongToBtcAmount, TestConstants, TestkitBaseClass, ToMilliSatoshiConversion}
import fr.acinq.eclair.wire.{AcceptChannel, ChannelTlv, Error, Init, OpenChannel, TlvStream}
import fr.acinq.eclair.{CltvExpiryDelta, LongToBtcAmount, TestConstants, TestKitBaseClass, ToMilliSatoshiConversion}
import org.scalatest.funsuite.FixtureAnyFunSuiteLike
import org.scalatest.{Outcome, Tag}
import scodec.bits.{ByteVector, HexStringSyntax}
@ -33,7 +33,7 @@ import scala.concurrent.duration._
* Created by PM on 05/07/2016.
*/
class WaitForOpenChannelStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
class WaitForOpenChannelStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with StateTestsHelperMethods {
case class FixtureParam(bob: TestFSMRef[State, Data, Channel], alice2bob: TestProbe, bob2alice: TestProbe, bob2blockchain: TestProbe)

View file

@ -23,8 +23,9 @@ import fr.acinq.eclair.blockchain.{MakeFundingTxResponse, TestWallet}
import fr.acinq.eclair.channel._
import fr.acinq.eclair.channel.states.StateTestsHelperMethods
import fr.acinq.eclair.wire._
import fr.acinq.eclair.{TestConstants, TestkitBaseClass}
import fr.acinq.eclair.{TestConstants, TestKitBaseClass}
import org.scalatest.Outcome
import org.scalatest.funsuite.FixtureAnyFunSuiteLike
import scodec.bits.ByteVector
import scala.concurrent.duration._
@ -34,7 +35,7 @@ import scala.concurrent.{Future, Promise}
* Created by PM on 05/07/2016.
*/
class WaitForFundingCreatedInternalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
class WaitForFundingCreatedInternalStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with StateTestsHelperMethods {
case class FixtureParam(alice: TestFSMRef[State, Data, Channel], alice2bob: TestProbe, bob2alice: TestProbe, alice2blockchain: TestProbe)

View file

@ -24,7 +24,8 @@ import fr.acinq.eclair.channel._
import fr.acinq.eclair.channel.states.StateTestsHelperMethods
import fr.acinq.eclair.transactions.Transactions
import fr.acinq.eclair.wire._
import fr.acinq.eclair.{LongToBtcAmount, TestConstants, TestkitBaseClass, ToMilliSatoshiConversion}
import fr.acinq.eclair.{LongToBtcAmount, TestConstants, TestKitBaseClass, ToMilliSatoshiConversion}
import org.scalatest.funsuite.FixtureAnyFunSuiteLike
import org.scalatest.{Outcome, Tag}
import scala.concurrent.duration._
@ -33,7 +34,7 @@ import scala.concurrent.duration._
* Created by PM on 05/07/2016.
*/
class WaitForFundingCreatedStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
class WaitForFundingCreatedStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with StateTestsHelperMethods {
case class FixtureParam(bob: TestFSMRef[State, Data, Channel], alice2bob: TestProbe, bob2alice: TestProbe, bob2blockchain: TestProbe)

View file

@ -24,8 +24,9 @@ import fr.acinq.eclair.channel.Channel.TickChannelOpenTimeout
import fr.acinq.eclair.channel._
import fr.acinq.eclair.channel.states.StateTestsHelperMethods
import fr.acinq.eclair.wire.{AcceptChannel, Error, FundingCreated, FundingSigned, Init, OpenChannel}
import fr.acinq.eclair.{TestConstants, TestkitBaseClass}
import fr.acinq.eclair.{TestConstants, TestKitBaseClass}
import org.scalatest.Outcome
import org.scalatest.funsuite.FixtureAnyFunSuiteLike
import scala.concurrent.duration._
@ -33,7 +34,7 @@ import scala.concurrent.duration._
* Created by PM on 05/07/2016.
*/
class WaitForFundingSignedStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
class WaitForFundingSignedStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with StateTestsHelperMethods {
case class FixtureParam(alice: TestFSMRef[State, Data, Channel], alice2bob: TestProbe, bob2alice: TestProbe, alice2blockchain: TestProbe)

View file

@ -25,8 +25,9 @@ import fr.acinq.eclair.channel._
import fr.acinq.eclair.channel.states.StateTestsHelperMethods
import fr.acinq.eclair.transactions.Scripts.multiSig2of2
import fr.acinq.eclair.wire.{AcceptChannel, Error, FundingCreated, FundingLocked, FundingSigned, Init, OpenChannel}
import fr.acinq.eclair.{LongToBtcAmount, TestConstants, TestkitBaseClass, randomKey}
import fr.acinq.eclair.{LongToBtcAmount, TestConstants, TestKitBaseClass, randomKey}
import org.scalatest.Outcome
import org.scalatest.funsuite.FixtureAnyFunSuiteLike
import scala.concurrent.duration._
@ -34,7 +35,7 @@ import scala.concurrent.duration._
* Created by PM on 05/07/2016.
*/
class WaitForFundingConfirmedStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
class WaitForFundingConfirmedStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with StateTestsHelperMethods {
case class FixtureParam(alice: TestFSMRef[State, Data, Channel], bob: TestFSMRef[State, Data, Channel], alice2bob: TestProbe, bob2alice: TestProbe, alice2blockchain: TestProbe)

View file

@ -24,8 +24,9 @@ import fr.acinq.eclair.blockchain._
import fr.acinq.eclair.channel._
import fr.acinq.eclair.channel.states.StateTestsHelperMethods
import fr.acinq.eclair.wire._
import fr.acinq.eclair.{TestConstants, TestkitBaseClass}
import fr.acinq.eclair.{TestConstants, TestKitBaseClass}
import org.scalatest.Outcome
import org.scalatest.funsuite.FixtureAnyFunSuiteLike
import scala.concurrent.duration._
@ -33,7 +34,7 @@ import scala.concurrent.duration._
* Created by PM on 05/07/2016.
*/
class WaitForFundingLockedStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
class WaitForFundingLockedStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with StateTestsHelperMethods {
case class FixtureParam(alice: TestFSMRef[State, Data, Channel], bob: TestFSMRef[State, Data, Channel], alice2bob: TestProbe, bob2alice: TestProbe, alice2blockchain: TestProbe, router: TestProbe)

View file

@ -39,7 +39,8 @@ import fr.acinq.eclair.transactions.DirectedHtlc.{incoming, outgoing}
import fr.acinq.eclair.transactions.Transactions
import fr.acinq.eclair.transactions.Transactions.{HtlcSuccessTx, htlcSuccessWeight, htlcTimeoutWeight, weight2fee}
import fr.acinq.eclair.wire.{AnnouncementSignatures, ChannelUpdate, ClosingSigned, CommitSig, Error, FailureMessageCodecs, PermanentChannelFailure, RevokeAndAck, Shutdown, UpdateAddHtlc, UpdateFailHtlc, UpdateFailMalformedHtlc, UpdateFee, UpdateFulfillHtlc}
import fr.acinq.eclair.{TestConstants, TestkitBaseClass, randomBytes32, _}
import fr.acinq.eclair._
import org.scalatest.funsuite.FixtureAnyFunSuiteLike
import org.scalatest.{Outcome, Tag}
import scodec.bits._
@ -49,7 +50,7 @@ import scala.concurrent.duration._
* Created by PM on 05/07/2016.
*/
class NormalStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
class NormalStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with StateTestsHelperMethods {
type FixtureParam = SetupFixture

View file

@ -31,7 +31,8 @@ import fr.acinq.eclair.payment.relay.CommandBuffer
import fr.acinq.eclair.router.Announcements
import fr.acinq.eclair.transactions.Transactions.HtlcSuccessTx
import fr.acinq.eclair.wire._
import fr.acinq.eclair.{CltvExpiry, CltvExpiryDelta, LongToBtcAmount, TestConstants, TestkitBaseClass, randomBytes32}
import fr.acinq.eclair.{CltvExpiry, CltvExpiryDelta, LongToBtcAmount, TestConstants, TestKitBaseClass, randomBytes32}
import org.scalatest.funsuite.FixtureAnyFunSuiteLike
import org.scalatest.{Outcome, Tag}
import scala.concurrent.duration._
@ -40,7 +41,7 @@ import scala.concurrent.duration._
* Created by PM on 05/07/2016.
*/
class OfflineStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
class OfflineStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with StateTestsHelperMethods {
type FixtureParam = SetupFixture

View file

@ -32,8 +32,9 @@ import fr.acinq.eclair.payment.relay.{CommandBuffer, Origin}
import fr.acinq.eclair.router.Router.ChannelHop
import fr.acinq.eclair.wire.Onion.FinalLegacyPayload
import fr.acinq.eclair.wire.{CommitSig, Error, FailureMessageCodecs, PermanentChannelFailure, RevokeAndAck, Shutdown, UpdateAddHtlc, UpdateFailHtlc, UpdateFailMalformedHtlc, UpdateFee, UpdateFulfillHtlc}
import fr.acinq.eclair.{CltvExpiry, CltvExpiryDelta, LongToBtcAmount, TestConstants, TestkitBaseClass, randomBytes32}
import fr.acinq.eclair.{CltvExpiry, CltvExpiryDelta, LongToBtcAmount, TestConstants, TestKitBaseClass, randomBytes32}
import org.scalatest.Outcome
import org.scalatest.funsuite.FixtureAnyFunSuiteLike
import scodec.bits.ByteVector
import scala.concurrent.duration._
@ -42,7 +43,7 @@ import scala.concurrent.duration._
* Created by PM on 05/07/2016.
*/
class ShutdownStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
class ShutdownStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with StateTestsHelperMethods {
type FixtureParam = SetupFixture

View file

@ -30,7 +30,8 @@ import fr.acinq.eclair.channel._
import fr.acinq.eclair.channel.states.StateTestsHelperMethods
import fr.acinq.eclair.payment.relay.Origin
import fr.acinq.eclair.wire.{ClosingSigned, Error, Shutdown}
import fr.acinq.eclair.{CltvExpiry, LongToBtcAmount, TestConstants, TestkitBaseClass}
import fr.acinq.eclair.{CltvExpiry, LongToBtcAmount, TestConstants, TestKitBaseClass}
import org.scalatest.funsuite.FixtureAnyFunSuiteLike
import org.scalatest.{Outcome, Tag}
import scodec.bits.ByteVector
@ -41,7 +42,7 @@ import scala.util.Success
* Created by PM on 05/07/2016.
*/
class NegotiatingStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
class NegotiatingStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with StateTestsHelperMethods {
type FixtureParam = SetupFixture

View file

@ -33,7 +33,8 @@ import fr.acinq.eclair.payment.relay.Relayer._
import fr.acinq.eclair.payment.relay.{CommandBuffer, Origin}
import fr.acinq.eclair.transactions.{Scripts, Transactions}
import fr.acinq.eclair.wire._
import fr.acinq.eclair.{CltvExpiry, LongToBtcAmount, TestConstants, TestkitBaseClass, randomBytes32}
import fr.acinq.eclair.{CltvExpiry, LongToBtcAmount, TestConstants, TestKitBaseClass, randomBytes32}
import org.scalatest.funsuite.FixtureAnyFunSuiteLike
import org.scalatest.{Outcome, Tag}
import scodec.bits.ByteVector
@ -44,7 +45,7 @@ import scala.concurrent.duration._
* Created by PM on 05/07/2016.
*/
class ClosingStateSpec extends TestkitBaseClass with StateTestsHelperMethods {
class ClosingStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with StateTestsHelperMethods {
case class FixtureParam(alice: TestFSMRef[State, Data, Channel], bob: TestFSMRef[State, Data, Channel], alice2bob: TestProbe, bob2alice: TestProbe, alice2blockchain: TestProbe, bob2blockchain: TestProbe, relayerA: TestProbe, relayerB: TestProbe, channelUpdateListener: TestProbe, bobCommitTxes: List[PublishableTxs])

View file

@ -18,9 +18,10 @@ package fr.acinq.eclair.crypto
import java.nio.charset.Charset
import akka.actor.{Actor, ActorLogging, ActorRef, ActorSystem, OneForOneStrategy, Props, Stash, SupervisorStrategy, Terminated}
import akka.actor.{Actor, ActorLogging, ActorRef, OneForOneStrategy, Props, Stash, SupervisorStrategy, Terminated}
import akka.io.Tcp
import akka.testkit.{TestActorRef, TestFSMRef, TestKit, TestProbe}
import akka.testkit.{TestActorRef, TestFSMRef, TestProbe}
import fr.acinq.eclair.TestKitBaseClass
import fr.acinq.eclair.crypto.Noise.{Chacha20Poly1305CipherFunctions, CipherState}
import fr.acinq.eclair.crypto.TransportHandler.{Encryptor, ExtendedCipherState, Listener}
import fr.acinq.eclair.wire.CommonCodecs
@ -34,7 +35,7 @@ import scala.annotation.tailrec
import scala.concurrent.duration._
class TransportHandlerSpec extends TestKit(ActorSystem("test")) with AnyFunSuiteLike with BeforeAndAfterAll {
class TransportHandlerSpec extends TestKitBaseClass with AnyFunSuiteLike with BeforeAndAfterAll {
import TransportHandlerSpec._

View file

@ -25,10 +25,10 @@ import akka.testkit.{TestKit, TestProbe}
import fr.acinq.eclair.channel.ChannelPersisted
import fr.acinq.eclair.db.sqlite.SqliteChannelsDb
import fr.acinq.eclair.wire.ChannelCodecsSpec
import fr.acinq.eclair.{TestConstants, TestUtils, randomBytes32}
import fr.acinq.eclair.{TestConstants, TestKitBaseClass, TestUtils, randomBytes32}
import org.scalatest.funsuite.AnyFunSuiteLike
class BackupHandlerSpec extends TestKit(ActorSystem("test")) with AnyFunSuiteLike {
class BackupHandlerSpec extends TestKitBaseClass with AnyFunSuiteLike {
test("process backups") {
val db = TestConstants.inMemoryDb()

View file

@ -53,7 +53,7 @@ import fr.acinq.eclair.router.{Announcements, AnnouncementsBatchValidationSpec}
import fr.acinq.eclair.transactions.Transactions
import fr.acinq.eclair.transactions.Transactions.{HtlcSuccessTx, HtlcTimeoutTx}
import fr.acinq.eclair.wire._
import fr.acinq.eclair.{CltvExpiryDelta, Kit, LongToBtcAmount, MilliSatoshi, Setup, ShortChannelId, randomBytes32}
import fr.acinq.eclair.{CltvExpiryDelta, Kit, LongToBtcAmount, MilliSatoshi, Setup, ShortChannelId, TestKitBaseClass, randomBytes32}
import grizzled.slf4j.Logging
import org.json4s.DefaultFormats
import org.json4s.JsonAST.{JString, JValue}
@ -71,7 +71,7 @@ import scala.jdk.CollectionConverters._
* Created by PM on 15/03/2017.
*/
class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService with AnyFunSuiteLike with BeforeAndAfterAll with Logging {
class IntegrationSpec extends TestKitBaseClass with BitcoindService with AnyFunSuiteLike with BeforeAndAfterAll with Logging {
var nodes: Map[String, Kit] = Map()
@ -117,7 +117,7 @@ class IntegrationSpec extends TestKit(ActorSystem("test")) with BitcoindService
nodes.foreach {
case (name, setup) =>
logger.info(s"stopping node $name")
setup.system.terminate()
TestKit.shutdownActorSystem(setup.system)
}
}

View file

@ -20,7 +20,7 @@ import java.io.File
import java.util.concurrent.atomic.AtomicLong
import java.util.concurrent.{CountDownLatch, TimeUnit}
import akka.actor.{ActorRef, ActorSystem, Props}
import akka.actor.{ActorRef, Props}
import akka.testkit.{TestFSMRef, TestKit, TestProbe}
import fr.acinq.bitcoin.ByteVector32
import fr.acinq.eclair.TestConstants.{Alice, Bob, TestFeeEstimator}
@ -29,7 +29,7 @@ import fr.acinq.eclair.blockchain.fee.FeeratesPerKw
import fr.acinq.eclair.channel._
import fr.acinq.eclair.payment.receive.{ForwardHandler, PaymentHandler}
import fr.acinq.eclair.wire.Init
import fr.acinq.eclair.{LongToBtcAmount, TestUtils}
import fr.acinq.eclair.{LongToBtcAmount, TestKitBaseClass, TestUtils}
import org.scalatest.funsuite.FixtureAnyFunSuiteLike
import org.scalatest.matchers.should.Matchers
import org.scalatest.{BeforeAndAfterAll, Outcome}
@ -41,7 +41,7 @@ import scala.io.Source
* Created by PM on 30/05/2016.
*/
class RustyTestsSpec extends TestKit(ActorSystem("test")) with Matchers with FixtureAnyFunSuiteLike with BeforeAndAfterAll {
class RustyTestsSpec extends TestKitBaseClass with Matchers with FixtureAnyFunSuiteLike with BeforeAndAfterAll {
case class FixtureParam(ref: List[String], res: List[String])

View file

@ -29,13 +29,14 @@ import fr.acinq.eclair.crypto.TransportHandler
import fr.acinq.eclair.router.Router.{GossipDecision, GossipOrigin, LocalGossip, Rebroadcast, RemoteGossip, SendChannelQuery}
import fr.acinq.eclair.router.{RoutingSyncSpec, _}
import fr.acinq.eclair.wire._
import org.scalatest.funsuite.FixtureAnyFunSuiteLike
import org.scalatest.{Outcome, Tag}
import scodec.bits._
import scala.collection.mutable
import scala.concurrent.duration._
class PeerConnectionSpec extends TestkitBaseClass with StateTestsHelperMethods {
class PeerConnectionSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with StateTestsHelperMethods {
def ipv4FromInet4(address: InetSocketAddress) = IPv4.apply(address.getAddress.asInstanceOf[Inet4Address], address.getPort)

View file

@ -16,8 +16,10 @@
package fr.acinq.eclair.io
import java.net.{InetAddress, ServerSocket}
import java.net.{InetAddress, ServerSocket, Socket}
import java.util.concurrent.Executors
import akka.actor.FSM
import akka.actor.Status.Failure
import akka.testkit.{TestFSMRef, TestProbe}
import com.google.common.net.HostAndPort
@ -30,23 +32,22 @@ import fr.acinq.eclair.channel.states.StateTestsHelperMethods
import fr.acinq.eclair.channel.{Channel, ChannelCreated, HasCommitments}
import fr.acinq.eclair.io.Peer._
import fr.acinq.eclair.wire.{ChannelCodecsSpec, Color, NodeAddress, NodeAnnouncement}
import org.scalatest.funsuite.FixtureAnyFunSuiteLike
import org.scalatest.{Outcome, Tag}
import scodec.bits.{ByteVector, _}
import scala.concurrent.duration._
import scala.concurrent.{ExecutionContext, Future}
class PeerSpec extends TestkitBaseClass with StateTestsHelperMethods {
class PeerSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with StateTestsHelperMethods {
val fakeIPAddress: NodeAddress = NodeAddress.fromParts("1.2.3.4", 42000).get
case class FixtureParam(nodeParams: NodeParams, remoteNodeId: PublicKey, switchboard: TestProbe, router: TestProbe, watcher: TestProbe, relayer: TestProbe, peer: TestFSMRef[Peer.State, Peer.Data, Peer], peerConnection: TestProbe)
case class FixtureParam(nodeParams: NodeParams, remoteNodeId: PublicKey, watcher: TestProbe, relayer: TestProbe, peer: TestFSMRef[Peer.State, Peer.Data, Peer], peerConnection: TestProbe)
override protected def withFixture(test: OneArgTest): Outcome = {
val switchboard = TestProbe()
val router = TestProbe()
val watcher = TestProbe()
val relayer = TestProbe()
val paymentHandler = TestProbe()
val wallet: EclairWallet = new TestWallet()
val remoteNodeId = Bob.nodeParams.nodeId
val peerConnection = TestProbe()
@ -57,17 +58,18 @@ class PeerSpec extends TestkitBaseClass with StateTestsHelperMethods {
.modify(_.maxFundingSatoshis).setToIf(test.tags.contains("high-max-funding-satoshis"))(Btc(0.9))
.modify(_.autoReconnect).setToIf(test.tags.contains("auto_reconnect"))(true)
if (test.tags.contains("with_node_announcements")) {
if (test.tags.contains("with_node_announcement")) {
val bobAnnouncement = NodeAnnouncement(randomBytes64, ByteVector.empty, 1, Bob.nodeParams.nodeId, Color(100.toByte, 200.toByte, 300.toByte), "node-alias", fakeIPAddress :: Nil)
aliceParams.db.network.addNode(bobAnnouncement)
}
val peer: TestFSMRef[Peer.State, Peer.Data, Peer] = TestFSMRef(new Peer(aliceParams, remoteNodeId, switchboard.ref, router.ref, watcher.ref, relayer.ref, wallet))
withFixture(test.toNoArgTest(FixtureParam(aliceParams, remoteNodeId, switchboard, router, watcher, relayer, peer, peerConnection)))
val peer: TestFSMRef[Peer.State, Peer.Data, Peer] = TestFSMRef(new Peer(aliceParams, remoteNodeId, watcher.ref, relayer.ref, wallet))
withFixture(test.toNoArgTest(FixtureParam(aliceParams, remoteNodeId, watcher, relayer, peer, peerConnection)))
}
def connect(remoteNodeId: PublicKey, switchboard: TestProbe, peer: TestFSMRef[Peer.State, Peer.Data, Peer], peerConnection: TestProbe, channels: Set[HasCommitments] = Set.empty, remoteInit: wire.Init = wire.Init(Bob.nodeParams.features)): Unit = {
def connect(remoteNodeId: PublicKey, peer: TestFSMRef[Peer.State, Peer.Data, Peer], peerConnection: TestProbe, channels: Set[HasCommitments] = Set.empty, remoteInit: wire.Init = wire.Init(Bob.nodeParams.features)): Unit = {
// let's simulate a connection
val switchboard = TestProbe()
switchboard.send(peer, Peer.Init(channels))
val localInit = wire.Init(peer.underlyingActor.nodeParams.features)
switchboard.send(peer, PeerConnection.ConnectionReady(peerConnection.ref, remoteNodeId, fakeIPAddress.socketAddress, outgoing = true, localInit, remoteInit))
@ -79,7 +81,7 @@ class PeerSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("restore existing channels") { f =>
import f._
val probe = TestProbe()
connect(remoteNodeId, switchboard, peer, peerConnection, channels = Set(ChannelCodecsSpec.normal))
connect(remoteNodeId, peer, peerConnection, channels = Set(ChannelCodecsSpec.normal))
probe.send(peer, Peer.GetPeerInfo)
probe.expectMsg(PeerInfo(remoteNodeId, "CONNECTED", Some(fakeIPAddress.socketAddress), 1))
}
@ -93,9 +95,12 @@ class PeerSpec extends TestkitBaseClass with StateTestsHelperMethods {
probe.expectMsg(s"no address found")
}
test("successfully connect to peer at user request and reconnect automatically", Tag("auto_reconnect")) { f =>
test("successfully connect to peer at user request") { f =>
import f._
// this actor listens to connection requests and creates connections
system.actorOf(ClientSpawner.props(nodeParams, TestProbe().ref, TestProbe().ref))
// we create a dummy tcp server and update bob's announcement to point to it
val mockServer = new ServerSocket(0, 1, InetAddress.getLocalHost) // port will be assigned automatically
val mockAddress = HostAndPort.fromParts(mockServer.getInetAddress.getHostAddress, mockServer.getLocalPort)
@ -106,9 +111,40 @@ class PeerSpec extends TestkitBaseClass with StateTestsHelperMethods {
probe.send(peer, Peer.Connect(remoteNodeId, Some(mockAddress)))
// assert our mock server got an incoming connection (the client was spawned with the address from node_announcement)
within(30 seconds) {
mockServer.accept()
}
val res = TestProbe()
Future {
val socket = mockServer.accept()
res.ref ! socket
}(ExecutionContext.fromExecutorService(Executors.newFixedThreadPool(1)))
res.expectMsgType[Socket](10 seconds)
mockServer.close()
}
test("successfully reconnect to peer at startup when there are existing channels", Tag("auto_reconnect")) { f =>
import f._
// this actor listens to connection requests and creates connections
system.actorOf(ClientSpawner.props(nodeParams, TestProbe().ref, TestProbe().ref))
// we create a dummy tcp server and update bob's announcement to point to it
val mockServer = new ServerSocket(0, 1, InetAddress.getLocalHost) // port will be assigned automatically
val mockAddress = NodeAddress.fromParts(mockServer.getInetAddress.getHostAddress, mockServer.getLocalPort).get
// we put the server address in the node db
val ann = NodeAnnouncement(randomBytes64, ByteVector.empty, 1, Bob.nodeParams.nodeId, Color(100.toByte, 200.toByte, 300.toByte), "node-alias", mockAddress :: Nil)
nodeParams.db.network.addNode(ann)
val probe = TestProbe()
probe.send(peer, Peer.Init(Set(ChannelCodecsSpec.normal)))
// assert our mock server got an incoming connection (the client was spawned with the address from node_announcement)
val res = TestProbe()
Future {
val socket = mockServer.accept()
res.ref ! socket
}(ExecutionContext.fromExecutorService(Executors.newFixedThreadPool(1)))
res.expectMsgType[Socket](10 seconds)
mockServer.close()
}
@ -117,7 +153,7 @@ class PeerSpec extends TestkitBaseClass with StateTestsHelperMethods {
import f._
val probe = TestProbe()
connect(remoteNodeId, switchboard, peer, peerConnection, channels = Set(ChannelCodecsSpec.normal))
connect(remoteNodeId, peer, peerConnection, channels = Set(ChannelCodecsSpec.normal))
probe.send(peer, Peer.Connect(remoteNodeId, None))
probe.expectMsg("already connected")
@ -127,7 +163,7 @@ class PeerSpec extends TestkitBaseClass with StateTestsHelperMethods {
import f._
val probe = TestProbe()
connect(remoteNodeId, switchboard, peer, peerConnection, channels = Set(ChannelCodecsSpec.normal))
connect(remoteNodeId, peer, peerConnection, channels = Set(ChannelCodecsSpec.normal))
probe.send(peer, Peer.GetPeerInfo)
assert(probe.expectMsgType[Peer.PeerInfo].state == "CONNECTED")
@ -139,7 +175,7 @@ class PeerSpec extends TestkitBaseClass with StateTestsHelperMethods {
test("handle new connection in state CONNECTED") { f =>
import f._
connect(remoteNodeId, switchboard, peer, peerConnection, channels = Set(ChannelCodecsSpec.normal))
connect(remoteNodeId, peer, peerConnection, channels = Set(ChannelCodecsSpec.normal))
// this is just to extract inits
val Peer.ConnectedData(_, _, localInit, remoteInit, _) = peer.stateData
@ -163,13 +199,38 @@ class PeerSpec extends TestkitBaseClass with StateTestsHelperMethods {
awaitCond(peer.stateData.asInstanceOf[Peer.ConnectedData].peerConnection === peerConnection3.ref)
}
test("send state transitions to child reconnection actor", Tag("auto_reconnect"), Tag("with_node_announcement")) { f =>
import f._
// monitor state changes of child reconnection task
val monitor = TestProbe()
val reconnectionTask = peer.underlyingActor.context.child("reconnection-task").get
monitor.send(reconnectionTask, FSM.SubscribeTransitionCallBack(monitor.ref))
monitor.expectMsg(FSM.CurrentState(reconnectionTask, ReconnectionTask.IDLE))
val probe = TestProbe()
probe.send(peer, Peer.Init(Set(ChannelCodecsSpec.normal)))
// the reconnection task will wait a little...
monitor.expectMsg(FSM.Transition(reconnectionTask, ReconnectionTask.IDLE, ReconnectionTask.WAITING))
// then it will trigger a reconnection request (which will be left unhandled because there is no listener)
monitor.expectMsg(FSM.Transition(reconnectionTask, ReconnectionTask.WAITING, ReconnectionTask.CONNECTING))
// we simulate a success
val dummyInit = wire.Init(peer.underlyingActor.nodeParams.features)
probe.send(peer, PeerConnection.ConnectionReady(peerConnection.ref, remoteNodeId, fakeIPAddress.socketAddress, outgoing = true, dummyInit, dummyInit))
// we make sure that the reconnection task has done a full circle
monitor.expectMsg(FSM.Transition(reconnectionTask, ReconnectionTask.CONNECTING, ReconnectionTask.IDLE))
}
test("don't spawn a wumbo channel if wumbo feature isn't enabled") { f =>
import f._
val probe = TestProbe()
val fundingAmountBig = Channel.MAX_FUNDING + 10000.sat
system.eventStream.subscribe(probe.ref, classOf[ChannelCreated])
connect(remoteNodeId, switchboard, peer, peerConnection)
connect(remoteNodeId, peer, peerConnection)
assert(peer.stateData.channels.isEmpty)
probe.send(peer, Peer.OpenChannel(remoteNodeId, fundingAmountBig, 0 msat, None, None, None))
@ -183,7 +244,7 @@ class PeerSpec extends TestkitBaseClass with StateTestsHelperMethods {
val probe = TestProbe()
val fundingAmountBig = Channel.MAX_FUNDING + 10000.sat
system.eventStream.subscribe(probe.ref, classOf[ChannelCreated])
connect(remoteNodeId, switchboard, peer, peerConnection) // Bob doesn't support wumbo, Alice does
connect(remoteNodeId, peer, peerConnection) // Bob doesn't support wumbo, Alice does
assert(peer.stateData.channels.isEmpty)
probe.send(peer, Peer.OpenChannel(remoteNodeId, fundingAmountBig, 0 msat, None, None, None))
@ -197,7 +258,7 @@ class PeerSpec extends TestkitBaseClass with StateTestsHelperMethods {
val probe = TestProbe()
val fundingAmountBig = Btc(1).toSatoshi
system.eventStream.subscribe(probe.ref, classOf[ChannelCreated])
connect(remoteNodeId, switchboard, peer, peerConnection, remoteInit = wire.Init(hex"80000")) // Bob supports wumbo
connect(remoteNodeId, peer, peerConnection, remoteInit = wire.Init(hex"80000")) // Bob supports wumbo
assert(peer.stateData.channels.isEmpty)
probe.send(peer, Peer.OpenChannel(remoteNodeId, fundingAmountBig, 0 msat, None, None, None))
@ -210,7 +271,7 @@ class PeerSpec extends TestkitBaseClass with StateTestsHelperMethods {
val probe = TestProbe()
system.eventStream.subscribe(probe.ref, classOf[ChannelCreated])
connect(remoteNodeId, switchboard, peer, peerConnection)
connect(remoteNodeId, peer, peerConnection)
assert(peer.stateData.channels.isEmpty)
probe.send(peer, Peer.OpenChannel(remoteNodeId, 12300 sat, 0 msat, None, None, None))

View file

@ -18,21 +18,27 @@ package fr.acinq.eclair.io
import java.net.{InetAddress, ServerSocket}
import akka.actor.FSM
import akka.testkit.{TestFSMRef, TestProbe}
import fr.acinq.bitcoin.Crypto.PublicKey
import fr.acinq.eclair.channel.states.StateTestsHelperMethods
import fr.acinq.eclair.io.Peer.ChannelId
import fr.acinq.eclair.io.ReconnectionTask.WaitingData
import fr.acinq.eclair.wire.{Color, NodeAddress, NodeAnnouncement}
import fr.acinq.eclair.{TestConstants, TestkitBaseClass, _}
import fr.acinq.eclair.{TestConstants, TestKitBaseClass, _}
import org.scalatest.funsuite.FixtureAnyFunSuiteLike
import org.scalatest.{Outcome, Tag}
import scodec.bits.ByteVector
import scala.concurrent.duration._
class ReconnectionTaskSpec extends TestkitBaseClass with StateTestsHelperMethods {
class ReconnectionTaskSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with StateTestsHelperMethods {
val fakeIPAddress = NodeAddress.fromParts("1.2.3.4", 42000).get
val fakeIPAddress = NodeAddress.fromParts("localhost", 42000).get
val channels = Map(Peer.FinalChannelId(randomBytes32) -> system.deadLetters)
val PeerNothingData = Peer.Nothing
val PeerDisconnectedData = Peer.DisconnectedData(channels)
val PeerConnectedData = Peer.ConnectedData(fakeIPAddress.socketAddress, system.deadLetters, null, null, channels.map { case (k: ChannelId, v) => (k, v) })
case class FixtureParam(nodeParams: NodeParams, remoteNodeId: PublicKey, reconnectionTask: TestFSMRef[ReconnectionTask.State, ReconnectionTask.Data, ReconnectionTask], monitor: TestProbe)
@ -50,9 +56,11 @@ class ReconnectionTaskSpec extends TestkitBaseClass with StateTestsHelperMethods
aliceParams.db.network.addNode(bobAnnouncement)
}
system.actorOf(ClientSpawner.props(aliceParams, TestProbe().ref, TestProbe().ref))
val monitor = TestProbe()
val reconnectionTask: TestFSMRef[ReconnectionTask.State, ReconnectionTask.Data, ReconnectionTask] =
TestFSMRef(new ReconnectionTask(aliceParams, remoteNodeId, TestProbe().ref, TestProbe().ref) {
TestFSMRef(new ReconnectionTask(aliceParams, remoteNodeId) {
onTransition {
case state -> nextState => monitor.ref ! TransitionWithData(state, nextState, stateData, nextStateData)
}
@ -65,15 +73,23 @@ class ReconnectionTaskSpec extends TestkitBaseClass with StateTestsHelperMethods
import f._
val peer = TestProbe()
peer.send(reconnectionTask, FSM.Transition(peer.ref, Peer.INSTANTIATING, Peer.DISCONNECTED))
monitor.expectNoMsg()
peer.send(reconnectionTask, Peer.Transition(PeerNothingData, PeerDisconnectedData))
monitor.expectNoMessage()
}
test("stay idle at startup if there are no channels", Tag("auto_reconnect"), Tag("with_node_announcements")) { f =>
import f._
val peer = TestProbe()
peer.send(reconnectionTask, Peer.Transition(PeerNothingData, Peer.DisconnectedData(Map.empty)))
monitor.expectNoMessage()
}
test("only try to connect once at startup if auto-reconnect is enabled but there are no known address", Tag("auto_reconnect")) { f =>
import f._
val peer = TestProbe()
peer.send(reconnectionTask, FSM.Transition(peer.ref, Peer.INSTANTIATING, Peer.DISCONNECTED))
peer.send(reconnectionTask, Peer.Transition(PeerNothingData, PeerDisconnectedData))
val TransitionWithData(ReconnectionTask.IDLE, ReconnectionTask.WAITING, _, _) = monitor.expectMsgType[TransitionWithData]
val TransitionWithData(ReconnectionTask.WAITING, ReconnectionTask.IDLE, _, _) = monitor.expectMsgType[TransitionWithData]
monitor.expectNoMsg()
@ -83,7 +99,7 @@ class ReconnectionTaskSpec extends TestkitBaseClass with StateTestsHelperMethods
import f._
val peer = TestProbe()
peer.send(reconnectionTask, FSM.Transition(peer.ref, Peer.INSTANTIATING, Peer.DISCONNECTED))
peer.send(reconnectionTask, Peer.Transition(PeerNothingData, PeerDisconnectedData))
val TransitionWithData(ReconnectionTask.IDLE, ReconnectionTask.WAITING, _, _) = monitor.expectMsgType[TransitionWithData]
val TransitionWithData(ReconnectionTask.WAITING, ReconnectionTask.CONNECTING, _, connectingData: ReconnectionTask.ConnectingData) = monitor.expectMsgType[TransitionWithData]
assert(connectingData.to === fakeIPAddress.socketAddress)
@ -96,12 +112,12 @@ class ReconnectionTaskSpec extends TestkitBaseClass with StateTestsHelperMethods
val probe = TestProbe()
val peer = TestProbe()
nodeParams.db.peers.addOrUpdatePeer(remoteNodeId, NodeAddress.fromParts("localhost", 42).get)
peer.send(reconnectionTask, FSM.Transition(peer.ref, Peer.INSTANTIATING, Peer.DISCONNECTED))
nodeParams.db.peers.addOrUpdatePeer(remoteNodeId, fakeIPAddress)
peer.send(reconnectionTask, Peer.Transition(PeerNothingData, PeerDisconnectedData))
val TransitionWithData(ReconnectionTask.IDLE, ReconnectionTask.WAITING, _, _) = monitor.expectMsgType[TransitionWithData]
probe.send(reconnectionTask, ReconnectionTask.TickReconnect)
val TransitionWithData(ReconnectionTask.WAITING, ReconnectionTask.CONNECTING, _, _) = monitor.expectMsgType[TransitionWithData]
peer.send(reconnectionTask, FSM.Transition(peer.ref, Peer.DISCONNECTED, Peer.CONNECTED))
peer.send(reconnectionTask, Peer.Transition(PeerDisconnectedData, PeerConnectedData))
val TransitionWithData(ReconnectionTask.CONNECTING, ReconnectionTask.IDLE, _, _) = monitor.expectMsgType[TransitionWithData]
// NB: we change the data to make it appear like we have been connected for a long time
@ -109,13 +125,13 @@ class ReconnectionTaskSpec extends TestkitBaseClass with StateTestsHelperMethods
val TransitionWithData(ReconnectionTask.IDLE, ReconnectionTask.IDLE, _, _) = monitor.expectMsgType[TransitionWithData]
// disconnection
peer.send(reconnectionTask, FSM.Transition(peer.ref, Peer.CONNECTED, Peer.DISCONNECTED))
peer.send(reconnectionTask, Peer.Transition(PeerConnectedData, PeerDisconnectedData))
// auto reconnect
val TransitionWithData(ReconnectionTask.IDLE, ReconnectionTask.WAITING, _, waitingData0: WaitingData) = monitor.expectMsgType[TransitionWithData]
assert(waitingData0.nextReconnectionDelay >= (200 milliseconds))
assert(waitingData0.nextReconnectionDelay <= (10 seconds))
probe.send(reconnectionTask, ReconnectionTask.TickReconnect) // we send it manually in order to not have to actually wait (duplicates don' matter since we look at transitions sequentially)
probe.send(reconnectionTask, ReconnectionTask.TickReconnect) // we send it manually in order to not have to actually wait (duplicates don't matter since we look at transitions sequentially)
val TransitionWithData(ReconnectionTask.WAITING, ReconnectionTask.CONNECTING, _, _) = monitor.expectMsgType[TransitionWithData]
val TransitionWithData(ReconnectionTask.CONNECTING, ReconnectionTask.WAITING, _, waitingData1: WaitingData) = monitor.expectMsgType[TransitionWithData]
@ -130,11 +146,11 @@ class ReconnectionTaskSpec extends TestkitBaseClass with StateTestsHelperMethods
probe.send(reconnectionTask, ReconnectionTask.TickReconnect)
val TransitionWithData(ReconnectionTask.WAITING, ReconnectionTask.CONNECTING, _, _) = monitor.expectMsgType[TransitionWithData]
// connection finally succeeds
peer.send(reconnectionTask, FSM.Transition(peer.ref, Peer.DISCONNECTED, Peer.CONNECTED))
peer.send(reconnectionTask, Peer.Transition(PeerDisconnectedData, PeerConnectedData))
val TransitionWithData(ReconnectionTask.CONNECTING, ReconnectionTask.IDLE, _, _) = monitor.expectMsgType[TransitionWithData]
// we are disconnected one more time
peer.send(reconnectionTask, FSM.Transition(peer.ref, Peer.CONNECTED, Peer.DISCONNECTED))
peer.send(reconnectionTask, Peer.Transition(PeerConnectedData, PeerDisconnectedData))
// the auto reconnect kicks off again, but this time we pick up the reconnect delay where we left it
val TransitionWithData(ReconnectionTask.IDLE, ReconnectionTask.WAITING, _, waitingData3: WaitingData) = monitor.expectMsgType[TransitionWithData]

View file

@ -1,19 +1,19 @@
package fr.acinq.eclair.io
import akka.actor.{ActorRef, ActorSystem}
import akka.testkit.{TestActorRef, TestKit, TestProbe}
import akka.actor.ActorRef
import akka.testkit.{TestActorRef, TestProbe}
import fr.acinq.bitcoin.ByteVector64
import fr.acinq.bitcoin.Crypto.PublicKey
import fr.acinq.eclair.NodeParams
import fr.acinq.eclair.TestConstants._
import fr.acinq.eclair.blockchain.TestWallet
import fr.acinq.eclair.wire._
import fr.acinq.eclair.{NodeParams, TestKitBaseClass}
import org.scalatest.funsuite.AnyFunSuiteLike
import scodec.bits._
class SwitchboardSpec extends TestKit(ActorSystem("test")) with AnyFunSuiteLike {
class SwitchboardSpec extends TestKitBaseClass with AnyFunSuiteLike {
class TestSwitchboard(nodeParams: NodeParams, remoteNodeId: PublicKey, remotePeer: TestProbe) extends Switchboard(nodeParams, TestProbe().ref, TestProbe().ref, TestProbe().ref, new TestWallet()) {
class TestSwitchboard(nodeParams: NodeParams, remoteNodeId: PublicKey, remotePeer: TestProbe) extends Switchboard(nodeParams, TestProbe().ref, TestProbe().ref, new TestWallet()) {
override def createPeer(remoteNodeId2: PublicKey): ActorRef = {
assert(remoteNodeId === remoteNodeId2)
remotePeer.ref

View file

@ -30,7 +30,7 @@ import fr.acinq.eclair.payment.receive.MultiPartPaymentFSM.HtlcPart
import fr.acinq.eclair.payment.receive.{MultiPartPaymentFSM, PaymentHandler}
import fr.acinq.eclair.payment.relay.CommandBuffer
import fr.acinq.eclair.wire._
import fr.acinq.eclair.{CltvExpiry, CltvExpiryDelta, LongToBtcAmount, NodeParams, ShortChannelId, TestConstants, randomKey}
import fr.acinq.eclair.{CltvExpiry, CltvExpiryDelta, LongToBtcAmount, NodeParams, ShortChannelId, TestConstants, TestKitBaseClass, randomKey}
import org.scalatest.Outcome
import org.scalatest.funsuite.FixtureAnyFunSuiteLike
import scodec.bits.HexStringSyntax
@ -41,7 +41,7 @@ import scala.concurrent.duration._
* Created by PM on 24/03/2017.
*/
class MultiPartHandlerSpec extends TestKit(ActorSystem("test")) with FixtureAnyFunSuiteLike {
class MultiPartHandlerSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike {
case class FixtureParam(nodeParams: NodeParams, defaultExpiry: CltvExpiry, commandBuffer: TestProbe, eventListener: TestProbe, sender: TestProbe) {
lazy val normalHandler = TestActorRef[PaymentHandler](PaymentHandler.props(nodeParams, commandBuffer.ref))

View file

@ -16,14 +16,13 @@
package fr.acinq.eclair.payment
import akka.actor.ActorSystem
import akka.actor.FSM.{CurrentState, SubscribeTransitionCallBack, Transition}
import akka.testkit.{TestActorRef, TestKit, TestProbe}
import akka.testkit.{TestActorRef, TestProbe}
import fr.acinq.bitcoin.ByteVector32
import fr.acinq.eclair.payment.receive.MultiPartPaymentFSM
import fr.acinq.eclair.payment.receive.MultiPartPaymentFSM._
import fr.acinq.eclair.wire.{IncorrectOrUnknownPaymentDetails, UpdateAddHtlc}
import fr.acinq.eclair.{CltvExpiry, LongToBtcAmount, MilliSatoshi, NodeParams, TestConstants, randomBytes32, wire}
import fr.acinq.eclair.{CltvExpiry, LongToBtcAmount, MilliSatoshi, NodeParams, TestConstants, TestKitBaseClass, randomBytes32, wire}
import org.scalatest.funsuite.AnyFunSuiteLike
import scodec.bits.ByteVector
@ -34,7 +33,7 @@ import scala.concurrent.duration._
* Created by t-bast on 18/07/2019.
*/
class MultiPartPaymentFSMSpec extends TestKit(ActorSystem("test")) with AnyFunSuiteLike {
class MultiPartPaymentFSMSpec extends TestKitBaseClass with AnyFunSuiteLike {
import MultiPartPaymentFSMSpec._

View file

@ -46,7 +46,7 @@ import scala.util.Random
* Created by t-bast on 18/07/2019.
*/
class MultiPartPaymentLifecycleSpec extends TestKit(ActorSystem("test")) with FixtureAnyFunSuiteLike {
class MultiPartPaymentLifecycleSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike {
import MultiPartPaymentLifecycleSpec._

View file

@ -33,8 +33,9 @@ import fr.acinq.eclair.payment.send.PaymentInitiator.SendPaymentConfig
import fr.acinq.eclair.payment.send.PaymentLifecycle.SendPayment
import fr.acinq.eclair.router.RouteNotFound
import fr.acinq.eclair.wire._
import fr.acinq.eclair.{CltvExpiry, CltvExpiryDelta, LongToBtcAmount, MilliSatoshi, NodeParams, ShortChannelId, TestConstants, TestkitBaseClass, nodeFee, randomBytes, randomBytes32, randomKey}
import fr.acinq.eclair.{CltvExpiry, CltvExpiryDelta, LongToBtcAmount, MilliSatoshi, NodeParams, ShortChannelId, TestConstants, TestKitBaseClass, nodeFee, randomBytes, randomBytes32, randomKey}
import org.scalatest.Outcome
import org.scalatest.funsuite.FixtureAnyFunSuiteLike
import scodec.bits.HexStringSyntax
import scala.collection.immutable.Queue
@ -45,7 +46,7 @@ import scala.util.Random
* Created by t-bast on 10/10/2019.
*/
class NodeRelayerSpec extends TestkitBaseClass {
class NodeRelayerSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike {
import NodeRelayerSpec._

View file

@ -21,12 +21,13 @@ import akka.actor.{ActorContext, ActorSystem}
import akka.event.DiagnosticLoggingAdapter
import akka.testkit.{TestKit, TestProbe}
import fr.acinq.eclair.TestConstants.Alice
import fr.acinq.eclair.TestKitBaseClass
import fr.acinq.eclair.payment.receive.{PaymentHandler, ReceiveHandler}
import org.scalatest.funsuite.AnyFunSuiteLike
import scala.concurrent.duration._
class PaymentHandlerSpec extends TestKit(ActorSystem("test")) with AnyFunSuiteLike {
class PaymentHandlerSpec extends TestKitBaseClass with AnyFunSuiteLike {
test("compose payment handlers") {
val handler = system.actorOf(PaymentHandler.props(Alice.nodeParams, TestProbe().ref))

View file

@ -35,7 +35,7 @@ import fr.acinq.eclair.router.Router.{NodeHop, RouteParams}
import fr.acinq.eclair.wire.Onion.{FinalLegacyPayload, FinalTlvPayload}
import fr.acinq.eclair.wire.OnionTlv.{AmountToForward, OutgoingCltv}
import fr.acinq.eclair.wire.{Onion, OnionCodecs, OnionTlv, TrampolineFeeInsufficient, _}
import fr.acinq.eclair.{CltvExpiryDelta, LongToBtcAmount, NodeParams, TestConstants, randomBytes32, randomKey}
import fr.acinq.eclair.{CltvExpiryDelta, LongToBtcAmount, NodeParams, TestConstants, TestKitBaseClass, randomBytes32, randomKey}
import org.scalatest.funsuite.FixtureAnyFunSuiteLike
import org.scalatest.{Outcome, Tag}
import scodec.bits.HexStringSyntax
@ -46,7 +46,7 @@ import scala.concurrent.duration._
* Created by t-bast on 25/07/2019.
*/
class PaymentInitiatorSpec extends TestKit(ActorSystem("test")) with FixtureAnyFunSuiteLike {
class PaymentInitiatorSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike {
case class FixtureParam(nodeParams: NodeParams, initiator: TestActorRef[PaymentInitiator], payFsm: TestProbe, multiPartPayFsm: TestProbe, sender: TestProbe, eventListener: TestProbe)

View file

@ -33,8 +33,9 @@ import fr.acinq.eclair.router.Router.ChannelHop
import fr.acinq.eclair.transactions.{DirectedHtlc, IncomingHtlc, OutgoingHtlc}
import fr.acinq.eclair.wire.Onion.FinalLegacyPayload
import fr.acinq.eclair.wire._
import fr.acinq.eclair.{CltvExpiry, LongToBtcAmount, NodeParams, TestConstants, TestkitBaseClass, randomBytes32}
import fr.acinq.eclair.{CltvExpiry, LongToBtcAmount, NodeParams, TestConstants, TestKitBaseClass, randomBytes32}
import org.scalatest.Outcome
import org.scalatest.funsuite.FixtureAnyFunSuiteLike
import scodec.bits.ByteVector
import scala.concurrent.Promise
@ -44,7 +45,7 @@ import scala.concurrent.duration._
* Created by t-bast on 21/11/2019.
*/
class PostRestartHtlcCleanerSpec extends TestkitBaseClass with StateTestsHelperMethods {
class PostRestartHtlcCleanerSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with StateTestsHelperMethods {
import PostRestartHtlcCleanerSpec._

View file

@ -32,8 +32,9 @@ import fr.acinq.eclair.router.Router.{ChannelHop, GetNetworkStats, GetNetworkSta
import fr.acinq.eclair.router.{Announcements, _}
import fr.acinq.eclair.wire.Onion.{ChannelRelayTlvPayload, FinalLegacyPayload, FinalTlvPayload, PerHopPayload}
import fr.acinq.eclair.wire._
import fr.acinq.eclair.{CltvExpiry, CltvExpiryDelta, LongToBtcAmount, NodeParams, ShortChannelId, TestConstants, TestkitBaseClass, UInt64, nodeFee, randomBytes32}
import fr.acinq.eclair.{CltvExpiry, CltvExpiryDelta, LongToBtcAmount, NodeParams, ShortChannelId, TestConstants, TestKitBaseClass, UInt64, nodeFee, randomBytes32}
import org.scalatest.Outcome
import org.scalatest.funsuite.FixtureAnyFunSuiteLike
import scodec.bits.ByteVector
import scala.concurrent.duration._
@ -42,7 +43,7 @@ import scala.concurrent.duration._
* Created by PM on 29/08/2016.
*/
class RelayerSpec extends TestkitBaseClass {
class RelayerSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike {
import PaymentPacketSpec._

View file

@ -30,8 +30,9 @@ import fr.acinq.eclair.router.Announcements._
import fr.acinq.eclair.router.Router.{ChannelDesc, ChannelMeta, GossipDecision, PrivateChannel}
import fr.acinq.eclair.transactions.Scripts
import fr.acinq.eclair.wire._
import fr.acinq.eclair.{TestkitBaseClass, randomKey, _}
import fr.acinq.eclair.{TestKitBaseClass, randomKey, _}
import org.scalatest.Outcome
import org.scalatest.funsuite.FixtureAnyFunSuiteLike
import scodec.bits.{ByteVector, HexStringSyntax}
import scala.concurrent.duration._
@ -42,7 +43,7 @@ import scala.concurrent.duration._
* Created by PM on 29/08/2016.
*/
abstract class BaseRouterSpec extends TestkitBaseClass {
abstract class BaseRouterSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike {
case class FixtureParam(nodeParams: NodeParams, router: ActorRef, watcher: TestProbe)

View file

@ -41,7 +41,7 @@ import scala.compat.Platform
import scala.concurrent.duration._
class RoutingSyncSpec extends TestKit(ActorSystem("test")) with AnyFunSuiteLike with ParallelTestExecution {
class RoutingSyncSpec extends TestKitBaseClass with AnyFunSuiteLike with ParallelTestExecution {
import RoutingSyncSpec._

View file

@ -19,12 +19,12 @@ package fr.acinq.eclair.tor
import java.net.InetSocketAddress
import java.nio.file.{Files, Paths}
import akka.actor.ActorSystem
import akka.actor.ActorNotFound
import akka.io.Tcp.Connected
import akka.testkit.{ImplicitSender, TestActorRef, TestKit}
import akka.testkit.{ImplicitSender, TestActorRef}
import akka.util.ByteString
import fr.acinq.eclair.TestUtils
import fr.acinq.eclair.wire.{NodeAddress, Tor2, Tor3}
import fr.acinq.eclair.{TestKitBaseClass, TestUtils}
import org.scalatest._
import org.scalatest.funsuite.AnyFunSuiteLike
import scodec.bits._
@ -32,11 +32,9 @@ import scodec.bits._
import scala.concurrent.duration._
import scala.concurrent.{Await, Promise}
class TorProtocolHandlerSpec extends TestKit(ActorSystem("test"))
class TorProtocolHandlerSpec extends TestKitBaseClass
with AnyFunSuiteLike
with ImplicitSender
with BeforeAndAfterEach
with BeforeAndAfterAll {
with ImplicitSender {
import TorProtocolHandler._
@ -47,9 +45,9 @@ class TorProtocolHandlerSpec extends TestKit(ActorSystem("test"))
val CookieFilePath = Paths.get(TestUtils.BUILD_DIRECTORY, "testtorcookie.dat")
val AuthCookie = hex"AA8593C52DF9713CC5FF6A1D0A045B3FADCAE57745B1348A62A6F5F88D940485"
override protected def beforeEach(): Unit = {
super.afterEach()
override def withFixture(test: NoArgTest) = {
PkFilePath.toFile.delete()
super.withFixture(test) // Invoke the test function
}
ignore("connect to real tor daemon") {