Merge branch 'haveno-dex:master' into haveno-reto

This commit is contained in:
boldsuck 2025-01-15 23:28:21 +01:00 committed by GitHub
commit 8523fb97d1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 55 additions and 44 deletions

View file

@ -26,22 +26,23 @@ jobs:
cache: gradle cache: gradle
- name: Build with Gradle - name: Build with Gradle
run: ./gradlew build --stacktrace --scan run: ./gradlew build --stacktrace --scan
- uses: actions/upload-artifact@v3 - uses: actions/upload-artifact@v4
if: failure() if: failure()
with: with:
name: error-reports-${{ matrix.os }} name: error-reports-${{ matrix.os }}
path: ${{ github.workspace }}/desktop/build/reports path: ${{ github.workspace }}/desktop/build/reports
- name: cache nodes dependencies - name: cache nodes dependencies
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
include-hidden-files: true include-hidden-files: true
name: cached-localnet name: cached-localnet
path: .localnet path: .localnet
overwrite: true
- name: Install dependencies - name: Install dependencies
if: ${{ matrix.os == 'ubuntu-22.04' }} if: ${{ matrix.os == 'ubuntu-22.04' }}
run: | run: |
sudo apt update sudo apt-get update
sudo apt install -y rpm libfuse2 flatpak flatpak-builder appstream sudo apt-get install -y rpm libfuse2 flatpak flatpak-builder appstream
flatpak remote-add --if-not-exists --user flathub https://dl.flathub.org/repo/flathub.flatpakrepo flatpak remote-add --if-not-exists --user flathub https://dl.flathub.org/repo/flathub.flatpakrepo
- name: Install WiX Toolset - name: Install WiX Toolset
if: ${{ matrix.os == 'windows-latest' }} if: ${{ matrix.os == 'windows-latest' }}
@ -99,41 +100,41 @@ jobs:
shell: powershell shell: powershell
# win # win
- uses: actions/upload-artifact@v3 - uses: actions/upload-artifact@v4
name: "Windows artifacts" name: "Windows artifacts"
if: ${{ matrix.os == 'windows-latest'}} if: ${{ matrix.os == 'windows-latest'}}
with: with:
name: haveno-windows name: haveno-windows
path: ${{ github.workspace }}/release-windows path: ${{ github.workspace }}/release-windows
# macos # macos
- uses: actions/upload-artifact@v3 - uses: actions/upload-artifact@v4
name: "macOS artifacts" name: "macOS artifacts"
if: ${{ matrix.os == 'macos-13' }} if: ${{ matrix.os == 'macos-13' }}
with: with:
name: haveno-macos name: haveno-macos
path: ${{ github.workspace }}/release-macos path: ${{ github.workspace }}/release-macos
# linux # linux
- uses: actions/upload-artifact@v3 - uses: actions/upload-artifact@v4
name: "Linux - deb artifact" name: "Linux - deb artifact"
if: ${{ matrix.os == 'ubuntu-22.04' }} if: ${{ matrix.os == 'ubuntu-22.04' }}
with: with:
name: haveno-linux-deb name: haveno-linux-deb
path: ${{ github.workspace }}/release-linux-deb path: ${{ github.workspace }}/release-linux-deb
- uses: actions/upload-artifact@v3 - uses: actions/upload-artifact@v4
name: "Linux - rpm artifact" name: "Linux - rpm artifact"
if: ${{ matrix.os == 'ubuntu-22.04' }} if: ${{ matrix.os == 'ubuntu-22.04' }}
with: with:
name: haveno-linux-rpm name: haveno-linux-rpm
path: ${{ github.workspace }}/release-linux-rpm path: ${{ github.workspace }}/release-linux-rpm
- uses: actions/upload-artifact@v3 - uses: actions/upload-artifact@v4
name: "Linux - AppImage artifact" name: "Linux - AppImage artifact"
if: ${{ matrix.os == 'ubuntu-22.04' }} if: ${{ matrix.os == 'ubuntu-22.04' }}
with: with:
name: haveno-linux-appimage name: haveno-linux-appimage
path: ${{ github.workspace }}/release-linux-appimage path: ${{ github.workspace }}/release-linux-appimage
- uses: actions/upload-artifact@v3 - uses: actions/upload-artifact@v4
name: "Linux - flatpak artifact" name: "Linux - flatpak artifact"
if: ${{ matrix.os == 'ubuntu-22.04' }} if: ${{ matrix.os == 'ubuntu-22.04' }}
with: with:

