Regtest: Bypass recursive Gradle invocations

This commit is contained in:
Alva Swanson 2023-09-12 15:38:12 +02:00
parent e0164dfc1b
commit f872d41d30
No known key found for this signature in database
GPG Key ID: 004760E77F753090
2 changed files with 113 additions and 64 deletions

View File

@ -2,9 +2,16 @@ package bisq.gradle.regtest_plugin
import org.gradle.api.Plugin import org.gradle.api.Plugin
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.file.RegularFile
import org.gradle.api.provider.Provider
import org.gradle.jvm.toolchain.JavaLanguageVersion
import org.gradle.jvm.toolchain.JavaToolchainService
import org.gradle.jvm.toolchain.JvmImplementation
import org.gradle.jvm.toolchain.JvmVendorSpec
import org.gradle.kotlin.dsl.register import org.gradle.kotlin.dsl.register
import javax.inject.Inject
class RegtestPlugin : Plugin<Project> { class RegtestPlugin @Inject constructor(private val javaToolchainService: JavaToolchainService) : Plugin<Project> {
companion object { companion object {
const val RPC_USER = "bisqdao" const val RPC_USER = "bisqdao"
@ -28,15 +35,17 @@ class RegtestPlugin : Plugin<Project> {
val startFirstSeedNodeTask = project.tasks.register<StartBisqTask>("startRegtestFirstSeednode") { val startFirstSeedNodeTask = project.tasks.register<StartBisqTask>("startRegtestFirstSeednode") {
dependsOn(startBitcoindTask) dependsOn(startBitcoindTask)
pidFile.set(project.layout.projectDirectory.file(".localnet/seednode_1.pid")) workingDirectory.set(project.layout.projectDirectory)
startScriptFile.set(project.layout.projectDirectory.file("bisq-seednode")) javaExecutable.set(getJavaExecutable())
libsDir.set(project.layout.projectDirectory.dir("seednode/build/app/lib"))
mainClass.set("bisq.seednode.SeedNodeMain")
arguments.set( arguments.set(
createSeedNodeArgs(5120, 2002, "seednode") createSeedNodeArgs(5120, 2002, "seednode")
) )
workingDirectory.set(project.layout.projectDirectory)
logFile.set(project.layout.projectDirectory.file(".localnet/seednode_1_shell.log")) logFile.set(project.layout.projectDirectory.file(".localnet/seednode_1_shell.log"))
pidFile.set(project.layout.projectDirectory.file(".localnet/seednode_1.pid"))
} }
val stopFirstSeedNodeTask = project.tasks.register<KillTask>("stopRegtestFirstSeednode") { val stopFirstSeedNodeTask = project.tasks.register<KillTask>("stopRegtestFirstSeednode") {
@ -47,15 +56,17 @@ class RegtestPlugin : Plugin<Project> {
dependsOn(startBitcoindTask) dependsOn(startBitcoindTask)
dependsOn(startFirstSeedNodeTask) dependsOn(startFirstSeedNodeTask)
pidFile.set(project.layout.projectDirectory.file(".localnet/seednode_2.pid")) workingDirectory.set(project.layout.projectDirectory)
startScriptFile.set(project.layout.projectDirectory.file("bisq-seednode")) javaExecutable.set(getJavaExecutable())
libsDir.set(project.layout.projectDirectory.dir("seednode/build/app/lib"))
mainClass.set("bisq.seednode.SeedNodeMain")
arguments.set( arguments.set(
createSeedNodeArgs(5121, 3002, "seednode2") createSeedNodeArgs(5121, 3002, "seednode2")
) )
workingDirectory.set(project.layout.projectDirectory)
logFile.set(project.layout.projectDirectory.file(".localnet/seednode_2_shell.log")) logFile.set(project.layout.projectDirectory.file(".localnet/seednode_2_shell.log"))
pidFile.set(project.layout.projectDirectory.file(".localnet/seednode_2.pid"))
} }
val stopSeedNodeTask = project.tasks.register<KillTask>("stopRegtestSecondSeednode") { val stopSeedNodeTask = project.tasks.register<KillTask>("stopRegtestSecondSeednode") {
@ -66,15 +77,17 @@ class RegtestPlugin : Plugin<Project> {
dependsOn(startFirstSeedNodeTask) dependsOn(startFirstSeedNodeTask)
dependsOn(startSecondSeedNodeTask) dependsOn(startSecondSeedNodeTask)
pidFile.set(project.layout.projectDirectory.file(".localnet/mediator.pid")) workingDirectory.set(project.layout.projectDirectory)
startScriptFile.set(project.layout.projectDirectory.file("bisq-desktop")) javaExecutable.set(getJavaExecutable())
libsDir.set(project.layout.projectDirectory.dir("desktop/build/app/lib"))
mainClass.set("bisq.desktop.app.BisqAppMain")
arguments.set( arguments.set(
createBisqUserArgs(4444, ".localnet/mediator", "Mediator") createBisqUserArgs(4444, ".localnet/mediator", "Mediator")
) )
workingDirectory.set(project.layout.projectDirectory)
logFile.set(project.layout.projectDirectory.file(".localnet/mediator_shell.log")) logFile.set(project.layout.projectDirectory.file(".localnet/mediator_shell.log"))
pidFile.set(project.layout.projectDirectory.file(".localnet/mediator.pid"))
} }
val stopMediatorTask = project.tasks.register<KillTask>("stopRegtestMediator") { val stopMediatorTask = project.tasks.register<KillTask>("stopRegtestMediator") {
@ -85,23 +98,26 @@ class RegtestPlugin : Plugin<Project> {
dependsOn(startFirstSeedNodeTask) dependsOn(startFirstSeedNodeTask)
dependsOn(startSecondSeedNodeTask) dependsOn(startSecondSeedNodeTask)
pidFile.set(project.layout.projectDirectory.file(".localnet/alice.pid")) workingDirectory.set(project.layout.projectDirectory)
startScriptFile.set(project.layout.projectDirectory.file("bisq-desktop")) javaExecutable.set(getJavaExecutable())
libsDir.set(project.layout.projectDirectory.dir("desktop/build/app/lib"))
mainClass.set("bisq.desktop.app.BisqAppMain")
val additionalArgs = listOf( val additionalArgs = listOf(
"--fullDaoNode=true", "--fullDaoNode=true",
"--rpcUser=bisqdao", "--rpcUser=bisqdao",
"--rpcPassword=bsq", "--rpcPassword=bsq",
"--rpcBlockNotificationPort=5122", "--rpcBlockNotificationPort=5122",
"--genesisBlockHeight=111", "--genesisBlockHeight=111",
"--genesisTxId=30af0050040befd8af25068cc697e418e09c2d8ebd8d411d2240591b9ec203cf" "--genesisTxId=30af0050040befd8af25068cc697e418e09c2d8ebd8d411d2240591b9ec203cf"
) )
arguments.set( arguments.set(
createBisqUserArgs(5555, ".localnet/alice", "Alice", additionalArgs) createBisqUserArgs(5555, ".localnet/alice", "Alice", additionalArgs)
) )
workingDirectory.set(project.layout.projectDirectory)
logFile.set(project.layout.projectDirectory.file(".localnet/alice_shell.log")) logFile.set(project.layout.projectDirectory.file(".localnet/alice_shell.log"))
pidFile.set(project.layout.projectDirectory.file(".localnet/alice.pid"))
} }
val stopAliceTask = project.tasks.register<KillTask>("stopRegtestAlice") { val stopAliceTask = project.tasks.register<KillTask>("stopRegtestAlice") {
@ -112,15 +128,17 @@ class RegtestPlugin : Plugin<Project> {
dependsOn(startMediatorTask) dependsOn(startMediatorTask)
dependsOn(startAliceTask) dependsOn(startAliceTask)
pidFile.set(project.layout.projectDirectory.file(".localnet/bob.pid")) workingDirectory.set(project.layout.projectDirectory)
startScriptFile.set(project.layout.projectDirectory.file("bisq-desktop")) javaExecutable.set(getJavaExecutable())
libsDir.set(project.layout.projectDirectory.dir("desktop/build/app/lib"))
mainClass.set("bisq.desktop.app.BisqAppMain")
arguments.set( arguments.set(
createBisqUserArgs(6666, ".localnet/bob", "Bob") createBisqUserArgs(6666, ".localnet/bob", "Bob")
) )
workingDirectory.set(project.layout.projectDirectory)
logFile.set(project.layout.projectDirectory.file(".localnet/bob_shell.log")) logFile.set(project.layout.projectDirectory.file(".localnet/bob_shell.log"))
pidFile.set(project.layout.projectDirectory.file(".localnet/bob.pid"))
} }
project.tasks.register<KillTask>("stopRegtest") { project.tasks.register<KillTask>("stopRegtest") {
@ -136,34 +154,43 @@ class RegtestPlugin : Plugin<Project> {
} }
} }
private fun createBisqUserArgs(nodePort: Int, private fun getJavaExecutable(): Provider<RegularFile> =
dataDir: String, javaToolchainService.launcherFor {
appName: String, languageVersion.set(JavaLanguageVersion.of(11))
additionalArgs: List<String> = emptyList()): List<String> = vendor.set(JvmVendorSpec.AZUL)
createBisqCommonArgs(nodePort) + implementation.set(JvmImplementation.VENDOR_SPECIFIC)
listOf( }.map { it.executablePath }
"--appDataDir=$dataDir",
"--appName=$appName" private fun createBisqUserArgs(
) + additionalArgs nodePort: Int,
dataDir: String,
appName: String,
additionalArgs: List<String> = emptyList()
): List<String> =
createBisqCommonArgs(nodePort) +
listOf(
"--appDataDir=$dataDir",
"--appName=$appName"
) + additionalArgs
private fun createSeedNodeArgs(blockNotificationPort: Int, nodePort: Int, appName: String): List<String> = private fun createSeedNodeArgs(blockNotificationPort: Int, nodePort: Int, appName: String): List<String> =
createBisqCommonArgs(nodePort) + createBisqCommonArgs(nodePort) +
listOf( listOf(
"--fullDaoNode=true", "--fullDaoNode=true",
"--rpcUser=${RPC_USER}", "--rpcUser=${RPC_USER}",
"--rpcPassword=${RPC_PASSWORD}", "--rpcPassword=${RPC_PASSWORD}",
"--rpcBlockNotificationPort=$blockNotificationPort", "--rpcBlockNotificationPort=$blockNotificationPort",
"--userDataDir=.localnet", "--userDataDir=.localnet",
"--appName=$appName" "--appName=$appName"
) )
private fun createBisqCommonArgs(nodePort: Int): List<String> = private fun createBisqCommonArgs(nodePort: Int): List<String> =
listOf( listOf(
"--baseCurrencyNetwork=BTC_REGTEST", "--baseCurrencyNetwork=BTC_REGTEST",
"--useLocalhostForP2P=true", "--useLocalhostForP2P=true",
"--useDevPrivilegeKeys=true", "--useDevPrivilegeKeys=true",
"--nodePort=$nodePort" "--nodePort=$nodePort"
) )
} }

View File

@ -4,23 +4,26 @@ import org.gradle.api.DefaultTask
import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.RegularFileProperty import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.ListProperty import org.gradle.api.provider.ListProperty
import org.gradle.api.tasks.Input import org.gradle.api.provider.Property
import org.gradle.api.tasks.InputDirectory import org.gradle.api.tasks.*
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.TaskAction
abstract class StartBisqTask : DefaultTask() { abstract class StartBisqTask : DefaultTask() {
@get:InputDirectory
abstract val workingDirectory: DirectoryProperty
@get:InputFile @get:InputFile
abstract val startScriptFile: RegularFileProperty abstract val javaExecutable: RegularFileProperty
@get:InputDirectory
abstract val libsDir: DirectoryProperty
@get:Input
abstract val mainClass: Property<String>
@get:Input @get:Input
abstract val arguments: ListProperty<String> abstract val arguments: ListProperty<String>
@get:InputDirectory
abstract val workingDirectory: DirectoryProperty
@get:Internal @get:Internal
abstract val logFile: RegularFileProperty abstract val logFile: RegularFileProperty
@ -30,15 +33,29 @@ abstract class StartBisqTask : DefaultTask() {
@TaskAction @TaskAction
fun run() { fun run() {
ProcessKiller(pidFile.asFile.get()) ProcessKiller(pidFile.asFile.get())
.kill() .kill()
// Wait until process stopped // Wait until process stopped
Thread.sleep(5000) Thread.sleep(5000)
val processBuilder = ProcessBuilder( val processBuilder = ProcessBuilder(
"bash", startScriptFile.asFile.get().absolutePath, arguments.get().joinToString(" ") javaExecutable.asFile.get().absolutePath,
"-XX:MaxRAM=8g",
"-Xss1280k",
"-XX:+UseG1GC",
"-XX:MaxHeapFreeRatio=10",
"-XX:MinHeapFreeRatio=5",
"-XX:+UseStringDeduplication",
"-Djava.net.preferIPv4Stack=true",
"-classpath", createClassPath(),
mainClass.get(),
) )
processBuilder.command()
.addAll(arguments.get())
processBuilder.directory(workingDirectory.asFile.get()) processBuilder.directory(workingDirectory.asFile.get())
processBuilder.redirectErrorStream(true) processBuilder.redirectErrorStream(true)
processBuilder.redirectOutput(logFile.asFile.get()) processBuilder.redirectOutput(logFile.asFile.get())
@ -47,7 +64,12 @@ abstract class StartBisqTask : DefaultTask() {
val pid = process.pid() val pid = process.pid()
pidFile.asFile pidFile.asFile
.get() .get()
.writeText(pid.toString()) .writeText(pid.toString())
}
private fun createClassPath(): String {
val libsDirFile = libsDir.asFile.get()
return libsDirFile.listFiles()!!.joinToString(separator = ":") { it.absolutePath }
} }
} }