Support for Tor Docker (#4223)

This commit is contained in:
rorp 2022-03-29 06:10:34 -07:00 committed by GitHub
parent 5eabe7640f
commit 715639033c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 47 additions and 16 deletions

3
.gitignore vendored
View File

@ -87,3 +87,6 @@ website/static/api
#OSX #OSX
.DS_Store .DS_Store
#Docker
data/

View File

@ -26,10 +26,15 @@ bitcoin-s.proxy.enabled = ${?BITCOIN_S_PROXY_ENABLED}
bitcoin-s.bitcoind-rpc.proxy.enabled = ${?BITCOIN_S_BITCOIND_RPC_PROXY_ENABLED} bitcoin-s.bitcoind-rpc.proxy.enabled = ${?BITCOIN_S_BITCOIND_RPC_PROXY_ENABLED}
bitcoin-s.node.proxy.enabled = ${?BITCOIN_S_NODE_PROXY_ENABLED} bitcoin-s.node.proxy.enabled = ${?BITCOIN_S_NODE_PROXY_ENABLED}
bitcoin-s.node.proxy.socks5 = ${?BITCOIN_S_NODE_PROXY_SOCKS5}
bitcoin-s.node.tor.enabled = ${?BITCOIN_S_NODE_TOR_ENABLED} bitcoin-s.node.tor.enabled = ${?BITCOIN_S_NODE_TOR_ENABLED}
bitcoin-s.node.tor.control = ${?BITCOIN_S_NODE_TOR_CONTROL}
bitcoin-s.node.tor.password = ${?BITCOIN_S_NODE_TOR_PASSWORD}
bitcoin-s.dlcnode.proxy.enabled = ${?BITCOIN_S_DLCNODE_PROXY_ENABLED} bitcoin-s.dlcnode.proxy.enabled = ${?BITCOIN_S_DLCNODE_PROXY_ENABLED}
bitcoin-s.dlcnode.proxy.socks5 = ${?BITCOIN_S_DLCNODE_PROXY_SOCKS5} bitcoin-s.dlcnode.proxy.socks5 = ${?BITCOIN_S_DLCNODE_PROXY_SOCKS5}
bitcoin-s.dlcnode.tor.enabled = ${?BITCOIN_S_DLCNODE_TOR_ENABLED} bitcoin-s.dlcnode.tor.enabled = ${?BITCOIN_S_DLCNODE_TOR_ENABLED}
bitcoin-s.dlcnode.tor.control = ${?BITCOIN_S_DLCNODE_TOR_CONTROL}
bitcoin-s.dlcnode.tor.password = ${?BITCOIN_S_DLCNODE_TOR_PASSWORD}
bitcoin-s.dlcnode.external-ip = ${?BITCOIN_S_DLCNODE_EXTERNAL_IP} bitcoin-s.dlcnode.external-ip = ${?BITCOIN_S_DLCNODE_EXTERNAL_IP}
bitcoin-s.wallet.allowExternalDLCAddresses = false bitcoin-s.wallet.allowExternalDLCAddresses = false

View File

@ -5,6 +5,7 @@ import akka.testkit.{TestActorRef, TestProbe}
import org.bitcoins.asyncutil.AsyncUtil import org.bitcoins.asyncutil.AsyncUtil
import org.bitcoins.core.number.UInt16 import org.bitcoins.core.number.UInt16
import org.bitcoins.core.protocol.tlv.{LnMessage, PingTLV, PongTLV} import org.bitcoins.core.protocol.tlv.{LnMessage, PingTLV, PongTLV}
import org.bitcoins.dlc.node.DLCDataHandler.Received
import org.bitcoins.dlc.node.peer.Peer import org.bitcoins.dlc.node.peer.Peer
import org.bitcoins.rpc.util.RpcUtil import org.bitcoins.rpc.util.RpcUtil
import org.bitcoins.server.BitcoinSAppConfig import org.bitcoins.server.BitcoinSAppConfig
@ -106,17 +107,17 @@ class DLCServerTorTest
ByteVector.fromValidHex("00112233445566778899aabbccddeeff")) ByteVector.fromValidHex("00112233445566778899aabbccddeeff"))
clientConnectionHandler = clientConnectionHandlerOpt.get clientConnectionHandler = clientConnectionHandlerOpt.get
_ = clientProbe.send(clientConnectionHandler, pingTLV) _ = clientProbe.send(clientConnectionHandler, pingTLV)
_ = serverProbe.expectMsg(timeout, LnMessage(pingTLV)) _ = serverProbe.expectMsg(timeout, Received(LnMessage(pingTLV)))
pongTLV = PongTLV.forIgnored( pongTLV = PongTLV.forIgnored(
ByteVector.fromValidHex("00112233445566778899aabbccddeeff")) ByteVector.fromValidHex("00112233445566778899aabbccddeeff"))
serverConnectionHandler = serverConnectionHandlerOpt.get serverConnectionHandler = serverConnectionHandlerOpt.get
_ = serverProbe.send(serverConnectionHandler, pongTLV) _ = serverProbe.send(serverConnectionHandler, pongTLV)
_ = clientProbe.expectMsg(timeout, LnMessage(pongTLV)) _ = clientProbe.expectMsg(timeout, Received(LnMessage(pongTLV)))
// 131063 - is a magic size for OS X when this test case starts failing (131073 overall TLV size) // 131063 - is a magic size for OS X when this test case starts failing (131073 overall TLV size)
ignored = ByteVector.fill(65000)(0x55) ignored = ByteVector.fill(65000)(0x55)
bigTLV = PongTLV.forIgnored(ignored) bigTLV = PongTLV.forIgnored(ignored)
_ = clientProbe.send(clientConnectionHandler, bigTLV) _ = clientProbe.send(clientConnectionHandler, bigTLV)
_ = serverProbe.expectMsg(timeout, LnMessage(bigTLV)) _ = serverProbe.expectMsg(timeout, Received(LnMessage(bigTLV)))
_ = clientProbe.send(clientConnectionHandler, _ = clientProbe.send(clientConnectionHandler,
DLCConnectionHandler.CloseConnection) DLCConnectionHandler.CloseConnection)
_ = clientProbe.send(clientConnectionHandler, pingTLV) _ = clientProbe.send(clientConnectionHandler, pingTLV)