View file

@ -9,7 +9,7 @@ jobs:
build: build:
if: github.repository == 'haveno-dex/haveno' if: github.repository == 'haveno-dex/haveno'
name: Publish coverage name: Publish coverage
runs-on: ubuntu-latest runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4

View file

@ -7,7 +7,7 @@ on:
jobs: jobs:
issueLabeled: issueLabeled:
runs-on: ubuntu-latest runs-on: ubuntu-22.04
steps: steps:
- name: Bounty explanation - name: Bounty explanation
uses: peter-evans/create-or-update-comment@v3 uses: peter-evans/create-or-update-comment@v3

View file

@ -117,6 +117,7 @@ public class Config {
public static final String BTC_FEE_INFO = "bitcoinFeeInfo"; public static final String BTC_FEE_INFO = "bitcoinFeeInfo";
public static final String BYPASS_MEMPOOL_VALIDATION = "bypassMempoolValidation"; public static final String BYPASS_MEMPOOL_VALIDATION = "bypassMempoolValidation";
public static final String PASSWORD_REQUIRED = "passwordRequired"; public static final String PASSWORD_REQUIRED = "passwordRequired";
public static final String UPDATE_XMR_BINARIES = "updateXmrBinaries";
// Default values for certain options // Default values for certain options
public static final int UNSPECIFIED_PORT = -1; public static final int UNSPECIFIED_PORT = -1;
@ -204,6 +205,7 @@ public class Config {
public final boolean republishMailboxEntries; public final boolean republishMailboxEntries;
public final boolean bypassMempoolValidation; public final boolean bypassMempoolValidation;
public final boolean passwordRequired; public final boolean passwordRequired;
public final boolean updateXmrBinaries;
// Properties derived from options but not exposed as options themselves // Properties derived from options but not exposed as options themselves
public final File torDir; public final File torDir;
@ -621,6 +623,13 @@ public class Config {
.ofType(boolean.class) .ofType(boolean.class)
.defaultsTo(false); .defaultsTo(false);
ArgumentAcceptingOptionSpec<Boolean> updateXmrBinariesOpt =
parser.accepts(UPDATE_XMR_BINARIES,
"Update Monero binaries if applicable")
.withRequiredArg()
.ofType(boolean.class)
.defaultsTo(true);
try { try {
CompositeOptionSet options = new CompositeOptionSet(); CompositeOptionSet options = new CompositeOptionSet();
@ -733,6 +742,7 @@ public class Config {
this.republishMailboxEntries = options.valueOf(republishMailboxEntriesOpt); this.republishMailboxEntries = options.valueOf(republishMailboxEntriesOpt);
this.bypassMempoolValidation = options.valueOf(bypassMempoolValidationOpt); this.bypassMempoolValidation = options.valueOf(bypassMempoolValidationOpt);
this.passwordRequired = options.valueOf(passwordRequiredOpt); this.passwordRequired = options.valueOf(passwordRequiredOpt);
this.updateXmrBinaries = options.valueOf(updateXmrBinariesOpt);
} catch (OptionException ex) { } catch (OptionException ex) {
throw new ConfigException("problem parsing option '%s': %s", throw new ConfigException("problem parsing option '%s': %s",
ex.options().get(0), ex.options().get(0),

View file

@ -239,8 +239,8 @@ public class CoreApi {
xmrConnectionService.stopCheckingConnection(); xmrConnectionService.stopCheckingConnection();
} }
public MoneroRpcConnection getBestAvailableXmrConnection() { public MoneroRpcConnection getBestXmrConnection() {
return xmrConnectionService.getBestAvailableConnection(); return xmrConnectionService.getBestConnection();
} }
public void setXmrConnectionAutoSwitch(boolean autoSwitch) { public void setXmrConnectionAutoSwitch(boolean autoSwitch) {

View file

@ -255,18 +255,17 @@ public final class XmrConnectionService {
updatePolling(); updatePolling();
} }
public MoneroRpcConnection getBestAvailableConnection() { public MoneroRpcConnection getBestConnection() {
accountService.checkAccountOpen(); return getBestConnection(new ArrayList<MoneroRpcConnection>());
List<MoneroRpcConnection> ignoredConnections = new ArrayList<MoneroRpcConnection>();
addLocalNodeIfIgnored(ignoredConnections);
return connectionManager.getBestAvailableConnection(ignoredConnections.toArray(new MoneroRpcConnection[0]));
} }
private MoneroRpcConnection getBestAvailableConnection(Collection<MoneroRpcConnection> ignoredConnections) { private MoneroRpcConnection getBestConnection(Collection<MoneroRpcConnection> ignoredConnections) {
accountService.checkAccountOpen(); accountService.checkAccountOpen();
Set<MoneroRpcConnection> ignoredConnectionsSet = new HashSet<>(ignoredConnections); Set<MoneroRpcConnection> ignoredConnectionsSet = new HashSet<>(ignoredConnections);
addLocalNodeIfIgnored(ignoredConnectionsSet); addLocalNodeIfIgnored(ignoredConnectionsSet);
return connectionManager.getBestAvailableConnection(ignoredConnectionsSet.toArray(new MoneroRpcConnection[0])); MoneroRpcConnection bestConnection = connectionManager.getBestAvailableConnection(ignoredConnectionsSet.toArray(new MoneroRpcConnection[0])); // checks connections
if (bestConnection == null && connectionManager.getConnections().size() == 1 && !ignoredConnectionsSet.contains(connectionManager.getConnections().get(0))) bestConnection = connectionManager.getConnections().get(0);
return bestConnection;
} }
private void addLocalNodeIfIgnored(Collection<MoneroRpcConnection> ignoredConnections) { private void addLocalNodeIfIgnored(Collection<MoneroRpcConnection> ignoredConnections) {
@ -278,7 +277,7 @@ public final class XmrConnectionService {
log.info("Skipping switch to best Monero connection because connection is fixed or auto switch is disabled"); log.info("Skipping switch to best Monero connection because connection is fixed or auto switch is disabled");
return; return;
} }
MoneroRpcConnection bestConnection = getBestAvailableConnection(); MoneroRpcConnection bestConnection = getBestConnection();
if (bestConnection != null) setConnection(bestConnection); if (bestConnection != null) setConnection(bestConnection);
} }
@ -329,7 +328,7 @@ public final class XmrConnectionService {
if (currentConnection != null) excludedConnections.add(currentConnection); if (currentConnection != null) excludedConnections.add(currentConnection);
// get connection to switch to // get connection to switch to
MoneroRpcConnection bestConnection = getBestAvailableConnection(excludedConnections); MoneroRpcConnection bestConnection = getBestConnection(excludedConnections);
// remove from excluded connections after period // remove from excluded connections after period
UserThread.runAfter(() -> { UserThread.runAfter(() -> {
@ -337,7 +336,7 @@ public final class XmrConnectionService {
}, EXCLUDE_CONNECTION_SECONDS); }, EXCLUDE_CONNECTION_SECONDS);
// return if no connection to switch to // return if no connection to switch to
if (bestConnection == null) { if (bestConnection == null || !Boolean.TRUE.equals(bestConnection.isConnected())) {
log.warn("No connection to switch to"); log.warn("No connection to switch to");
return false; return false;
} }
@ -545,7 +544,7 @@ public final class XmrConnectionService {
if (isConnected) { if (isConnected) {
setConnection(connection.getUri()); setConnection(connection.getUri());
} else if (getConnection() != null && getConnection().getUri().equals(connection.getUri())) { } else if (getConnection() != null && getConnection().getUri().equals(connection.getUri())) {
MoneroRpcConnection bestConnection = getBestAvailableConnection(); MoneroRpcConnection bestConnection = getBestConnection();
if (bestConnection != null) setConnection(bestConnection); // switch to best connection if (bestConnection != null) setConnection(bestConnection); // switch to best connection
} }
} }
@ -610,7 +609,7 @@ public final class XmrConnectionService {
// update connection // update connection
if (connectionManager.getConnection() == null || connectionManager.getAutoSwitch()) { if (connectionManager.getConnection() == null || connectionManager.getAutoSwitch()) {
MoneroRpcConnection bestConnection = getBestAvailableConnection(); MoneroRpcConnection bestConnection = getBestConnection();
if (bestConnection != null) setConnection(bestConnection); if (bestConnection != null) setConnection(bestConnection);
} }
} else if (!isInitialized) { } else if (!isInitialized) {
@ -725,8 +724,8 @@ public final class XmrConnectionService {
// poll daemon // poll daemon
if (daemon == null) switchToBestConnection(); if (daemon == null) switchToBestConnection();
if (daemon == null) throw new RuntimeException("No connection to Monero daemon");
try { try {
if (daemon == null) throw new RuntimeException("No connection to Monero daemon");
lastInfo = daemon.getInfo(); lastInfo = daemon.getInfo();
} catch (Exception e) { } catch (Exception e) {
@ -753,6 +752,7 @@ public final class XmrConnectionService {
// switch to best connection // switch to best connection
switchToBestConnection(); switchToBestConnection();
if (daemon == null) throw new RuntimeException("No connection to Monero daemon after error handling");
lastInfo = daemon.getInfo(); // caught internally if still fails lastInfo = daemon.getInfo(); // caught internally if still fails
} }

View file

@ -369,7 +369,7 @@ public class HavenoSetup {
// install monerod // install monerod
File monerodFile = new File(XmrLocalNode.MONEROD_PATH); File monerodFile = new File(XmrLocalNode.MONEROD_PATH);
String monerodResourcePath = "bin/" + XmrLocalNode.MONEROD_NAME; String monerodResourcePath = "bin/" + XmrLocalNode.MONEROD_NAME;
if (!monerodFile.exists() || !FileUtil.resourceEqualToFile(monerodResourcePath, monerodFile)) { if (!monerodFile.exists() || (config.updateXmrBinaries && !FileUtil.resourceEqualToFile(monerodResourcePath, monerodFile))) {
log.info("Installing monerod"); log.info("Installing monerod");
monerodFile.getParentFile().mkdirs(); monerodFile.getParentFile().mkdirs();
FileUtil.resourceToFile("bin/" + XmrLocalNode.MONEROD_NAME, monerodFile); FileUtil.resourceToFile("bin/" + XmrLocalNode.MONEROD_NAME, monerodFile);
@ -379,7 +379,7 @@ public class HavenoSetup {
// install monero-wallet-rpc // install monero-wallet-rpc
File moneroWalletRpcFile = new File(XmrWalletService.MONERO_WALLET_RPC_PATH); File moneroWalletRpcFile = new File(XmrWalletService.MONERO_WALLET_RPC_PATH);
String moneroWalletRpcResourcePath = "bin/" + XmrWalletService.MONERO_WALLET_RPC_NAME; String moneroWalletRpcResourcePath = "bin/" + XmrWalletService.MONERO_WALLET_RPC_NAME;
if (!moneroWalletRpcFile.exists() || !FileUtil.resourceEqualToFile(moneroWalletRpcResourcePath, moneroWalletRpcFile)) { if (!moneroWalletRpcFile.exists() || (config.updateXmrBinaries && !FileUtil.resourceEqualToFile(moneroWalletRpcResourcePath, moneroWalletRpcFile))) {
log.info("Installing monero-wallet-rpc"); log.info("Installing monero-wallet-rpc");
moneroWalletRpcFile.getParentFile().mkdirs(); moneroWalletRpcFile.getParentFile().mkdirs();
FileUtil.resourceToFile(moneroWalletRpcResourcePath, moneroWalletRpcFile); FileUtil.resourceToFile(moneroWalletRpcResourcePath, moneroWalletRpcFile);

View file

@ -47,8 +47,8 @@ import haveno.proto.grpc.CheckConnectionsReply;
import haveno.proto.grpc.CheckConnectionsRequest; import haveno.proto.grpc.CheckConnectionsRequest;
import haveno.proto.grpc.GetAutoSwitchReply; import haveno.proto.grpc.GetAutoSwitchReply;
import haveno.proto.grpc.GetAutoSwitchRequest; import haveno.proto.grpc.GetAutoSwitchRequest;
import haveno.proto.grpc.GetBestAvailableConnectionReply; import haveno.proto.grpc.GetBestConnectionReply;
import haveno.proto.grpc.GetBestAvailableConnectionRequest; import haveno.proto.grpc.GetBestConnectionRequest;
import haveno.proto.grpc.GetConnectionReply; import haveno.proto.grpc.GetConnectionReply;
import haveno.proto.grpc.GetConnectionRequest; import haveno.proto.grpc.GetConnectionRequest;
import haveno.proto.grpc.GetConnectionsReply; import haveno.proto.grpc.GetConnectionsReply;
@ -68,7 +68,7 @@ import static haveno.proto.grpc.XmrConnectionsGrpc.XmrConnectionsImplBase;
import static haveno.proto.grpc.XmrConnectionsGrpc.getAddConnectionMethod; import static haveno.proto.grpc.XmrConnectionsGrpc.getAddConnectionMethod;
import static haveno.proto.grpc.XmrConnectionsGrpc.getCheckConnectionMethod; import static haveno.proto.grpc.XmrConnectionsGrpc.getCheckConnectionMethod;
import static haveno.proto.grpc.XmrConnectionsGrpc.getCheckConnectionsMethod; import static haveno.proto.grpc.XmrConnectionsGrpc.getCheckConnectionsMethod;
import static haveno.proto.grpc.XmrConnectionsGrpc.getGetBestAvailableConnectionMethod; import static haveno.proto.grpc.XmrConnectionsGrpc.getGetBestConnectionMethod;
import static haveno.proto.grpc.XmrConnectionsGrpc.getGetConnectionMethod; import static haveno.proto.grpc.XmrConnectionsGrpc.getGetConnectionMethod;
import static haveno.proto.grpc.XmrConnectionsGrpc.getGetConnectionsMethod; import static haveno.proto.grpc.XmrConnectionsGrpc.getGetConnectionsMethod;
import static haveno.proto.grpc.XmrConnectionsGrpc.getRemoveConnectionMethod; import static haveno.proto.grpc.XmrConnectionsGrpc.getRemoveConnectionMethod;
@ -201,12 +201,12 @@ class GrpcXmrConnectionService extends XmrConnectionsImplBase {
} }
@Override @Override
public void getBestAvailableConnection(GetBestAvailableConnectionRequest request, public void getBestConnection(GetBestConnectionRequest request,
StreamObserver<GetBestAvailableConnectionReply> responseObserver) { StreamObserver<GetBestConnectionReply> responseObserver) {
handleRequest(responseObserver, () -> { handleRequest(responseObserver, () -> {
MoneroRpcConnection connection = coreApi.getBestAvailableXmrConnection(); MoneroRpcConnection connection = coreApi.getBestXmrConnection();
UrlConnection replyConnection = toUrlConnection(connection); UrlConnection replyConnection = toUrlConnection(connection);
GetBestAvailableConnectionReply.Builder builder = GetBestAvailableConnectionReply.newBuilder(); GetBestConnectionReply.Builder builder = GetBestConnectionReply.newBuilder();
if (replyConnection != null) { if (replyConnection != null) {
builder.setConnection(replyConnection); builder.setConnection(replyConnection);
} }
@ -314,7 +314,7 @@ class GrpcXmrConnectionService extends XmrConnectionsImplBase {
put(getCheckConnectionsMethod().getFullMethodName(), new GrpcCallRateMeter(allowedCallsPerTimeWindow, SECONDS)); put(getCheckConnectionsMethod().getFullMethodName(), new GrpcCallRateMeter(allowedCallsPerTimeWindow, SECONDS));
put(getStartCheckingConnectionMethod().getFullMethodName(), new GrpcCallRateMeter(allowedCallsPerTimeWindow, SECONDS)); put(getStartCheckingConnectionMethod().getFullMethodName(), new GrpcCallRateMeter(allowedCallsPerTimeWindow, SECONDS));
put(getStopCheckingConnectionMethod().getFullMethodName(), new GrpcCallRateMeter(allowedCallsPerTimeWindow, SECONDS)); put(getStopCheckingConnectionMethod().getFullMethodName(), new GrpcCallRateMeter(allowedCallsPerTimeWindow, SECONDS));
put(getGetBestAvailableConnectionMethod().getFullMethodName(), new GrpcCallRateMeter(allowedCallsPerTimeWindow, SECONDS)); put(getGetBestConnectionMethod().getFullMethodName(), new GrpcCallRateMeter(allowedCallsPerTimeWindow, SECONDS));
put(getSetAutoSwitchMethod().getFullMethodName(), new GrpcCallRateMeter(allowedCallsPerTimeWindow, SECONDS)); put(getSetAutoSwitchMethod().getFullMethodName(), new GrpcCallRateMeter(allowedCallsPerTimeWindow, SECONDS));
}} }}
))); )));

View file

@ -216,7 +216,7 @@ public class HavenoAppMain extends HavenoExecutable {
// Set the dialog content // Set the dialog content
VBox vbox = new VBox(10); VBox vbox = new VBox(10);
vbox.getChildren().addAll(new ImageView(ImageUtil.getImageByPath("logo_splash.png")), versionField, passwordField, errorMessageField); vbox.getChildren().addAll(new ImageView(ImageUtil.getImageByPath("logo_splash.png")), passwordField, errorMessageField, versionField);
vbox.setAlignment(Pos.TOP_CENTER); vbox.setAlignment(Pos.TOP_CENTER);
getDialogPane().setContent(vbox); getDialogPane().setContent(vbox);

View file

@ -511,8 +511,6 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
ImageView logo = new ImageView(); ImageView logo = new ImageView();
logo.setId(Config.baseCurrencyNetwork() == BaseCurrencyNetwork.XMR_MAINNET ? "image-splash-logo" : "image-splash-testnet-logo"); logo.setId(Config.baseCurrencyNetwork() == BaseCurrencyNetwork.XMR_MAINNET ? "image-splash-logo" : "image-splash-testnet-logo");
Label versionLabel = new Label("v" + Version.VERSION);
// createBitcoinInfoBox // createBitcoinInfoBox
xmrSplashInfo = new AutoTooltipLabel(); xmrSplashInfo = new AutoTooltipLabel();
xmrSplashInfo.textProperty().bind(model.getXmrInfo()); xmrSplashInfo.textProperty().bind(model.getXmrInfo());
@ -624,7 +622,9 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
splashP2PNetworkBox.setPrefHeight(40); splashP2PNetworkBox.setPrefHeight(40);
splashP2PNetworkBox.getChildren().addAll(splashP2PNetworkLabel, splashP2PNetworkBusyAnimation, splashP2PNetworkIcon, showTorNetworkSettingsButton); splashP2PNetworkBox.getChildren().addAll(splashP2PNetworkLabel, splashP2PNetworkBusyAnimation, splashP2PNetworkIcon, showTorNetworkSettingsButton);
vBox.getChildren().addAll(logo, versionLabel, blockchainSyncBox, xmrSyncIndicator, splashP2PNetworkBox); Label versionLabel = new Label("v" + Version.VERSION);
vBox.getChildren().addAll(logo, blockchainSyncBox, xmrSyncIndicator, splashP2PNetworkBox, versionLabel);
return vBox; return vBox;
} }

View file

@ -319,7 +319,7 @@ service XmrConnections {
} }
rpc StopCheckingConnection(StopCheckingConnectionRequest) returns (StopCheckingConnectionReply) { rpc StopCheckingConnection(StopCheckingConnectionRequest) returns (StopCheckingConnectionReply) {
} }
rpc GetBestAvailableConnection(GetBestAvailableConnectionRequest) returns (GetBestAvailableConnectionReply) { rpc GetBestConnection(GetBestConnectionRequest) returns (GetBestConnectionReply) {
} }
rpc SetAutoSwitch(SetAutoSwitchRequest) returns (SetAutoSwitchReply) { rpc SetAutoSwitch(SetAutoSwitchRequest) returns (SetAutoSwitchReply) {
} }
@ -400,9 +400,9 @@ message StopCheckingConnectionRequest {}
message StopCheckingConnectionReply {} message StopCheckingConnectionReply {}
message GetBestAvailableConnectionRequest {} message GetBestConnectionRequest {}
message GetBestAvailableConnectionReply { message GetBestConnectionReply {
UrlConnection connection = 1; UrlConnection connection = 1;
} }