some more changes

This commit is contained in:
rorp 2020-01-14 13:53:12 -08:00
parent 2f9d3606ca
commit 74fa1e61af
4 changed files with 113 additions and 60 deletions

View file

@ -21,28 +21,47 @@ object EclairBench extends App with EclairRpcTestUtil {
implicit val system = ActorSystem()
import system.dispatcher
val networkSize = 1
val paymentCount = 10
val channelAmount = 10000000000L.msats
val outputFileName = "test.csv"
// put compiled test jar files into binaries/eclair/${version} directory
// release
val EclairVersion = Option.empty[String]
val EclairCommit = Option.empty[String]
// None means current release
val TestEclairVersion = Option.empty[String]
val TestEclairCommit = Option.empty[String]
// val TestEclairVersion = Option("0.3.3-SNAPSHOT")
// val TestEclairCommit = Option("84825ff")
val SenderEclairVersion = Option.empty[String]
val SenderEclairCommit = Option.empty[String]
// psql
// compiled binary can be found here:
// https://s3-us-west-1.amazonaws.com/suredbits.com/eclair/eclair-node-0.3.3-SNAPSHOT-949f1ec-psql.jar
// put it into binaries/eclair/0.3.3-SNAPSHOT directory
// val EclairVersion = Option("0.3.3-SNAPSHOT")
// val EclairCommit = Option("949f1ec-psql")
val NetworkSize = 10
val PaymentCount = 2000
val ChannelAmount = 10000000000L.msats
val PaymentAmount = 10.msats
val OutputFileName = "test.csv"
val LogbackXml = None // Some("~/logback.xml")
// don't forget to recreate `eclair` Postgres database before starting a new test
EclairRpcTestUtil.customConfigMap = Map(
"eclair.db.driver" -> "psql"
"eclair.db.driver" -> "psql",
// "eclair.db.psql.pool.max-size" -> 12,
"eclair.db.psql.lock-type" -> "none"
// "eclair.db.psql.lock-type" -> "optimistic"
// "eclair.db.psql.lock-type" -> "exclusive"
)
def sendPayments(network: Network, amount: MilliSatoshis, count: Int)(
object Progress {
private var count = 0
private var percentage = 0
def inc(): Unit = synchronized {
count += 1
val newPercentage = count * 100 / (NetworkSize * PaymentCount)
if (newPercentage % 10 == 0 && newPercentage != percentage) {
percentage = newPercentage
print(s"$percentage% ")
}
}
}
def sendPayments(network: EclairNetwork, amount: MilliSatoshis, count: Int)(
implicit ec: ExecutionContext): Future[Vector[PaymentId]] =
for {
testNodeInfo <- network.testEclairNode.getInfo
@ -64,25 +83,26 @@ object EclairBench extends App with EclairRpcTestUtil {
None)
} yield {
logPaymentId(paymentHash, id)
Progress.inc()
acc :+ id
}
}
})
} yield paymentIds.flatten
def runTests(network: Network): Future[Vector[PaymentLogEntry]] = {
def runTests(network: EclairNetwork): Future[Vector[PaymentLogEntry]] = {
println("Setting up the test network")
for {
_ <- network.testEclairNode.connectToWebSocket(logEvent)
_ = println(
s"Set up ${networkSize} nodes, that will send $paymentCount paments to the test node each")
s"Set up ${NetworkSize} nodes, that will send $PaymentCount payments to the test node each")
_ = println(
s"Test node data directory: ${network.testEclairNode.instance.authCredentials.datadir
.getOrElse("")}")
_ = println("Testing...")
_ <- sendPayments(network, 1000.msats, paymentCount)
_ <- sendPayments(network, PaymentAmount, PaymentCount)
_ <- TestAsyncUtil.retryUntilSatisfied(
condition = paymentLog.size() == networkSize * paymentCount,
condition = paymentLog.size() == NetworkSize * PaymentCount,
duration = 1.second,
maxTries = 100)
_ <- TestAsyncUtil
@ -90,7 +110,7 @@ object EclairBench extends App with EclairRpcTestUtil {
paymentLog.values().asScala.forall(_.completed),
duration = 1.second,
maxTries = 100)
_ = println("Done!")
_ = println("\nDone!")
} yield {
paymentLog
.values()
@ -101,10 +121,13 @@ object EclairBench extends App with EclairRpcTestUtil {
}
val res: Future[Unit] = for {
network <- Network.start(EclairVersion,
EclairCommit,
networkSize,
channelAmount)
network <- EclairNetwork.start(TestEclairVersion,
TestEclairCommit,
SenderEclairVersion,
SenderEclairCommit,
NetworkSize,
ChannelAmount,
LogbackXml)
log <- runTests(network).recoverWith {
case e: Throwable =>
e.printStackTrace()
@ -122,7 +145,7 @@ object EclairBench extends App with EclairRpcTestUtil {
case (x, i) =>
s"${x.paymentSentAt - first.paymentSentAt},${i + 1},${x.toCSV}"
}
val outputFile = new File(outputFileName)
val outputFile = new File(OutputFileName)
Files.write(outputFile.toPath,
csv.asJava,
StandardOpenOption.CREATE,

View file

@ -704,10 +704,13 @@ class EclairRpcClient(val instance: EclairInstance, binary: Option[File] = None)
require(instance.authCredentials.datadir.isDefined,
s"A datadir needs to be provided to start eclair")
if (process.isEmpty) {
val p = Process(
s"java -jar -Declair.datadir=${instance.authCredentials.datadir.get} $pathToEclairJar &")
val logback = instance.logbackXmlPath
.map(path => s"-Dlogback.configurationFile=$path")
.getOrElse("")
val cmd =
s"java -jar -Declair.datadir=${instance.authCredentials.datadir.get} $logback $pathToEclairJar &"
val p = Process(cmd)
val result = p.run()
logger.debug(
s"Starting eclair with datadir ${instance.authCredentials.datadir.get}")

View file

@ -15,6 +15,7 @@ sealed trait EclairInstance {
def uri: URI
def rpcUri: URI
def authCredentials: EclairAuthCredentials
def logbackXmlPath: Option[String]
}
/**
@ -29,57 +30,67 @@ object EclairInstance {
network: NetworkParameters,
uri: URI,
rpcUri: URI,
authCredentials: EclairAuthCredentials)
authCredentials: EclairAuthCredentials,
logbackXmlPath: Option[String])
extends EclairInstance
def apply(
network: NetworkParameters,
uri: URI,
rpcUri: URI,
authCredentials: EclairAuthCredentials): EclairInstance = {
EclairInstanceImpl(network, uri, rpcUri, authCredentials)
authCredentials: EclairAuthCredentials,
logbackXmlPath: Option[String]): EclairInstance = {
EclairInstanceImpl(network, uri, rpcUri, authCredentials, logbackXmlPath)
}
private val DEFAULT_DATADIR = Paths.get(Properties.userHome, ".eclair")
private val DEFAULT_CONF_FILE = DEFAULT_DATADIR.resolve("eclair.conf")
def fromDatadir(datadir: File = DEFAULT_DATADIR.toFile): EclairInstance = {
def fromDatadir(
datadir: File = DEFAULT_DATADIR.toFile,
logbackXml: Option[String]): EclairInstance = {
require(datadir.exists, s"${datadir.getPath} does not exist!")
require(datadir.isDirectory, s"${datadir.getPath} is not a directory!")
val eclairConf = new File(datadir.getAbsolutePath + "/eclair.conf")
fromConfigFile(eclairConf)
fromConfigFile(eclairConf, logbackXml)
}
def fromConfigFile(file: File = DEFAULT_CONF_FILE.toFile): EclairInstance = {
def fromConfigFile(
file: File = DEFAULT_CONF_FILE.toFile,
logbackXml: Option[String]): EclairInstance = {
require(file.exists, s"${file.getPath} does not exist!")
require(file.isFile, s"${file.getPath} is not a file!")
val config = ConfigFactory.parseFile(file)
fromConfig(config, file.getParentFile)
fromConfig(config, file.getParentFile, logbackXml)
}
/**
* $fromConfigDoc
*/
def fromConfig(config: Config, datadir: File): EclairInstance = {
fromConfig(config, Some(datadir))
def fromConfig(
config: Config,
datadir: File,
logbackXml: Option[String]): EclairInstance = {
fromConfig(config, Some(datadir), logbackXml)
}
/**
* $fromConfigDoc
*/
def fromConfig(config: Config): EclairInstance = {
fromConfig(config, None)
fromConfig(config, None, None)
}
private def fromConfig(
config: Config,
datadir: Option[File]): EclairInstance = {
datadir: Option[File],
logbackXml: Option[String]): EclairInstance = {
val chain = ConfigUtil.getStringOrElse(config, "eclair.chain", "testnet")
// default conf: https://github.com/ACINQ/eclair/blob/master/eclair-core/src/main/resources/reference.conf
@ -116,7 +127,8 @@ object EclairInstance {
val instance = EclairInstance(network = np,
uri = uri,
rpcUri = rpcUri,
authCredentials = eclairAuth)
authCredentials = eclairAuth,
logbackXml)
instance
}

View file

@ -163,25 +163,32 @@ trait EclairRpcTestUtil extends BitcoinSLogger {
}
/** Assumes bitcoind is running already and you have specified correct bindings in eclair.conf */
def cannonicalEclairInstance(): EclairInstance = {
def cannonicalEclairInstance(
logbackXml: Option[String] = None): EclairInstance = {
val datadir = cannonicalDatadir
eclairInstance(datadir)
eclairInstance(datadir, logbackXml)
}
def eclairInstance(datadir: File): EclairInstance = {
val instance = EclairInstance.fromDatadir(datadir)
def eclairInstance(
datadir: File,
logbackXml: Option[String]): EclairInstance = {
val instance = EclairInstance.fromDatadir(datadir, logbackXml)
instance
}
/** Starts the given bitcoind instance and then starts the eclair instance */
def eclairInstance(bitcoindRpc: BitcoindRpcClient): EclairInstance = {
def eclairInstance(
bitcoindRpc: BitcoindRpcClient,
logbackXml: Option[String] = None): EclairInstance = {
val datadir = eclairDataDir(bitcoindRpc, false)
eclairInstance(datadir)
eclairInstance(datadir, logbackXml)
}
def randomEclairInstance(bitcoindRpc: BitcoindRpcClient): EclairInstance = {
def randomEclairInstance(
bitcoindRpc: BitcoindRpcClient,
logbackXml: Option[String] = None): EclairInstance = {
val datadir = eclairDataDir(bitcoindRpc, false)
eclairInstance(datadir)
eclairInstance(datadir, logbackXml)
}
def randomEclairClient(
@ -699,7 +706,7 @@ trait EclairRpcTestUtil extends BitcoinSLogger {
shutdownF
}
case class Network(
case class EclairNetwork(
bitcoind: BitcoindRpcClient,
testEclairNode: EclairRpcClient,
networkEclairNodes: Vector[EclairRpcClient],
@ -713,31 +720,36 @@ trait EclairRpcTestUtil extends BitcoinSLogger {
} yield ()
}
object Network {
object EclairNetwork {
def start(
eclairVersion: Option[String],
eclairCommit: Option[String],
testEclairVersion: Option[String],
testEclairCommit: Option[String],
senderEclairVersion: Option[String],
senderEclairCommit: Option[String],
networkSize: Int,
channelAmount: MilliSatoshis)(
implicit system: ActorSystem): Future[Network] = {
channelAmount: MilliSatoshis,
logbackXml: Option[String])(
implicit system: ActorSystem): Future[EclairNetwork] = {
import system.dispatcher
for {
bitcoind <- startedBitcoindRpcClient()
testEclairInstance = EclairRpcTestUtil.eclairInstance(bitcoind)
testEclairInstance = EclairRpcTestUtil.eclairInstance(bitcoind,
logbackXml =
logbackXml)
testEclairNode = new EclairRpcClient(
testEclairInstance,
binary(eclairVersion, eclairCommit))
binary(testEclairVersion, testEclairCommit))
_ <- testEclairNode.start()
_ <- awaitEclairInSync(testEclairNode, bitcoind)
networkEclairInstances = 1
.to(networkSize)
.toVector
.map(_ => EclairRpcTestUtil.eclairInstance(bitcoind))
.map(_ =>
EclairRpcTestUtil.eclairInstance(bitcoind, logbackXml = logbackXml))
networkEclairNodes = networkEclairInstances.map(
new EclairRpcClient(_,
binary(Some(EclairRpcClient.version),
Some(EclairRpcClient.commit))))
binary(senderEclairVersion, senderEclairCommit)))
_ <- Future.sequence(networkEclairNodes.map(_.start()))
_ <- Future.sequence(
networkEclairNodes.map(awaitEclairInSync(_, bitcoind)))
@ -756,7 +768,10 @@ trait EclairRpcTestUtil extends BitcoinSLogger {
}
_ <- Future.sequence(
channelIds.map(awaitChannelOpened(testEclairNode, _)))
} yield Network(bitcoind, testEclairNode, networkEclairNodes, channelIds)
} yield EclairNetwork(bitcoind,
testEclairNode,
networkEclairNodes,
channelIds)
}
}