mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2024-11-19 01:40:55 +01:00
Tor support for BTC RPC (#3470)
* Tor support for BTC RPC * change config format
This commit is contained in:
parent
1051e6365a
commit
ca40af5d94
@ -53,6 +53,8 @@ class BitcoindConfigPane(
|
||||
minWidth = 300
|
||||
}
|
||||
|
||||
private val torCheckBox: CheckBox = new CheckBox()
|
||||
|
||||
private var nextRow: Int = 0
|
||||
|
||||
val gridPane: GridPane = new GridPane() {
|
||||
@ -80,6 +82,10 @@ class BitcoindConfigPane(
|
||||
add(new Label("Bitcoin Core Version"), 0, nextRow)
|
||||
add(versionComboBox, 1, nextRow)
|
||||
nextRow += 1
|
||||
|
||||
add(new Label("Use Tor"), 0, nextRow)
|
||||
add(torCheckBox, 1, nextRow)
|
||||
nextRow += 1
|
||||
}
|
||||
|
||||
val launchButton: Button = new Button("Launch Wallet") {
|
||||
@ -94,7 +100,14 @@ class BitcoindConfigPane(
|
||||
}
|
||||
|
||||
def getConfig: Config = {
|
||||
val configStr =
|
||||
val proxyConfStr =
|
||||
if (hostTF.text.value.contains(".onion") || torCheckBox.selected.value) {
|
||||
s"""
|
||||
|bitcoin-s.proxy.enabled = true
|
||||
|""".stripMargin
|
||||
} else ""
|
||||
|
||||
val configStr = proxyConfStr +
|
||||
s"""
|
||||
|bitcoin-s.node.mode = bitcoind
|
||||
|bitcoin-s.bitcoind-rpc.isRemote = true
|
||||
|
@ -70,6 +70,8 @@ class NeutrinoConfigPane(
|
||||
minWidth = 300
|
||||
}
|
||||
|
||||
private val torCheckBox: CheckBox = new CheckBox()
|
||||
|
||||
private var nextRow: Int = 0
|
||||
|
||||
val gridPane: GridPane = new GridPane() {
|
||||
@ -84,6 +86,10 @@ class NeutrinoConfigPane(
|
||||
add(new Label("Peer Address"), 0, nextRow)
|
||||
add(peerAddressTF, 1, nextRow)
|
||||
nextRow += 1
|
||||
|
||||
add(new Label("Use Tor"), 0, nextRow)
|
||||
add(torCheckBox, 1, nextRow)
|
||||
nextRow += 1
|
||||
}
|
||||
|
||||
val launchButton: Button = new Button("Launch Wallet") {
|
||||
@ -99,11 +105,15 @@ class NeutrinoConfigPane(
|
||||
|
||||
def getConfig: Config = {
|
||||
// Auto-enable proxy for .onion peers
|
||||
val proxyConfStr = if (peerAddressTF.text.value.contains(".onion")) {
|
||||
s"""
|
||||
|bitcoin-s.proxy.enabled = true
|
||||
|""".stripMargin
|
||||
} else ""
|
||||
val proxyConfStr =
|
||||
if (
|
||||
peerAddressTF.text.value.contains(
|
||||
".onion") || torCheckBox.selected.value
|
||||
) {
|
||||
s"""
|
||||
|bitcoin-s.proxy.enabled = true
|
||||
|""".stripMargin
|
||||
} else ""
|
||||
val configStr = proxyConfStr +
|
||||
s"""
|
||||
|bitcoin-s.network = ${DatadirUtil.networkStrToDirName(
|
||||
|
@ -2,11 +2,13 @@ package org.bitcoins.server
|
||||
|
||||
import akka.actor.ActorSystem
|
||||
import com.typesafe.config.Config
|
||||
import org.bitcoins.core.util.NetworkUtil
|
||||
import org.bitcoins.db._
|
||||
import org.bitcoins.node.NodeType
|
||||
import org.bitcoins.node.config.NodeAppConfig
|
||||
import org.bitcoins.rpc.client.common.{BitcoindRpcClient, BitcoindVersion}
|
||||
import org.bitcoins.rpc.config._
|
||||
import org.bitcoins.tor.Socks5ProxyParams
|
||||
|
||||
import java.io.File
|
||||
import java.net.{InetSocketAddress, URI}
|
||||
@ -90,6 +92,22 @@ case class BitcoindRpcAppConfig(
|
||||
lazy val rpcPassword: String =
|
||||
config.getString("bitcoin-s.bitcoind-rpc.rpcpassword")
|
||||
|
||||
lazy val socks5ProxyParams: Option[Socks5ProxyParams] = {
|
||||
if (config.getBoolean("bitcoin-s.proxy.enabled")) {
|
||||
Some(
|
||||
Socks5ProxyParams(
|
||||
address = NetworkUtil.parseInetSocketAddress(
|
||||
config.getString("bitcoin-s.proxy.socks5"),
|
||||
Socks5ProxyParams.DefaultPort),
|
||||
credentialsOpt = None,
|
||||
randomizeCredentials = true
|
||||
)
|
||||
)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
lazy val versionOpt: Option[BitcoindVersion] =
|
||||
config
|
||||
.getStringOrNone("bitcoin-s.bitcoind-rpc.version")
|
||||
@ -140,7 +158,8 @@ case class BitcoindRpcAppConfig(
|
||||
zmqConfig = zmqConfig,
|
||||
binary = binaryOpt.getOrElse(fallbackBinary),
|
||||
datadir = bitcoindDataDir,
|
||||
isRemote = isRemote
|
||||
isRemote = isRemote,
|
||||
proxyParams = socks5ProxyParams
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,10 @@ package org.bitcoins.rpc.client.common
|
||||
import akka.actor.ActorSystem
|
||||
import akka.http.javadsl.model.headers.HttpCredentials
|
||||
import akka.http.scaladsl.model._
|
||||
import akka.http.scaladsl.settings.{
|
||||
ClientConnectionSettings,
|
||||
ConnectionPoolSettings
|
||||
}
|
||||
import akka.http.scaladsl.unmarshalling.Unmarshal
|
||||
import akka.http.scaladsl.{Http, HttpExt}
|
||||
import akka.stream.StreamTcpException
|
||||
@ -22,6 +26,7 @@ import org.bitcoins.rpc.config.BitcoindAuthCredentials.{
|
||||
}
|
||||
import org.bitcoins.rpc.config.{BitcoindAuthCredentials, BitcoindInstance}
|
||||
import org.bitcoins.rpc.util.NativeProcessFactory
|
||||
import org.bitcoins.tor.Socks5ClientTransport
|
||||
import play.api.libs.json._
|
||||
|
||||
import java.nio.file.{Files, Path}
|
||||
@ -325,8 +330,21 @@ trait Client
|
||||
/** Cached http client to send requests to bitcoind with */
|
||||
private lazy val httpClient: HttpExt = Http(system)
|
||||
|
||||
private lazy val httpConnectionPoolSettings: ConnectionPoolSettings =
|
||||
instance.proxyParams match {
|
||||
case Some(proxyParams) =>
|
||||
val socks5ClientTransport = new Socks5ClientTransport(proxyParams)
|
||||
|
||||
val clientConnectionSettings =
|
||||
ClientConnectionSettings(system).withTransport(socks5ClientTransport)
|
||||
|
||||
ConnectionPoolSettings(system).withConnectionSettings(
|
||||
clientConnectionSettings)
|
||||
case None => ConnectionPoolSettings(system)
|
||||
}
|
||||
|
||||
protected def sendRequest(req: HttpRequest): Future[HttpResponse] = {
|
||||
httpClient.singleRequest(req)
|
||||
httpClient.singleRequest(req, settings = httpConnectionPoolSettings)
|
||||
}
|
||||
|
||||
/** Parses the payload of the given response into JSON.
|
||||
|
@ -4,6 +4,7 @@ import grizzled.slf4j.Logging
|
||||
import org.bitcoins.core.api.commons.InstanceFactory
|
||||
import org.bitcoins.core.config.NetworkParameters
|
||||
import org.bitcoins.rpc.client.common.BitcoindVersion
|
||||
import org.bitcoins.tor.Socks5ProxyParams
|
||||
|
||||
import java.io.{File, FileNotFoundException}
|
||||
import java.net.URI
|
||||
@ -65,6 +66,8 @@ sealed trait BitcoindInstance extends Logging {
|
||||
}
|
||||
|
||||
def p2pPort: Int = uri.getPort
|
||||
|
||||
def proxyParams: Option[Socks5ProxyParams]
|
||||
}
|
||||
|
||||
object BitcoindInstance extends InstanceFactory[BitcoindInstance] {
|
||||
@ -77,7 +80,8 @@ object BitcoindInstance extends InstanceFactory[BitcoindInstance] {
|
||||
zmqConfig: ZmqConfig,
|
||||
binary: File,
|
||||
datadir: File,
|
||||
isRemote: Boolean
|
||||
isRemote: Boolean,
|
||||
proxyParams: Option[Socks5ProxyParams]
|
||||
) extends BitcoindInstance
|
||||
|
||||
def apply(
|
||||
@ -88,7 +92,8 @@ object BitcoindInstance extends InstanceFactory[BitcoindInstance] {
|
||||
zmqConfig: ZmqConfig = ZmqConfig(),
|
||||
binary: File = DEFAULT_BITCOIND_LOCATION,
|
||||
datadir: File = BitcoindConfig.DEFAULT_DATADIR,
|
||||
isRemote: Boolean = false
|
||||
isRemote: Boolean = false,
|
||||
proxyParams: Option[Socks5ProxyParams] = None
|
||||
): BitcoindInstance = {
|
||||
BitcoindInstanceImpl(network,
|
||||
uri,
|
||||
@ -97,7 +102,8 @@ object BitcoindInstance extends InstanceFactory[BitcoindInstance] {
|
||||
zmqConfig = zmqConfig,
|
||||
binary = binary,
|
||||
datadir = datadir,
|
||||
isRemote = isRemote)
|
||||
isRemote = isRemote,
|
||||
proxyParams = proxyParams)
|
||||
}
|
||||
|
||||
lazy val DEFAULT_BITCOIND_LOCATION: File = {
|
||||
|
@ -122,7 +122,8 @@ lazy val bitcoindRpc = project
|
||||
.settings(CommonSettings.prodSettings: _*)
|
||||
.dependsOn(
|
||||
asyncUtilsJVM,
|
||||
appCommons
|
||||
appCommons,
|
||||
tor
|
||||
)
|
||||
|
||||
lazy val eclairRpc = project
|
||||
|
@ -1,34 +1,18 @@
|
||||
package org.bitcoins.core.util
|
||||
|
||||
import java.net.InetSocketAddress
|
||||
import java.net.{InetSocketAddress, URI}
|
||||
|
||||
abstract class NetworkUtil {
|
||||
|
||||
private def parsePort(port: String): Int = {
|
||||
lazy val errorMsg = s"Invalid peer port: $port"
|
||||
try {
|
||||
val res = port.toInt
|
||||
if (res < 0 || res > 0xffff) {
|
||||
throw new RuntimeException(errorMsg)
|
||||
}
|
||||
res
|
||||
} catch {
|
||||
case _: NumberFormatException =>
|
||||
throw new RuntimeException(errorMsg)
|
||||
}
|
||||
}
|
||||
|
||||
/** Parses a string that looks like this to [[java.net.InetSocketAddress]]
|
||||
* "neutrino.testnet3.suredbits.com:18333"
|
||||
*/
|
||||
def parseInetSocketAddress(
|
||||
address: String,
|
||||
defaultPort: Int): InetSocketAddress = {
|
||||
address.split(":") match {
|
||||
case Array(host) => new InetSocketAddress(host, defaultPort)
|
||||
case Array(host, port) => new InetSocketAddress(host, parsePort(port))
|
||||
case _ => throw new RuntimeException(s"Invalid peer address: $address")
|
||||
}
|
||||
val uri = new URI("tcp://" + address)
|
||||
val port = if (uri.getPort < 0) defaultPort else uri.getPort
|
||||
InetSocketAddress.createUnresolved(uri.getHost, port)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@ import org.bitcoins.chain.models.{
|
||||
CompactFilterDAO,
|
||||
CompactFilterHeaderDAO
|
||||
}
|
||||
import org.bitcoins.core.util.Mutable
|
||||
import org.bitcoins.core.util.{Mutable, NetworkUtil}
|
||||
import org.bitcoins.db.{AppConfigFactory, DbAppConfig, JdbcProfileComponent}
|
||||
import org.bitcoins.node._
|
||||
import org.bitcoins.node.db.NodeDbManagement
|
||||
@ -17,7 +17,6 @@ import org.bitcoins.node.models.Peer
|
||||
import org.bitcoins.node.networking.peer.DataMessageHandler
|
||||
import org.bitcoins.tor.Socks5ProxyParams
|
||||
|
||||
import java.net.{InetSocketAddress, URI}
|
||||
import java.nio.file.Path
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
|
||||
@ -91,11 +90,11 @@ case class NodeAppConfig(
|
||||
|
||||
lazy val socks5ProxyParams: Option[Socks5ProxyParams] = {
|
||||
if (config.getBoolean("bitcoin-s.proxy.enabled")) {
|
||||
val uri = new URI("tcp://" + config.getString("bitcoin-s.proxy.socks5"))
|
||||
val sock5 = InetSocketAddress.createUnresolved(uri.getHost, uri.getPort)
|
||||
Some(
|
||||
Socks5ProxyParams(
|
||||
address = sock5,
|
||||
address = NetworkUtil.parseInetSocketAddress(
|
||||
config.getString("bitcoin-s.proxy.socks5"),
|
||||
Socks5ProxyParams.DefaultPort),
|
||||
credentialsOpt = None,
|
||||
randomizeCredentials = true
|
||||
)
|
||||
|
@ -251,6 +251,8 @@ case class Socks5ProxyParams(
|
||||
|
||||
object Socks5ProxyParams {
|
||||
|
||||
val DefaultPort = 9050
|
||||
|
||||
def proxyCredentials(
|
||||
proxyParams: Socks5ProxyParams): Option[Socks5Connection.Credentials] =
|
||||
if (proxyParams.randomizeCredentials) {
|
||||
|
Loading…
Reference in New Issue
Block a user