View File

@ -52,7 +52,7 @@ This will build a `Dockerfile` that is located in `app/server/target/docker/stag
You can now build the docker image with You can now build the docker image with
``` ```
docker build app/server/target/docker/stage/ -t bitcoin-s-server:latest docker build app/server/target/docker/stage/ -t bitcoinscala/bitcoin-s-server:latest
``` ```
Finally, let's run the image! It's important that you correctly configure port forwarding with the docker container so Finally, let's run the image! It's important that you correctly configure port forwarding with the docker container so

5
tor/Dockerfile Normal file
View File

@ -0,0 +1,5 @@
FROM --platform=linux/amd64 ubuntu:22.04
COPY src/main/resources/linux_64 .
CMD ./tor

View File

@ -1,5 +1,6 @@
package org.bitcoins.tor package org.bitcoins.tor
import akka.Done
import akka.actor.{ import akka.actor.{
Actor, Actor,
ActorLogging, ActorLogging,
@ -14,6 +15,7 @@ import akka.util.ByteString
import grizzled.slf4j.Logging import grizzled.slf4j.Logging
import org.bitcoins.tor.TorProtocolHandler.Authentication import org.bitcoins.tor.TorProtocolHandler.Authentication
import java.io.IOException
import java.net.InetSocketAddress import java.net.InetSocketAddress
import java.nio.file.Path import java.nio.file.Path
import scala.concurrent.{Future, Promise} import scala.concurrent.{Future, Promise}
@ -24,7 +26,10 @@ import scala.concurrent.{Future, Promise}
* @param protocolHandlerProps Tor protocol handler props * @param protocolHandlerProps Tor protocol handler props
* @param ec execution context * @param ec execution context
*/ */
class TorController(address: InetSocketAddress, protocolHandlerProps: Props) class TorController(
address: InetSocketAddress,
protocolHandlerProps: Props,
connectedPromiseOpt: Option[Promise[Done]])
extends Actor extends Actor
with ActorLogging { with ActorLogging {
@ -36,9 +41,14 @@ class TorController(address: InetSocketAddress, protocolHandlerProps: Props)
override def receive: Receive = { override def receive: Receive = {
case e @ CommandFailed(_: Connect) => case e @ CommandFailed(_: Connect) =>
val errMessage = s"Cannot connect to Tor control address $address"
e.cause match { e.cause match {
case Some(ex) => log.error(ex, "Cannot connect") case Some(ex) =>
case _ => log.error("Cannot connect") log.error(ex, errMessage)
connectedPromiseOpt.foreach(_.failure(ex))
case _ =>
log.error(errMessage)
connectedPromiseOpt.foreach(_.failure(new IOException(errMessage)))
} }
context.stop(self) context.stop(self)
case c: Connected => case c: Connected =>
@ -48,6 +58,7 @@ class TorController(address: InetSocketAddress, protocolHandlerProps: Props)
connection ! Register(self) connection ! Register(self)
context.watch(connection) context.watch(connection)
context.watch(protocolHandler) context.watch(protocolHandler)
connectedPromiseOpt.foreach(_.success(Done))
context.become { context.become {
case data: ByteString => case data: ByteString =>
connection ! Write(data) connection ! Write(data)
@ -76,8 +87,11 @@ class TorController(address: InetSocketAddress, protocolHandlerProps: Props)
object TorController extends Logging { object TorController extends Logging {
def props(address: InetSocketAddress, protocolHandlerProps: Props) = def props(
Props(new TorController(address, protocolHandlerProps)) address: InetSocketAddress,
protocolHandlerProps: Props,
connectedPromiseOpt: Option[Promise[Done]]) =
Props(new TorController(address, protocolHandlerProps, connectedPromiseOpt))
case object SendFailed case object SendFailed
@ -101,6 +115,7 @@ object TorController extends Logging {
system: ActorSystem): Future[InetSocketAddress] = { system: ActorSystem): Future[InetSocketAddress] = {
import system.dispatcher import system.dispatcher
val promiseTorAddress = Promise[InetSocketAddress]() val promiseTorAddress = Promise[InetSocketAddress]()
val promiseConnected = Promise[Done]()
val protocolHandlerProps = TorProtocolHandler.props( val protocolHandlerProps = TorProtocolHandler.props(
version = TorProtocolHandler.V3, version = TorProtocolHandler.V3,
@ -113,16 +128,18 @@ object TorController extends Logging {
val _ = system.actorOf( val _ = system.actorOf(
TorController.props(address = controlAddress, TorController.props(address = controlAddress,
protocolHandlerProps = protocolHandlerProps), protocolHandlerProps = protocolHandlerProps,
connectedPromiseOpt = Some(promiseConnected)),
s"tor-${System.currentTimeMillis()}" s"tor-${System.currentTimeMillis()}"
) )
val addressF = promiseTorAddress.future for {
_ <- promiseConnected.future
addressF.foreach(address => torAddress <- promiseTorAddress.future
logger.info(s"Created hidden service with address=$address")) } yield {
logger.info(s"Created hidden service with address=$torAddress")
addressF torAddress
}
} }
} }