Merge branch 'haveno-dex:master' into external-tor-usage

This commit is contained in:
PromptPunksFauxCough 2025-03-06 01:10:11 +00:00 committed by GitHub
commit aeb3c50cb4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 53 additions and 53 deletions

View file

@ -68,7 +68,6 @@ import java.util.stream.Stream;
import javafx.beans.property.LongProperty; import javafx.beans.property.LongProperty;
import javafx.beans.property.ReadOnlyDoubleProperty; import javafx.beans.property.ReadOnlyDoubleProperty;
import javafx.beans.value.ChangeListener; import javafx.beans.value.ChangeListener;
import lombok.Getter;
import monero.common.MoneroError; import monero.common.MoneroError;
import monero.common.MoneroRpcConnection; import monero.common.MoneroRpcConnection;
import monero.common.MoneroRpcError; import monero.common.MoneroRpcError;
@ -145,8 +144,7 @@ public class XmrWalletService extends XmrWalletBase {
private TradeManager tradeManager; private TradeManager tradeManager;
private ExecutorService syncWalletThreadPool = Executors.newFixedThreadPool(10); // TODO: adjust based on connection type private ExecutorService syncWalletThreadPool = Executors.newFixedThreadPool(10); // TODO: adjust based on connection type
@Getter private final Object lock = new Object();
public final Object lock = new Object();
private TaskLooper pollLooper; private TaskLooper pollLooper;
private boolean pollInProgress; private boolean pollInProgress;
private Long pollPeriodMs; private Long pollPeriodMs;
@ -740,7 +738,7 @@ public class XmrWalletService extends XmrWalletBase {
MoneroDaemonRpc daemon = getDaemon(); MoneroDaemonRpc daemon = getDaemon();
MoneroWallet wallet = getWallet(); MoneroWallet wallet = getWallet();
MoneroTx tx = null; MoneroTx tx = null;
synchronized (daemon) { synchronized (lock) {
try { try {
// verify tx not submitted to pool // verify tx not submitted to pool
@ -926,7 +924,7 @@ public class XmrWalletService extends XmrWalletBase {
} }
// shut down threads // shut down threads
synchronized (getLock()) { synchronized (lock) {
List<Runnable> shutDownThreads = new ArrayList<>(); List<Runnable> shutDownThreads = new ArrayList<>();
shutDownThreads.add(() -> ThreadUtils.shutDown(THREAD_ID)); shutDownThreads.add(() -> ThreadUtils.shutDown(THREAD_ID));
ThreadUtils.awaitTasks(shutDownThreads); ThreadUtils.awaitTasks(shutDownThreads);

View file

@ -3201,14 +3201,16 @@ DOMESTIC_WIRE_TRANSFER=Domestic Wire Transfer
# suppress inspection "UnusedProperty" # suppress inspection "UnusedProperty"
BSQ_SWAP=BSQ Swap BSQ_SWAP=BSQ Swap
# Deprecated: Cannot be deleted as it would break old trade history entries
# suppress inspection "UnusedProperty" # suppress inspection "UnusedProperty"
OK_PAY=OKPay OK_PAY=OKPay
# suppress inspection "UnusedProperty" # suppress inspection "UnusedProperty"
CASH_APP=Cash App CASH_APP=Cash App
# suppress inspection "UnusedProperty" # suppress inspection "UnusedProperty"
VENMO=Venmo VENMO=Venmo
# suppress inspection "UnusedProperty"
PAYPAL=PayPal PAYPAL=PayPal
# suppress inspection "UnusedProperty"
PAYSAFE=Paysafe
# suppress inspection "UnusedProperty" # suppress inspection "UnusedProperty"
UPHOLD_SHORT=Uphold UPHOLD_SHORT=Uphold
@ -3304,9 +3306,10 @@ OK_PAY_SHORT=OKPay
CASH_APP_SHORT=Cash App CASH_APP_SHORT=Cash App
# suppress inspection "UnusedProperty" # suppress inspection "UnusedProperty"
VENMO_SHORT=Venmo VENMO_SHORT=Venmo
# suppress inspection "UnusedProperty"
PAYPAL_SHORT=PayPal PAYPAL_SHORT=PayPal
# suppress inspection "UnusedProperty" # suppress inspection "UnusedProperty"
PAYSAFE=Paysafe PAYSAFE_SHORT=Paysafe
#################################################################### ####################################################################

View file

@ -208,29 +208,29 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
root.getChildren().addAll(toolBox, priceChartPane, volumeChartPane, tableView, footer); root.getChildren().addAll(toolBox, priceChartPane, volumeChartPane, tableView, footer);
timeUnitChangeListener = (observable, oldValue, newValue) -> { timeUnitChangeListener = (observable, oldValue, newValue) -> UserThread.execute(() -> {
if (newValue != null) { if (newValue != null) {
model.setTickUnit((TradesChartsViewModel.TickUnit) newValue.getUserData()); model.setTickUnit((TradesChartsViewModel.TickUnit) newValue.getUserData());
priceAxisX.setTickLabelFormatter(getTimeAxisStringConverter()); priceAxisX.setTickLabelFormatter(getTimeAxisStringConverter());
volumeAxisX.setTickLabelFormatter(getTimeAxisStringConverter()); volumeAxisX.setTickLabelFormatter(getTimeAxisStringConverter());
volumeInUsdAxisX.setTickLabelFormatter(getTimeAxisStringConverter()); volumeInUsdAxisX.setTickLabelFormatter(getTimeAxisStringConverter());
} }
}; });
priceAxisYWidthListener = (observable, oldValue, newValue) -> { priceAxisYWidthListener = (observable, oldValue, newValue) -> UserThread.execute(() -> {
priceAxisYWidth = (double) newValue; priceAxisYWidth = (double) newValue;
layoutChart(); layoutChart();
}; });
volumeAxisYWidthListener = (observable, oldValue, newValue) -> { volumeAxisYWidthListener = (observable, oldValue, newValue) -> UserThread.execute(() -> {
volumeAxisYWidth = (double) newValue; volumeAxisYWidth = (double) newValue;
layoutChart(); layoutChart();
}; });
tradeStatisticsByCurrencyListener = c -> { tradeStatisticsByCurrencyListener = c -> UserThread.execute(() -> {
nrOfTradeStatisticsLabel.setText(Res.get("market.trades.nrOfTrades", model.tradeStatisticsByCurrency.size())); nrOfTradeStatisticsLabel.setText(Res.get("market.trades.nrOfTrades", model.tradeStatisticsByCurrency.size()));
fillList(); fillList();
}; });
parentHeightListener = (observable, oldValue, newValue) -> layout(); parentHeightListener = (observable, oldValue, newValue) -> UserThread.execute(this::layout);
priceColumnLabelListener = (o, oldVal, newVal) -> priceColumn.setGraphic(new AutoTooltipLabel(newVal)); priceColumnLabelListener = (o, oldVal, newVal) -> UserThread.execute(() -> priceColumn.setGraphic(new AutoTooltipLabel(newVal)));
// Need to render on next frame as otherwise there are issues in the chart rendering // Need to render on next frame as otherwise there are issues in the chart rendering
itemsChangeListener = c -> UserThread.execute(this::updateChartData); itemsChangeListener = c -> UserThread.execute(this::updateChartData);
@ -238,6 +238,7 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
currencySelectionBinding = EasyBind.combine( currencySelectionBinding = EasyBind.combine(
model.showAllTradeCurrenciesProperty, model.selectedTradeCurrencyProperty, model.showAllTradeCurrenciesProperty, model.selectedTradeCurrencyProperty,
(showAll, selectedTradeCurrency) -> { (showAll, selectedTradeCurrency) -> {
UserThread.execute(() -> {
priceChart.setVisible(!showAll); priceChart.setVisible(!showAll);
priceChart.setManaged(!showAll); priceChart.setManaged(!showAll);
priceColumn.setSortable(!showAll); priceColumn.setSortable(!showAll);
@ -263,6 +264,8 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
} }
layout(); layout();
});
return null; return null;
}); });
} }
@ -286,14 +289,14 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
currencyComboBox.getSelectionModel().select(model.getSelectedCurrencyListItem().get()); currencyComboBox.getSelectionModel().select(model.getSelectedCurrencyListItem().get());
currencyComboBox.getEditor().setText(new CurrencyStringConverter(currencyComboBox).toString(currencyComboBox.getSelectionModel().getSelectedItem())); currencyComboBox.getEditor().setText(new CurrencyStringConverter(currencyComboBox).toString(currencyComboBox.getSelectionModel().getSelectedItem()));
currencyComboBox.setOnChangeConfirmed(e -> { currencyComboBox.setOnChangeConfirmed(e -> UserThread.execute(() -> {
if (currencyComboBox.getEditor().getText().isEmpty()) if (currencyComboBox.getEditor().getText().isEmpty())
currencyComboBox.getSelectionModel().select(SHOW_ALL); currencyComboBox.getSelectionModel().select(SHOW_ALL);
CurrencyListItem selectedItem = currencyComboBox.getSelectionModel().getSelectedItem(); CurrencyListItem selectedItem = currencyComboBox.getSelectionModel().getSelectedItem();
if (selectedItem != null) { if (selectedItem != null) {
model.onSetTradeCurrency(selectedItem.tradeCurrency); model.onSetTradeCurrency(selectedItem.tradeCurrency);
} }
}); }));
toggleGroup.getToggles().get(model.tickUnit.ordinal()).setSelected(true); toggleGroup.getToggles().get(model.tickUnit.ordinal()).setSelected(true);

View file

@ -22,7 +22,6 @@ 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;
@ -56,8 +55,7 @@ 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 {
@ -74,7 +72,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, socks5ProxyProvider); networkNode = new TorNetworkNodeDirectBind(port, networkProtoResolver, banFilter, maxConnections, hiddenServiceAddress);
} }
} }
} }

View file

@ -1,7 +1,6 @@
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;
@ -10,6 +9,7 @@ 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,18 +25,16 @@ 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
@ -49,7 +47,7 @@ public class TorNetworkNodeDirectBind extends TorNetworkNode {
@Override @Override
public Socks5Proxy getSocksProxy() { public Socks5Proxy getSocksProxy() {
Socks5Proxy proxy = new Socks5Proxy(socks5ProxyProvider.getSocks5Proxy().getInetAddress(), socks5ProxyProvider.getSocks5Proxy().getPort()); // TODO: can/should we return the same socks5 proxy directly? Socks5Proxy proxy = new Socks5Proxy(InetAddress.getLoopbackAddress(), TOR_DATA_PORT);
proxy.resolveAddrLocally(false); proxy.resolveAddrLocally(false);
return proxy; return proxy;
} }
@ -59,7 +57,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(getSocksProxy().getInetAddress(), getSocksProxy().getPort()); Socket sock = new Socket(InetAddress.getLoopbackAddress(), TOR_DATA_PORT);
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")) {