Merge branch 'haveno-dex:master' into install_qubes

This commit is contained in:
PromptPunksFauxCough 2025-02-28 20:34:39 +00:00 committed by GitHub
commit a7760734a3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 59 additions and 37 deletions

View file

@ -23,6 +23,10 @@ Main features:
See the [FAQ on our website](https://haveno.exchange/faq/) for more information. See the [FAQ on our website](https://haveno.exchange/faq/) for more information.
## Haveno Demo
https://github.com/user-attachments/assets/eb6b3af0-78ce-46a7-bfa1-2aacd8649d47
## Installing Haveno ## Installing Haveno
Haveno can be installed on Linux, macOS, and Windows by using a third party installer and network. Haveno can be installed on Linux, macOS, and Windows by using a third party installer and network.
@ -34,7 +38,7 @@ Haveno can be installed on Linux, macOS, and Windows by using a third party inst
A test network is also available for users to make test trades using Monero's stagenet. See the [instructions](https://github.com/haveno-dex/haveno/blob/master/docs/installing.md) to build Haveno and connect to the test network. A test network is also available for users to make test trades using Monero's stagenet. See the [instructions](https://github.com/haveno-dex/haveno/blob/master/docs/installing.md) to build Haveno and connect to the test network.
Alternatively, you can [create your own mainnet network](create-mainnet.md). Alternatively, you can [create your own mainnet network](https://github.com/haveno-dex/haveno/blob/master/docs/create-mainnet.md).
Note that Haveno is being actively developed. If you find issues or bugs, please let us know. Note that Haveno is being actively developed. If you find issues or bugs, please let us know.

View file

@ -19,9 +19,9 @@ On Windows, first install MSYS2:
4. Update pacman: `pacman -Syy` 4. Update pacman: `pacman -Syy`
5. Install dependencies. During installation, use default=all by leaving the input blank and pressing enter. 5. Install dependencies. During installation, use default=all by leaving the input blank and pressing enter.
64-bit: `pacman -S mingw-w64-x86_64-toolchain make mingw-w64-x86_64-cmake git` 64-bit: `pacman -S mingw-w64-x86_64-toolchain make mingw-w64-x86_64-cmake git zip unzip`
32-bit: `pacman -S mingw-w64-i686-toolchain make mingw-w64-i686-cmake git` 32-bit: `pacman -S mingw-w64-i686-toolchain make mingw-w64-i686-cmake git zip unzip`
On all platforms, install Java JDK 21: On all platforms, install Java JDK 21:
@ -30,6 +30,8 @@ curl -s "https://get.sdkman.io" | bash
sdk install java 21.0.2.fx-librca sdk install java 21.0.2.fx-librca
``` ```
Restart the terminal for the changes to take effect.
## Build Haveno ## Build Haveno
If it's the first time you are building Haveno, run the following commands to download the repository, the needed dependencies, and build the latest release. If using a third party network, replace the repository URL with theirs: If it's the first time you are building Haveno, run the following commands to download the repository, the needed dependencies, and build the latest release. If using a third party network, replace the repository URL with theirs:

View file

@ -1,5 +1,4 @@
-----BEGIN PGP PUBLIC KEY BLOCK----- -----BEGIN PGP PUBLIC KEY BLOCK-----
Comment: GPGTools - https://gpgtools.org
mQINBFpYwMsBEACpSn/AxDOGCELE9lmYPfvBzgw2+1xS3TX7kYdlvVDQf+8eCgGz mQINBFpYwMsBEACpSn/AxDOGCELE9lmYPfvBzgw2+1xS3TX7kYdlvVDQf+8eCgGz
8ZpBY3lXdga/yMZZBoDknGzjlyaiG/vi7NljMQmWd5eGyhyfkWpeDXYLbiB5HlKe 8ZpBY3lXdga/yMZZBoDknGzjlyaiG/vi7NljMQmWd5eGyhyfkWpeDXYLbiB5HlKe
@ -25,29 +24,42 @@ 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
mqKdaDoa OIOn09L8hqHQrADORCGz/0OLun7TXxOzH5pqdgi56h7H1S1Lxmx/BmzC6qEtW2o8
=bRX1 vLeBxFNDmezddiENYZ35yh6yyqXxil35eNY5Ky9oJ7slABEBAAGJAjYEGAEKACAW
IQRS/XwBh3ypaMlxGNBVoQ3Uit7l7wUCWljAywIbDAAKCRBVoQ3Uit7l7398EACc
l4rVvJfg9gGmrMyppuFV2JKn/ms61ZkS6Z6lDLyGsYSU2OCdh+W0+iQABFN/w6ev
4IWL6hm89ua/eD1JAzymf9tzLwTBWm/G4iP/6U/oycEBVyq1xCFobgTRb6ioS/Ds
TItZKsrNxOOeqrrnqIUM2Wyss0wGKxAUF/P3zX/6mhrliM3K3VqgDtTsZzvywU2S
IeCa59bKQYd51v1OpNyy0rF7D5Ab/RCB8UevNEfHLLU/XC2sVM6gYV1/oij6vDKl
lw+YWSigQspVsm3X4RnOBRfjrM3blgz+J1WoTRg+6RV/YQjIuiubiEY/GzLVWoTe
2wYsGTKd50EQBgjubqaqMDGhib+wPc0NeJTyhBDn/t5EFI9l1MOI7kZlYlPdYaSE
cuB3/+Fq8twIaiAn/ZjIJJv7SNXs/pqFkEYaKWGeFkzWyIUK0lLWhDkBwXCRYpyr
keEl8cZqxR6Wd+yLd0mWecycmR6y8qU/a8tMa5uyVhfvsEFaH6r805lbSIsG2AA7
i/3w78qJaPOa0nqA0nWVRp72NrYqTIa9PqgQ6zot7Umhc1PqZndP4QZnjcUtXImJ
8QOhIvsNL+/Zm4CssJ4DE6vsEA8p16yB3jadaF6hrxVPW0OgYQwykueKTx5tGZRI
PNPr3mpTV6VyFbY0jNj5UabE5ZqrN2HCGpqinWg6Gg==
=4SFl
-----END PGP PUBLIC KEY BLOCK----- -----END PGP PUBLIC KEY BLOCK-----

View file

@ -22,6 +22,7 @@ import com.google.inject.Provider;
import com.google.inject.name.Named; import com.google.inject.name.Named;
import haveno.common.config.Config; import haveno.common.config.Config;
import haveno.common.proto.network.NetworkProtoResolver; import haveno.common.proto.network.NetworkProtoResolver;
import haveno.network.Socks5ProxyProvider;
import haveno.network.p2p.network.BanFilter; import haveno.network.p2p.network.BanFilter;
import haveno.network.p2p.network.BridgeAddressProvider; import haveno.network.p2p.network.BridgeAddressProvider;
import haveno.network.p2p.network.LocalhostNetworkNode; import haveno.network.p2p.network.LocalhostNetworkNode;
@ -55,7 +56,8 @@ public class NetworkNodeProvider implements Provider<NetworkNode> {
@Named(Config.TOR_CONTROL_PASSWORD) String password, @Named(Config.TOR_CONTROL_PASSWORD) String password,
@Nullable @Named(Config.TOR_CONTROL_COOKIE_FILE) File cookieFile, @Nullable @Named(Config.TOR_CONTROL_COOKIE_FILE) File cookieFile,
@Named(Config.TOR_STREAM_ISOLATION) boolean streamIsolation, @Named(Config.TOR_STREAM_ISOLATION) boolean streamIsolation,
@Named(Config.TOR_CONTROL_USE_SAFE_COOKIE_AUTH) boolean useSafeCookieAuthentication) { @Named(Config.TOR_CONTROL_USE_SAFE_COOKIE_AUTH) boolean useSafeCookieAuthentication,
Socks5ProxyProvider socks5ProxyProvider) {
if (useLocalhostForP2P) { if (useLocalhostForP2P) {
networkNode = new LocalhostNetworkNode(port, networkProtoResolver, banFilter, maxConnections); networkNode = new LocalhostNetworkNode(port, networkProtoResolver, banFilter, maxConnections);
} else { } else {
@ -72,7 +74,7 @@ public class NetworkNodeProvider implements Provider<NetworkNode> {
if (torMode instanceof NewTor || torMode instanceof RunningTor) { if (torMode instanceof NewTor || torMode instanceof RunningTor) {
networkNode = new TorNetworkNodeNetlayer(port, networkProtoResolver, torMode, banFilter, maxConnections, streamIsolation, controlHost); networkNode = new TorNetworkNodeNetlayer(port, networkProtoResolver, torMode, banFilter, maxConnections, streamIsolation, controlHost);
} else { } else {
networkNode = new TorNetworkNodeDirectBind(port, networkProtoResolver, banFilter, maxConnections, hiddenServiceAddress); networkNode = new TorNetworkNodeDirectBind(port, networkProtoResolver, banFilter, maxConnections, hiddenServiceAddress, socks5ProxyProvider);
} }
} }
} }

View file

@ -1,6 +1,7 @@
package haveno.network.p2p.network; package haveno.network.p2p.network;
import haveno.common.util.Hex; import haveno.common.util.Hex;
import haveno.network.Socks5ProxyProvider;
import haveno.network.p2p.NodeAddress; import haveno.network.p2p.NodeAddress;
import haveno.common.UserThread; import haveno.common.UserThread;
@ -9,7 +10,6 @@ import haveno.common.proto.network.NetworkProtoResolver;
import com.runjva.sourceforge.jsocks.protocol.Socks5Proxy; import com.runjva.sourceforge.jsocks.protocol.Socks5Proxy;
import java.net.Socket; import java.net.Socket;
import java.net.InetAddress;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.io.IOException; import java.io.IOException;
@ -25,16 +25,18 @@ import static com.google.common.base.Preconditions.checkArgument;
@Slf4j @Slf4j
public class TorNetworkNodeDirectBind extends TorNetworkNode { public class TorNetworkNodeDirectBind extends TorNetworkNode {
private static final int TOR_DATA_PORT = 9050; // TODO: config option?
private final String serviceAddress; private final String serviceAddress;
private final Socks5ProxyProvider socks5ProxyProvider;
public TorNetworkNodeDirectBind(int servicePort, public TorNetworkNodeDirectBind(int servicePort,
NetworkProtoResolver networkProtoResolver, NetworkProtoResolver networkProtoResolver,
@Nullable BanFilter banFilter, @Nullable BanFilter banFilter,
int maxConnections, int maxConnections,
String hiddenServiceAddress) { String hiddenServiceAddress,
Socks5ProxyProvider socks5ProxyProvider) {
super(servicePort, networkProtoResolver, banFilter, maxConnections); super(servicePort, networkProtoResolver, banFilter, maxConnections);
this.serviceAddress = hiddenServiceAddress; this.serviceAddress = hiddenServiceAddress;
this.socks5ProxyProvider = socks5ProxyProvider;
} }
@Override @Override
@ -47,7 +49,7 @@ public class TorNetworkNodeDirectBind extends TorNetworkNode {
@Override @Override
public Socks5Proxy getSocksProxy() { public Socks5Proxy getSocksProxy() {
Socks5Proxy proxy = new Socks5Proxy(InetAddress.getLoopbackAddress(), TOR_DATA_PORT); Socks5Proxy proxy = new Socks5Proxy(socks5ProxyProvider.getSocks5Proxy().getInetAddress(), socks5ProxyProvider.getSocks5Proxy().getPort()); // TODO: can/should we return the same socks5 proxy directly?
proxy.resolveAddrLocally(false); proxy.resolveAddrLocally(false);
return proxy; return proxy;
} }
@ -57,7 +59,7 @@ public class TorNetworkNodeDirectBind extends TorNetworkNode {
// https://datatracker.ietf.org/doc/html/rfc1928 SOCKS5 Protocol // https://datatracker.ietf.org/doc/html/rfc1928 SOCKS5 Protocol
try { try {
checkArgument(peerNodeAddress.getHostName().endsWith(".onion"), "PeerAddress is not an onion address"); checkArgument(peerNodeAddress.getHostName().endsWith(".onion"), "PeerAddress is not an onion address");
Socket sock = new Socket(InetAddress.getLoopbackAddress(), TOR_DATA_PORT); Socket sock = new Socket(getSocksProxy().getInetAddress(), getSocksProxy().getPort());
sock.getOutputStream().write(Hex.decode("050100")); sock.getOutputStream().write(Hex.decode("050100"));
String response = Hex.encode(sock.getInputStream().readNBytes(2)); String response = Hex.encode(sock.getInputStream().readNBytes(2));
if (!response.equalsIgnoreCase("0500")) { if (!response.equalsIgnoreCase("0500")) {