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
.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.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.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.socks5 = ${?BITCOIN_S_DLCNODE_PROXY_SOCKS5}
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.wallet.allowExternalDLCAddresses = false

View File

@ -5,6 +5,7 @@ import akka.testkit.{TestActorRef, TestProbe}
import org.bitcoins.asyncutil.AsyncUtil
import org.bitcoins.core.number.UInt16
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.rpc.util.RpcUtil
import org.bitcoins.server.BitcoinSAppConfig
@ -106,17 +107,17 @@ class DLCServerTorTest
ByteVector.fromValidHex("00112233445566778899aabbccddeeff"))
clientConnectionHandler = clientConnectionHandlerOpt.get
_ = clientProbe.send(clientConnectionHandler, pingTLV)
_ = serverProbe.expectMsg(timeout, LnMessage(pingTLV))
_ = serverProbe.expectMsg(timeout, Received(LnMessage(pingTLV)))
pongTLV = PongTLV.forIgnored(
ByteVector.fromValidHex("00112233445566778899aabbccddeeff"))
serverConnectionHandler = serverConnectionHandlerOpt.get
_ = 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)
ignored = ByteVector.fill(65000)(0x55)
bigTLV = PongTLV.forIgnored(ignored)
_ = clientProbe.send(clientConnectionHandler, bigTLV)
_ = serverProbe.expectMsg(timeout, LnMessage(bigTLV))
_ = serverProbe.expectMsg(timeout, Received(LnMessage(bigTLV)))
_ = clientProbe.send(clientConnectionHandler,
DLCConnectionHandler.CloseConnection)
_ = 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
```
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

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