mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2025-02-22 22:36:34 +01:00
Adds typesafe-config parsing of bitcoin.conf (#279)
* Adds typesafe-config parsing of bitcoin.conf Adds ZmqConfig trait * Only add datadir if not present * Use old and new config settings
This commit is contained in:
parent
abcd7c5d6d
commit
1301336231
8 changed files with 364 additions and 41 deletions
|
@ -15,6 +15,7 @@ object Deps {
|
|||
val scodecV = "1.1.6"
|
||||
val junitV = "0.11"
|
||||
val nativeLoaderV = "2.3.2"
|
||||
val typesafeConfigV = "1.3.3"
|
||||
|
||||
val bitcoinsV = "0.0.1-SNAPSHOT"
|
||||
}
|
||||
|
@ -27,6 +28,7 @@ object Deps {
|
|||
val akkaHttp = "com.typesafe.akka" %% "akka-http" % V.akkav withSources() withJavadoc()
|
||||
val akkaStream = "com.typesafe.akka" %% "akka-stream" % V.akkaStreamv withSources() withJavadoc()
|
||||
val playJson = "com.typesafe.play" %% "play-json" % V.playv withSources() withJavadoc()
|
||||
val typesafeConfig = "com.typesafe" % "config" % V.typesafeConfigV withSources() withJavadoc()
|
||||
|
||||
val logback = "ch.qos.logback" % "logback-classic" % V.logback withSources() withJavadoc()
|
||||
|
||||
|
@ -85,6 +87,7 @@ object Deps {
|
|||
Compile.akkaStream,
|
||||
Compile.playJson,
|
||||
Compile.slf4j,
|
||||
Compile.typesafeConfig,
|
||||
Test.akkaHttp,
|
||||
Test.akkaStream,
|
||||
Test.logback,
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
package org.bitcoins.rpc.config
|
||||
|
||||
import java.io.File
|
||||
import java.net.URI
|
||||
import java.nio.file.Paths
|
||||
|
||||
import org.bitcoins.core.config.NetworkParameters
|
||||
import com.typesafe.config._
|
||||
import org.bitcoins.core.config._
|
||||
|
||||
import scala.util.{Failure, Properties, Success, Try}
|
||||
|
||||
/**
|
||||
* Created by chris on 4/29/17.
|
||||
|
@ -15,9 +20,9 @@ sealed trait BitcoindInstance {
|
|||
def uri: URI
|
||||
def rpcUri: URI
|
||||
def authCredentials: BitcoindAuthCredentials
|
||||
def zmqConfig: ZmqConfig
|
||||
|
||||
def rpcPort: Int = authCredentials.rpcPort
|
||||
def zmqPortOpt: Option[Int]
|
||||
}
|
||||
|
||||
object BitcoindInstance {
|
||||
|
@ -26,15 +31,144 @@ object BitcoindInstance {
|
|||
uri: URI,
|
||||
rpcUri: URI,
|
||||
authCredentials: BitcoindAuthCredentials,
|
||||
zmqPortOpt: Option[Int])
|
||||
extends BitcoindInstance
|
||||
zmqConfig: ZmqConfig = ZmqConfig()
|
||||
) extends BitcoindInstance
|
||||
|
||||
def apply(
|
||||
network: NetworkParameters,
|
||||
uri: URI,
|
||||
rpcUri: URI,
|
||||
authCredentials: BitcoindAuthCredentials,
|
||||
zmqPortOpt: Option[Int] = None): BitcoindInstance = {
|
||||
BitcoindInstanceImpl(network, uri, rpcUri, authCredentials, zmqPortOpt)
|
||||
zmqConfig: ZmqConfig = ZmqConfig()
|
||||
): BitcoindInstance = {
|
||||
BitcoindInstanceImpl(network,
|
||||
uri,
|
||||
rpcUri,
|
||||
authCredentials,
|
||||
zmqConfig = zmqConfig)
|
||||
}
|
||||
|
||||
private val DEFAULT_DATADIR =
|
||||
Paths.get(Properties.userHome, ".bitcoin")
|
||||
|
||||
private val DEFAULT_CONF_FILE = DEFAULT_DATADIR.resolve("bitcoin.conf")
|
||||
|
||||
def fromDatadir(datadir: File = DEFAULT_DATADIR.toFile): BitcoindInstance = {
|
||||
require(datadir.exists, s"${datadir.getPath} does not exist!")
|
||||
require(datadir.isDirectory, s"${datadir.getPath} is not a directory!")
|
||||
|
||||
val file = Paths.get(datadir.getAbsolutePath, "bitcoin.conf").toFile
|
||||
fromConfigFile(file)
|
||||
}
|
||||
|
||||
def fromConfigFile(
|
||||
file: File = DEFAULT_CONF_FILE.toFile): BitcoindInstance = {
|
||||
require(file.exists, s"${file.getPath} does not exist!")
|
||||
require(file.isFile, s"${file.getPath} is not a file!")
|
||||
|
||||
val config = ConfigFactory.parseFile(
|
||||
file,
|
||||
ConfigParseOptions.defaults
|
||||
.setSyntax(ConfigSyntax.PROPERTIES)) // bitcoin.conf is not a proper .conf file, uses Java properties=like syntax
|
||||
|
||||
val configWithDatadir =
|
||||
if (config.hasPath("datadir")) {
|
||||
config
|
||||
} else {
|
||||
config.withValue("datadir",
|
||||
ConfigValueFactory.fromAnyRef(file.getParent))
|
||||
}
|
||||
|
||||
fromConfig(configWithDatadir)
|
||||
}
|
||||
|
||||
def fromConfig(config: Config): BitcoindInstance = {
|
||||
val datadirStr = Try(config.getString("datadir"))
|
||||
.getOrElse(
|
||||
throw new IllegalArgumentException(
|
||||
"Provided config does not contain \"datadir\" setting!"))
|
||||
|
||||
val datadir = new File(datadirStr)
|
||||
require(datadir.exists, s"Datadir $datadirStr does not exist!")
|
||||
require(datadir.isDirectory, s"Datadir $datadirStr is not directory")
|
||||
fromConfig(config, datadir)
|
||||
}
|
||||
|
||||
def fromConfig(
|
||||
config: Config,
|
||||
datadir: File
|
||||
): BitcoindInstance = {
|
||||
val network = getNetwork(config)
|
||||
|
||||
val uri = getUri(config, network)
|
||||
val rpcUri = getRpcUri(config, network)
|
||||
|
||||
val username = config.getString("rpcuser")
|
||||
val password = config.getString("rpcpassword")
|
||||
val authCredentials =
|
||||
BitcoindAuthCredentials(username = username,
|
||||
password = password,
|
||||
rpcPort = rpcUri.getPort,
|
||||
datadir = datadir)
|
||||
|
||||
BitcoindInstance(network,
|
||||
uri,
|
||||
rpcUri,
|
||||
authCredentials,
|
||||
zmqConfig = ZmqConfig.fromConfig(config))
|
||||
}
|
||||
|
||||
private def isSet(config: Config, path: String): Boolean = {
|
||||
Try(config.getInt(path))
|
||||
.map(_ == 1)
|
||||
.getOrElse(false)
|
||||
}
|
||||
|
||||
private def getNetwork(config: Config): BitcoinNetwork = {
|
||||
val isTestnet = isSet(config, path = "testnet")
|
||||
val isRegTest = isSet(config, path = "regtest")
|
||||
|
||||
(isRegTest, isTestnet) match {
|
||||
case (true, true) =>
|
||||
throw new IllegalArgumentException(
|
||||
""""Cannot set both "regtest" and "testnet" options""")
|
||||
case (true, false) => RegTest
|
||||
case (false, true) => TestNet3
|
||||
case (false, false) => MainNet
|
||||
}
|
||||
}
|
||||
|
||||
private def getUri(config: Config, network: NetworkParameters): URI = {
|
||||
val port = Try(config.getInt("port")).getOrElse(network.port)
|
||||
val host = Try(config.getString("bind")).getOrElse("localhost")
|
||||
val uriT = Try {
|
||||
new URI(s"http://$host:$port")
|
||||
}
|
||||
|
||||
uriT match {
|
||||
case Success(uriSuccess) => uriSuccess
|
||||
case Failure(exception) =>
|
||||
throw new IllegalArgumentException(
|
||||
s"Could not construct URI from host $host and port $port",
|
||||
exception)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private def getRpcUri(config: Config, network: NetworkParameters): URI = {
|
||||
val rpcPort = Try(config.getInt("rpcport")).getOrElse(network.rpcPort)
|
||||
val rpcHost = Try(config.getString("rpcbind")).getOrElse("localhost")
|
||||
|
||||
val rpcUriT = Try {
|
||||
new URI(s"http://$rpcHost:$rpcPort")
|
||||
}
|
||||
rpcUriT match {
|
||||
case Success(uriSuccess) => uriSuccess
|
||||
case Failure(exception) =>
|
||||
throw new IllegalArgumentException(
|
||||
s"Could not construct URI from host $rpcHost and port $rpcPort",
|
||||
exception)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
90
rpc/src/main/scala/org/bitcoins/rpc/config/ZmqConfig.scala
Normal file
90
rpc/src/main/scala/org/bitcoins/rpc/config/ZmqConfig.scala
Normal file
|
@ -0,0 +1,90 @@
|
|||
package org.bitcoins.rpc.config
|
||||
import java.net.URI
|
||||
|
||||
import com.typesafe.config.Config
|
||||
|
||||
import scala.util.Try
|
||||
|
||||
sealed trait ZmqConfig {
|
||||
def hashBlock: Option[URI]
|
||||
def rawBlock: Option[URI]
|
||||
def hashTx: Option[URI]
|
||||
def rawTx: Option[URI]
|
||||
}
|
||||
|
||||
object ZmqConfig {
|
||||
private case class ZmqConfigImpl(
|
||||
hashBlock: Option[URI],
|
||||
rawBlock: Option[URI],
|
||||
hashTx: Option[URI],
|
||||
rawTx: Option[URI]
|
||||
) extends ZmqConfig
|
||||
|
||||
def apply(
|
||||
hashBlock: Option[URI] = None,
|
||||
rawBlock: Option[URI] = None,
|
||||
hashTx: Option[URI] = None,
|
||||
rawTx: Option[URI] = None
|
||||
): ZmqConfig =
|
||||
ZmqConfigImpl(hashBlock = hashBlock,
|
||||
rawBlock = rawBlock,
|
||||
hashTx = hashTx,
|
||||
rawTx = rawTx)
|
||||
|
||||
/**
|
||||
* Creates a `ZmqConfig` with all `URI`s set to
|
||||
* `localhost` and the same port
|
||||
*/
|
||||
def fromPort(port: Int): ZmqConfig = {
|
||||
val uri = new URI(s"tcp://localhost:$port")
|
||||
ZmqConfig(hashBlock = Some(uri),
|
||||
rawBlock = Some(uri),
|
||||
hashTx = Some(uri),
|
||||
rawTx = Some(uri))
|
||||
}
|
||||
|
||||
def fromConfig(config: Config): ZmqConfig =
|
||||
ZmqConfig(hashBlock = hashBlockUri(config),
|
||||
hashTx = hashTxUri(config),
|
||||
rawBlock = rawBlockUri(config),
|
||||
rawTx = rawTxUri(config))
|
||||
|
||||
private val RAW_BLOCK_KEY = "zmqpubrawblock"
|
||||
private val RAW_TX_KEY = "zmqpubrawtx"
|
||||
private val HASH_BLOCK_KEY = "zmqpubhashblock"
|
||||
private val HASH_TX_KEY = "zmqpubhashtx"
|
||||
|
||||
private val ZMQ_CONFIG_KEYS =
|
||||
List(RAW_TX_KEY, RAW_BLOCK_KEY, HASH_TX_KEY, HASH_BLOCK_KEY)
|
||||
|
||||
private def isValidZmqConfigKey(key: String): Boolean =
|
||||
ZMQ_CONFIG_KEYS.contains(key)
|
||||
|
||||
private def getZmqUri(config: Config, path: String): Option[URI] = {
|
||||
require(
|
||||
isValidZmqConfigKey(path),
|
||||
s"$path is not a valid ZMQ config key. Valid keys: ${ZMQ_CONFIG_KEYS.mkString(", ")}")
|
||||
|
||||
if (config.hasPath(path)) {
|
||||
Try(config.getString(path))
|
||||
.map(str => Some(new URI(str)))
|
||||
.getOrElse(throw new IllegalArgumentException(
|
||||
s"$path in config is not a valid URI"))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
private def rawBlockUri(config: Config): Option[URI] =
|
||||
getZmqUri(config, RAW_BLOCK_KEY)
|
||||
|
||||
private def rawTxUri(config: Config): Option[URI] =
|
||||
getZmqUri(config, RAW_TX_KEY)
|
||||
|
||||
private def hashBlockUri(config: Config): Option[URI] =
|
||||
getZmqUri(config, HASH_BLOCK_KEY)
|
||||
|
||||
private def hashTxUri(config: Config): Option[URI] =
|
||||
getZmqUri(config, HASH_TX_KEY)
|
||||
|
||||
}
|
9
rpc/src/test/resources/sample-bitcoin.conf
Normal file
9
rpc/src/test/resources/sample-bitcoin.conf
Normal file
|
@ -0,0 +1,9 @@
|
|||
testnet=0
|
||||
regtest=1
|
||||
rpcuser=user
|
||||
rpcpassword=password
|
||||
zmqpubrawblock=tcp://127.0.0.1:29005
|
||||
zmppubrawtx=tcp://127.0.0.1:29001
|
||||
rpcport=18336
|
||||
port=9000
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
package org.bitcoins.rpc
|
||||
import java.io.{File, PrintWriter}
|
||||
import java.nio.file.{Files, Path}
|
||||
|
||||
import akka.actor.ActorSystem
|
||||
import akka.testkit.TestKit
|
||||
import org.bitcoins.core.currency.Bitcoins
|
||||
import org.bitcoins.rpc.client.BitcoindRpcClient
|
||||
import org.bitcoins.rpc.config.BitcoindInstance
|
||||
import org.scalatest.{AsyncFlatSpec, BeforeAndAfterAll}
|
||||
|
||||
import scala.concurrent.Future
|
||||
import scala.io.Source
|
||||
|
||||
class BitcoindInstanceTest extends AsyncFlatSpec with BeforeAndAfterAll {
|
||||
|
||||
private implicit val actorSystem: ActorSystem = ActorSystem(
|
||||
"BitcoindInstanceTest")
|
||||
|
||||
private val sampleConf: Seq[String] =
|
||||
Source.fromResource("sample-bitcoin.conf").mkString.split("\n")
|
||||
private val datadir: Path = Files.createTempDirectory(null)
|
||||
|
||||
override protected def beforeAll(): Unit = {
|
||||
val confFile = new File(datadir.toString + "/bitcoin.conf")
|
||||
val pw = new PrintWriter(confFile)
|
||||
sampleConf.foreach(line => pw.write(line + "\n"))
|
||||
pw.close()
|
||||
}
|
||||
|
||||
override protected def afterAll(): Unit = {
|
||||
TestKit.shutdownActorSystem(actorSystem)
|
||||
}
|
||||
|
||||
behavior of "BitcoindInstance"
|
||||
|
||||
it should "parse a bitcoin.conf file, start bitcoind, mine some blocks and quit" in {
|
||||
val instance = BitcoindInstance.fromDatadir(datadir.toFile)
|
||||
val client = new BitcoindRpcClient(instance)
|
||||
BitcoindRpcTestUtil.startServers(Vector(client))
|
||||
RpcUtil.awaitServer(client)
|
||||
|
||||
for {
|
||||
_ <- client.generate(101)
|
||||
balance <- client.getBalance
|
||||
_ <- {
|
||||
assert(balance > Bitcoins(0))
|
||||
client.stop()
|
||||
}
|
||||
_ <- Future.successful(RpcUtil.awaitServerShutdown(client))
|
||||
} yield succeed
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -92,7 +92,7 @@ class RpcUtilTest extends AsyncFlatSpec with BeforeAndAfterAll {
|
|||
}
|
||||
}
|
||||
|
||||
"TestUtil" should "create a temp bitcoin directory when creating a DaemonInstance, and then delete it" in {
|
||||
"BitcoindRpcUtil" should "create a temp bitcoin directory when creating a DaemonInstance, and then delete it" in {
|
||||
val instance = BitcoindRpcTestUtil.instance(BitcoindRpcTestUtil.randomPort,
|
||||
BitcoindRpcTestUtil.randomPort)
|
||||
val dir = instance.authCredentials.datadir
|
||||
|
@ -120,7 +120,7 @@ class RpcUtilTest extends AsyncFlatSpec with BeforeAndAfterAll {
|
|||
assert(t.isFailure)
|
||||
}
|
||||
|
||||
"TestUtil" should "be able to create a connected node pair with 100 blocks and then delete them" in {
|
||||
it should "be able to create a connected node pair with 100 blocks and then delete them" in {
|
||||
BitcoindRpcTestUtil.createNodePair().flatMap {
|
||||
case (client1, client2) =>
|
||||
assert(client1.getDaemon.authCredentials.datadir.isDirectory)
|
||||
|
|
|
@ -17,7 +17,7 @@ import org.bitcoins.core.util.BitcoinSLogger
|
|||
import org.bitcoins.eclair.rpc.client.EclairRpcClient
|
||||
import org.bitcoins.eclair.rpc.config.EclairInstance
|
||||
import org.bitcoins.rpc.client.BitcoindRpcClient
|
||||
import org.bitcoins.rpc.config.BitcoindInstance
|
||||
import org.bitcoins.rpc.config.{BitcoindInstance, ZmqConfig}
|
||||
import org.bitcoins.rpc.{BitcoindRpcTestUtil, RpcUtil}
|
||||
|
||||
import scala.concurrent.Future
|
||||
|
@ -47,7 +47,7 @@ trait EclairTestUtil extends BitcoinSLogger {
|
|||
uri = uri,
|
||||
rpcUri = rpcUri,
|
||||
authCredentials = auth,
|
||||
zmqPortOpt = Some(zmqPort))
|
||||
zmqConfig = ZmqConfig.fromPort(zmqPort))
|
||||
}
|
||||
|
||||
//cribbed from https://github.com/Christewart/eclair/blob/bad02e2c0e8bd039336998d318a861736edfa0ad/eclair-core/src/test/scala/fr/acinq/eclair/integration/IntegrationSpec.scala#L140-L153
|
||||
|
@ -65,7 +65,11 @@ trait EclairTestUtil extends BitcoinSLogger {
|
|||
"eclair.bitcoind.rpcuser" -> bitcoindInstance.authCredentials.username,
|
||||
"eclair.bitcoind.rpcpassword" -> bitcoindInstance.authCredentials.password,
|
||||
"eclair.bitcoind.rpcport" -> bitcoindInstance.authCredentials.rpcPort,
|
||||
"eclair.bitcoind.zmq" -> s"tcp://127.0.0.1:${bitcoindInstance.zmqPortOpt.get}",
|
||||
// newer versions of Eclair has removed this config setting, in favor of
|
||||
// the below it. All three are included here for good measure
|
||||
"eclair.bitcoind.zmq" -> bitcoindInstance.zmqConfig.rawTx.get.toString,
|
||||
"eclair.bitcoind.zmqblock" -> bitcoindInstance.zmqConfig.rawBlock.get.toString,
|
||||
"eclair.bitcoind.zmqtx" -> bitcoindInstance.zmqConfig.rawTx.get.toString,
|
||||
"eclair.api.enabled" -> true,
|
||||
"eclair.api.binding-ip" -> "127.0.0.1",
|
||||
"eclair.api.password" -> "abc123",
|
||||
|
@ -332,7 +336,6 @@ trait EclairTestUtil extends BitcoinSLogger {
|
|||
rpcUri = new URI(s"http://localhost:${bitcoindRpcPort}"),
|
||||
authCredentials =
|
||||
eclairRpcClient.instance.authCredentials.bitcoinAuthOpt.get,
|
||||
None
|
||||
)
|
||||
new BitcoindRpcClient(bitcoindInstance)
|
||||
}
|
||||
|
|
|
@ -5,12 +5,19 @@ import java.net.URI
|
|||
|
||||
import akka.actor.ActorSystem
|
||||
import akka.stream.ActorMaterializer
|
||||
import com.typesafe.config.{Config, ConfigFactory}
|
||||
import org.bitcoins.core.config.RegTest
|
||||
import org.bitcoins.core.crypto.DoubleSha256Digest
|
||||
import org.bitcoins.core.util.BitcoinSLogger
|
||||
import org.bitcoins.rpc.client.BitcoindRpcClient
|
||||
import org.bitcoins.rpc.config.{BitcoindAuthCredentials, BitcoindInstance}
|
||||
import org.bitcoins.rpc.config.{
|
||||
BitcoindAuthCredentials,
|
||||
BitcoindInstance,
|
||||
ZmqConfig
|
||||
}
|
||||
|
||||
import scala.collection.immutable.Map
|
||||
import scala.collection.JavaConverters.{asScalaSet, mapAsJavaMap}
|
||||
import scala.concurrent.duration.{DurationInt, FiniteDuration}
|
||||
import scala.concurrent.{ExecutionContext, Future, Promise}
|
||||
import scala.util.{Failure, Success, Try}
|
||||
|
@ -20,6 +27,34 @@ trait BitcoindRpcTestUtil extends BitcoinSLogger {
|
|||
def randomDirName: String =
|
||||
0.until(5).map(_ => scala.util.Random.alphanumeric.head).mkString
|
||||
|
||||
def config(
|
||||
uri: URI,
|
||||
rpcUri: URI,
|
||||
zmqPort: Int,
|
||||
pruneMode: Boolean): Config = {
|
||||
val pass = randomDirName
|
||||
val username = "random_user_name"
|
||||
val values = Map(
|
||||
"rpcuser" -> username,
|
||||
"rpcpassword" -> pass,
|
||||
"rpcport" -> rpcUri.getPort,
|
||||
"port" -> uri.getPort,
|
||||
"daemon" -> "1",
|
||||
"server" -> "1",
|
||||
"debug" -> "1",
|
||||
"regtest" -> "1",
|
||||
"walletbroadcast" -> "0",
|
||||
"zmqpubhashtx" -> s"tcp://127.0.0.1:$zmqPort",
|
||||
"zmqpubhashblock" -> s"tcp://127.0.0.1:$zmqPort",
|
||||
"zmqpubrawtx" -> s"tcp://127.0.0.1:$zmqPort",
|
||||
"zmqpubrawblock" -> s"tcp://127.0.0.1:$zmqPort",
|
||||
"prune" -> (if (pruneMode) "1" else "0")
|
||||
)
|
||||
val javaMap = mapAsJavaMap(values)
|
||||
|
||||
ConfigFactory.parseMap(javaMap)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a datadir and places the username/password combo
|
||||
* in the bitcoin.conf in the datadir
|
||||
|
@ -29,39 +64,33 @@ trait BitcoindRpcTestUtil extends BitcoinSLogger {
|
|||
rpcUri: URI,
|
||||
zmqPort: Int,
|
||||
pruneMode: Boolean): BitcoindAuthCredentials = {
|
||||
val d = "/tmp/" + randomDirName
|
||||
val f = new java.io.File(d)
|
||||
f.mkdir()
|
||||
val conf = new java.io.File(f.getAbsolutePath + "/bitcoin.conf")
|
||||
conf.createNewFile()
|
||||
val username = "random_user_name"
|
||||
val pass = randomDirName
|
||||
val pw = new PrintWriter(conf)
|
||||
pw.write("rpcuser=" + username + "\n")
|
||||
pw.write("rpcpassword=" + pass + "\n")
|
||||
pw.write("rpcport=" + rpcUri.getPort + "\n")
|
||||
pw.write("port=" + uri.getPort + "\n")
|
||||
pw.write("daemon=1\n")
|
||||
pw.write("server=1\n")
|
||||
pw.write("debug=1\n")
|
||||
pw.write("regtest=1\n")
|
||||
pw.write("walletbroadcast=0\n")
|
||||
val conf = config(uri, rpcUri, zmqPort, pruneMode)
|
||||
val confSet = asScalaSet(conf.entrySet).toSet
|
||||
val confStr =
|
||||
confSet
|
||||
.map(entry => {
|
||||
val key = entry.getKey
|
||||
val value = entry.getValue.unwrapped
|
||||
s"$key=$value"})
|
||||
.mkString("\n")
|
||||
|
||||
pw.write(s"zmqpubhashtx=tcp://127.0.0.1:${zmqPort}\n")
|
||||
pw.write(s"zmqpubhashblock=tcp://127.0.0.1:${zmqPort}\n")
|
||||
pw.write(s"zmqpubrawtx=tcp://127.0.0.1:${zmqPort}\n")
|
||||
pw.write(s"zmqpubrawblock=tcp://127.0.0.1:${zmqPort}\n")
|
||||
val datadir = new java.io.File("/tmp/" + randomDirName)
|
||||
datadir.mkdir()
|
||||
|
||||
if (pruneMode) {
|
||||
logger.info(s"Creating pruned node for ${f.getAbsolutePath}")
|
||||
pw.write("prune=1\n")
|
||||
}
|
||||
val confFile = new java.io.File(datadir.getAbsolutePath + "/bitcoin.conf")
|
||||
confFile.createNewFile()
|
||||
|
||||
val pw = new PrintWriter(confFile)
|
||||
pw.write(confStr)
|
||||
pw.close()
|
||||
BitcoindAuthCredentials(username, pass, rpcUri.getPort, f)
|
||||
|
||||
val username = conf.getString("rpcuser")
|
||||
val pass = conf.getString("rpcpassword")
|
||||
|
||||
BitcoindAuthCredentials(username, pass, rpcUri.getPort, datadir)
|
||||
}
|
||||
|
||||
lazy val network = RegTest
|
||||
lazy val network: RegTest.type = RegTest
|
||||
|
||||
def instance(
|
||||
port: Int = randomPort,
|
||||
|
@ -75,7 +104,7 @@ trait BitcoindRpcTestUtil extends BitcoinSLogger {
|
|||
uri = uri,
|
||||
rpcUri = rpcUri,
|
||||
authCredentials = auth,
|
||||
zmqPortOpt = Some(zmqPort))
|
||||
zmqConfig = ZmqConfig.fromPort(zmqPort))
|
||||
|
||||
instance
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue