mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-03-03 02:39:18 +01:00
some more changes
This commit is contained in:
parent
2f9d3606ca
commit
74fa1e61af
4 changed files with 113 additions and 60 deletions
|
@ -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,
|
||||
|
|
|
@ -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}")
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue