diff --git a/application/build.gradle.kts b/application/build.gradle.kts index de87aa453d..44e80c8694 100644 --- a/application/build.gradle.kts +++ b/application/build.gradle.kts @@ -17,5 +17,4 @@ dependencies { implementation("network:network") implementation(libs.typesafe.config) - implementation(libs.bouncycastle.pg) } diff --git a/application/src/main/java/bisq/application/ApplicationService.java b/application/src/main/java/bisq/application/ApplicationService.java index 55b54f57bb..561915cb76 100644 --- a/application/src/main/java/bisq/application/ApplicationService.java +++ b/application/src/main/java/bisq/application/ApplicationService.java @@ -17,7 +17,6 @@ package bisq.application; -import bisq.application.migration.MigrationService; import bisq.common.application.ApplicationVersion; import bisq.common.application.DevMode; import bisq.common.application.OptionUtils; @@ -29,8 +28,6 @@ import bisq.common.locale.LocaleRepository; import bisq.common.logging.AsciiLogo; import bisq.common.logging.LogSetup; -import bisq.common.platform.MemoryReport; -import bisq.common.platform.PlatformUtils; import bisq.common.util.ExceptionUtil; import bisq.i18n.Res; import bisq.persistence.PersistenceService; @@ -74,11 +71,11 @@ private static String resolveAppName(String[] args, com.typesafe.config.Config c @ToString @EqualsAndHashCode public static final class Config { - private static Config from(com.typesafe.config.Config config, String[] args) { + private static Config from(com.typesafe.config.Config config, String[] args, Path userDataDir) { String appName = resolveAppName(args, config); Path appDataDir = OptionUtils.findOptionValue(args, "--data-dir") .map(Path::of) - .orElse(PlatformUtils.getUserDataDir().resolve(appName)); + .orElse(userDataDir.resolve(appName)); return new Config(appDataDir, appName, config.getBoolean("devMode"), @@ -125,19 +122,16 @@ public Config(Path baseDir, protected final Config config; @Getter protected final PersistenceService persistenceService; - private final MigrationService migrationService; - @SuppressWarnings("FieldCanBeLocal") // Pin it so that it does not get GC'ed - private final MemoryReport memoryReport; private FileLock instanceLock; - public ApplicationService(String configFileName, String[] args) { + public ApplicationService(String configFileName, String[] args, Path userDataDir) { com.typesafe.config.Config defaultTypesafeConfig = ConfigFactory.load(configFileName); defaultTypesafeConfig.checkValid(ConfigFactory.defaultReference(), configFileName); String appName = resolveAppName(args, defaultTypesafeConfig.getConfig("application")); Path appDataDir = OptionUtils.findOptionValue(args, "--data-dir") .map(Path::of) - .orElse(PlatformUtils.getUserDataDir().resolve(appName)); + .orElse(userDataDir.resolve(appName)); File customConfigFile = Path.of(appDataDir.toString(), "bisq.conf").toFile(); com.typesafe.config.Config typesafeConfig; boolean customConfigProvided = customConfigFile.exists(); @@ -153,7 +147,7 @@ public ApplicationService(String configFileName, String[] args) { } typesafeAppConfig = typesafeConfig.getConfig("application"); - config = Config.from(typesafeAppConfig, args); + config = Config.from(typesafeAppConfig, args, userDataDir); Path dataDir = config.getBaseDir(); try { @@ -173,9 +167,6 @@ public ApplicationService(String configFileName, String[] args) { log.info("Using custom config file"); } - memoryReport = MemoryReport.getINSTANCE(); - memoryReport.printPeriodically(config.getMemoryReportIntervalSec(), config.isIncludeThreadListInMemoryReport()); - DevMode.setDevMode(config.isDevMode()); Locale locale = LocaleRepository.getDefaultLocale(); @@ -187,7 +178,6 @@ public ApplicationService(String configFileName, String[] args) { String absoluteDataDirPath = dataDir.toAbsolutePath().toString(); persistenceService = new PersistenceService(absoluteDataDirPath); - migrationService = new MigrationService(dataDir); } private void checkInstanceLock() { @@ -214,9 +204,7 @@ public CompletableFuture readAllPersisted() { return persistenceService.readAllPersisted(); } - public CompletableFuture initialize() { - return migrationService.runMigrations(); - } + public abstract CompletableFuture initialize(); public abstract CompletableFuture shutdown(); diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/State.java b/application/src/main/java/bisq/application/State.java similarity index 96% rename from apps/desktop/desktop/src/main/java/bisq/desktop/State.java rename to application/src/main/java/bisq/application/State.java index 587c8b4ab7..946cfc23e5 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/State.java +++ b/application/src/main/java/bisq/application/State.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.desktop; +package bisq.application; public enum State { INITIALIZE_APP, diff --git a/apps/desktop/desktop-app-launcher/build.gradle.kts b/apps/desktop/desktop-app-launcher/build.gradle.kts index 029af8d6cb..0f490e1f3b 100644 --- a/apps/desktop/desktop-app-launcher/build.gradle.kts +++ b/apps/desktop/desktop-app-launcher/build.gradle.kts @@ -37,7 +37,9 @@ javafx { dependencies { implementation("bisq:common") implementation("bisq:security") + implementation("bisq:java-se") implementation("bisq:application") + implementation("bisq:evolution") implementation(project(":desktop-app")) } diff --git a/apps/desktop/desktop-app-launcher/src/main/java/bisq/desktop_app_launcher/DesktopAppLauncher.java b/apps/desktop/desktop-app-launcher/src/main/java/bisq/desktop_app_launcher/DesktopAppLauncher.java index a1f66943c8..2552852c73 100644 --- a/apps/desktop/desktop-app-launcher/src/main/java/bisq/desktop_app_launcher/DesktopAppLauncher.java +++ b/apps/desktop/desktop-app-launcher/src/main/java/bisq/desktop_app_launcher/DesktopAppLauncher.java @@ -23,8 +23,8 @@ import bisq.common.threading.ThreadName; import bisq.common.util.ExceptionUtil; import bisq.desktop_app.DesktopApp; -import bisq.updater.DownloadedFilesVerification; -import bisq.updater.UpdaterUtils; +import bisq.evolution.updater.DownloadedFilesVerification; +import bisq.evolution.updater.UpdaterUtils; import lombok.extern.slf4j.Slf4j; import java.io.File; @@ -38,7 +38,7 @@ import java.util.List; import java.util.Optional; -import static bisq.updater.UpdaterUtils.*; +import static bisq.evolution.updater.UpdaterUtils.*; /** * We ship the binary with the current version of the DesktopApp and with the JRE. diff --git a/apps/desktop/desktop-app-launcher/src/main/java/bisq/desktop_app_launcher/Options.java b/apps/desktop/desktop-app-launcher/src/main/java/bisq/desktop_app_launcher/Options.java index 71d531897c..24e7878511 100644 --- a/apps/desktop/desktop-app-launcher/src/main/java/bisq/desktop_app_launcher/Options.java +++ b/apps/desktop/desktop-app-launcher/src/main/java/bisq/desktop_app_launcher/Options.java @@ -17,7 +17,7 @@ package bisq.desktop_app_launcher; -import bisq.common.jvm.JvmUtils; +import bisq.java_se.utils.JvmUtils; import lombok.Getter; import lombok.extern.slf4j.Slf4j; diff --git a/apps/desktop/desktop-app/build.gradle.kts b/apps/desktop/desktop-app/build.gradle.kts index e5ffffbc82..721f9b0b8a 100644 --- a/apps/desktop/desktop-app/build.gradle.kts +++ b/apps/desktop/desktop-app/build.gradle.kts @@ -35,6 +35,7 @@ javafx { dependencies { implementation("bisq:persistence") + implementation("bisq:java-se") implementation("bisq:i18n") implementation("bisq:security") implementation("bisq:identity") @@ -50,6 +51,8 @@ dependencies { implementation("bisq:presentation") implementation("bisq:bisq-easy") implementation("bisq:application") + implementation("bisq:evolution") + implementation("bisq:os-specific") implementation(project(":desktop")) diff --git a/apps/desktop/desktop-app/src/main/java/bisq/desktop_app/DesktopApplicationService.java b/apps/desktop/desktop-app/src/main/java/bisq/desktop_app/DesktopApplicationService.java index 007e8e9e6a..4a9b42977d 100644 --- a/apps/desktop/desktop-app/src/main/java/bisq/desktop_app/DesktopApplicationService.java +++ b/apps/desktop/desktop-app/src/main/java/bisq/desktop_app/DesktopApplicationService.java @@ -18,24 +18,30 @@ package bisq.desktop_app; import bisq.account.AccountService; -import bisq.application.ApplicationService; import bisq.application.ShutDownHandler; +import bisq.application.State; import bisq.bisq_easy.BisqEasyService; import bisq.bonded_roles.BondedRolesService; import bisq.bonded_roles.security_manager.alert.AlertNotificationsService; import bisq.chat.ChatService; import bisq.common.application.Service; import bisq.common.observable.Observable; +import bisq.common.platform.OS; import bisq.common.util.CompletableFutureUtils; import bisq.common.util.ExceptionUtil; import bisq.contract.ContractService; import bisq.desktop.ServiceProvider; -import bisq.desktop.State; import bisq.desktop.webcam.WebcamAppService; +import bisq.evolution.updater.UpdaterService; import bisq.identity.IdentityService; +import bisq.java_se.application.JavaSeApplicationService; import bisq.network.NetworkService; import bisq.network.NetworkServiceConfig; import bisq.offer.OfferService; +import bisq.os_specific.notifications.linux.LinuxNotificationService; +import bisq.os_specific.notifications.osx.OsxNotificationService; +import bisq.os_specific.notifications.other.AwtNotificationService; +import bisq.presentation.notifications.OsSpecificNotificationService; import bisq.presentation.notifications.SystemNotificationService; import bisq.security.SecurityService; import bisq.settings.DontShowAgainService; @@ -43,7 +49,6 @@ import bisq.settings.SettingsService; import bisq.support.SupportService; import bisq.trade.TradeService; -import bisq.updater.UpdaterService; import bisq.user.UserService; import bisq.wallets.core.BitcoinWalletSelection; import bisq.wallets.core.WalletService; @@ -65,7 +70,7 @@ */ @Slf4j -public class DesktopApplicationService extends ApplicationService { +public class DesktopApplicationService extends JavaSeApplicationService { public static final long STARTUP_TIMEOUT_SEC = 300; public static final long SHUTDOWN_TIMEOUT_SEC = 10; @@ -103,6 +108,7 @@ public DesktopApplicationService(String[] args, ShutDownHandler shutDownHandler) super("desktop", args); securityService = new SecurityService(persistenceService, SecurityService.Config.from(getConfig("security"))); + com.typesafe.config.Config bitcoinWalletConfig = getConfig("bitcoinWallet"); BitcoinWalletSelection bitcoinWalletSelection = bitcoinWalletConfig.getEnum(BitcoinWalletSelection.class, "bitcoinWalletSelection"); //noinspection SwitchStatementWithTooFewBranches @@ -124,7 +130,8 @@ public DesktopApplicationService(String[] args, ShutDownHandler shutDownHandler) persistenceService, securityService.getKeyBundleService(), securityService.getHashCashProofOfWorkService(), - securityService.getEquihashProofOfWorkService()); + securityService.getEquihashProofOfWorkService(), + memoryReportService); identityService = new IdentityService(persistenceService, securityService.getKeyBundleService(), @@ -146,7 +153,7 @@ public DesktopApplicationService(String[] args, ShutDownHandler shutDownHandler) settingsService = new SettingsService(persistenceService); - systemNotificationService = new SystemNotificationService(config.getBaseDir(), settingsService); + systemNotificationService = new SystemNotificationService(findSystemNotificationDelegate()); offerService = new OfferService(networkService, identityService, persistenceService); @@ -170,7 +177,6 @@ public DesktopApplicationService(String[] args, ShutDownHandler shutDownHandler) bisqEasyService = new BisqEasyService(persistenceService, securityService, - walletService, networkService, identityService, bondedRolesService, @@ -217,9 +223,29 @@ public DesktopApplicationService(String[] args, ShutDownHandler shutDownHandler) webcamAppService); } + private Optional findSystemNotificationDelegate() { + try { + switch (OS.getOS()) { + case LINUX: + return Optional.of(new LinuxNotificationService(config.getBaseDir(), settingsService)); + case MAC_OS: + return Optional.of(new OsxNotificationService()); + case WINDOWS: + return Optional.of(new AwtNotificationService()); + default: + case ANDROID: + return Optional.empty(); + } + } catch (Exception e) { + log.warn("Could not create SystemNotificationDelegate for {}", OS.getOsName()); + return Optional.empty(); + } + } + @Override public CompletableFuture initialize() { - return super.initialize() + return migrationService.initialize() + .thenCompose(result -> memoryReportService.initialize()) .thenCompose(result -> securityService.initialize()) .thenCompose(result -> { setState(State.INITIALIZE_NETWORK); @@ -311,6 +337,8 @@ public CompletableFuture shutdown() { .thenCompose(result -> walletService.map(service -> service.shutdown().exceptionally(this::logError)) .orElse(CompletableFuture.completedFuture(true))) .thenCompose(result -> securityService.shutdown().exceptionally(this::logError)) + .thenCompose(result -> memoryReportService.shutdown().exceptionally(this::logError)) + .thenCompose(result -> migrationService.shutdown().exceptionally(this::logError)) .orTimeout(SHUTDOWN_TIMEOUT_SEC, TimeUnit.SECONDS) .handle((result, throwable) -> { if (throwable == null) { diff --git a/apps/desktop/desktop-app/src/main/resources/desktop.conf b/apps/desktop/desktop-app/src/main/resources/desktop.conf index 3d3f7f003d..f7f42f796b 100644 --- a/apps/desktop/desktop-app/src/main/resources/desktop.conf +++ b/apps/desktop/desktop-app/src/main/resources/desktop.conf @@ -186,6 +186,7 @@ application { devModeDelayInMs = 300 sendMessageThrottleTime = 200 receiveMessageThrottleTime = 200 + connectTimeoutMs = 3000 } tor { bootstrapTimeout = 240 diff --git a/apps/desktop/desktop/build.gradle.kts b/apps/desktop/desktop/build.gradle.kts index 3b72a78bd6..70f00cce59 100644 --- a/apps/desktop/desktop/build.gradle.kts +++ b/apps/desktop/desktop/build.gradle.kts @@ -34,8 +34,8 @@ dependencies { implementation("bisq:presentation") implementation("bisq:bisq-easy") implementation("bisq:application") + implementation("bisq:evolution") - implementation("network:network-common") implementation("network:network") implementation("network:network-identity") diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/DesktopController.java b/apps/desktop/desktop/src/main/java/bisq/desktop/DesktopController.java index 1045c5fdd7..61d8fa565b 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/DesktopController.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/DesktopController.java @@ -17,6 +17,7 @@ package bisq.desktop; +import bisq.application.State; import bisq.bisq_easy.NavigationTarget; import bisq.chat.notifications.ChatNotificationService; import bisq.common.observable.Observable; @@ -29,6 +30,7 @@ import bisq.desktop.common.view.Navigation; import bisq.desktop.common.view.NavigationController; import bisq.desktop.components.cathash.CatHash; +import bisq.desktop.components.cathash.JavaFxCatHashService; import bisq.desktop.components.overlay.Overlay; import bisq.desktop.components.overlay.Popup; import bisq.desktop.main.MainController; @@ -115,7 +117,8 @@ public void init() { Browser.initialize(applicationJavaFxApplicationData.getHostServices(), settingsService, dontShowAgainService); Transitions.setSettingsService(settingsService); AnchorPane viewRoot = view.getRoot(); - CatHash.setBaseDir(serviceProvider.getConfig().getBaseDir()); + + CatHash.setDelegate(new JavaFxCatHashService(serviceProvider.getConfig().getBaseDir())); Navigation.init(settingsService); Overlay.init(serviceProvider, viewRoot); diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/ServiceProvider.java b/apps/desktop/desktop/src/main/java/bisq/desktop/ServiceProvider.java index 79bf7de7a6..9f1bed8d78 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/ServiceProvider.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/ServiceProvider.java @@ -41,7 +41,7 @@ import bisq.settings.SettingsService; import bisq.support.SupportService; import bisq.trade.TradeService; -import bisq.updater.UpdaterService; +import bisq.evolution.updater.UpdaterService; import bisq.user.UserService; import bisq.wallets.core.WalletService; import lombok.Getter; diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/common/standby/PreventStandbyModeService.java b/apps/desktop/desktop/src/main/java/bisq/desktop/common/standby/PreventStandbyModeService.java index 9d127a3f4a..8aa84792bf 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/common/standby/PreventStandbyModeService.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/common/standby/PreventStandbyModeService.java @@ -38,6 +38,9 @@ public PreventStandbyModeService(ServiceProvider serviceProvider) { } public void initialize() { + if(OS.isAndroid()){ + return; + } settingsService.getPreventStandbyMode().addObserver(preventStandbyMode -> { if (preventStandbyMode) { this.preventStandbyMode.initialize(); diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/components/cathash/CatHash.java b/apps/desktop/desktop/src/main/java/bisq/desktop/components/cathash/CatHash.java index 77ce1733df..cbc2401040 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/components/cathash/CatHash.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/components/cathash/CatHash.java @@ -17,167 +17,34 @@ package bisq.desktop.components.cathash; -import bisq.common.encoding.Hex; -import bisq.common.file.FileUtils; -import bisq.common.util.ByteArrayUtils; -import bisq.desktop.common.utils.ImageUtil; +import bisq.user.cathash.BucketConfig; import bisq.user.profile.UserProfile; import javafx.scene.image.Image; import lombok.Setter; import lombok.extern.slf4j.Slf4j; -import java.io.File; -import java.io.IOException; -import java.math.BigInteger; -import java.nio.file.Path; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.stream.Collectors; -import java.util.stream.Stream; +import java.util.Collection; // Derived from https://github.com/neuhalje/android-robohash @Slf4j public class CatHash { - // Largest size in offerbook is 60px, in reputationListView it is 40px and in chats 30px. - // Larger images are used only rarely and are not cached. - public static final double SIZE_OF_CACHED_ICONS = 60; - - // This is a 120*120 image meaning 14400 pixels. At 4 bytes each, that takes 57.6 KB in memory (and on disk as we use raw format). - // With 5000 images we would get about 288 MB. - private static final int MAX_CACHE_SIZE = 5000; - - private static final ConcurrentHashMap CACHE = new ConcurrentHashMap<>(); @Setter - private static Path baseDir; + private static JavaFxCatHashService delegate; public static Image getImage(UserProfile userProfile, double size) { - return getImage(userProfile.getPubKeyHash(), - userProfile.getProofOfWork().getSolution(), - userProfile.getAvatarVersion(), - size); + return delegate.getImage(userProfile, size); } public static Image getImage(byte[] pubKeyHash, byte[] powSolution, int avatarVersion, double size) { - byte[] combined = ByteArrayUtils.concat(powSolution, pubKeyHash); - BigInteger catHashInput = new BigInteger(combined); - String userProfileId = Hex.encode(pubKeyHash); - File iconsDir = Path.of(getCatHashIconsDirectory().toString(), "v" + avatarVersion).toFile(); - File iconFile = Path.of(iconsDir.getAbsolutePath(), userProfileId + ".raw").toFile(); - - boolean useCache = size <= SIZE_OF_CACHED_ICONS; - if (useCache) { - // First approach is to look up the cache - if (CACHE.containsKey(catHashInput)) { - return CACHE.get(catHashInput); - } - - - if (!iconsDir.exists()) { - try { - FileUtils.makeDirs(iconsDir); - } catch (IOException e) { - log.error(e.toString()); - } - } - - // Next approach is to read the image from file - if (iconFile.exists()) { - try { - Image image = ImageUtil.readRawImage(iconFile); - if (CACHE.size() < MAX_CACHE_SIZE) { - CACHE.put(catHashInput, image); - } - return image; - } catch (Exception e) { - log.error("Read image failed", e); - } - } - } - - // Image size might be larger as our cached images, or we did not find it in the - // cache and also not from persisted files. We create the image. This is an expensive operation taking - // about 12 ms on a high-end laptop, and it needs to be done on the UI thread. - long ts = System.currentTimeMillis(); - BucketConfig bucketConfig = getBucketConfig(avatarVersion); - int[] buckets = BucketEncoder.encode(catHashInput, bucketConfig.getBucketSizes()); - String[] paths = BucketEncoder.toPaths(buckets, bucketConfig.getPathTemplates()); - // For retina support we scale by 2 - Image image = ImageUtil.composeImage(paths, 2 * SIZE_OF_CACHED_ICONS); - log.info("Creating user profile icon for {} took {} ms.", userProfileId, System.currentTimeMillis() - ts); - if (useCache && CACHE.size() < MAX_CACHE_SIZE) { - CACHE.put(catHashInput, image); - - // We use the MAX_CACHE_SIZE also as limit for files on disk - try { - ImageUtil.writeRawImage(image, iconFile); - } catch (IOException e) { - log.error("Write image failed", e); - } - } - return image; + return delegate.getImage(pubKeyHash, powSolution, avatarVersion, size); } // Remove the user profile icons which are not contained anymore in the current user profile list public static void pruneOutdatedProfileIcons(Collection userProfiles) { - if (userProfiles.isEmpty()) { - return; - } - File iconsDirectory = getCatHashIconsDirectory().toFile(); - File[] versionDirs = iconsDirectory.listFiles(); - if (versionDirs == null) { - return; - } - Map> iconFilesByVersion = Stream.of(versionDirs) - .filter(File::isDirectory) - .filter(dir -> dir.listFiles() != null) - .collect(Collectors.toMap(File::getName, - dir -> Arrays.asList(Objects.requireNonNull(dir.listFiles())))); - - Map> userProfilesByVersion = userProfiles.stream() - .collect(Collectors.groupingBy(UserProfile::getAvatarVersion)); - - iconFilesByVersion.forEach((versionDir, iconFiles) -> { - try { - int version = Integer.parseInt(versionDir - .replace("v", "")); - Set fromDisk = iconFiles.stream() - .map(File::getName) - .collect(Collectors.toSet()); - Set fromData = Optional.of(userProfilesByVersion.get(version).stream() - .map(userProfile -> userProfile.getId() + ".raw") - .collect(Collectors.toSet())) - .orElse(new HashSet<>()); - Set toRemove = new HashSet<>(fromDisk); - toRemove.removeAll(fromData); - log.info("We remove following user profile icons which are not found in the current user profile list:{}", toRemove); - toRemove.forEach(fileName -> { - File file = Path.of(iconsDirectory.getAbsolutePath(), versionDir, fileName).toFile(); - try { - log.error("Remove {}", file); - FileUtils.deleteFile(file); - } catch (IOException e) { - log.error("Failed to remove file {}", file, e); - } - }); - } catch (Exception e) { - log.error("Unexpected versionDir {}", versionDir, e); - } - }); + delegate.pruneOutdatedProfileIcons(userProfiles); } public static int currentAvatarsVersion() { return BucketConfig.CURRENT_VERSION; } - - private static Path getCatHashIconsDirectory() { - return Path.of(baseDir.toString(), "db", "cache", "cat_hash_icons"); - } - - private static BucketConfig getBucketConfig(int avatarVersion) { - if (avatarVersion == 0) { - return new BucketConfigV0(); - } else { - throw new IllegalArgumentException("Provided avatarVersion not supported. avatarVersion=" + avatarVersion); - } - } } diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/components/cathash/JavaFxCatHashService.java b/apps/desktop/desktop/src/main/java/bisq/desktop/components/cathash/JavaFxCatHashService.java new file mode 100644 index 0000000000..637f69124a --- /dev/null +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/components/cathash/JavaFxCatHashService.java @@ -0,0 +1,47 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.components.cathash; + +import bisq.desktop.common.utils.ImageUtil; +import bisq.user.cathash.CatHashService; +import javafx.scene.image.Image; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; + +public class JavaFxCatHashService extends CatHashService { + public JavaFxCatHashService(Path baseDir) { + super(baseDir); + } + + @Override + protected Image composeImage(String[] paths, double size) { + return ImageUtil.composeImage(paths, size); + } + + @Override + protected void writeRawImage(Image image, File iconFile) throws IOException { + ImageUtil.writeRawImage(image, iconFile); + } + + @Override + protected Image readRawImage(File iconFile) throws IOException { + return ImageUtil.readRawImage(iconFile); + } +} diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/MainController.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/MainController.java index 4284f28b94..96a19abe78 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/MainController.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/MainController.java @@ -32,8 +32,8 @@ import bisq.desktop.main.left.LeftNavController; import bisq.desktop.main.notification.NotificationPanelController; import bisq.desktop.main.top.TopPanelController; -import bisq.updater.UpdaterService; -import bisq.updater.UpdaterUtils; +import bisq.evolution.updater.UpdaterService; +import bisq.evolution.updater.UpdaterUtils; import lombok.Getter; import lombok.extern.slf4j.Slf4j; diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/bonded_roles/BondedRolesListItem.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/bonded_roles/BondedRolesListItem.java index 0ed31b8aa3..0c9ffd9e1d 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/bonded_roles/BondedRolesListItem.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/bonded_roles/BondedRolesListItem.java @@ -22,8 +22,8 @@ import bisq.bonded_roles.bonded_role.BondedRole; import bisq.i18n.Res; import bisq.network.NetworkService; -import bisq.network.common.Address; -import bisq.network.common.AddressByTransportTypeMap; +import bisq.common.network.Address; +import bisq.common.network.AddressByTransportTypeMap; import bisq.user.UserService; import bisq.user.profile.UserProfile; import bisq.user.profile.UserProfileService; diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/bonded_roles/nodes/tabs/registration/NodeRegistrationController.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/bonded_roles/nodes/tabs/registration/NodeRegistrationController.java index 7c33ac0d05..2519af8e87 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/bonded_roles/nodes/tabs/registration/NodeRegistrationController.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/bonded_roles/nodes/tabs/registration/NodeRegistrationController.java @@ -28,9 +28,9 @@ import bisq.desktop.main.content.network.bonded_roles.tabs.registration.BondedRolesRegistrationController; import bisq.desktop.main.content.network.bonded_roles.tabs.registration.BondedRolesRegistrationModel; import bisq.desktop.main.content.network.bonded_roles.tabs.registration.BondedRolesRegistrationView; -import bisq.network.common.Address; -import bisq.network.common.AddressByTransportTypeMap; -import bisq.network.common.TransportType; +import bisq.common.network.Address; +import bisq.common.network.AddressByTransportTypeMap; +import bisq.common.network.TransportType; import bisq.user.identity.UserIdentity; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/bonded_roles/tabs/registration/BondedRolesRegistrationModel.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/bonded_roles/tabs/registration/BondedRolesRegistrationModel.java index 7749808d71..d67feaebd8 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/bonded_roles/tabs/registration/BondedRolesRegistrationModel.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/bonded_roles/tabs/registration/BondedRolesRegistrationModel.java @@ -19,7 +19,7 @@ import bisq.bonded_roles.BondedRoleType; import bisq.desktop.common.view.Model; -import bisq.network.common.AddressByTransportTypeMap; +import bisq.common.network.AddressByTransportTypeMap; import bisq.user.identity.UserIdentity; import javafx.beans.property.*; import lombok.Getter; diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/my_node/MyNetworkNodeController.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/my_node/MyNetworkNodeController.java index c481caf5f2..5030acb01b 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/my_node/MyNetworkNodeController.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/my_node/MyNetworkNodeController.java @@ -21,7 +21,7 @@ import bisq.desktop.common.view.Controller; import bisq.desktop.main.content.network.my_node.transport.TransportController; import bisq.network.NetworkService; -import bisq.network.common.TransportType; +import bisq.common.network.TransportType; import javafx.scene.Node; import lombok.Getter; import lombok.extern.slf4j.Slf4j; diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/my_node/MyNetworkNodeModel.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/my_node/MyNetworkNodeModel.java index fa462338eb..186b080823 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/my_node/MyNetworkNodeModel.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/my_node/MyNetworkNodeModel.java @@ -18,7 +18,7 @@ package bisq.desktop.main.content.network.my_node; import bisq.desktop.common.view.Model; -import bisq.network.common.TransportType; +import bisq.common.network.TransportType; import lombok.Getter; import lombok.extern.slf4j.Slf4j; diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/my_node/transport/ConnectionListItem.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/my_node/transport/ConnectionListItem.java index 2a953bd92b..a0ee31694b 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/my_node/transport/ConnectionListItem.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/my_node/transport/ConnectionListItem.java @@ -24,7 +24,7 @@ import bisq.i18n.Res; import bisq.identity.Identity; import bisq.identity.IdentityService; -import bisq.network.common.Address; +import bisq.common.network.Address; import bisq.network.p2p.message.EnvelopePayloadMessage; import bisq.network.p2p.node.CloseReason; import bisq.network.p2p.node.Connection; diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/my_node/transport/ConnectionsAndNodes.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/my_node/transport/ConnectionsAndNodes.java index 91c92a5ee1..b55bfc9b57 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/my_node/transport/ConnectionsAndNodes.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/my_node/transport/ConnectionsAndNodes.java @@ -26,7 +26,7 @@ import bisq.desktop.components.table.TableList; import bisq.i18n.Res; import bisq.identity.IdentityService; -import bisq.network.common.TransportType; +import bisq.common.network.TransportType; import bisq.network.identity.NetworkId; import bisq.network.p2p.ServiceNode; import bisq.network.p2p.message.EnvelopePayloadMessage; diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/my_node/transport/NodeListItem.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/my_node/transport/NodeListItem.java index 6a54a106d6..d13f0eb7b2 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/my_node/transport/NodeListItem.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/my_node/transport/NodeListItem.java @@ -22,7 +22,7 @@ import bisq.i18n.Res; import bisq.identity.Identity; import bisq.identity.IdentityService; -import bisq.network.common.Address; +import bisq.common.network.Address; import bisq.network.identity.NetworkId; import bisq.network.p2p.message.EnvelopePayloadMessage; import bisq.network.p2p.node.CloseReason; diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/my_node/transport/SystemLoad.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/my_node/transport/SystemLoad.java index a8deeb21d5..d9eaa1563b 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/my_node/transport/SystemLoad.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/my_node/transport/SystemLoad.java @@ -21,7 +21,7 @@ import bisq.desktop.ServiceProvider; import bisq.i18n.Res; import bisq.network.NetworkService; -import bisq.network.common.TransportType; +import bisq.common.network.TransportType; import bisq.network.p2p.ServiceNode; import bisq.network.p2p.node.authorization.token.hash_cash.HashCashTokenService; import bisq.network.p2p.node.network_load.NetworkLoad; diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/my_node/transport/Traffic.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/my_node/transport/Traffic.java index e17fe663ed..4a97fdfda6 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/my_node/transport/Traffic.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/my_node/transport/Traffic.java @@ -20,7 +20,7 @@ import bisq.common.formatter.DataSizeFormatter; import bisq.desktop.ServiceProvider; import bisq.i18n.Res; -import bisq.network.common.TransportType; +import bisq.common.network.TransportType; import bisq.network.p2p.ServiceNode; import bisq.network.p2p.node.network_load.NetworkLoad; import bisq.network.p2p.node.network_load.NetworkLoadService; diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/my_node/transport/TransportController.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/my_node/transport/TransportController.java index 48fd2e7b19..4baef27cc1 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/my_node/transport/TransportController.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/my_node/transport/TransportController.java @@ -20,8 +20,8 @@ import bisq.desktop.ServiceProvider; import bisq.desktop.common.view.Controller; import bisq.i18n.Res; -import bisq.network.common.Address; -import bisq.network.common.TransportType; +import bisq.common.network.Address; +import bisq.common.network.TransportType; import bisq.network.p2p.ServiceNode; import bisq.network.p2p.node.Node; import lombok.Getter; diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/my_node/transport/TransportModel.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/my_node/transport/TransportModel.java index e92da11e3e..7acd48becb 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/my_node/transport/TransportModel.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/network/my_node/transport/TransportModel.java @@ -18,7 +18,7 @@ package bisq.desktop.main.content.network.my_node.transport; import bisq.desktop.common.view.Model; -import bisq.network.common.TransportType; +import bisq.common.network.TransportType; import bisq.network.p2p.node.Node; import lombok.Getter; import lombok.Setter; diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/settings/notifications/NotificationsSettingsController.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/settings/notifications/NotificationsSettingsController.java index 9832042c80..8f9ac4e62c 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/settings/notifications/NotificationsSettingsController.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/settings/notifications/NotificationsSettingsController.java @@ -26,7 +26,7 @@ import bisq.settings.ChatNotificationType; import bisq.settings.CookieKey; import bisq.settings.SettingsService; -import bisq.updater.UpdaterService; +import bisq.evolution.updater.UpdaterService; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.fxmisc.easybind.EasyBind; diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/left/LeftNavController.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/left/LeftNavController.java index 002c5a56dc..4b614d86d1 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/left/LeftNavController.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/left/LeftNavController.java @@ -32,7 +32,7 @@ import bisq.desktop.common.view.Navigation; import bisq.settings.CookieKey; import bisq.settings.SettingsService; -import bisq.updater.UpdaterService; +import bisq.evolution.updater.UpdaterService; import bisq.user.identity.UserIdentity; import bisq.user.identity.UserIdentityService; import lombok.Getter; diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/left/NetworkInfo.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/left/NetworkInfo.java index 60f65df311..d1397f10f1 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/left/NetworkInfo.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/left/NetworkInfo.java @@ -12,7 +12,7 @@ import bisq.desktop.components.controls.BisqTooltip; import bisq.i18n.Res; import bisq.network.NetworkService; -import bisq.network.common.TransportType; +import bisq.common.network.TransportType; import bisq.network.identity.NetworkId; import bisq.network.p2p.message.EnvelopePayloadMessage; import bisq.network.p2p.node.CloseReason; diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/top/MarketPriceComponent.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/top/MarketPriceComponent.java index fc53e0c607..8ffbf8cf75 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/top/MarketPriceComponent.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/top/MarketPriceComponent.java @@ -33,7 +33,7 @@ import bisq.desktop.components.controls.ComboBoxWithSearch; import bisq.desktop.components.controls.ProgressBarWithLabel; import bisq.i18n.Res; -import bisq.network.common.Address; +import bisq.common.network.Address; import bisq.network.identity.NetworkId; import bisq.presentation.formatters.DateFormatter; import bisq.presentation.formatters.PriceFormatter; diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/overlay/update/UpdaterController.java b/apps/desktop/desktop/src/main/java/bisq/desktop/overlay/update/UpdaterController.java index 16dc55c441..8b50f6519d 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/overlay/update/UpdaterController.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/overlay/update/UpdaterController.java @@ -29,16 +29,16 @@ import bisq.i18n.Res; import bisq.settings.CookieKey; import bisq.settings.SettingsService; -import bisq.updater.DownloadItem; -import bisq.updater.UpdaterService; -import bisq.updater.UpdaterUtils; +import bisq.evolution.updater.DownloadItem; +import bisq.evolution.updater.UpdaterService; +import bisq.evolution.updater.UpdaterUtils; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import java.io.IOException; import java.util.concurrent.CancellationException; -import static bisq.updater.UpdaterUtils.RELEASES_URL; +import static bisq.evolution.updater.UpdaterUtils.RELEASES_URL; @Slf4j public class UpdaterController implements Controller { diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/overlay/update/UpdaterView.java b/apps/desktop/desktop/src/main/java/bisq/desktop/overlay/update/UpdaterView.java index 1139ea3031..fb9203292c 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/overlay/update/UpdaterView.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/overlay/update/UpdaterView.java @@ -25,8 +25,8 @@ import bisq.desktop.overlay.OverlayModel; import bisq.i18n.Res; import bisq.presentation.formatters.PercentageFormatter; -import bisq.updater.DownloadItem; -import bisq.updater.UpdaterUtils; +import bisq.evolution.updater.DownloadItem; +import bisq.evolution.updater.UpdaterUtils; import javafx.beans.property.BooleanProperty; import javafx.beans.property.DoubleProperty; import javafx.beans.property.SimpleBooleanProperty; diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/splash/SplashController.java b/apps/desktop/desktop/src/main/java/bisq/desktop/splash/SplashController.java index 9dbab828ff..1357f18b27 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/splash/SplashController.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/splash/SplashController.java @@ -21,13 +21,13 @@ import bisq.common.observable.Observable; import bisq.common.observable.Pin; import bisq.desktop.ServiceProvider; -import bisq.desktop.State; +import bisq.application.State; import bisq.desktop.common.threading.UIThread; import bisq.desktop.common.view.Controller; import bisq.desktop.splash.temp.BootstrapStateDisplay; import bisq.i18n.Res; import bisq.network.NetworkService; -import bisq.network.common.TransportType; +import bisq.common.network.TransportType; import lombok.Getter; import lombok.extern.slf4j.Slf4j; diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/splash/temp/BootstrapStateDisplay.java b/apps/desktop/desktop/src/main/java/bisq/desktop/splash/temp/BootstrapStateDisplay.java index 6d3e05f886..3312b8fd7e 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/splash/temp/BootstrapStateDisplay.java +++ b/apps/desktop/desktop/src/main/java/bisq/desktop/splash/temp/BootstrapStateDisplay.java @@ -24,7 +24,7 @@ import bisq.i18n.Res; import bisq.network.NetworkService; import bisq.network.p2p.node.transport.BootstrapInfo; -import bisq.network.common.TransportType; +import bisq.common.network.TransportType; import bisq.presentation.formatters.PercentageFormatter; import bisq.settings.CookieKey; import bisq.settings.SettingsService; diff --git a/apps/oracle-node-app/build.gradle.kts b/apps/oracle-node-app/build.gradle.kts index 2fb210f785..32d5c14798 100644 --- a/apps/oracle-node-app/build.gradle.kts +++ b/apps/oracle-node-app/build.gradle.kts @@ -16,13 +16,14 @@ application { dependencies { implementation("bisq:persistence") + implementation("bisq:java-se") implementation("bisq:security") implementation("bisq:identity") implementation("bisq:bonded-roles") implementation("bisq:user") implementation("bisq:application") + implementation("bisq:evolution") - implementation("network:network-common") implementation("network:network") implementation("network:network-identity") diff --git a/apps/oracle-node-app/src/main/java/bisq/oracle_node/OracleNodeApp.java b/apps/oracle-node-app/src/main/java/bisq/oracle_node/OracleNodeApp.java index eb4641973b..be292b1bbb 100644 --- a/apps/oracle-node-app/src/main/java/bisq/oracle_node/OracleNodeApp.java +++ b/apps/oracle-node-app/src/main/java/bisq/oracle_node/OracleNodeApp.java @@ -20,7 +20,7 @@ import bisq.application.Executable; import bisq.common.file.FileUtils; import bisq.common.threading.ThreadName; -import bisq.network.common.AddressByTransportTypeMap; +import bisq.common.network.AddressByTransportTypeMap; import com.google.gson.GsonBuilder; import lombok.extern.slf4j.Slf4j; diff --git a/apps/oracle-node-app/src/main/java/bisq/oracle_node/OracleNodeApplicationService.java b/apps/oracle-node-app/src/main/java/bisq/oracle_node/OracleNodeApplicationService.java index 9e0a102e6a..2ac2b2ef39 100644 --- a/apps/oracle-node-app/src/main/java/bisq/oracle_node/OracleNodeApplicationService.java +++ b/apps/oracle-node-app/src/main/java/bisq/oracle_node/OracleNodeApplicationService.java @@ -17,10 +17,10 @@ package bisq.oracle_node; -import bisq.application.ApplicationService; import bisq.bonded_roles.BondedRolesService; import bisq.bonded_roles.market_price.MarketPriceRequestService; import bisq.identity.IdentityService; +import bisq.java_se.application.JavaSeApplicationService; import bisq.network.NetworkService; import bisq.network.NetworkServiceConfig; import bisq.security.SecurityService; @@ -34,7 +34,7 @@ @Slf4j @Getter -public class OracleNodeApplicationService extends ApplicationService { +public class OracleNodeApplicationService extends JavaSeApplicationService { private final IdentityService identityService; private final SecurityService securityService; private final NetworkService networkService; @@ -52,7 +52,8 @@ public OracleNodeApplicationService(String[] args) { persistenceService, securityService.getKeyBundleService(), securityService.getHashCashProofOfWorkService(), - securityService.getEquihashProofOfWorkService()); + securityService.getEquihashProofOfWorkService(), + memoryReportService); identityService = new IdentityService(persistenceService, securityService.getKeyBundleService(), @@ -75,12 +76,14 @@ public OracleNodeApplicationService(String[] args) { networkService, persistenceService, bondedRolesService.getAuthorizedBondedRolesService(), - marketPriceRequestService); + marketPriceRequestService, + memoryReportService); } @Override public CompletableFuture initialize() { - return super.initialize() + return migrationService.initialize() + .thenCompose(result -> memoryReportService.initialize()) .thenCompose(result -> securityService.initialize()) .thenCompose(result -> networkService.initialize()) .thenCompose(result -> identityService.initialize()) @@ -106,6 +109,8 @@ public CompletableFuture shutdown() { .thenCompose(result -> identityService.shutdown()) .thenCompose(result -> networkService.shutdown()) .thenCompose(result -> securityService.shutdown()) + .thenCompose(result -> memoryReportService.shutdown()) + .thenCompose(result -> migrationService.shutdown()) .orTimeout(2, TimeUnit.MINUTES) .handle((result, throwable) -> throwable == null) .join()); diff --git a/apps/oracle-node-app/src/main/java/bisq/oracle_node/OracleNodeService.java b/apps/oracle-node-app/src/main/java/bisq/oracle_node/OracleNodeService.java index 2719a229e7..5c901e05be 100644 --- a/apps/oracle-node-app/src/main/java/bisq/oracle_node/OracleNodeService.java +++ b/apps/oracle-node-app/src/main/java/bisq/oracle_node/OracleNodeService.java @@ -26,6 +26,7 @@ import bisq.common.application.Service; import bisq.common.encoding.Hex; import bisq.common.observable.collection.CollectionObserver; +import bisq.common.platform.MemoryReportService; import bisq.common.timer.Scheduler; import bisq.common.util.StringUtils; import bisq.identity.Identity; @@ -117,7 +118,8 @@ public OracleNodeService(Config config, NetworkService networkService, PersistenceService persistenceService, AuthorizedBondedRolesService authorizedBondedRolesService, - MarketPriceRequestService marketPriceRequestService) { + MarketPriceRequestService marketPriceRequestService, + MemoryReportService memoryReportService) { this.identityService = identityService; this.networkService = networkService; this.authorizedBondedRolesService = authorizedBondedRolesService; @@ -145,6 +147,7 @@ public OracleNodeService(Config config, networkService, persistenceService, authorizedBondedRolesService, + memoryReportService, authorizedPrivateKey, authorizedPublicKey, ignoreSecurityManager, diff --git a/apps/oracle-node-app/src/main/java/bisq/oracle_node/bisq1_bridge/Bisq1BridgeHttpService.java b/apps/oracle-node-app/src/main/java/bisq/oracle_node/bisq1_bridge/Bisq1BridgeHttpService.java index 0e348943a9..ff89a4c79e 100644 --- a/apps/oracle-node-app/src/main/java/bisq/oracle_node/bisq1_bridge/Bisq1BridgeHttpService.java +++ b/apps/oracle-node-app/src/main/java/bisq/oracle_node/bisq1_bridge/Bisq1BridgeHttpService.java @@ -24,7 +24,7 @@ import bisq.common.encoding.Hex; import bisq.common.threading.ExecutorFactory; import bisq.network.NetworkService; -import bisq.network.common.TransportType; +import bisq.common.network.TransportType; import bisq.network.http.BaseHttpClient; import bisq.oracle_node.bisq1_bridge.dto.BondedReputationDto; import bisq.oracle_node.bisq1_bridge.dto.BondedRoleVerificationDto; diff --git a/apps/oracle-node-app/src/main/java/bisq/oracle_node/bisq1_bridge/Bisq1BridgeService.java b/apps/oracle-node-app/src/main/java/bisq/oracle_node/bisq1_bridge/Bisq1BridgeService.java index 9559bc9eac..18b81de220 100644 --- a/apps/oracle-node-app/src/main/java/bisq/oracle_node/bisq1_bridge/Bisq1BridgeService.java +++ b/apps/oracle-node-app/src/main/java/bisq/oracle_node/bisq1_bridge/Bisq1BridgeService.java @@ -26,7 +26,7 @@ import bisq.bonded_roles.security_manager.alert.AuthorizedAlertData; import bisq.common.application.Service; import bisq.common.encoding.Hex; -import bisq.common.platform.MemoryReport; +import bisq.common.platform.MemoryReportService; import bisq.common.threading.ThreadName; import bisq.common.timer.Scheduler; import bisq.common.util.CompletableFutureUtils; @@ -93,6 +93,7 @@ public static Bisq1BridgeService.Config from(com.typesafe.config.Config config) private final NetworkService networkService; private final Bisq1BridgeHttpService httpService; private final AuthorizedBondedRolesService authorizedBondedRolesService; + private final MemoryReportService memoryReportService; private final PrivateKey authorizedPrivateKey; private final PublicKey authorizedPublicKey; private final boolean ignoreSecurityManager; @@ -107,13 +108,12 @@ public static Bisq1BridgeService.Config from(com.typesafe.config.Config config) @Nullable private Scheduler periodicRequestDoaDataScheduler, initialDelayScheduler; - @SuppressWarnings("FieldCanBeLocal") // Pin it so that it does not get GC'ed - private final MemoryReport memoryReport; public Bisq1BridgeService(Config config, NetworkService networkService, PersistenceService persistenceService, AuthorizedBondedRolesService authorizedBondedRolesService, + MemoryReportService memoryReportService, PrivateKey authorizedPrivateKey, PublicKey authorizedPublicKey, boolean ignoreSecurityManager, @@ -124,12 +124,12 @@ public Bisq1BridgeService(Config config, this.authorizedPublicKey = authorizedPublicKey; this.ignoreSecurityManager = ignoreSecurityManager; this.staticPublicKeysProvided = staticPublicKeysProvided; + this.memoryReportService = memoryReportService; Bisq1BridgeHttpService.Config httpServiceConfig = Bisq1BridgeHttpService.Config.from(config.getHttpService()); httpService = new Bisq1BridgeHttpService(httpServiceConfig, networkService); persistence = persistenceService.getOrCreatePersistence(this, DbSubDirectory.PRIVATE, persistableStore); - memoryReport = MemoryReport.getINSTANCE(); } @@ -222,11 +222,11 @@ public void onAuthorizedDataAdded(AuthorizedData authorizedData) { private void initialRepublish() { log.info("Start republishAuthorizedBondedRoles"); republishAuthorizedBondedRoles(); - memoryReport.logReport(); + memoryReportService.logReport(); log.info("Completed republishAuthorizedBondedRoles"); log.info("Start request and publish DaoData"); requestDaoData().join(); // takes about 6 minutes for 500 items - memoryReport.logReport(); + memoryReportService.logReport(); log.info("Completed request and publish DaoData"); periodicRequestDoaDataScheduler = Scheduler.run(this::periodicRepublish) .host(this) @@ -237,7 +237,7 @@ private void initialRepublish() { private void periodicRepublish() { log.info("periodicRequestDoaDataScheduler: Start requestDoaData"); requestDaoData().join(); - memoryReport.logReport(); + memoryReportService.logReport(); log.info("periodicRequestDoaDataScheduler: Completed requestDoaData"); } diff --git a/apps/oracle-node-app/src/main/resources/oracle_node.conf b/apps/oracle-node-app/src/main/resources/oracle_node.conf index 336f28a223..8d8de3ab13 100644 --- a/apps/oracle-node-app/src/main/resources/oracle_node.conf +++ b/apps/oracle-node-app/src/main/resources/oracle_node.conf @@ -189,6 +189,7 @@ application { devModeDelayInMs = 300 sendMessageThrottleTime = 200 receiveMessageThrottleTime = 200 + connectTimeoutMs = 3000 } tor { bootstrapTimeout = 240 diff --git a/apps/rest-api-app/build.gradle.kts b/apps/rest-api-app/build.gradle.kts index e96e050f3b..4b35a07d60 100644 --- a/apps/rest-api-app/build.gradle.kts +++ b/apps/rest-api-app/build.gradle.kts @@ -9,6 +9,7 @@ application { dependencies { implementation("bisq:persistence") + implementation("bisq:java-se") implementation("bisq:i18n") implementation("bisq:security") implementation("bisq:identity") @@ -24,8 +25,9 @@ dependencies { implementation("bisq:presentation") implementation("bisq:bisq-easy") implementation("bisq:application") + implementation("bisq:evolution") + implementation("bisq:os-specific") - implementation("network:network-common") implementation("network:network") implementation("bitcoind:core") implementation("wallets:wallet") diff --git a/apps/rest-api-app/src/main/java/bisq/rest_api/RestApiApplicationService.java b/apps/rest-api-app/src/main/java/bisq/rest_api/RestApiApplicationService.java index 4376b746e8..cf42857939 100644 --- a/apps/rest-api-app/src/main/java/bisq/rest_api/RestApiApplicationService.java +++ b/apps/rest-api-app/src/main/java/bisq/rest_api/RestApiApplicationService.java @@ -18,18 +18,23 @@ package bisq.rest_api; import bisq.account.AccountService; -import bisq.application.ApplicationService; import bisq.bisq_easy.BisqEasyService; import bisq.bonded_roles.BondedRolesService; import bisq.chat.ChatService; import bisq.common.application.Service; import bisq.common.observable.Observable; +import bisq.common.platform.OS; import bisq.common.util.CompletableFutureUtils; import bisq.contract.ContractService; import bisq.identity.IdentityService; +import bisq.java_se.application.JavaSeApplicationService; import bisq.network.NetworkService; import bisq.network.NetworkServiceConfig; import bisq.offer.OfferService; +import bisq.os_specific.notifications.linux.LinuxNotificationService; +import bisq.os_specific.notifications.osx.OsxNotificationService; +import bisq.os_specific.notifications.other.AwtNotificationService; +import bisq.presentation.notifications.OsSpecificNotificationService; import bisq.presentation.notifications.SystemNotificationService; import bisq.security.SecurityService; import bisq.security.keys.KeyBundleService; @@ -37,8 +42,8 @@ import bisq.support.SupportService; import bisq.trade.TradeService; import bisq.user.UserService; -import bisq.wallets.core.WalletService; import bisq.wallets.core.BitcoinWalletSelection; +import bisq.wallets.core.WalletService; import lombok.Getter; import lombok.extern.slf4j.Slf4j; @@ -57,7 +62,7 @@ */ @Getter @Slf4j -public class RestApiApplicationService extends ApplicationService { +public class RestApiApplicationService extends JavaSeApplicationService { public enum State { INITIALIZE_APP, INITIALIZE_NETWORK, @@ -87,6 +92,7 @@ public enum State { public RestApiApplicationService(String[] args) { super("rest_api", args); + securityService = new SecurityService(persistenceService, SecurityService.Config.from(getConfig("security"))); com.typesafe.config.Config bitcoinWalletConfig = getConfig("bitcoinWallet"); BitcoinWalletSelection bitcoinWalletSelection = bitcoinWalletConfig.getEnum(BitcoinWalletSelection.class, "bitcoinWalletSelection"); @@ -109,7 +115,8 @@ public RestApiApplicationService(String[] args) { persistenceService, securityService.getKeyBundleService(), securityService.getHashCashProofOfWorkService(), - securityService.getEquihashProofOfWorkService()); + securityService.getEquihashProofOfWorkService(), + memoryReportService); identityService = new IdentityService(persistenceService, securityService.getKeyBundleService(), @@ -131,7 +138,7 @@ public RestApiApplicationService(String[] args) { settingsService = new SettingsService(persistenceService); - systemNotificationService = new SystemNotificationService(config.getBaseDir(), settingsService); + systemNotificationService = new SystemNotificationService(findSystemNotificationDelegate()); offerService = new OfferService(networkService, identityService, persistenceService); @@ -149,7 +156,6 @@ public RestApiApplicationService(String[] args) { bisqEasyService = new BisqEasyService(persistenceService, securityService, - walletService, networkService, identityService, bondedRolesService, @@ -167,7 +173,8 @@ public RestApiApplicationService(String[] args) { @Override public CompletableFuture initialize() { - return super.initialize() + return migrationService.initialize() + .thenCompose(result -> memoryReportService.initialize()) .thenCompose(result -> securityService.initialize()) .thenCompose(result -> { setState(State.INITIALIZE_NETWORK); @@ -247,6 +254,8 @@ public CompletableFuture shutdown() { .thenCompose(result -> walletService.map(Service::shutdown) .orElse(CompletableFuture.completedFuture(true))) .thenCompose(result -> securityService.shutdown()) + .thenCompose(result -> memoryReportService.shutdown()) + .thenCompose(result -> migrationService.shutdown()) .orTimeout(10, TimeUnit.SECONDS) .handle((result, throwable) -> throwable == null) .join()); @@ -262,5 +271,22 @@ private void setState(State newState) { "New state %s must have a higher ordinal as the current state %s", newState, state.get()); state.set(newState); log.info("New state {}", newState); + } private Optional findSystemNotificationDelegate() { + try { + switch (OS.getOS()) { + case LINUX: + return Optional.of(new LinuxNotificationService(config.getBaseDir(), settingsService)); + case MAC_OS: + return Optional.of(new OsxNotificationService()); + case WINDOWS: + return Optional.of(new AwtNotificationService()); + default: + case ANDROID: + return Optional.empty(); + } + } catch (Exception e) { + log.warn("Could not create SystemNotificationDelegate for {}", OS.getOsName()); + return Optional.empty(); + } } } diff --git a/apps/rest-api-app/src/main/java/bisq/rest_api/endpoints/ReportApi.java b/apps/rest-api-app/src/main/java/bisq/rest_api/endpoints/ReportApi.java index 34846565b1..ce7a20d686 100644 --- a/apps/rest-api-app/src/main/java/bisq/rest_api/endpoints/ReportApi.java +++ b/apps/rest-api-app/src/main/java/bisq/rest_api/endpoints/ReportApi.java @@ -20,7 +20,7 @@ import bisq.common.util.CollectionUtil; import bisq.common.util.CompletableFutureUtils; import bisq.network.NetworkService; -import bisq.network.common.Address; +import bisq.common.network.Address; import bisq.network.p2p.services.reporting.Report; import bisq.rest_api.JaxRsApplication; import bisq.rest_api.RestApiApplicationService; diff --git a/apps/rest-api-app/src/main/resources/rest_api.conf b/apps/rest-api-app/src/main/resources/rest_api.conf index 2b2c19526d..a82263c1c5 100644 --- a/apps/rest-api-app/src/main/resources/rest_api.conf +++ b/apps/rest-api-app/src/main/resources/rest_api.conf @@ -185,6 +185,7 @@ application { devModeDelayInMs = 300 sendMessageThrottleTime = 200 receiveMessageThrottleTime = 200 + connectTimeoutMs = 3000 } tor { bootstrapTimeout = 240 diff --git a/apps/seed-node-app/build.gradle.kts b/apps/seed-node-app/build.gradle.kts index c3b023414e..080a41cb8d 100644 --- a/apps/seed-node-app/build.gradle.kts +++ b/apps/seed-node-app/build.gradle.kts @@ -9,13 +9,14 @@ application { dependencies { implementation("bisq:persistence") + implementation("bisq:java-se") implementation("bisq:security") implementation("bisq:bonded-roles") - implementation("bisq:application") implementation("bisq:identity") implementation("bisq:user") + implementation("bisq:application") + implementation("bisq:evolution") - implementation("network:network-common") implementation("network:network") implementation("network:network-identity") diff --git a/apps/seed-node-app/src/main/java/bisq/seed_node/SeedNodeApp.java b/apps/seed-node-app/src/main/java/bisq/seed_node/SeedNodeApp.java index d7cfb286de..4a21ee436b 100644 --- a/apps/seed-node-app/src/main/java/bisq/seed_node/SeedNodeApp.java +++ b/apps/seed-node-app/src/main/java/bisq/seed_node/SeedNodeApp.java @@ -20,7 +20,7 @@ import bisq.application.Executable; import bisq.common.file.FileUtils; import bisq.common.threading.ThreadName; -import bisq.network.common.AddressByTransportTypeMap; +import bisq.common.network.AddressByTransportTypeMap; import com.google.gson.GsonBuilder; import lombok.extern.slf4j.Slf4j; diff --git a/apps/seed-node-app/src/main/java/bisq/seed_node/SeedNodeApplicationService.java b/apps/seed-node-app/src/main/java/bisq/seed_node/SeedNodeApplicationService.java index ae473a669d..c47ba4eb46 100644 --- a/apps/seed-node-app/src/main/java/bisq/seed_node/SeedNodeApplicationService.java +++ b/apps/seed-node-app/src/main/java/bisq/seed_node/SeedNodeApplicationService.java @@ -17,9 +17,9 @@ package bisq.seed_node; -import bisq.application.ApplicationService; import bisq.bonded_roles.BondedRolesService; import bisq.identity.IdentityService; +import bisq.java_se.application.JavaSeApplicationService; import bisq.network.NetworkService; import bisq.network.NetworkServiceConfig; import bisq.security.SecurityService; @@ -41,7 +41,7 @@ */ @Getter @Slf4j -public class SeedNodeApplicationService extends ApplicationService { +public class SeedNodeApplicationService extends JavaSeApplicationService { protected final NetworkService networkService; protected final IdentityService identityService; protected final SecurityService securityService; @@ -59,7 +59,8 @@ public SeedNodeApplicationService(String[] args) { persistenceService, securityService.getKeyBundleService(), securityService.getHashCashProofOfWorkService(), - securityService.getEquihashProofOfWorkService()); + securityService.getEquihashProofOfWorkService(), + memoryReportService); identityService = new IdentityService(persistenceService, securityService.getKeyBundleService(), @@ -75,7 +76,8 @@ public SeedNodeApplicationService(String[] args) { @Override public CompletableFuture initialize() { - return super.initialize() + return migrationService.initialize() + .thenCompose(result -> memoryReportService.initialize()) .thenCompose(result -> securityService.initialize()) .thenCompose(result -> networkService.initialize()) .thenCompose(result -> identityService.initialize()) @@ -102,6 +104,8 @@ public CompletableFuture shutdown() { .thenCompose(result -> identityService.shutdown()) .thenCompose(result -> networkService.shutdown()) .thenCompose(result -> securityService.shutdown()) + .thenCompose(result -> memoryReportService.shutdown()) + .thenCompose(result -> migrationService.shutdown()) .orTimeout(10, TimeUnit.SECONDS) .handle((result, throwable) -> { if (throwable != null) { diff --git a/apps/seed-node-app/src/main/resources/seed_node.conf b/apps/seed-node-app/src/main/resources/seed_node.conf index a962befd47..e3ce616e6d 100644 --- a/apps/seed-node-app/src/main/resources/seed_node.conf +++ b/apps/seed-node-app/src/main/resources/seed_node.conf @@ -174,6 +174,7 @@ application { devModeDelayInMs = 300 sendMessageThrottleTime = 200 receiveMessageThrottleTime = 200 + connectTimeoutMs = 3000 } tor { bootstrapTimeout = 240 diff --git a/bisq-easy/src/main/java/bisq/bisq_easy/BisqEasyService.java b/bisq-easy/src/main/java/bisq/bisq_easy/BisqEasyService.java index cadf657dae..44c5a1d766 100644 --- a/bisq-easy/src/main/java/bisq/bisq_easy/BisqEasyService.java +++ b/bisq-easy/src/main/java/bisq/bisq_easy/BisqEasyService.java @@ -41,12 +41,10 @@ import bisq.user.UserService; import bisq.user.identity.UserIdentity; import bisq.user.identity.UserIdentityService; -import bisq.wallets.core.WalletService; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import java.util.Collection; -import java.util.Optional; import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; @@ -57,7 +55,6 @@ public class BisqEasyService implements Service { private final PersistenceService persistenceService; private final SecurityService securityService; - private final Optional walletService; private final NetworkService networkService; private final IdentityService identityService; private final BondedRolesService bondedRolesService; @@ -78,7 +75,6 @@ public class BisqEasyService implements Service { public BisqEasyService(PersistenceService persistenceService, SecurityService securityService, - Optional walletService, NetworkService networkService, IdentityService identityService, BondedRolesService bondedRolesService, @@ -93,7 +89,6 @@ public BisqEasyService(PersistenceService persistenceService, TradeService tradeService) { this.persistenceService = persistenceService; this.securityService = securityService; - this.walletService = walletService; this.networkService = networkService; this.identityService = identityService; this.bondedRolesService = bondedRolesService; diff --git a/bonded-roles/build.gradle.kts b/bonded-roles/build.gradle.kts index f7e4c37d79..a4b580b0f0 100644 --- a/bonded-roles/build.gradle.kts +++ b/bonded-roles/build.gradle.kts @@ -10,7 +10,6 @@ dependencies { implementation(project(":identity")) implementation(project(":settings")) - implementation("network:network-common") implementation("network:network-identity") implementation("network:network") diff --git a/bonded-roles/src/main/java/bisq/bonded_roles/bonded_role/AuthorizedBondedRole.java b/bonded-roles/src/main/java/bisq/bonded_roles/bonded_role/AuthorizedBondedRole.java index 86e26a5720..099c51da7c 100644 --- a/bonded-roles/src/main/java/bisq/bonded_roles/bonded_role/AuthorizedBondedRole.java +++ b/bonded-roles/src/main/java/bisq/bonded_roles/bonded_role/AuthorizedBondedRole.java @@ -25,7 +25,7 @@ import bisq.common.proto.ProtoResolver; import bisq.common.proto.UnresolvableProtobufMessageException; import bisq.common.validation.NetworkDataValidation; -import bisq.network.common.AddressByTransportTypeMap; +import bisq.common.network.AddressByTransportTypeMap; import bisq.network.identity.NetworkId; import bisq.network.p2p.services.data.storage.DistributedData; import bisq.network.p2p.services.data.storage.MetaData; diff --git a/bonded-roles/src/main/java/bisq/bonded_roles/explorer/ExplorerService.java b/bonded-roles/src/main/java/bisq/bonded_roles/explorer/ExplorerService.java index c2b6ec73f2..807e6b345c 100644 --- a/bonded-roles/src/main/java/bisq/bonded_roles/explorer/ExplorerService.java +++ b/bonded-roles/src/main/java/bisq/bonded_roles/explorer/ExplorerService.java @@ -25,7 +25,7 @@ import bisq.common.util.CollectionUtil; import bisq.common.util.ExceptionUtil; import bisq.network.NetworkService; -import bisq.network.common.TransportType; +import bisq.common.network.TransportType; import bisq.network.http.BaseHttpClient; import bisq.network.http.utils.HttpException; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/bonded-roles/src/main/java/bisq/bonded_roles/market_price/MarketPriceRequestService.java b/bonded-roles/src/main/java/bisq/bonded_roles/market_price/MarketPriceRequestService.java index e31333db9e..d478e785eb 100644 --- a/bonded-roles/src/main/java/bisq/bonded_roles/market_price/MarketPriceRequestService.java +++ b/bonded-roles/src/main/java/bisq/bonded_roles/market_price/MarketPriceRequestService.java @@ -31,7 +31,7 @@ import bisq.common.util.ExceptionUtil; import bisq.common.util.MathUtils; import bisq.network.NetworkService; -import bisq.network.common.TransportType; +import bisq.common.network.TransportType; import bisq.network.http.BaseHttpClient; import bisq.network.http.utils.HttpException; import com.google.gson.Gson; diff --git a/bonded-roles/src/main/java/bisq/bonded_roles/registration/BondedRoleRegistrationRequest.java b/bonded-roles/src/main/java/bisq/bonded_roles/registration/BondedRoleRegistrationRequest.java index 23da108061..ce826da2a5 100644 --- a/bonded-roles/src/main/java/bisq/bonded_roles/registration/BondedRoleRegistrationRequest.java +++ b/bonded-roles/src/main/java/bisq/bonded_roles/registration/BondedRoleRegistrationRequest.java @@ -21,7 +21,7 @@ import bisq.common.proto.ProtoResolver; import bisq.common.proto.UnresolvableProtobufMessageException; import bisq.common.validation.NetworkDataValidation; -import bisq.network.common.AddressByTransportTypeMap; +import bisq.common.network.AddressByTransportTypeMap; import bisq.network.identity.NetworkId; import bisq.network.p2p.message.ExternalNetworkMessage; import bisq.network.p2p.services.data.storage.MetaData; diff --git a/bonded-roles/src/main/java/bisq/bonded_roles/registration/BondedRoleRegistrationService.java b/bonded-roles/src/main/java/bisq/bonded_roles/registration/BondedRoleRegistrationService.java index 68a3e06032..f400ed6d5e 100644 --- a/bonded-roles/src/main/java/bisq/bonded_roles/registration/BondedRoleRegistrationService.java +++ b/bonded-roles/src/main/java/bisq/bonded_roles/registration/BondedRoleRegistrationService.java @@ -24,7 +24,7 @@ import bisq.common.encoding.Hex; import bisq.common.observable.collection.ObservableSet; import bisq.network.NetworkService; -import bisq.network.common.AddressByTransportTypeMap; +import bisq.common.network.AddressByTransportTypeMap; import bisq.network.identity.NetworkId; import bisq.network.identity.NetworkIdWithKeyPair; import bisq.security.DigestUtil; diff --git a/bonded-roles/src/main/proto/bonded_roles.proto b/bonded-roles/src/main/proto/bonded_roles.proto index 0b74c21d4c..10da66f25d 100644 --- a/bonded-roles/src/main/proto/bonded_roles.proto +++ b/bonded-roles/src/main/proto/bonded_roles.proto @@ -3,7 +3,6 @@ package bonded_roles; option java_package = "bisq.bonded_roles.protobuf"; option java_multiple_files = true; import "common.proto"; -import "network_common.proto"; import "network_identity.proto"; enum BondedRoleType { @@ -34,7 +33,7 @@ message BondedRoleRegistrationRequest { BondedRoleType bondedRoleType = 3; string bondUserName = 4; string signatureBase64 = 5; - optional network.common.AddressByTransportTypeMap addressByTransportTypeMap = 6; + optional common.AddressByTransportTypeMap addressByTransportTypeMap = 6; network.identity.NetworkId networkId = 7; bool isCancellationRequest = 8; } @@ -45,7 +44,7 @@ message AuthorizedBondedRole { BondedRoleType bondedRoleType = 3; string bondUserName = 4; string signatureBase64 = 5; - optional network.common.AddressByTransportTypeMap addressByTransportTypeMap = 6; + optional common.AddressByTransportTypeMap addressByTransportTypeMap = 6; network.identity.NetworkId networkId = 7; optional AuthorizedOracleNode authorizingOracleNode = 8; bool staticPublicKeysProvided = 9; diff --git a/common/src/main/java/bisq/common/facades/FacadeProvider.java b/common/src/main/java/bisq/common/facades/FacadeProvider.java new file mode 100644 index 0000000000..4f9a294d09 --- /dev/null +++ b/common/src/main/java/bisq/common/facades/FacadeProvider.java @@ -0,0 +1,60 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.common.facades; + +import bisq.common.network.DefaultLocalhostFacade; +import bisq.common.network.LocalhostFacade; + +import static com.google.common.base.Preconditions.checkNotNull; + +// The JDKs for Java SE and Android have different API support, thus, we use a +// facade with Android compatible APIs by default and set for Java SE based applicationServices +// the Java SE facade. +// Guava has a different version of its library for Android, thus we apply the facade approach as well. +public class FacadeProvider { + private static JdkFacade jdkFacade; + private static GuavaFacade guavaFacade; + private static LocalhostFacade localhostFacade = new DefaultLocalhostFacade(); + + public static void setJdkFacade(JdkFacade jdkFacade) { + FacadeProvider.jdkFacade = jdkFacade; + } + + public static void setGuavaFacade(GuavaFacade guavaFacade) { + FacadeProvider.guavaFacade = guavaFacade; + } + + public static JdkFacade getJdkFacade() { + checkNotNull(jdkFacade, "jdkFacade is not set."); + return jdkFacade; + } + + public static GuavaFacade getGuavaFacade() { + checkNotNull(guavaFacade, "guavaFacade is not set."); + return guavaFacade; + } + + public static LocalhostFacade getLocalhostFacade() { + return localhostFacade; + } + + public static void setLocalhostFacade(LocalhostFacade localhostFacade) { + FacadeProvider.localhostFacade = localhostFacade; + } + +} diff --git a/common/src/main/java/bisq/common/facades/GuavaFacade.java b/common/src/main/java/bisq/common/facades/GuavaFacade.java new file mode 100644 index 0000000000..55f4457125 --- /dev/null +++ b/common/src/main/java/bisq/common/facades/GuavaFacade.java @@ -0,0 +1,30 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.common.facades; + +import com.google.common.primitives.ImmutableIntArray; + +import java.util.stream.IntStream; + +public interface GuavaFacade { + IntStream toIntStream(ImmutableIntArray array); + + IntStream parallel(IntStream value); + + ImmutableIntArray copyOf(IntStream value); +} diff --git a/common/src/main/java/bisq/common/facades/JdkFacade.java b/common/src/main/java/bisq/common/facades/JdkFacade.java new file mode 100644 index 0000000000..470fe26464 --- /dev/null +++ b/common/src/main/java/bisq/common/facades/JdkFacade.java @@ -0,0 +1,32 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.common.facades; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.stream.Stream; + +public interface JdkFacade { + String getMyPid(); + + Stream getProcessCommandLineStream(); + + void redirectError(ProcessBuilder processBuilder); + + void redirectOutput(ProcessBuilder processBuilder); +} diff --git a/common/src/main/java/bisq/common/facades/android/AndroidGuavaFacade.java b/common/src/main/java/bisq/common/facades/android/AndroidGuavaFacade.java new file mode 100644 index 0000000000..8398de9d42 --- /dev/null +++ b/common/src/main/java/bisq/common/facades/android/AndroidGuavaFacade.java @@ -0,0 +1,41 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.common.facades.android; + +import bisq.common.facades.GuavaFacade; +import com.google.common.primitives.ImmutableIntArray; + +import java.util.stream.IntStream; + +public class AndroidGuavaFacade implements GuavaFacade { + @Override + public IntStream toIntStream(ImmutableIntArray value) { + return IntStream.range(0, value.length()).map(value::get); + } + + @Override + public IntStream parallel(IntStream value) { + ImmutableIntArray array = ImmutableIntArray.copyOf(value.toArray()); + return IntStream.range(0, array.length()).map(array::get).parallel(); + } + + @Override + public ImmutableIntArray copyOf(IntStream value) { + return ImmutableIntArray.copyOf(value.toArray()); + } +} diff --git a/common/src/main/java/bisq/common/facades/android/AndroidJdkFacade.java b/common/src/main/java/bisq/common/facades/android/AndroidJdkFacade.java new file mode 100644 index 0000000000..acc68df985 --- /dev/null +++ b/common/src/main/java/bisq/common/facades/android/AndroidJdkFacade.java @@ -0,0 +1,55 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.common.facades.android; + +import bisq.common.facades.JdkFacade; + +import java.io.File; +import java.util.stream.Stream; + +public class AndroidJdkFacade implements JdkFacade { + private final String myPid; + + public AndroidJdkFacade(int myPid) { + this.myPid = String.valueOf(myPid); + } + + @Override + public String getMyPid() { + return myPid; + } + + @Override + public Stream getProcessCommandLineStream() { + // TODO + throw new UnsupportedOperationException("Not supported yet."); + // return ProcessHandle.allProcesses().map(processHandle -> processHandle.info().commandLine().orElse("")); + } + + @Override + public void redirectError(ProcessBuilder processBuilder) { + // ProcessBuilder.Redirect.DISCARD not supported on Android + processBuilder.redirectError(new File("/dev/null")); + } + + @Override + public void redirectOutput(ProcessBuilder processBuilder) { + // ProcessBuilder.Redirect.DISCARD not supported on Android + processBuilder.redirectError(new File("/dev/null")); + } +} diff --git a/network/network-common/src/main/java/bisq/network/common/Address.java b/common/src/main/java/bisq/common/network/Address.java similarity index 88% rename from network/network-common/src/main/java/bisq/network/common/Address.java rename to common/src/main/java/bisq/common/network/Address.java index 0a2ae04393..3c3d9f0663 100644 --- a/network/network-common/src/main/java/bisq/network/common/Address.java +++ b/common/src/main/java/bisq/common/network/Address.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.network.common; +package bisq.common.network; import bisq.common.proto.NetworkProto; import bisq.common.util.StringUtils; @@ -23,18 +23,15 @@ import com.google.common.net.InetAddresses; import lombok.EqualsAndHashCode; import lombok.Getter; +import lombok.extern.slf4j.Slf4j; import java.util.StringTokenizer; import static com.google.common.base.Preconditions.checkArgument; - +@Slf4j @EqualsAndHashCode @Getter public final class Address implements NetworkProto, Comparable
{ - public static Address localHost(int port) { - return new Address("127.0.0.1", port); - } - public static Address fromFullAddress(String fullAddress) { StringTokenizer st = new StringTokenizer(fullAddress, ":"); String host = maybeConvertLocalHost(st.nextToken()); @@ -71,18 +68,18 @@ public void verify() { } @Override - public bisq.network.common.protobuf.Address toProto(boolean serializeForHash) { + public bisq.common.protobuf.Address toProto(boolean serializeForHash) { return resolveProto(serializeForHash); } @Override - public bisq.network.common.protobuf.Address.Builder getBuilder(boolean serializeForHash) { - return bisq.network.common.protobuf.Address.newBuilder() + public bisq.common.protobuf.Address.Builder getBuilder(boolean serializeForHash) { + return bisq.common.protobuf.Address.newBuilder() .setHost(host) .setPort(port); } - public static Address fromProto(bisq.network.common.protobuf.Address proto) { + public static Address fromProto(bisq.common.protobuf.Address proto) { return new Address(proto.getHost(), proto.getPort()); } @@ -99,6 +96,10 @@ public boolean isI2pAddress() { return !isClearNetAddress() && !isTorAddress(); } + public boolean isLocalhost() { + return host.equals("127.0.0.1"); + } + public TransportType getTransportType() { if (isClearNetAddress()) { return TransportType.CLEAR; @@ -117,7 +118,7 @@ public String getFullAddress() { @Override public String toString() { - if (host.equals("127.0.0.1")) { + if (isLocalhost()) { return "[" + port + "]"; } else { return StringUtils.truncate(host, 1000) + ":" + port; diff --git a/network/network-common/src/main/java/bisq/network/common/AddressByTransportTypeMap.java b/common/src/main/java/bisq/common/network/AddressByTransportTypeMap.java similarity index 89% rename from network/network-common/src/main/java/bisq/network/common/AddressByTransportTypeMap.java rename to common/src/main/java/bisq/common/network/AddressByTransportTypeMap.java index 335c21c9c3..be8ec80d77 100644 --- a/network/network-common/src/main/java/bisq/network/common/AddressByTransportTypeMap.java +++ b/common/src/main/java/bisq/common/network/AddressByTransportTypeMap.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.network.common; +package bisq.common.network; import bisq.common.proto.NetworkProto; import lombok.EqualsAndHashCode; @@ -63,19 +63,19 @@ public void verify() { } @Override - public bisq.network.common.protobuf.AddressByTransportTypeMap toProto(boolean serializeForHash) { + public bisq.common.protobuf.AddressByTransportTypeMap toProto(boolean serializeForHash) { return resolveProto(serializeForHash); } @Override - public bisq.network.common.protobuf.AddressByTransportTypeMap.Builder getBuilder(boolean serializeForHash) { - return bisq.network.common.protobuf.AddressByTransportTypeMap.newBuilder() + public bisq.common.protobuf.AddressByTransportTypeMap.Builder getBuilder(boolean serializeForHash) { + return bisq.common.protobuf.AddressByTransportTypeMap.newBuilder() .putAllAddressByTransportType(map.entrySet().stream() .collect(Collectors.toMap(e -> e.getKey().name(), e -> e.getValue().toProto(serializeForHash)))); } - public static AddressByTransportTypeMap fromProto(bisq.network.common.protobuf.AddressByTransportTypeMap proto) { + public static AddressByTransportTypeMap fromProto(bisq.common.protobuf.AddressByTransportTypeMap proto) { Map map = proto.getAddressByTransportTypeMap().entrySet().stream() .collect(Collectors.toMap(e -> Enum.valueOf(TransportType.class, e.getKey()), e -> Address.fromProto(e.getValue()))); diff --git a/network/network-common/src/main/java/bisq/network/common/AddressOwnershipProof.java b/common/src/main/java/bisq/common/network/AddressOwnershipProof.java similarity index 97% rename from network/network-common/src/main/java/bisq/network/common/AddressOwnershipProof.java rename to common/src/main/java/bisq/common/network/AddressOwnershipProof.java index aed320e784..14ba1bd350 100644 --- a/network/network-common/src/main/java/bisq/network/common/AddressOwnershipProof.java +++ b/common/src/main/java/bisq/common/network/AddressOwnershipProof.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.network.common; +package bisq.common.network; import lombok.Getter; diff --git a/network/network-common/src/main/java/bisq/network/common/AddressOwnershipProofGenerator.java b/common/src/main/java/bisq/common/network/AddressOwnershipProofGenerator.java similarity index 96% rename from network/network-common/src/main/java/bisq/network/common/AddressOwnershipProofGenerator.java rename to common/src/main/java/bisq/common/network/AddressOwnershipProofGenerator.java index 05ff07a73c..8640a4868b 100644 --- a/network/network-common/src/main/java/bisq/network/common/AddressOwnershipProofGenerator.java +++ b/common/src/main/java/bisq/common/network/AddressOwnershipProofGenerator.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.network.common; +package bisq.common.network; public interface AddressOwnershipProofGenerator { AddressOwnershipProof generate(Address myAddress, Address peerAddress); diff --git a/common/src/main/java/bisq/common/network/AndroidEmulatorLocalhostFacade.java b/common/src/main/java/bisq/common/network/AndroidEmulatorLocalhostFacade.java new file mode 100644 index 0000000000..0933ca26f3 --- /dev/null +++ b/common/src/main/java/bisq/common/network/AndroidEmulatorLocalhostFacade.java @@ -0,0 +1,39 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.common.network; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class AndroidEmulatorLocalhostFacade implements LocalhostFacade { + public Address toMyLocalhost(int port) { + log.info("The android app is running in the emulator. We convert our localhost " + + "address to `10.0.2.15`"); + return new Address("10.0.2.15", port); + } + + public Address toPeersLocalhost(Address address) { + if (address.isLocalhost()) { + log.info("The android app is running in the emulator. We convert the target localhost " + + "address `127.0.0.1` to `10.0.2.2`"); + return new Address("10.0.2.2", address.getPort()); + } else { + return address; + } + } +} diff --git a/common/src/main/java/bisq/common/network/DefaultLocalhostFacade.java b/common/src/main/java/bisq/common/network/DefaultLocalhostFacade.java new file mode 100644 index 0000000000..1b2aabe1f3 --- /dev/null +++ b/common/src/main/java/bisq/common/network/DefaultLocalhostFacade.java @@ -0,0 +1,31 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.common.network; + +import com.google.common.annotations.VisibleForTesting; + +public class DefaultLocalhostFacade implements LocalhostFacade { + @VisibleForTesting + public static Address toLocalHostAddress(int port) { + return new Address("127.0.0.1", port); + } + + public Address toMyLocalhost(int port) { + return toLocalHostAddress(port); + } +} diff --git a/network/network-common/src/main/java/bisq/network/common/DefaultPeerSocket.java b/common/src/main/java/bisq/common/network/DefaultPeerSocket.java similarity index 97% rename from network/network-common/src/main/java/bisq/network/common/DefaultPeerSocket.java rename to common/src/main/java/bisq/common/network/DefaultPeerSocket.java index d8eb9047bf..ea0b56eb33 100644 --- a/network/network-common/src/main/java/bisq/network/common/DefaultPeerSocket.java +++ b/common/src/main/java/bisq/common/network/DefaultPeerSocket.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.network.common; +package bisq.common.network; import lombok.Getter; diff --git a/common/src/main/java/bisq/common/network/LocalhostFacade.java b/common/src/main/java/bisq/common/network/LocalhostFacade.java new file mode 100644 index 0000000000..2ed71d01ef --- /dev/null +++ b/common/src/main/java/bisq/common/network/LocalhostFacade.java @@ -0,0 +1,30 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.common.network; + +/** + * For Android running in emulator we need to convert the localhost addresses to the IP addresses used by the emulator. + * To support that we use a facade which by default use the loop-back address 127.0.0.1. + */ +public interface LocalhostFacade { + Address toMyLocalhost(int port); + + default Address toPeersLocalhost(Address address) { + return address; + } +} diff --git a/network/network-common/src/main/java/bisq/network/common/PeerSocket.java b/common/src/main/java/bisq/common/network/PeerSocket.java similarity index 96% rename from network/network-common/src/main/java/bisq/network/common/PeerSocket.java rename to common/src/main/java/bisq/common/network/PeerSocket.java index 795ef35893..8ac78183ae 100644 --- a/network/network-common/src/main/java/bisq/network/common/PeerSocket.java +++ b/common/src/main/java/bisq/common/network/PeerSocket.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.network.common; +package bisq.common.network; import java.io.Closeable; import java.io.InputStream; diff --git a/network/network-common/src/main/java/bisq/network/common/TransportConfig.java b/common/src/main/java/bisq/common/network/TransportConfig.java similarity index 97% rename from network/network-common/src/main/java/bisq/network/common/TransportConfig.java rename to common/src/main/java/bisq/common/network/TransportConfig.java index 76d158ffdc..20ea5953b5 100644 --- a/network/network-common/src/main/java/bisq/network/common/TransportConfig.java +++ b/common/src/main/java/bisq/common/network/TransportConfig.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.network.common; +package bisq.common.network; import java.nio.file.Path; diff --git a/network/network-common/src/main/java/bisq/network/common/TransportType.java b/common/src/main/java/bisq/common/network/TransportType.java similarity index 97% rename from network/network-common/src/main/java/bisq/network/common/TransportType.java rename to common/src/main/java/bisq/common/network/TransportType.java index 6af87bfeab..08518e1316 100644 --- a/network/network-common/src/main/java/bisq/network/common/TransportType.java +++ b/common/src/main/java/bisq/common/network/TransportType.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.network.common; +package bisq.common.network; /** * We do not use a protobuf enum for Type as it is used as key in a protobuf map and that does not support enums. diff --git a/common/src/main/java/bisq/common/platform/MemoryReportService.java b/common/src/main/java/bisq/common/platform/MemoryReportService.java new file mode 100644 index 0000000000..7319a38c74 --- /dev/null +++ b/common/src/main/java/bisq/common/platform/MemoryReportService.java @@ -0,0 +1,33 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.common.platform; + +import bisq.common.application.Service; + +public interface MemoryReportService extends Service { + void logReport(); + + long getUsedMemoryInBytes(); + + long getUsedMemoryInMB(); + + long getFreeMemoryInMB(); + + long getTotalMemoryInMB(); + +} diff --git a/common/src/main/java/bisq/common/platform/OS.java b/common/src/main/java/bisq/common/platform/OS.java index 03e03d3265..ec1c6e5f57 100644 --- a/common/src/main/java/bisq/common/platform/OS.java +++ b/common/src/main/java/bisq/common/platform/OS.java @@ -24,7 +24,8 @@ public enum OS { LINUX("linux"), MAC_OS("macos"), - WINDOWS("win"); + WINDOWS("win"), + ANDROID("android"); @Getter private final String canonicalName; @@ -41,6 +42,8 @@ public static OS getOS() { return OS.MAC_OS; } else if (isWindows(osName)) { return OS.WINDOWS; + } else if (isAndroid()) { + return OS.ANDROID; } throw new IllegalStateException("Running on unsupported OS: " + osName); } @@ -50,7 +53,7 @@ public static boolean isLinux() { } public static boolean isLinux(String osName) { - return osName.contains("linux"); + return osName.contains("linux") && !isAndroid(); } public static boolean isMacOs() { @@ -69,6 +72,22 @@ public static boolean isWindows(String osName) { return osName.contains("win"); } + public static boolean isAndroid(String osName) { + return isLinux(osName) && isAndroid(); + } + + public static boolean isAndroid() { + // Alternatively we could use `java.vendor` but it seems it is less reliable. + // String property = System.getProperty("java.vendor"); + // return "The Android Project".equals(property); + try { + Class.forName("android.os.Build"); + return true; + } catch (ClassNotFoundException e) { + return false; + } + } + public static String getOsName() { return System.getProperty("os.name").toLowerCase(Locale.US); } @@ -76,4 +95,8 @@ public static String getOsName() { public static String getOsVersion() { return System.getProperty("os.version"); } + + public static String getJavaVendor() { + return System.getProperty("java.vendor"); + } } diff --git a/common/src/main/java/bisq/common/platform/Platform.java b/common/src/main/java/bisq/common/platform/Platform.java index e5b21c8dc4..a24acdbb62 100644 --- a/common/src/main/java/bisq/common/platform/Platform.java +++ b/common/src/main/java/bisq/common/platform/Platform.java @@ -27,7 +27,10 @@ public enum Platform { MACOS_ARM_64("macos_arm64"), WIN_X86_64("win_x86_64"), - WIN_ARM_64("win_arm64"); + WIN_ARM_64("win_arm64"), + + ANDROID_X86_64("android_x86_64"), + ANDROID_ARM_64("android_arm64"); @Getter private final String platformName; @@ -52,6 +55,10 @@ public static Platform getPlatform() { case X86_64 -> WIN_X86_64; case ARM_64 -> WIN_ARM_64; }; + case ANDROID -> switch (architecture) { + case X86_64 -> ANDROID_X86_64; + case ARM_64 -> ANDROID_ARM_64; + }; }; } diff --git a/common/src/main/java/bisq/common/platform/PlatformUtils.java b/common/src/main/java/bisq/common/platform/PlatformUtils.java index da559861c2..f324292b4a 100644 --- a/common/src/main/java/bisq/common/platform/PlatformUtils.java +++ b/common/src/main/java/bisq/common/platform/PlatformUtils.java @@ -41,6 +41,11 @@ public static Path getUserDataDir() { return Paths.get(System.getProperty("user.home"), "Library", "Application Support"); } + if (OS.isAndroid()) { + throw new RuntimeException("getUserDataDir is not supported for Android platform. " + + "Provide the user data dir from the Android activity instead."); + } + // *nix return Paths.get(System.getProperty("user.home"), ".local", "share"); } diff --git a/common/src/main/java/bisq/common/platform/Version.java b/common/src/main/java/bisq/common/platform/Version.java index 0878f331a2..84b3c39b68 100644 --- a/common/src/main/java/bisq/common/platform/Version.java +++ b/common/src/main/java/bisq/common/platform/Version.java @@ -55,6 +55,10 @@ public boolean below(Version other) { return compareTo(other) < 0; } + public boolean belowOrEqual(String other) { + return belowOrEqual(new Version(other)); + } + public boolean belowOrEqual(Version other) { return compareTo(other) <= 0; } @@ -67,6 +71,10 @@ public boolean above(Version other) { return compareTo(other) > 0; } + public boolean aboveOrEqual(String other) { + return aboveOrEqual(new Version(other)); + } + public boolean aboveOrEqual(Version other) { return compareTo(other) >= 0; } diff --git a/common/src/main/java/bisq/common/util/CompletableFutureUtils.java b/common/src/main/java/bisq/common/util/CompletableFutureUtils.java index b7895100f0..1c72feae0a 100644 --- a/common/src/main/java/bisq/common/util/CompletableFutureUtils.java +++ b/common/src/main/java/bisq/common/util/CompletableFutureUtils.java @@ -20,7 +20,6 @@ import java.util.Collection; import java.util.List; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; import java.util.stream.Stream; diff --git a/common/src/main/java/bisq/common/util/StringUtils.java b/common/src/main/java/bisq/common/util/StringUtils.java index 76c898e542..ce01ab9325 100644 --- a/common/src/main/java/bisq/common/util/StringUtils.java +++ b/common/src/main/java/bisq/common/util/StringUtils.java @@ -18,6 +18,7 @@ package bisq.common.util; import bisq.common.data.Pair; +import bisq.common.platform.OS; import bisq.common.platform.PlatformUtils; import com.google.common.base.CaseFormat; import lombok.extern.slf4j.Slf4j; @@ -241,6 +242,10 @@ public static String formatTime(long time) { } public static String maskHomeDirectory(String string) { + // TODO: check out if we can reliably mask it on Android + if (OS.isAndroid()) { + return string; + } return string.replace(PlatformUtils.getHomeDirectory(), ""); } } diff --git a/common/src/main/proto/common.proto b/common/src/main/proto/common.proto index 85d49d96eb..82e21821c9 100644 --- a/common/src/main/proto/common.proto +++ b/common/src/main/proto/common.proto @@ -91,4 +91,13 @@ message ByteArrayMapEntry { message StringLongPair { string key = 1; sint64 value = 2; +} + +message Address { + string host = 1; + sint32 port = 2; +} + +message AddressByTransportTypeMap { + map addressByTransportType = 1; } \ No newline at end of file diff --git a/evolution/build.gradle.kts b/evolution/build.gradle.kts new file mode 100644 index 0000000000..806ef7976b --- /dev/null +++ b/evolution/build.gradle.kts @@ -0,0 +1,17 @@ +plugins { + id("bisq.java-library") +} + +dependencies { + implementation(project(":common")) + implementation(project(":security")) + implementation(project(":persistence")) + implementation(project(":settings")) + implementation(project(":bonded-roles")) + implementation(project(":application")) + + implementation("network:network") + + implementation(libs.typesafe.config) + implementation(libs.bouncycastle.pg) +} diff --git a/application/src/main/java/bisq/application/migration/MigrationService.java b/evolution/src/main/java/bisq/evolution/migration/MigrationService.java similarity index 80% rename from application/src/main/java/bisq/application/migration/MigrationService.java rename to evolution/src/main/java/bisq/evolution/migration/MigrationService.java index 4f39f0e3c9..d5d2e691a8 100644 --- a/application/src/main/java/bisq/application/migration/MigrationService.java +++ b/evolution/src/main/java/bisq/evolution/migration/MigrationService.java @@ -1,6 +1,7 @@ -package bisq.application.migration; +package bisq.evolution.migration; import bisq.common.application.ApplicationVersion; +import bisq.common.application.Service; import bisq.common.platform.Version; import java.io.File; @@ -9,7 +10,7 @@ import java.nio.file.Path; import java.util.concurrent.CompletableFuture; -public class MigrationService { +public class MigrationService implements Service { static final Version VERSION_BEFORE_MIGRATION_SERVICE_INTRODUCED = new Version("2.1.1"); private final Path dataDir; private final File dataDirVersionFile; @@ -19,7 +20,8 @@ public MigrationService(Path dataDir) { this.dataDirVersionFile = dataDir.resolve("version").toFile(); } - public CompletableFuture runMigrations() { + @Override + public CompletableFuture initialize() { Version dataDirVersion = getDataDirVersion(); Version appVersion = ApplicationVersion.getVersion(); @@ -31,6 +33,11 @@ public CompletableFuture runMigrations() { return CompletableFuture.completedFuture(true); } + @Override + public CompletableFuture shutdown() { + return CompletableFuture.completedFuture(true); + } + Version getDataDirVersion() { if (!dataDirVersionFile.exists()) { return VERSION_BEFORE_MIGRATION_SERVICE_INTRODUCED; diff --git a/application/src/main/java/bisq/application/migration/Migrator.java b/evolution/src/main/java/bisq/evolution/migration/Migrator.java similarity index 86% rename from application/src/main/java/bisq/application/migration/Migrator.java rename to evolution/src/main/java/bisq/evolution/migration/Migrator.java index b945d941c9..8c1513e5ac 100644 --- a/application/src/main/java/bisq/application/migration/Migrator.java +++ b/evolution/src/main/java/bisq/evolution/migration/Migrator.java @@ -1,10 +1,10 @@ -package bisq.application.migration; +package bisq.evolution.migration; -import bisq.application.migration.migrations.Migration; -import bisq.application.migration.migrations.MigrationFailedException; -import bisq.application.migration.migrations.MigrationsForV2_1_2; import bisq.common.application.ApplicationVersion; import bisq.common.platform.Version; +import bisq.evolution.migration.migrations.Migration; +import bisq.evolution.migration.migrations.MigrationFailedException; +import bisq.evolution.migration.migrations.MigrationsForV2_1_2; import lombok.extern.slf4j.Slf4j; import java.io.IOException; diff --git a/application/src/main/java/bisq/application/migration/migrations/Migration.java b/evolution/src/main/java/bisq/evolution/migration/migrations/Migration.java similarity index 76% rename from application/src/main/java/bisq/application/migration/migrations/Migration.java rename to evolution/src/main/java/bisq/evolution/migration/migrations/Migration.java index bfdf3bbb45..0f5261421f 100644 --- a/application/src/main/java/bisq/application/migration/migrations/Migration.java +++ b/evolution/src/main/java/bisq/evolution/migration/migrations/Migration.java @@ -1,4 +1,4 @@ -package bisq.application.migration.migrations; +package bisq.evolution.migration.migrations; import bisq.common.platform.Version; diff --git a/application/src/main/java/bisq/application/migration/migrations/MigrationFailedException.java b/evolution/src/main/java/bisq/evolution/migration/migrations/MigrationFailedException.java similarity index 76% rename from application/src/main/java/bisq/application/migration/migrations/MigrationFailedException.java rename to evolution/src/main/java/bisq/evolution/migration/migrations/MigrationFailedException.java index 1a3f173f8e..1a7f8c6cd8 100644 --- a/application/src/main/java/bisq/application/migration/migrations/MigrationFailedException.java +++ b/evolution/src/main/java/bisq/evolution/migration/migrations/MigrationFailedException.java @@ -1,4 +1,4 @@ -package bisq.application.migration.migrations; +package bisq.evolution.migration.migrations; public class MigrationFailedException extends RuntimeException { public MigrationFailedException(Throwable cause) { diff --git a/application/src/main/java/bisq/application/migration/migrations/MigrationsForV2_1_2.java b/evolution/src/main/java/bisq/evolution/migration/migrations/MigrationsForV2_1_2.java similarity index 93% rename from application/src/main/java/bisq/application/migration/migrations/MigrationsForV2_1_2.java rename to evolution/src/main/java/bisq/evolution/migration/migrations/MigrationsForV2_1_2.java index 76a94db2a4..f5f09cc485 100644 --- a/application/src/main/java/bisq/application/migration/migrations/MigrationsForV2_1_2.java +++ b/evolution/src/main/java/bisq/evolution/migration/migrations/MigrationsForV2_1_2.java @@ -1,4 +1,4 @@ -package bisq.application.migration.migrations; +package bisq.evolution.migration.migrations; import bisq.common.file.FileUtils; import bisq.common.platform.OS; diff --git a/application/src/main/java/bisq/updater/DownloadItem.java b/evolution/src/main/java/bisq/evolution/updater/DownloadItem.java similarity index 97% rename from application/src/main/java/bisq/updater/DownloadItem.java rename to evolution/src/main/java/bisq/evolution/updater/DownloadItem.java index dbff25d066..c04f759ca7 100644 --- a/application/src/main/java/bisq/updater/DownloadItem.java +++ b/evolution/src/main/java/bisq/evolution/updater/DownloadItem.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.updater; +package bisq.evolution.updater; import bisq.common.observable.Observable; import lombok.EqualsAndHashCode; @@ -28,7 +28,7 @@ import java.util.ArrayList; import java.util.List; -import static bisq.updater.UpdaterUtils.*; +import static bisq.evolution.updater.UpdaterUtils.*; @Slf4j @ToString diff --git a/application/src/main/java/bisq/updater/DownloadedFilesVerification.java b/evolution/src/main/java/bisq/evolution/updater/DownloadedFilesVerification.java similarity index 97% rename from application/src/main/java/bisq/updater/DownloadedFilesVerification.java rename to evolution/src/main/java/bisq/evolution/updater/DownloadedFilesVerification.java index 4358196b82..f39edac97c 100644 --- a/application/src/main/java/bisq/updater/DownloadedFilesVerification.java +++ b/evolution/src/main/java/bisq/evolution/updater/DownloadedFilesVerification.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.updater; +package bisq.evolution.updater; import bisq.common.file.FileUtils; import bisq.security.PgPUtils; @@ -26,7 +26,7 @@ import java.nio.file.Path; import java.util.List; -import static bisq.updater.UpdaterUtils.*; +import static bisq.evolution.updater.UpdaterUtils.*; import static com.google.common.base.Preconditions.checkArgument; @Slf4j diff --git a/application/src/main/java/bisq/updater/UpdaterService.java b/evolution/src/main/java/bisq/evolution/updater/UpdaterService.java similarity index 99% rename from application/src/main/java/bisq/updater/UpdaterService.java rename to evolution/src/main/java/bisq/evolution/updater/UpdaterService.java index f96d355f43..211aeaecad 100644 --- a/application/src/main/java/bisq/updater/UpdaterService.java +++ b/evolution/src/main/java/bisq/evolution/updater/UpdaterService.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.updater; +package bisq.evolution.updater; import bisq.application.ApplicationService; import bisq.bonded_roles.release.ReleaseNotification; @@ -46,7 +46,7 @@ import java.util.concurrent.CompletionStage; import java.util.concurrent.ExecutorService; -import static bisq.updater.UpdaterUtils.*; +import static bisq.evolution.updater.UpdaterUtils.*; import static com.google.common.base.Preconditions.checkArgument; @Slf4j diff --git a/application/src/main/java/bisq/updater/UpdaterUtils.java b/evolution/src/main/java/bisq/evolution/updater/UpdaterUtils.java similarity index 98% rename from application/src/main/java/bisq/updater/UpdaterUtils.java rename to evolution/src/main/java/bisq/evolution/updater/UpdaterUtils.java index 4c3dab902a..d853cf536c 100644 --- a/application/src/main/java/bisq/updater/UpdaterUtils.java +++ b/evolution/src/main/java/bisq/evolution/updater/UpdaterUtils.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.updater; +package bisq.evolution.updater; import bisq.common.file.FileUtils; import bisq.common.platform.Platform; diff --git a/application/src/main/resources/keys/387C8307.asc b/evolution/src/main/resources/keys/387C8307.asc similarity index 100% rename from application/src/main/resources/keys/387C8307.asc rename to evolution/src/main/resources/keys/387C8307.asc diff --git a/application/src/main/resources/keys/E222AA02.asc b/evolution/src/main/resources/keys/E222AA02.asc similarity index 100% rename from application/src/main/resources/keys/E222AA02.asc rename to evolution/src/main/resources/keys/E222AA02.asc diff --git a/application/src/test/java/bisq/application/migration/MigrationServiceTests.java b/evolution/src/test/java/bisq/evolution/migration/MigrationServiceTests.java similarity index 97% rename from application/src/test/java/bisq/application/migration/MigrationServiceTests.java rename to evolution/src/test/java/bisq/evolution/migration/MigrationServiceTests.java index f93d09c2cc..976b9b1560 100644 --- a/application/src/test/java/bisq/application/migration/MigrationServiceTests.java +++ b/evolution/src/test/java/bisq/evolution/migration/MigrationServiceTests.java @@ -1,4 +1,4 @@ -package bisq.application.migration; +package bisq.evolution.migration; import bisq.common.platform.InvalidVersionException; import bisq.common.platform.Version; diff --git a/application/src/test/java/bisq/application/migration/MigratorTest.java b/evolution/src/test/java/bisq/evolution/migration/MigratorTest.java similarity index 96% rename from application/src/test/java/bisq/application/migration/MigratorTest.java rename to evolution/src/test/java/bisq/evolution/migration/MigratorTest.java index cc7016ed95..92173163c7 100644 --- a/application/src/test/java/bisq/application/migration/MigratorTest.java +++ b/evolution/src/test/java/bisq/evolution/migration/MigratorTest.java @@ -1,4 +1,4 @@ -package bisq.application.migration; +package bisq.evolution.migration; import bisq.common.application.ApplicationVersion; import bisq.common.platform.Version; diff --git a/application/src/test/java/bisq/application/migration/migrations/MigrationsForV2_1_2Tests.java b/evolution/src/test/java/bisq/evolution/migration/migrations/MigrationsForV2_1_2Tests.java similarity index 98% rename from application/src/test/java/bisq/application/migration/migrations/MigrationsForV2_1_2Tests.java rename to evolution/src/test/java/bisq/evolution/migration/migrations/MigrationsForV2_1_2Tests.java index bb7668b617..d4de37bc9b 100644 --- a/application/src/test/java/bisq/application/migration/migrations/MigrationsForV2_1_2Tests.java +++ b/evolution/src/test/java/bisq/evolution/migration/migrations/MigrationsForV2_1_2Tests.java @@ -1,4 +1,4 @@ -package bisq.application.migration.migrations; +package bisq.evolution.migration.migrations; import bisq.common.platform.Version; import org.junit.jupiter.api.Test; diff --git a/application/src/test/java/bisq/updater/UpdaterIntegrationTest.java b/evolution/src/test/java/bisq/evolution/updater/UpdaterIntegrationTest.java similarity index 97% rename from application/src/test/java/bisq/updater/UpdaterIntegrationTest.java rename to evolution/src/test/java/bisq/evolution/updater/UpdaterIntegrationTest.java index 2d9191bf58..841513c2e7 100644 --- a/application/src/test/java/bisq/updater/UpdaterIntegrationTest.java +++ b/evolution/src/test/java/bisq/evolution/updater/UpdaterIntegrationTest.java @@ -15,10 +15,13 @@ * along with Bisq. If not, see . */ -package bisq.updater; +package bisq.evolution.updater; import bisq.common.file.FileUtils; import bisq.common.threading.ExecutorFactory; +import bisq.evolution.updater.DownloadItem; +import bisq.evolution.updater.UpdaterService; +import bisq.evolution.updater.UpdaterUtils; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -32,7 +35,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; -import static bisq.updater.UpdaterUtils.*; +import static bisq.evolution.updater.UpdaterUtils.*; import static org.junit.jupiter.api.Assertions.*; // Tests deactivated as they fail on CI due FileNotFoundException probably related to the srcBaseDir location. diff --git a/application/src/test/resources/1.9.10/387C8307.asc b/evolution/src/test/resources/1.9.10/387C8307.asc similarity index 100% rename from application/src/test/resources/1.9.10/387C8307.asc rename to evolution/src/test/resources/1.9.10/387C8307.asc diff --git a/application/src/test/resources/1.9.10/desktop_app-1.9.10-all.jar b/evolution/src/test/resources/1.9.10/desktop_app-1.9.10-all.jar similarity index 100% rename from application/src/test/resources/1.9.10/desktop_app-1.9.10-all.jar rename to evolution/src/test/resources/1.9.10/desktop_app-1.9.10-all.jar diff --git a/application/src/test/resources/1.9.10/desktop_app-1.9.10-all.jar.asc b/evolution/src/test/resources/1.9.10/desktop_app-1.9.10-all.jar.asc similarity index 100% rename from application/src/test/resources/1.9.10/desktop_app-1.9.10-all.jar.asc rename to evolution/src/test/resources/1.9.10/desktop_app-1.9.10-all.jar.asc diff --git a/application/src/test/resources/1.9.10/from_bisq_webpage_387C8307.asc b/evolution/src/test/resources/1.9.10/from_bisq_webpage_387C8307.asc similarity index 100% rename from application/src/test/resources/1.9.10/from_bisq_webpage_387C8307.asc rename to evolution/src/test/resources/1.9.10/from_bisq_webpage_387C8307.asc diff --git a/application/src/test/resources/1.9.10/signingkey.asc b/evolution/src/test/resources/1.9.10/signingkey.asc similarity index 100% rename from application/src/test/resources/1.9.10/signingkey.asc rename to evolution/src/test/resources/1.9.10/signingkey.asc diff --git a/application/src/test/resources/1.9.9/387C8307.asc b/evolution/src/test/resources/1.9.9/387C8307.asc similarity index 100% rename from application/src/test/resources/1.9.9/387C8307.asc rename to evolution/src/test/resources/1.9.9/387C8307.asc diff --git a/application/src/test/resources/1.9.9/Bisq2-1.9.9.dmg b/evolution/src/test/resources/1.9.9/Bisq2-1.9.9.dmg similarity index 100% rename from application/src/test/resources/1.9.9/Bisq2-1.9.9.dmg rename to evolution/src/test/resources/1.9.9/Bisq2-1.9.9.dmg diff --git a/application/src/test/resources/1.9.9/Bisq2-1.9.9.dmg.asc b/evolution/src/test/resources/1.9.9/Bisq2-1.9.9.dmg.asc similarity index 100% rename from application/src/test/resources/1.9.9/Bisq2-1.9.9.dmg.asc rename to evolution/src/test/resources/1.9.9/Bisq2-1.9.9.dmg.asc diff --git a/application/src/test/resources/1.9.9/from_bisq_webpage_387C8307.asc b/evolution/src/test/resources/1.9.9/from_bisq_webpage_387C8307.asc similarity index 100% rename from application/src/test/resources/1.9.9/from_bisq_webpage_387C8307.asc rename to evolution/src/test/resources/1.9.9/from_bisq_webpage_387C8307.asc diff --git a/application/src/test/resources/1.9.9/signingkey.asc b/evolution/src/test/resources/1.9.9/signingkey.asc similarity index 100% rename from application/src/test/resources/1.9.9/signingkey.asc rename to evolution/src/test/resources/1.9.9/signingkey.asc diff --git a/application/src/test/resources/keys/387C8307.asc b/evolution/src/test/resources/keys/387C8307.asc similarity index 100% rename from application/src/test/resources/keys/387C8307.asc rename to evolution/src/test/resources/keys/387C8307.asc diff --git a/identity/build.gradle.kts b/identity/build.gradle.kts index e226de0a2f..a9da7dddee 100644 --- a/identity/build.gradle.kts +++ b/identity/build.gradle.kts @@ -7,7 +7,6 @@ dependencies { implementation(project(":persistence")) implementation(project(":security")) - implementation("network:network-common") implementation("network:network") implementation("network:network-identity") diff --git a/identity/src/main/java/bisq/identity/IdentityService.java b/identity/src/main/java/bisq/identity/IdentityService.java index 96923a02c9..a902838ba0 100644 --- a/identity/src/main/java/bisq/identity/IdentityService.java +++ b/identity/src/main/java/bisq/identity/IdentityService.java @@ -22,7 +22,7 @@ import bisq.common.observable.Observable; import bisq.network.NetworkIdService; import bisq.network.NetworkService; -import bisq.network.common.TransportType; +import bisq.common.network.TransportType; import bisq.network.identity.NetworkId; import bisq.network.p2p.node.Node; import bisq.persistence.DbSubDirectory; @@ -32,7 +32,6 @@ import bisq.security.keys.KeyBundle; import bisq.security.keys.KeyBundleService; import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.Streams; import lombok.Getter; import lombok.extern.slf4j.Slf4j; @@ -42,6 +41,7 @@ import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Stream; @Slf4j public class IdentityService implements PersistenceClient, Service { @@ -193,8 +193,8 @@ public Optional findRetiredIdentityByNetworkId(NetworkId networkId) { public Optional findAnyIdentityByNetworkId(NetworkId networkId) { synchronized (lock) { - return Streams.concat(persistableStore.getDefaultIdentity().stream(), - getActiveIdentityByTag().values().stream(), + return Stream.concat(Stream.concat(persistableStore.getDefaultIdentity().stream(), + getActiveIdentityByTag().values().stream()), getRetired().stream()) .filter(e -> e.getNetworkId().equals(networkId)) .findAny(); diff --git a/identity/src/test/java/bisq/identity/IdentityServiceTest.java b/identity/src/test/java/bisq/identity/IdentityServiceTest.java index 22fa7990e2..ee8d563670 100644 --- a/identity/src/test/java/bisq/identity/IdentityServiceTest.java +++ b/identity/src/test/java/bisq/identity/IdentityServiceTest.java @@ -17,10 +17,10 @@ package bisq.identity; +import bisq.common.network.DefaultLocalhostFacade; import bisq.network.NetworkService; -import bisq.network.common.Address; -import bisq.network.common.AddressByTransportTypeMap; -import bisq.network.common.TransportType; +import bisq.common.network.AddressByTransportTypeMap; +import bisq.common.network.TransportType; import bisq.network.identity.NetworkId; import bisq.network.p2p.node.Node; import bisq.persistence.PersistenceService; @@ -160,7 +160,7 @@ void findInvalidIdentity() { @Test void findInvalidIdentityByNetworkId() { AddressByTransportTypeMap addressByTransportTypeMap = new AddressByTransportTypeMap( - Map.of(TransportType.CLEAR, Address.localHost(1234))); + Map.of(TransportType.CLEAR, DefaultLocalhostFacade.toLocalHostAddress(1234))); String keyId = keyBundleService.getKeyIdFromTag("myTag2"); KeyPair keyPair = keyBundleService.getOrCreateKeyBundle(keyId).getKeyPair(); @@ -192,7 +192,7 @@ void findActiveIdentityByNetworkId() { @Test void findInvalidRetiredIdentity() { AddressByTransportTypeMap addressByTransportTypeMap = new AddressByTransportTypeMap( - Map.of(TransportType.CLEAR, Address.localHost(1234))); + Map.of(TransportType.CLEAR, DefaultLocalhostFacade.toLocalHostAddress(1234))); String keyId = keyBundleService.getKeyIdFromTag("myTag3"); KeyPair keyPair = keyBundleService.getOrCreateKeyBundle(keyId).getKeyPair(); var pubKey = new PubKey(keyPair.getPublic(), keyId); diff --git a/java-se/build.gradle.kts b/java-se/build.gradle.kts new file mode 100644 index 0000000000..aaf081bfe4 --- /dev/null +++ b/java-se/build.gradle.kts @@ -0,0 +1,16 @@ +plugins { + id("bisq.java-library") +} + +dependencies { + implementation("bisq:common") + implementation("bisq:security") + implementation("bisq:application") + implementation("bisq:evolution") + implementation("bisq:evolution") + implementation("tor:tor") + implementation("tor:tor-common") + implementation("network:network") + + implementation(libs.typesafe.config) +} diff --git a/java-se/src/main/java/bisq/java_se/application/JavaSeApplicationService.java b/java-se/src/main/java/bisq/java_se/application/JavaSeApplicationService.java new file mode 100644 index 0000000000..377799dd30 --- /dev/null +++ b/java-se/src/main/java/bisq/java_se/application/JavaSeApplicationService.java @@ -0,0 +1,49 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.java_se.application; + +import bisq.application.ApplicationService; +import bisq.common.facades.FacadeProvider; +import bisq.common.platform.MemoryReportService; +import bisq.common.platform.PlatformUtils; +import bisq.evolution.migration.MigrationService; +import bisq.java_se.facades.JavaSeGuavaFacade; +import bisq.java_se.facades.JavaSeJdkFacade; +import bisq.java_se.jvm.JvmMemoryReportService; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +@Getter +@Slf4j +public abstract class JavaSeApplicationService extends ApplicationService { + protected final MigrationService migrationService; + protected final MemoryReportService memoryReportService; + + public JavaSeApplicationService(String configFileName, String[] args) { + super(configFileName, args, PlatformUtils.getUserDataDir()); + + // The JDKs for Java SE and Android have different API support, thus, we use a + // facade with Android compatible APIs by default and set for Java SE based applicationServices + // the Java SE facade. + FacadeProvider.setGuavaFacade(new JavaSeGuavaFacade()); + FacadeProvider.setJdkFacade(new JavaSeJdkFacade()); + + migrationService = new MigrationService(getConfig().getBaseDir()); + memoryReportService = new JvmMemoryReportService(getConfig().getMemoryReportIntervalSec(), getConfig().isIncludeThreadListInMemoryReport()); + } +} diff --git a/java-se/src/main/java/bisq/java_se/facades/JavaSeGuavaFacade.java b/java-se/src/main/java/bisq/java_se/facades/JavaSeGuavaFacade.java new file mode 100644 index 0000000000..f19da3cd59 --- /dev/null +++ b/java-se/src/main/java/bisq/java_se/facades/JavaSeGuavaFacade.java @@ -0,0 +1,40 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.java_se.facades; + +import bisq.common.facades.GuavaFacade; +import com.google.common.primitives.ImmutableIntArray; + +import java.util.stream.IntStream; + +public class JavaSeGuavaFacade implements GuavaFacade { + @Override + public IntStream toIntStream(ImmutableIntArray value) { + return value.stream(); + } + + @Override + public IntStream parallel(IntStream value) { + return value.parallel(); + } + + @Override + public ImmutableIntArray copyOf(IntStream value) { + return ImmutableIntArray.copyOf(value); + } +} diff --git a/java-se/src/main/java/bisq/java_se/facades/JavaSeJdkFacade.java b/java-se/src/main/java/bisq/java_se/facades/JavaSeJdkFacade.java new file mode 100644 index 0000000000..4e1cceec73 --- /dev/null +++ b/java-se/src/main/java/bisq/java_se/facades/JavaSeJdkFacade.java @@ -0,0 +1,51 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.java_se.facades; + +import bisq.common.facades.JdkFacade; +import lombok.extern.slf4j.Slf4j; + +import java.io.IOException; +import java.lang.management.ManagementFactory; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.stream.Stream; + +@Slf4j +public class JavaSeJdkFacade implements JdkFacade { + @Override + public String getMyPid() { + String processName = ManagementFactory.getRuntimeMXBean().getName(); + return processName.split("@")[0]; + } + + @Override + public Stream getProcessCommandLineStream() { + return ProcessHandle.allProcesses().map(processHandle -> processHandle.info().commandLine().orElse("")); + } + + @Override + public void redirectError(ProcessBuilder processBuilder) { + processBuilder.redirectError(ProcessBuilder.Redirect.DISCARD); + } + + @Override + public void redirectOutput(ProcessBuilder processBuilder) { + processBuilder.redirectOutput(ProcessBuilder.Redirect.DISCARD); + } +} diff --git a/common/src/main/java/bisq/common/platform/MemoryReport.java b/java-se/src/main/java/bisq/java_se/jvm/JvmMemoryReportService.java similarity index 87% rename from common/src/main/java/bisq/common/platform/MemoryReport.java rename to java-se/src/main/java/bisq/java_se/jvm/JvmMemoryReportService.java index 8eef2d441a..3e37bec9ff 100644 --- a/common/src/main/java/bisq/common/platform/MemoryReport.java +++ b/java-se/src/main/java/bisq/java_se/jvm/JvmMemoryReportService.java @@ -15,43 +15,52 @@ * along with Bisq. If not, see . */ -package bisq.common.platform; +package bisq.java_se.jvm; import bisq.common.formatter.DataSizeFormatter; import bisq.common.formatter.SimpleTimeFormatter; -import bisq.common.threading.ThreadProfiler; +import bisq.common.platform.MemoryReportService; +import bisq.common.platform.OS; import bisq.common.timer.Scheduler; import bisq.common.util.StringUtils; +import bisq.java_se.utils.ThreadProfiler; import com.sun.management.UnixOperatingSystemMXBean; -import lombok.Getter; import lombok.extern.slf4j.Slf4j; import java.lang.management.ManagementFactory; import java.util.Set; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; @Slf4j -public class MemoryReport { - @Getter - private static final MemoryReport INSTANCE = new MemoryReport(); - +public class JvmMemoryReportService implements MemoryReportService { + private final int memoryReportIntervalSec; + private final boolean includeThreadListInMemoryReport; private Scheduler scheduler; - private boolean includeThreadListInMemoryReport; - public MemoryReport() { + public JvmMemoryReportService(int memoryReportIntervalSec, boolean includeThreadListInMemoryReport) { + this.memoryReportIntervalSec = memoryReportIntervalSec; + this.includeThreadListInMemoryReport = includeThreadListInMemoryReport; } - public void printPeriodically(int memoryReportIntervalSec, boolean includeThreadListInMemoryReport) { - this.includeThreadListInMemoryReport = includeThreadListInMemoryReport; - if (scheduler != null) { - scheduler.stop(); - } + @Override + public CompletableFuture initialize() { scheduler = Scheduler.run(this::logReport) - .host(MemoryReport.class) + .host(JvmMemoryReportService.class) .runnableName("logReport") .periodically(30, memoryReportIntervalSec, TimeUnit.SECONDS); + return CompletableFuture.completedFuture(true); + } + + @Override + public CompletableFuture shutdown() { + if (scheduler != null) { + scheduler.stop(); + } + return CompletableFuture.completedFuture(true); } + @Override public void logReport() { Runtime runtime = Runtime.getRuntime(); long free = runtime.freeMemory(); @@ -148,22 +157,26 @@ public void logReport() { } } - public static long getUsedMemoryInBytes() { + @Override + public long getUsedMemoryInBytes() { Runtime runtime = Runtime.getRuntime(); long free = runtime.freeMemory(); long total = runtime.totalMemory(); return total - free; } - public static long getUsedMemoryInMB() { + @Override + public long getUsedMemoryInMB() { return getUsedMemoryInBytes() / 1024 / 1024; } - public static long getFreeMemoryInMB() { + @Override + public long getFreeMemoryInMB() { return Runtime.getRuntime().freeMemory() / 1024 / 1024; } - public static long getTotalMemoryInMB() { + @Override + public long getTotalMemoryInMB() { return Runtime.getRuntime().totalMemory() / 1024 / 1024; } } diff --git a/java-se/src/main/java/bisq/java_se/package-info.java b/java-se/src/main/java/bisq/java_se/package-info.java new file mode 100644 index 0000000000..5ba6503285 --- /dev/null +++ b/java-se/src/main/java/bisq/java_se/package-info.java @@ -0,0 +1,22 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +/** + * The java-se module hosts classes which are part of Java Standard Edition but not of the JDK used in the Android SDK. + * For code re-use in Android we isolate those classes to that module. + */ +package bisq.java_se; \ No newline at end of file diff --git a/common/src/main/java/bisq/common/file/FileCreationWatcher.java b/java-se/src/main/java/bisq/java_se/utils/FileCreationWatcher.java similarity index 99% rename from common/src/main/java/bisq/common/file/FileCreationWatcher.java rename to java-se/src/main/java/bisq/java_se/utils/FileCreationWatcher.java index 7fbf940ac5..2e449e4e70 100644 --- a/common/src/main/java/bisq/common/file/FileCreationWatcher.java +++ b/java-se/src/main/java/bisq/java_se/utils/FileCreationWatcher.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.common.file; +package bisq.java_se.utils; import com.sun.nio.file.SensitivityWatchEventModifier; import lombok.extern.slf4j.Slf4j; diff --git a/common/src/main/java/bisq/common/jvm/JvmUtils.java b/java-se/src/main/java/bisq/java_se/utils/JvmUtils.java similarity index 98% rename from common/src/main/java/bisq/common/jvm/JvmUtils.java rename to java-se/src/main/java/bisq/java_se/utils/JvmUtils.java index c3486b30e5..06392f3650 100644 --- a/common/src/main/java/bisq/common/jvm/JvmUtils.java +++ b/java-se/src/main/java/bisq/java_se/utils/JvmUtils.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.common.jvm; +package bisq.java_se.utils; import lombok.extern.slf4j.Slf4j; diff --git a/network/tor/tor/src/main/java/bisq/tor/process/Pid.java b/java-se/src/main/java/bisq/java_se/utils/PidUtil.java similarity index 94% rename from network/tor/tor/src/main/java/bisq/tor/process/Pid.java rename to java-se/src/main/java/bisq/java_se/utils/PidUtil.java index c7c11fe99c..b7ccab55eb 100644 --- a/network/tor/tor/src/main/java/bisq/tor/process/Pid.java +++ b/java-se/src/main/java/bisq/java_se/utils/PidUtil.java @@ -15,11 +15,11 @@ * along with Bisq. If not, see . */ -package bisq.tor.process; +package bisq.java_se.utils; import java.lang.management.ManagementFactory; -public class Pid { +public class PidUtil { public static String getMyPid() { String processName = ManagementFactory.getRuntimeMXBean().getName(); return processName.split("@")[0]; diff --git a/common/src/main/java/bisq/common/threading/ThreadProfiler.java b/java-se/src/main/java/bisq/java_se/utils/ThreadProfiler.java similarity index 98% rename from common/src/main/java/bisq/common/threading/ThreadProfiler.java rename to java-se/src/main/java/bisq/java_se/utils/ThreadProfiler.java index f1739947c2..d1fb38e6e8 100644 --- a/common/src/main/java/bisq/common/threading/ThreadProfiler.java +++ b/java-se/src/main/java/bisq/java_se/utils/ThreadProfiler.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.common.threading; +package bisq.java_se.utils; import java.lang.management.ManagementFactory; import java.lang.management.ThreadMXBean; diff --git a/network/i2p-v2/build.gradle.kts b/network/i2p-v2/build.gradle.kts index b83e8d5d2a..a27d3501d5 100644 --- a/network/i2p-v2/build.gradle.kts +++ b/network/i2p-v2/build.gradle.kts @@ -3,6 +3,5 @@ plugins { } dependencies { - implementation(project(":network-common")) implementation(libs.bundles.i2p.v2) } diff --git a/network/i2p-v2/src/main/java/bisq/network/i2p/I2pAddressOwnershipProofGenerator.java b/network/i2p-v2/src/main/java/bisq/network/i2p/I2pAddressOwnershipProofGenerator.java index bbada2777c..d8028f8b97 100644 --- a/network/i2p-v2/src/main/java/bisq/network/i2p/I2pAddressOwnershipProofGenerator.java +++ b/network/i2p-v2/src/main/java/bisq/network/i2p/I2pAddressOwnershipProofGenerator.java @@ -17,9 +17,9 @@ package bisq.network.i2p; -import bisq.network.common.Address; -import bisq.network.common.AddressOwnershipProof; -import bisq.network.common.AddressOwnershipProofGenerator; +import bisq.common.network.Address; +import bisq.common.network.AddressOwnershipProof; +import bisq.common.network.AddressOwnershipProofGenerator; public class I2pAddressOwnershipProofGenerator implements AddressOwnershipProofGenerator { @Override diff --git a/network/i2p-v2/src/main/java/bisq/network/i2p/I2pSocket.java b/network/i2p-v2/src/main/java/bisq/network/i2p/I2pSocket.java index 904676a728..a342fe137e 100644 --- a/network/i2p-v2/src/main/java/bisq/network/i2p/I2pSocket.java +++ b/network/i2p-v2/src/main/java/bisq/network/i2p/I2pSocket.java @@ -17,7 +17,7 @@ package bisq.network.i2p; -import bisq.network.common.PeerSocket; +import bisq.common.network.PeerSocket; import lombok.Getter; import net.i2p.client.streaming.I2PSocket; diff --git a/network/network-common/build.gradle.kts b/network/network-common/build.gradle.kts deleted file mode 100644 index ec79ed680b..0000000000 --- a/network/network-common/build.gradle.kts +++ /dev/null @@ -1,4 +0,0 @@ -plugins { - id("bisq.java-library") - id("bisq.protobuf") -} \ No newline at end of file diff --git a/network/network-common/src/main/proto/network_common.proto b/network/network-common/src/main/proto/network_common.proto deleted file mode 100644 index 962503bbe7..0000000000 --- a/network/network-common/src/main/proto/network_common.proto +++ /dev/null @@ -1,13 +0,0 @@ -syntax = "proto3"; -package network.common; -option java_package = "bisq.network.common.protobuf"; -option java_multiple_files = true; - -message Address { - string host = 1; - sint32 port = 2; -} - -message AddressByTransportTypeMap { - map addressByTransportType = 1; -} \ No newline at end of file diff --git a/network/network-identity/build.gradle.kts b/network/network-identity/build.gradle.kts index 2b76856d77..dba40be559 100644 --- a/network/network-identity/build.gradle.kts +++ b/network/network-identity/build.gradle.kts @@ -4,7 +4,7 @@ plugins { } dependencies { - implementation(project(":network-common")) + implementation("bisq:common") implementation("bisq:security") implementation(libs.bouncycastle) diff --git a/network/network-identity/src/main/java/bisq/network/identity/NetworkId.java b/network/network-identity/src/main/java/bisq/network/identity/NetworkId.java index 66ff5a4062..a1826b03d2 100644 --- a/network/network-identity/src/main/java/bisq/network/identity/NetworkId.java +++ b/network/network-identity/src/main/java/bisq/network/identity/NetworkId.java @@ -18,7 +18,7 @@ package bisq.network.identity; import bisq.common.proto.NetworkProto; -import bisq.network.common.AddressByTransportTypeMap; +import bisq.common.network.AddressByTransportTypeMap; import bisq.security.keys.PubKey; import com.google.common.base.Joiner; import lombok.EqualsAndHashCode; diff --git a/network/network-identity/src/main/proto/network_identity.proto b/network/network-identity/src/main/proto/network_identity.proto index 23f31e1906..bab423363a 100644 --- a/network/network-identity/src/main/proto/network_identity.proto +++ b/network/network-identity/src/main/proto/network_identity.proto @@ -2,10 +2,10 @@ syntax = "proto3"; package network.identity; option java_package = "bisq.network.identity.protobuf"; option java_multiple_files = true; -import "network_common.proto"; +import "common.proto"; import "security.proto"; message NetworkId { - network.common.AddressByTransportTypeMap addressByNetworkTypeMap = 1; + common.AddressByTransportTypeMap addressByNetworkTypeMap = 1; security.PubKey pubKey = 2; } \ No newline at end of file diff --git a/network/network/build.gradle.kts b/network/network/build.gradle.kts index 0ea9a225c0..391717b68e 100644 --- a/network/network/build.gradle.kts +++ b/network/network/build.gradle.kts @@ -5,10 +5,10 @@ plugins { } dependencies { + implementation("bisq:common") implementation("bisq:security") implementation("bisq:persistence") - implementation(project(":network-common")) implementation(project(":network-identity")) implementation(project(":i2p")) implementation("tor:tor") diff --git a/network/network/src/integrationTest/java/bisq/network/p2p/NetworkEnvelopeSocketChannelTests.java b/network/network/src/integrationTest/java/bisq/network/p2p/NetworkEnvelopeSocketChannelTests.java index 2ad37b8f50..1d212726ac 100644 --- a/network/network/src/integrationTest/java/bisq/network/p2p/NetworkEnvelopeSocketChannelTests.java +++ b/network/network/src/integrationTest/java/bisq/network/p2p/NetworkEnvelopeSocketChannelTests.java @@ -19,9 +19,10 @@ import bisq.common.application.ApplicationVersion; import bisq.common.file.FileUtils; +import bisq.common.network.DefaultLocalhostFacade; import bisq.common.util.NetworkUtils; -import bisq.network.common.Address; -import bisq.network.common.TransportType; +import bisq.common.network.Address; +import bisq.common.network.TransportType; import bisq.network.p2p.message.NetworkEnvelope; import bisq.network.p2p.node.Capability; import bisq.network.p2p.node.Feature; @@ -188,11 +189,11 @@ private NetworkEnvelope createHandshakeRequestMessage() { List supportedTransportTypes = new ArrayList<>(1); supportedTransportTypes.add(TransportType.CLEAR); - Capability peerCapability = createCapability(Address.localHost(2345), supportedTransportTypes); + Capability peerCapability = createCapability(DefaultLocalhostFacade.toLocalHostAddress(2345), supportedTransportTypes); ConnectionHandshake.Request request = new ConnectionHandshake.Request(peerCapability, Optional.empty(), new NetworkLoad(), 0); AuthorizationService authorizationService = createAuthorizationService(); - Capability responderCapability = createCapability(Address.localHost(1234), supportedTransportTypes); + Capability responderCapability = createCapability(DefaultLocalhostFacade.toLocalHostAddress(1234), supportedTransportTypes); AuthorizationToken token = authorizationService.createToken(request, new NetworkLoad(), diff --git a/network/network/src/integrationTest/java/bisq/network/p2p/OutboundConnectionsMultiplexerTest.java b/network/network/src/integrationTest/java/bisq/network/p2p/OutboundConnectionsMultiplexerTest.java index 34b91a8f69..5081610c65 100644 --- a/network/network/src/integrationTest/java/bisq/network/p2p/OutboundConnectionsMultiplexerTest.java +++ b/network/network/src/integrationTest/java/bisq/network/p2p/OutboundConnectionsMultiplexerTest.java @@ -19,9 +19,10 @@ import bisq.common.application.ApplicationVersion; import bisq.common.file.FileUtils; +import bisq.common.network.DefaultLocalhostFacade; import bisq.common.util.NetworkUtils; -import bisq.network.common.Address; -import bisq.network.common.TransportType; +import bisq.common.network.Address; +import bisq.common.network.TransportType; import bisq.network.p2p.node.*; import bisq.network.p2p.node.authorization.AuthorizationService; import bisq.network.p2p.node.authorization.AuthorizationTokenType; @@ -59,7 +60,7 @@ void startServerAndConnectAfterItsReady() throws IOException, InterruptedExcepti ArrayList supportedTransportTypes = new ArrayList<>(); supportedTransportTypes.add(TransportType.CLEAR); - Address serverAddress = Address.localHost(NetworkUtils.findFreeSystemPort()); + Address serverAddress = DefaultLocalhostFacade.toLocalHostAddress(NetworkUtils.findFreeSystemPort()); Capability serverCapability = createCapability(serverAddress, supportedTransportTypes); ServerChannel serverChannel = new ServerChannel( serverCapability, @@ -83,7 +84,7 @@ void startServerAndConnectAfterItsReady() throws IOException, InterruptedExcepti } AuthorizationService authorizationService = createAuthorizationService(); - Address outboundAddress = Address.localHost(NetworkUtils.findFreeSystemPort()); + Address outboundAddress = DefaultLocalhostFacade.toLocalHostAddress(NetworkUtils.findFreeSystemPort()); Capability outboundCapability = createCapability(outboundAddress, supportedTransportTypes); Selector selector = SelectorProvider.provider().openSelector(); diff --git a/network/network/src/main/java/bisq/network/NetworkIdService.java b/network/network/src/main/java/bisq/network/NetworkIdService.java index bc17d50c70..de06dd4b28 100644 --- a/network/network/src/main/java/bisq/network/NetworkIdService.java +++ b/network/network/src/main/java/bisq/network/NetworkIdService.java @@ -19,11 +19,12 @@ import bisq.common.application.Service; +import bisq.common.facades.FacadeProvider; import bisq.common.file.FileUtils; import bisq.common.util.NetworkUtils; -import bisq.network.common.Address; -import bisq.network.common.AddressByTransportTypeMap; -import bisq.network.common.TransportType; +import bisq.common.network.Address; +import bisq.common.network.AddressByTransportTypeMap; +import bisq.common.network.TransportType; import bisq.network.identity.NetworkId; import bisq.persistence.DbSubDirectory; import bisq.persistence.Persistence; @@ -167,7 +168,7 @@ private Address getAddressByTransport(KeyBundle keyBundle, int port, TransportTy return switch (transportType) { case TOR -> new Address(keyBundle.getTorKeyPair().getOnionAddress(), port); case I2P -> throw new RuntimeException("I2P not unsupported yet"); - case CLEAR -> Address.localHost(port); + case CLEAR -> FacadeProvider.getLocalhostFacade().toMyLocalhost(port); }; } diff --git a/network/network/src/main/java/bisq/network/NetworkService.java b/network/network/src/main/java/bisq/network/NetworkService.java index f93c5908f0..710bf51652 100644 --- a/network/network/src/main/java/bisq/network/NetworkService.java +++ b/network/network/src/main/java/bisq/network/NetworkService.java @@ -21,12 +21,13 @@ import bisq.common.application.Service; import bisq.common.observable.Observable; import bisq.common.observable.map.ObservableHashMap; +import bisq.common.platform.MemoryReportService; import bisq.common.threading.ExecutorFactory; import bisq.common.threading.ThreadName; import bisq.common.util.CompletableFutureUtils; -import bisq.network.common.Address; -import bisq.network.common.AddressByTransportTypeMap; -import bisq.network.common.TransportType; +import bisq.common.network.Address; +import bisq.common.network.AddressByTransportTypeMap; +import bisq.common.network.TransportType; import bisq.network.http.BaseHttpClient; import bisq.network.http.HttpClientsByTransport; import bisq.network.identity.NetworkId; @@ -77,7 +78,7 @@ import java.util.function.Predicate; import java.util.stream.Collectors; -import static bisq.network.common.TransportType.TOR; +import static bisq.common.network.TransportType.TOR; import static bisq.network.p2p.services.data.DataService.Listener; import static com.google.common.base.Preconditions.checkArgument; import static java.util.concurrent.CompletableFuture.supplyAsync; @@ -121,7 +122,8 @@ public NetworkService(NetworkServiceConfig config, PersistenceService persistenceService, KeyBundleService keyBundleService, HashCashProofOfWorkService hashCashProofOfWorkService, - EquihashProofOfWorkService equihashProofOfWorkService) { + EquihashProofOfWorkService equihashProofOfWorkService, + MemoryReportService memoryReportService) { socks5ProxyAddress = config.getSocks5ProxyAddress(); supportedTransportTypes = config.getSupportedTransportTypes(); defaultPortByTransportType = config.getDefaultPortByTransportType(); @@ -162,7 +164,8 @@ public NetworkService(NetworkServiceConfig config, equihashProofOfWorkService, dataService, messageDeliveryStatusService, - resendMessageService); + resendMessageService, + memoryReportService); persistence = persistenceService.getOrCreatePersistence(this, DbSubDirectory.CACHE, persistableStore); } diff --git a/network/network/src/main/java/bisq/network/NetworkServiceConfig.java b/network/network/src/main/java/bisq/network/NetworkServiceConfig.java index fa180de2da..4e73f8df82 100644 --- a/network/network/src/main/java/bisq/network/NetworkServiceConfig.java +++ b/network/network/src/main/java/bisq/network/NetworkServiceConfig.java @@ -18,9 +18,9 @@ package bisq.network; import bisq.common.application.ConfigUtil; -import bisq.network.common.Address; -import bisq.network.common.TransportConfig; -import bisq.network.common.TransportType; +import bisq.common.network.Address; +import bisq.common.network.TransportConfig; +import bisq.common.network.TransportType; import bisq.network.p2p.ServiceNode; import bisq.network.p2p.node.Feature; import bisq.network.p2p.node.authorization.AuthorizationService; diff --git a/network/network/src/main/java/bisq/network/NetworkServiceStore.java b/network/network/src/main/java/bisq/network/NetworkServiceStore.java index 30ea72f97a..ae7eeda7c3 100644 --- a/network/network/src/main/java/bisq/network/NetworkServiceStore.java +++ b/network/network/src/main/java/bisq/network/NetworkServiceStore.java @@ -19,7 +19,7 @@ import bisq.common.proto.ProtoResolver; import bisq.common.proto.UnresolvableProtobufMessageException; -import bisq.network.common.AddressByTransportTypeMap; +import bisq.common.network.AddressByTransportTypeMap; import bisq.network.identity.NetworkId; import bisq.persistence.PersistableStore; import com.google.protobuf.InvalidProtocolBufferException; diff --git a/network/network/src/main/java/bisq/network/SendMessageResult.java b/network/network/src/main/java/bisq/network/SendMessageResult.java index ecc8081411..7fc2e19962 100644 --- a/network/network/src/main/java/bisq/network/SendMessageResult.java +++ b/network/network/src/main/java/bisq/network/SendMessageResult.java @@ -1,6 +1,6 @@ package bisq.network; -import bisq.network.common.TransportType; +import bisq.common.network.TransportType; import bisq.network.p2p.services.confidential.SendConfidentialMessageResult; import java.util.HashMap; diff --git a/network/network/src/main/java/bisq/network/http/HttpClientsByTransport.java b/network/network/src/main/java/bisq/network/http/HttpClientsByTransport.java index 8a97bfd0c1..0a9e31c9f7 100644 --- a/network/network/src/main/java/bisq/network/http/HttpClientsByTransport.java +++ b/network/network/src/main/java/bisq/network/http/HttpClientsByTransport.java @@ -17,7 +17,7 @@ package bisq.network.http; -import bisq.network.common.TransportType; +import bisq.common.network.TransportType; import bisq.network.http.utils.Socks5ProxyProvider; import com.runjva.sourceforge.jsocks.protocol.Socks5Proxy; diff --git a/network/network/src/main/java/bisq/network/p2p/ServiceNode.java b/network/network/src/main/java/bisq/network/p2p/ServiceNode.java index 3990bdabb6..bfab3e6bc3 100644 --- a/network/network/src/main/java/bisq/network/p2p/ServiceNode.java +++ b/network/network/src/main/java/bisq/network/p2p/ServiceNode.java @@ -19,9 +19,10 @@ import bisq.common.observable.Observable; +import bisq.common.platform.MemoryReportService; import bisq.network.NetworkService; -import bisq.network.common.Address; -import bisq.network.common.TransportType; +import bisq.common.network.Address; +import bisq.common.network.TransportType; import bisq.network.identity.NetworkId; import bisq.network.p2p.message.EnvelopePayloadMessage; import bisq.network.p2p.node.CloseReason; @@ -116,6 +117,7 @@ public enum SupportedService { private final Set
seedNodeAddresses; @Getter private final TransportType transportType; + private final MemoryReportService memoryReportService; private final NetworkLoadSnapshot networkLoadSnapshot; @Getter @@ -158,7 +160,8 @@ public enum SupportedService { Optional resendMessageService, AuthorizationService authorizationService, Set
seedNodeAddresses, - TransportType transportType) { + TransportType transportType, + MemoryReportService memoryReportService) { this.config = config; this.nodeConfig = nodeConfig; this.peerGroupServiceConfig = peerGroupServiceConfig; @@ -168,6 +171,7 @@ public enum SupportedService { this.messageDeliveryStatusService = messageDeliveryStatusService; this.seedNodeAddresses = seedNodeAddresses; this.transportType = transportType; + this.memoryReportService = memoryReportService; this.networkLoadSnapshot = new NetworkLoadSnapshot(); @@ -249,7 +253,8 @@ Node getInitializedDefaultNode(NetworkId defaultNetworkId) { supportedServices.contains(ServiceNode.SupportedService.REPORT_RESPONSE) ? Optional.of(new ReportResponseService(defaultNode, dataService.orElseThrow(), - networkLoadSnapshot)) : + networkLoadSnapshot, + memoryReportService)) : Optional.empty(); networkLoadService = supportedServices.contains(ServiceNode.SupportedService.DATA) && diff --git a/network/network/src/main/java/bisq/network/p2p/ServiceNodesByTransport.java b/network/network/src/main/java/bisq/network/p2p/ServiceNodesByTransport.java index e63246726c..30c53f6d07 100644 --- a/network/network/src/main/java/bisq/network/p2p/ServiceNodesByTransport.java +++ b/network/network/src/main/java/bisq/network/p2p/ServiceNodesByTransport.java @@ -19,15 +19,16 @@ import bisq.common.data.Pair; +import bisq.common.network.Address; +import bisq.common.network.AddressByTransportTypeMap; +import bisq.common.network.TransportConfig; +import bisq.common.network.TransportType; import bisq.common.observable.Observable; +import bisq.common.platform.MemoryReportService; import bisq.common.threading.ThreadName; import bisq.common.util.CompletableFutureUtils; import bisq.common.util.StringUtils; import bisq.network.SendMessageResult; -import bisq.network.common.Address; -import bisq.network.common.AddressByTransportTypeMap; -import bisq.network.common.TransportConfig; -import bisq.network.common.TransportType; import bisq.network.identity.NetworkId; import bisq.network.p2p.message.EnvelopePayloadMessage; import bisq.network.p2p.node.Connection; @@ -88,7 +89,8 @@ public ServiceNodesByTransport(Map configByTrans EquihashProofOfWorkService equihashProofOfWorkService, Optional dataService, Optional messageDeliveryStatusService, - Optional resendMessageService) { + Optional resendMessageService, + MemoryReportService memoryReportService) { this.supportedTransportTypes = supportedTransportTypes; authorizationService = new AuthorizationService(authorizationServiceConfig, @@ -122,7 +124,8 @@ public ServiceNodesByTransport(Map configByTrans resendMessageService, authorizationService, seedAddresses, - transportType); + transportType, + memoryReportService); map.put(transportType, serviceNode); }); } @@ -183,8 +186,12 @@ public void addSeedNodes(Set seedNodeMaps) { } public void addSeedNode(AddressByTransportTypeMap seedNodeMap) { - supportedTransportTypes.forEach(transportType -> - map.get(transportType).addSeedNodeAddress(seedNodeMap.get(transportType))); + supportedTransportTypes.forEach(transportType -> { + if (seedNodeMap.containsKey(transportType)) { + Address seedNodeAddress = seedNodeMap.get(transportType); + map.get(transportType).addSeedNodeAddress(seedNodeAddress); + } + }); } public void removeSeedNode(AddressByTransportTypeMap seedNode) { diff --git a/network/network/src/main/java/bisq/network/p2p/node/Capability.java b/network/network/src/main/java/bisq/network/p2p/node/Capability.java index ec6edc4092..6c16e7219e 100644 --- a/network/network/src/main/java/bisq/network/p2p/node/Capability.java +++ b/network/network/src/main/java/bisq/network/p2p/node/Capability.java @@ -22,8 +22,8 @@ import bisq.common.proto.NetworkProto; import bisq.common.proto.ProtobufUtils; import bisq.common.validation.NetworkDataValidation; -import bisq.network.common.Address; -import bisq.network.common.TransportType; +import bisq.common.network.Address; +import bisq.common.network.TransportType; import com.google.common.annotations.VisibleForTesting; import lombok.EqualsAndHashCode; import lombok.Getter; diff --git a/network/network/src/main/java/bisq/network/p2p/node/Connection.java b/network/network/src/main/java/bisq/network/p2p/node/Connection.java index e887f0c501..b2c36dcdac 100644 --- a/network/network/src/main/java/bisq/network/p2p/node/Connection.java +++ b/network/network/src/main/java/bisq/network/p2p/node/Connection.java @@ -21,9 +21,9 @@ import bisq.common.util.ExceptionUtil; import bisq.common.util.StringUtils; import bisq.network.NetworkService; -import bisq.network.common.Address; -import bisq.network.common.DefaultPeerSocket; -import bisq.network.common.PeerSocket; +import bisq.common.network.Address; +import bisq.common.network.DefaultPeerSocket; +import bisq.common.network.PeerSocket; import bisq.network.p2p.message.EnvelopePayloadMessage; import bisq.network.p2p.message.NetworkEnvelope; import bisq.network.p2p.node.authorization.AuthorizationToken; diff --git a/network/network/src/main/java/bisq/network/p2p/node/ConnectionChannel.java b/network/network/src/main/java/bisq/network/p2p/node/ConnectionChannel.java index cda37bc412..485da2e3ac 100644 --- a/network/network/src/main/java/bisq/network/p2p/node/ConnectionChannel.java +++ b/network/network/src/main/java/bisq/network/p2p/node/ConnectionChannel.java @@ -19,7 +19,7 @@ import bisq.common.util.StringUtils; import bisq.network.NetworkService; -import bisq.network.common.Address; +import bisq.common.network.Address; import bisq.network.p2p.message.EnvelopePayloadMessage; import bisq.network.p2p.message.NetworkEnvelope; import bisq.network.p2p.node.authorization.AuthorizationToken; diff --git a/network/network/src/main/java/bisq/network/p2p/node/InboundConnectionsManager.java b/network/network/src/main/java/bisq/network/p2p/node/InboundConnectionsManager.java index 057f9b53a5..c2274f28e2 100644 --- a/network/network/src/main/java/bisq/network/p2p/node/InboundConnectionsManager.java +++ b/network/network/src/main/java/bisq/network/p2p/node/InboundConnectionsManager.java @@ -18,7 +18,7 @@ package bisq.network.p2p.node; import bisq.common.data.Pair; -import bisq.network.common.Address; +import bisq.common.network.Address; import bisq.network.p2p.message.NetworkEnvelope; import bisq.network.p2p.node.authorization.AuthorizationService; import bisq.network.p2p.node.envelope.NetworkEnvelopeSocketChannel; diff --git a/network/network/src/main/java/bisq/network/p2p/node/Node.java b/network/network/src/main/java/bisq/network/p2p/node/Node.java index 8a848d41f7..25392b8b52 100644 --- a/network/network/src/main/java/bisq/network/p2p/node/Node.java +++ b/network/network/src/main/java/bisq/network/p2p/node/Node.java @@ -25,9 +25,9 @@ import bisq.common.util.ExceptionUtil; import bisq.common.util.StringUtils; import bisq.network.NetworkService; -import bisq.network.common.Address; -import bisq.network.common.TransportConfig; -import bisq.network.common.TransportType; +import bisq.common.network.Address; +import bisq.common.network.TransportConfig; +import bisq.common.network.TransportType; import bisq.network.identity.NetworkId; import bisq.network.p2p.message.EnvelopePayloadMessage; import bisq.network.p2p.node.authorization.AuthorizationService; diff --git a/network/network/src/main/java/bisq/network/p2p/node/NodesById.java b/network/network/src/main/java/bisq/network/p2p/node/NodesById.java index c317eb8385..fd7939a277 100644 --- a/network/network/src/main/java/bisq/network/p2p/node/NodesById.java +++ b/network/network/src/main/java/bisq/network/p2p/node/NodesById.java @@ -19,7 +19,7 @@ import bisq.common.util.CompletableFutureUtils; -import bisq.network.common.Address; +import bisq.common.network.Address; import bisq.network.identity.NetworkId; import bisq.network.p2p.message.EnvelopePayloadMessage; import bisq.network.p2p.node.authorization.AuthorizationService; diff --git a/network/network/src/main/java/bisq/network/p2p/node/OutboundConnection.java b/network/network/src/main/java/bisq/network/p2p/node/OutboundConnection.java index 223d79c222..0eccf93978 100644 --- a/network/network/src/main/java/bisq/network/p2p/node/OutboundConnection.java +++ b/network/network/src/main/java/bisq/network/p2p/node/OutboundConnection.java @@ -17,7 +17,7 @@ package bisq.network.p2p.node; -import bisq.network.common.Address; +import bisq.common.network.Address; import bisq.network.p2p.node.network_load.ConnectionMetrics; import bisq.network.p2p.node.network_load.NetworkLoadSnapshot; import lombok.Getter; diff --git a/network/network/src/main/java/bisq/network/p2p/node/OutboundConnectionChannel.java b/network/network/src/main/java/bisq/network/p2p/node/OutboundConnectionChannel.java index fe02c931f1..accc763bfc 100644 --- a/network/network/src/main/java/bisq/network/p2p/node/OutboundConnectionChannel.java +++ b/network/network/src/main/java/bisq/network/p2p/node/OutboundConnectionChannel.java @@ -17,7 +17,7 @@ package bisq.network.p2p.node; -import bisq.network.common.Address; +import bisq.common.network.Address; import bisq.network.p2p.node.envelope.NetworkEnvelopeSocketChannel; import bisq.network.p2p.node.network_load.ConnectionMetrics; import bisq.network.p2p.node.network_load.NetworkLoadSnapshot; diff --git a/network/network/src/main/java/bisq/network/p2p/node/OutboundConnectionManager.java b/network/network/src/main/java/bisq/network/p2p/node/OutboundConnectionManager.java index 663c710cff..2cfafb1d1b 100644 --- a/network/network/src/main/java/bisq/network/p2p/node/OutboundConnectionManager.java +++ b/network/network/src/main/java/bisq/network/p2p/node/OutboundConnectionManager.java @@ -17,7 +17,7 @@ package bisq.network.p2p.node; -import bisq.network.common.Address; +import bisq.common.network.Address; import bisq.network.p2p.message.NetworkEnvelope; import bisq.network.p2p.node.authorization.AuthorizationService; import bisq.network.p2p.node.envelope.NetworkEnvelopeSocketChannel; diff --git a/network/network/src/main/java/bisq/network/p2p/node/OutboundConnectionMultiplexer.java b/network/network/src/main/java/bisq/network/p2p/node/OutboundConnectionMultiplexer.java index 48a4eaa49c..4d79b7043e 100644 --- a/network/network/src/main/java/bisq/network/p2p/node/OutboundConnectionMultiplexer.java +++ b/network/network/src/main/java/bisq/network/p2p/node/OutboundConnectionMultiplexer.java @@ -18,7 +18,7 @@ package bisq.network.p2p.node; import bisq.common.threading.ThreadName; -import bisq.network.common.Address; +import bisq.common.network.Address; import lombok.extern.slf4j.Slf4j; import java.io.IOException; diff --git a/network/network/src/main/java/bisq/network/p2p/node/PeerConnectionsManager.java b/network/network/src/main/java/bisq/network/p2p/node/PeerConnectionsManager.java index bdba020ee7..c950b20eb9 100644 --- a/network/network/src/main/java/bisq/network/p2p/node/PeerConnectionsManager.java +++ b/network/network/src/main/java/bisq/network/p2p/node/PeerConnectionsManager.java @@ -17,8 +17,8 @@ package bisq.network.p2p.node; -import bisq.network.common.Address; -import bisq.network.common.TransportType; +import bisq.common.network.Address; +import bisq.common.network.TransportType; import bisq.network.identity.NetworkId; import bisq.network.p2p.node.authorization.AuthorizationService; import bisq.network.p2p.node.network_load.NetworkLoad; diff --git a/network/network/src/main/java/bisq/network/p2p/node/Server.java b/network/network/src/main/java/bisq/network/p2p/node/Server.java index 6a8c7d1930..f562f0546c 100644 --- a/network/network/src/main/java/bisq/network/p2p/node/Server.java +++ b/network/network/src/main/java/bisq/network/p2p/node/Server.java @@ -20,7 +20,7 @@ import bisq.common.threading.ThreadName; import bisq.common.util.StringUtils; import bisq.network.NetworkService; -import bisq.network.common.Address; +import bisq.common.network.Address; import bisq.network.p2p.node.transport.ServerSocketResult; import lombok.Getter; import lombok.extern.slf4j.Slf4j; diff --git a/network/network/src/main/java/bisq/network/p2p/node/ServerChannel.java b/network/network/src/main/java/bisq/network/p2p/node/ServerChannel.java index 1ad9cedcc8..cf25c44eaa 100644 --- a/network/network/src/main/java/bisq/network/p2p/node/ServerChannel.java +++ b/network/network/src/main/java/bisq/network/p2p/node/ServerChannel.java @@ -18,7 +18,7 @@ package bisq.network.p2p.node; import bisq.common.threading.ThreadName; -import bisq.network.common.Address; +import bisq.common.network.Address; import bisq.network.p2p.node.authorization.AuthorizationService; import bisq.network.p2p.node.network_load.NetworkLoad; import bisq.network.p2p.services.peer_group.BanList; diff --git a/network/network/src/main/java/bisq/network/p2p/node/envelope/NetworkEnvelopeSocket.java b/network/network/src/main/java/bisq/network/p2p/node/envelope/NetworkEnvelopeSocket.java index 7da9697518..cb9f7a4e2a 100644 --- a/network/network/src/main/java/bisq/network/p2p/node/envelope/NetworkEnvelopeSocket.java +++ b/network/network/src/main/java/bisq/network/p2p/node/envelope/NetworkEnvelopeSocket.java @@ -17,7 +17,7 @@ package bisq.network.p2p.node.envelope; -import bisq.network.common.PeerSocket; +import bisq.common.network.PeerSocket; import bisq.network.p2p.message.NetworkEnvelope; import lombok.extern.slf4j.Slf4j; diff --git a/network/network/src/main/java/bisq/network/p2p/node/handshake/ConnectionHandshake.java b/network/network/src/main/java/bisq/network/p2p/node/handshake/ConnectionHandshake.java index 8c2c5e2b5b..6b584c854d 100644 --- a/network/network/src/main/java/bisq/network/p2p/node/handshake/ConnectionHandshake.java +++ b/network/network/src/main/java/bisq/network/p2p/node/handshake/ConnectionHandshake.java @@ -19,9 +19,9 @@ import bisq.common.encoding.Hex; import bisq.common.util.StringUtils; -import bisq.network.common.Address; -import bisq.network.common.DefaultPeerSocket; -import bisq.network.common.PeerSocket; +import bisq.common.network.Address; +import bisq.common.network.DefaultPeerSocket; +import bisq.common.network.PeerSocket; import bisq.network.p2p.message.EnvelopePayloadMessage; import bisq.network.p2p.message.NetworkEnvelope; import bisq.network.p2p.node.Capability; diff --git a/network/network/src/main/java/bisq/network/p2p/node/handshake/ConnectionHandshakeInitiator.java b/network/network/src/main/java/bisq/network/p2p/node/handshake/ConnectionHandshakeInitiator.java index f3c2138b49..c35f2141a1 100644 --- a/network/network/src/main/java/bisq/network/p2p/node/handshake/ConnectionHandshakeInitiator.java +++ b/network/network/src/main/java/bisq/network/p2p/node/handshake/ConnectionHandshakeInitiator.java @@ -18,9 +18,9 @@ package bisq.network.p2p.node.handshake; import bisq.common.util.StringUtils; -import bisq.network.common.Address; -import bisq.network.common.AddressOwnershipProof; -import bisq.network.common.AddressOwnershipProofGenerator; +import bisq.common.network.Address; +import bisq.common.network.AddressOwnershipProof; +import bisq.common.network.AddressOwnershipProofGenerator; import bisq.network.p2p.message.NetworkEnvelope; import bisq.network.p2p.node.Capability; import bisq.network.p2p.node.ConnectionException; diff --git a/network/network/src/main/java/bisq/network/p2p/node/handshake/ConnectionHandshakeResponder.java b/network/network/src/main/java/bisq/network/p2p/node/handshake/ConnectionHandshakeResponder.java index 87029655ca..ec53605f5e 100644 --- a/network/network/src/main/java/bisq/network/p2p/node/handshake/ConnectionHandshakeResponder.java +++ b/network/network/src/main/java/bisq/network/p2p/node/handshake/ConnectionHandshakeResponder.java @@ -20,7 +20,7 @@ import bisq.common.data.Pair; import bisq.common.encoding.Hex; import bisq.common.util.StringUtils; -import bisq.network.common.Address; +import bisq.common.network.Address; import bisq.network.p2p.message.NetworkEnvelope; import bisq.network.p2p.node.Capability; import bisq.network.p2p.node.ConnectionException; diff --git a/network/network/src/main/java/bisq/network/p2p/node/handshake/OnionAddressValidation.java b/network/network/src/main/java/bisq/network/p2p/node/handshake/OnionAddressValidation.java index 4b953d7e2c..aebbc87ff5 100644 --- a/network/network/src/main/java/bisq/network/p2p/node/handshake/OnionAddressValidation.java +++ b/network/network/src/main/java/bisq/network/p2p/node/handshake/OnionAddressValidation.java @@ -1,6 +1,6 @@ package bisq.network.p2p.node.handshake; -import bisq.network.common.Address; +import bisq.common.network.Address; import bisq.security.TorSignatureUtil; import bisq.security.keys.TorKeyUtils; import lombok.extern.slf4j.Slf4j; diff --git a/network/network/src/main/java/bisq/network/p2p/node/transport/ClearNetTransportService.java b/network/network/src/main/java/bisq/network/p2p/node/transport/ClearNetTransportService.java index afa35d7796..d17679f1cb 100644 --- a/network/network/src/main/java/bisq/network/p2p/node/transport/ClearNetTransportService.java +++ b/network/network/src/main/java/bisq/network/p2p/node/transport/ClearNetTransportService.java @@ -1,9 +1,9 @@ package bisq.network.p2p.node.transport; +import bisq.common.network.Address; +import bisq.common.network.TransportConfig; +import bisq.common.network.TransportType; import bisq.common.timer.Scheduler; -import bisq.network.common.Address; -import bisq.network.common.TransportConfig; -import bisq.network.common.TransportType; import bisq.network.identity.NetworkId; import bisq.security.keys.KeyBundle; import lombok.EqualsAndHashCode; @@ -12,6 +12,7 @@ import lombok.extern.slf4j.Slf4j; import java.io.IOException; +import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.nio.file.Path; @@ -19,6 +20,8 @@ import java.util.concurrent.CompletionException; import java.util.concurrent.TimeUnit; +import static bisq.common.facades.FacadeProvider.getLocalhostFacade; + @Slf4j public class ClearNetTransportService implements TransportService { @@ -35,7 +38,8 @@ public static Config from(Path dataDir, com.typesafe.config.Config config) { (int) TimeUnit.SECONDS.toMillis(config.getInt("userNodeSocketTimeout")), config.getInt("devModeDelayInMs"), config.getInt("sendMessageThrottleTime"), - config.getInt("receiveMessageThrottleTime") + config.getInt("receiveMessageThrottleTime"), + config.getInt("connectTimeoutMs") ); } @@ -46,6 +50,7 @@ public static Config from(Path dataDir, com.typesafe.config.Config config) { private final int devModeDelayInMs; private final int sendMessageThrottleTime; private final int receiveMessageThrottleTime; + private final int connectTimeoutMs; public Config(Path dataDir, int defaultNodePort, @@ -53,7 +58,8 @@ public Config(Path dataDir, int userNodeSocketTimeout, int devModeDelayInMs, int sendMessageThrottleTime, - int receiveMessageThrottleTime) { + int receiveMessageThrottleTime, + int connectTimeoutMs) { this.dataDir = dataDir; this.defaultNodePort = defaultNodePort; this.defaultNodeSocketTimeout = defaultNodeSocketTimeout; @@ -61,10 +67,12 @@ public Config(Path dataDir, this.devModeDelayInMs = devModeDelayInMs; this.sendMessageThrottleTime = sendMessageThrottleTime; this.receiveMessageThrottleTime = receiveMessageThrottleTime; + this.connectTimeoutMs = connectTimeoutMs; } } private final int devModeDelayInMs; + private final int connectTimeoutMs; private int numSocketsCreated = 0; @Getter private final BootstrapInfo bootstrapInfo = new BootstrapInfo(); @@ -73,6 +81,7 @@ public Config(Path dataDir, public ClearNetTransportService(TransportConfig config) { devModeDelayInMs = config.getDevModeDelayInMs(); + connectTimeoutMs = ((Config) config).getConnectTimeoutMs(); } @Override @@ -115,14 +124,14 @@ public ServerSocketResult getServerSocket(NetworkId networkId, KeyBundle keyBund maybeSimulateDelay(); try { ServerSocket serverSocket = new ServerSocket(port); - Address address = Address.localHost(port); + Address myAddress = getLocalhostFacade().toMyLocalhost(port); log.debug("ServerSocket created at port {}", port); bootstrapInfo.getBootstrapState().set(BootstrapState.SERVICE_PUBLISHED); bootstrapInfo.getBootstrapProgress().set(0.5); - bootstrapInfo.getBootstrapDetails().set("Server created: " + address); + bootstrapInfo.getBootstrapDetails().set("Server created: " + myAddress); - return new ServerSocketResult(serverSocket, address); + return new ServerSocketResult(serverSocket, myAddress); } catch (IOException e) { log.error("{}. Server port {}", e, port); throw new CompletionException(e); @@ -131,9 +140,13 @@ public ServerSocketResult getServerSocket(NetworkId networkId, KeyBundle keyBund @Override public Socket getSocket(Address address) throws IOException { + address = getLocalhostFacade().toPeersLocalhost(address); + log.debug("Create new Socket to {}", address); maybeSimulateDelay(); - Socket socket = new Socket(address.getHost(), address.getPort()); + Socket socket = new Socket(); + socket.connect(new InetSocketAddress(address.getHost(), address.getPort()), connectTimeoutMs); + numSocketsCreated++; bootstrapInfo.getBootstrapState().set(BootstrapState.CONNECTED_TO_PEERS); diff --git a/network/network/src/main/java/bisq/network/p2p/node/transport/I2PTransportService.java b/network/network/src/main/java/bisq/network/p2p/node/transport/I2PTransportService.java index 5d6bc8f4d5..a42939044b 100644 --- a/network/network/src/main/java/bisq/network/p2p/node/transport/I2PTransportService.java +++ b/network/network/src/main/java/bisq/network/p2p/node/transport/I2PTransportService.java @@ -5,9 +5,9 @@ import bisq.i2p.I2pClient; import bisq.i2p.I2pEmbeddedRouter; import bisq.network.NetworkService; -import bisq.network.common.Address; -import bisq.network.common.TransportConfig; -import bisq.network.common.TransportType; +import bisq.common.network.Address; +import bisq.common.network.TransportConfig; +import bisq.common.network.TransportType; import bisq.network.identity.NetworkId; import bisq.network.p2p.node.ConnectionException; import bisq.security.keys.KeyBundle; diff --git a/network/network/src/main/java/bisq/network/p2p/node/transport/ServerSocketResult.java b/network/network/src/main/java/bisq/network/p2p/node/transport/ServerSocketResult.java index 94a40fda4b..52411a5cbb 100644 --- a/network/network/src/main/java/bisq/network/p2p/node/transport/ServerSocketResult.java +++ b/network/network/src/main/java/bisq/network/p2p/node/transport/ServerSocketResult.java @@ -17,7 +17,7 @@ package bisq.network.p2p.node.transport; -import bisq.network.common.Address; +import bisq.common.network.Address; import bisq.tor.onionservice.CreateOnionServiceResponse; import lombok.EqualsAndHashCode; import lombok.Getter; diff --git a/network/network/src/main/java/bisq/network/p2p/node/transport/TorTransportService.java b/network/network/src/main/java/bisq/network/p2p/node/transport/TorTransportService.java index b860c3b6cd..7366e6cb3b 100644 --- a/network/network/src/main/java/bisq/network/p2p/node/transport/TorTransportService.java +++ b/network/network/src/main/java/bisq/network/p2p/node/transport/TorTransportService.java @@ -1,9 +1,9 @@ package bisq.network.p2p.node.transport; import bisq.common.timer.Scheduler; -import bisq.network.common.Address; -import bisq.network.common.TransportConfig; -import bisq.network.common.TransportType; +import bisq.common.network.Address; +import bisq.common.network.TransportConfig; +import bisq.common.network.TransportType; import bisq.network.identity.NetworkId; import bisq.network.p2p.node.ConnectionException; import bisq.security.keys.KeyBundle; diff --git a/network/network/src/main/java/bisq/network/p2p/node/transport/TransportService.java b/network/network/src/main/java/bisq/network/p2p/node/transport/TransportService.java index 397b77c6fd..8461a63d67 100644 --- a/network/network/src/main/java/bisq/network/p2p/node/transport/TransportService.java +++ b/network/network/src/main/java/bisq/network/p2p/node/transport/TransportService.java @@ -17,9 +17,9 @@ package bisq.network.p2p.node.transport; -import bisq.network.common.Address; -import bisq.network.common.TransportConfig; -import bisq.network.common.TransportType; +import bisq.common.network.Address; +import bisq.common.network.TransportConfig; +import bisq.common.network.TransportType; import bisq.network.identity.NetworkId; import bisq.security.keys.KeyBundle; import com.runjva.sourceforge.jsocks.protocol.Socks5Proxy; diff --git a/network/network/src/main/java/bisq/network/p2p/node/transport/socket_channel/ClearNetSocketChannelFactory.java b/network/network/src/main/java/bisq/network/p2p/node/transport/socket_channel/ClearNetSocketChannelFactory.java index 764a3f8449..d9df09ddbd 100644 --- a/network/network/src/main/java/bisq/network/p2p/node/transport/socket_channel/ClearNetSocketChannelFactory.java +++ b/network/network/src/main/java/bisq/network/p2p/node/transport/socket_channel/ClearNetSocketChannelFactory.java @@ -17,7 +17,7 @@ package bisq.network.p2p.node.transport.socket_channel; -import bisq.network.common.Address; +import bisq.common.network.Address; import java.io.IOException; import java.nio.channels.SocketChannel; diff --git a/network/network/src/main/java/bisq/network/p2p/node/transport/socket_channel/SocketChannelFactory.java b/network/network/src/main/java/bisq/network/p2p/node/transport/socket_channel/SocketChannelFactory.java index 0a822dc7f8..56e78eb683 100644 --- a/network/network/src/main/java/bisq/network/p2p/node/transport/socket_channel/SocketChannelFactory.java +++ b/network/network/src/main/java/bisq/network/p2p/node/transport/socket_channel/SocketChannelFactory.java @@ -17,7 +17,7 @@ package bisq.network.p2p.node.transport.socket_channel; -import bisq.network.common.Address; +import bisq.common.network.Address; import java.io.IOException; import java.nio.channels.SocketChannel; diff --git a/network/network/src/main/java/bisq/network/p2p/node/transport/socket_channel/TorSocketChannelFactory.java b/network/network/src/main/java/bisq/network/p2p/node/transport/socket_channel/TorSocketChannelFactory.java index a59e65735a..ced94a7a63 100644 --- a/network/network/src/main/java/bisq/network/p2p/node/transport/socket_channel/TorSocketChannelFactory.java +++ b/network/network/src/main/java/bisq/network/p2p/node/transport/socket_channel/TorSocketChannelFactory.java @@ -17,7 +17,7 @@ package bisq.network.p2p.node.transport.socket_channel; -import bisq.network.common.Address; +import bisq.common.network.Address; import bisq.tor.nio.TorSocketChannel; import bisq.tor.nio.TorSocksConnectionData; diff --git a/network/network/src/main/java/bisq/network/p2p/services/confidential/ConfidentialMessageService.java b/network/network/src/main/java/bisq/network/p2p/services/confidential/ConfidentialMessageService.java index b834ce8f16..ee37c0f57b 100644 --- a/network/network/src/main/java/bisq/network/p2p/services/confidential/ConfidentialMessageService.java +++ b/network/network/src/main/java/bisq/network/p2p/services/confidential/ConfidentialMessageService.java @@ -20,7 +20,7 @@ import bisq.common.threading.ExecutorFactory; import bisq.common.threading.ThreadName; import bisq.common.util.CompletableFutureUtils; -import bisq.network.common.Address; +import bisq.common.network.Address; import bisq.network.identity.NetworkId; import bisq.network.p2p.message.EnvelopePayloadMessage; import bisq.network.p2p.node.CloseReason; diff --git a/network/network/src/main/java/bisq/network/p2p/services/peer_group/BanList.java b/network/network/src/main/java/bisq/network/p2p/services/peer_group/BanList.java index d72c37886a..ee21a03b5f 100644 --- a/network/network/src/main/java/bisq/network/p2p/services/peer_group/BanList.java +++ b/network/network/src/main/java/bisq/network/p2p/services/peer_group/BanList.java @@ -17,7 +17,7 @@ package bisq.network.p2p.services.peer_group; -import bisq.network.common.Address; +import bisq.common.network.Address; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.ToString; diff --git a/network/network/src/main/java/bisq/network/p2p/services/peer_group/Peer.java b/network/network/src/main/java/bisq/network/p2p/services/peer_group/Peer.java index ed2ca2ffb3..38a69fc9da 100644 --- a/network/network/src/main/java/bisq/network/p2p/services/peer_group/Peer.java +++ b/network/network/src/main/java/bisq/network/p2p/services/peer_group/Peer.java @@ -20,7 +20,7 @@ import bisq.common.annotation.ExcludeForHash; import bisq.common.proto.NetworkProto; import bisq.common.validation.NetworkDataValidation; -import bisq.network.common.Address; +import bisq.common.network.Address; import bisq.network.p2p.node.Capability; import bisq.network.p2p.node.network_load.NetworkLoad; import lombok.EqualsAndHashCode; diff --git a/network/network/src/main/java/bisq/network/p2p/services/peer_group/PeerGroupManager.java b/network/network/src/main/java/bisq/network/p2p/services/peer_group/PeerGroupManager.java index 31d0170cff..c0eeb3d167 100644 --- a/network/network/src/main/java/bisq/network/p2p/services/peer_group/PeerGroupManager.java +++ b/network/network/src/main/java/bisq/network/p2p/services/peer_group/PeerGroupManager.java @@ -20,7 +20,7 @@ import bisq.common.timer.Scheduler; import bisq.common.util.StringUtils; import bisq.network.NetworkService; -import bisq.network.common.Address; +import bisq.common.network.Address; import bisq.network.identity.NetworkId; import bisq.network.p2p.message.EnvelopePayloadMessage; import bisq.network.p2p.node.CloseReason; diff --git a/network/network/src/main/java/bisq/network/p2p/services/peer_group/PeerGroupService.java b/network/network/src/main/java/bisq/network/p2p/services/peer_group/PeerGroupService.java index ca6d50160b..cff3cdd48d 100644 --- a/network/network/src/main/java/bisq/network/p2p/services/peer_group/PeerGroupService.java +++ b/network/network/src/main/java/bisq/network/p2p/services/peer_group/PeerGroupService.java @@ -17,10 +17,10 @@ package bisq.network.p2p.services.peer_group; +import bisq.common.network.Address; +import bisq.common.network.TransportType; import bisq.common.util.CollectionUtil; import bisq.common.util.StringUtils; -import bisq.network.common.Address; -import bisq.network.common.TransportType; import bisq.network.p2p.node.Connection; import bisq.network.p2p.node.Node; import bisq.persistence.DbSubDirectory; @@ -268,7 +268,9 @@ public int getTargetNumConnectedPeers() { /////////////////////////////////////////////////////////////////////////////////////////////////// public void addSeedNodeAddress(Address seedNodeAddress) { - this.seedNodeAddresses.add(seedNodeAddress); + if (seedNodeAddress != null) { + this.seedNodeAddresses.add(seedNodeAddress); + } } public void removeSeedNodeAddress(Address seedNodeAddress) { diff --git a/network/network/src/main/java/bisq/network/p2p/services/peer_group/PeerGroupStore.java b/network/network/src/main/java/bisq/network/p2p/services/peer_group/PeerGroupStore.java index a355ece9e7..5fd386750c 100644 --- a/network/network/src/main/java/bisq/network/p2p/services/peer_group/PeerGroupStore.java +++ b/network/network/src/main/java/bisq/network/p2p/services/peer_group/PeerGroupStore.java @@ -19,7 +19,7 @@ import bisq.common.proto.ProtoResolver; import bisq.common.proto.UnresolvableProtobufMessageException; -import bisq.network.common.Address; +import bisq.common.network.Address; import bisq.persistence.PersistableStore; import com.google.protobuf.InvalidProtocolBufferException; import lombok.extern.slf4j.Slf4j; diff --git a/network/network/src/main/java/bisq/network/p2p/services/peer_group/exchange/PeerExchangeAttempt.java b/network/network/src/main/java/bisq/network/p2p/services/peer_group/exchange/PeerExchangeAttempt.java index 309ecb69e4..967c0851fa 100644 --- a/network/network/src/main/java/bisq/network/p2p/services/peer_group/exchange/PeerExchangeAttempt.java +++ b/network/network/src/main/java/bisq/network/p2p/services/peer_group/exchange/PeerExchangeAttempt.java @@ -20,7 +20,7 @@ import bisq.common.observable.Observable; import bisq.common.threading.ThreadName; import bisq.common.util.ExceptionUtil; -import bisq.network.common.Address; +import bisq.common.network.Address; import bisq.network.p2p.node.Connection; import bisq.network.p2p.node.Node; import bisq.network.p2p.services.peer_group.Peer; diff --git a/network/network/src/main/java/bisq/network/p2p/services/peer_group/exchange/PeerExchangeService.java b/network/network/src/main/java/bisq/network/p2p/services/peer_group/exchange/PeerExchangeService.java index 2d10f25468..01f8cba1f1 100644 --- a/network/network/src/main/java/bisq/network/p2p/services/peer_group/exchange/PeerExchangeService.java +++ b/network/network/src/main/java/bisq/network/p2p/services/peer_group/exchange/PeerExchangeService.java @@ -20,7 +20,7 @@ import bisq.common.observable.Pin; import bisq.common.threading.ThreadName; import bisq.common.util.ExceptionUtil; -import bisq.network.common.Address; +import bisq.common.network.Address; import bisq.network.identity.NetworkId; import bisq.network.p2p.message.EnvelopePayloadMessage; import bisq.network.p2p.node.CloseReason; diff --git a/network/network/src/main/java/bisq/network/p2p/services/peer_group/exchange/PeerExchangeStrategy.java b/network/network/src/main/java/bisq/network/p2p/services/peer_group/exchange/PeerExchangeStrategy.java index 57f9f4ad68..55d5ab6acd 100644 --- a/network/network/src/main/java/bisq/network/p2p/services/peer_group/exchange/PeerExchangeStrategy.java +++ b/network/network/src/main/java/bisq/network/p2p/services/peer_group/exchange/PeerExchangeStrategy.java @@ -18,7 +18,7 @@ package bisq.network.p2p.services.peer_group.exchange; import bisq.common.util.CollectionUtil; -import bisq.network.common.Address; +import bisq.common.network.Address; import bisq.network.p2p.node.Node; import bisq.network.p2p.services.peer_group.Peer; import bisq.network.p2p.services.peer_group.PeerGroupService; diff --git a/network/network/src/main/java/bisq/network/p2p/services/reporting/ReportRequestService.java b/network/network/src/main/java/bisq/network/p2p/services/reporting/ReportRequestService.java index a39c4b77f8..5bdd6e8e2d 100644 --- a/network/network/src/main/java/bisq/network/p2p/services/reporting/ReportRequestService.java +++ b/network/network/src/main/java/bisq/network/p2p/services/reporting/ReportRequestService.java @@ -17,7 +17,7 @@ package bisq.network.p2p.services.reporting; -import bisq.network.common.Address; +import bisq.common.network.Address; import bisq.network.identity.NetworkId; import bisq.network.p2p.message.EnvelopePayloadMessage; import bisq.network.p2p.node.CloseReason; diff --git a/network/network/src/main/java/bisq/network/p2p/services/reporting/ReportResponseService.java b/network/network/src/main/java/bisq/network/p2p/services/reporting/ReportResponseService.java index c806095b02..3fb80ccb46 100644 --- a/network/network/src/main/java/bisq/network/p2p/services/reporting/ReportResponseService.java +++ b/network/network/src/main/java/bisq/network/p2p/services/reporting/ReportResponseService.java @@ -17,7 +17,7 @@ package bisq.network.p2p.services.reporting; -import bisq.common.platform.MemoryReport; +import bisq.common.platform.MemoryReportService; import bisq.common.threading.ThreadName; import bisq.network.NetworkService; import bisq.network.identity.NetworkId; @@ -43,13 +43,16 @@ public class ReportResponseService implements Node.Listener { private final Node node; private final DataService dataService; private final NetworkLoadSnapshot networkLoadSnapshot; + private final MemoryReportService memoryReportService; public ReportResponseService(Node node, DataService dataService, - NetworkLoadSnapshot networkLoadSnapshot) { + NetworkLoadSnapshot networkLoadSnapshot, + MemoryReportService memoryReportService) { this.node = node; this.dataService = dataService; this.networkLoadSnapshot = networkLoadSnapshot; + this.memoryReportService = memoryReportService; node.addListener(this); } @@ -112,7 +115,7 @@ private Report createStorageReport() { int numConnections = node.getNumConnections(); - int memoryUsed = (int) MemoryReport.getUsedMemoryInMB(); + int memoryUsed = (int) memoryReportService.getUsedMemoryInMB(); int numThreads = Thread.activeCount(); double nodeLoad = networkLoadSnapshot.getCurrentNetworkLoad().getLoad(); diff --git a/network/network/src/main/proto/network.proto b/network/network/src/main/proto/network.proto index 55adf5aee8..0f82d0fe12 100644 --- a/network/network/src/main/proto/network.proto +++ b/network/network/src/main/proto/network.proto @@ -3,7 +3,6 @@ package network; option java_package = "bisq.network.protobuf"; option java_multiple_files = true; import "common.proto"; -import "network_common.proto"; import "network_identity.proto"; import "security.proto"; import "google/protobuf/any.proto"; @@ -26,7 +25,7 @@ enum Feature { } message Capability { - network.common.Address address = 1; + common.Address address = 1; repeated string supportedTransportTypes = 2; repeated Feature features = 3; sint32 version = 4; @@ -342,7 +341,7 @@ message DataStore { } message NetworkServiceStore { - repeated network.common.AddressByTransportTypeMap seedNodes = 1; + repeated common.AddressByTransportTypeMap seedNodes = 1; map networkIdByTag = 2 [deprecated = true]; // Moved to NetworkIdStore } diff --git a/network/network/src/test/java/bisq/network/p2p/ConnectionHandshakeResponderTest.java b/network/network/src/test/java/bisq/network/p2p/ConnectionHandshakeResponderTest.java index f77b17bf11..8d09e1327e 100644 --- a/network/network/src/test/java/bisq/network/p2p/ConnectionHandshakeResponderTest.java +++ b/network/network/src/test/java/bisq/network/p2p/ConnectionHandshakeResponderTest.java @@ -19,8 +19,9 @@ import bisq.common.application.ApplicationVersion; import bisq.common.file.FileUtils; -import bisq.network.common.Address; -import bisq.network.common.TransportType; +import bisq.common.network.Address; +import bisq.common.network.DefaultLocalhostFacade; +import bisq.common.network.TransportType; import bisq.network.p2p.message.NetworkEnvelope; import bisq.network.p2p.node.Capability; import bisq.network.p2p.node.ConnectionException; @@ -57,7 +58,7 @@ public class ConnectionHandshakeResponderTest { public ConnectionHandshakeResponderTest() throws IOException { supportedTransportTypes.add(TransportType.CLEAR); - this.responderCapability = createCapability(Address.localHost(1234), supportedTransportTypes); + this.responderCapability = createCapability(DefaultLocalhostFacade.toLocalHostAddress(1234), supportedTransportTypes); this.authorizationService = createAuthorizationService(); this.handshakeResponder = new ConnectionHandshakeResponder( banList, @@ -98,7 +99,7 @@ void wrongEnvelopeVersion() throws IOException { ConnectionHandshake.Request request = new ConnectionHandshake.Request(responderCapability, Optional.empty(), new NetworkLoad(), 0); AuthorizationToken token = authorizationService.createToken(request, new NetworkLoad(), - Address.localHost(1234).toString(), + DefaultLocalhostFacade.toLocalHostAddress(1234).toString(), 0, new ArrayList<>()); NetworkEnvelope requestNetworkEnvelope = new NetworkEnvelope(NetworkEnvelope.networkVersion + 1000, token, request); List allEnvelopesToReceive = List.of(requestNetworkEnvelope); @@ -113,7 +114,7 @@ void wrongNetworkMessage() throws IOException { AuthorizationToken token = authorizationService.createToken( response, new NetworkLoad(), - Address.localHost(1234).toString(), + DefaultLocalhostFacade.toLocalHostAddress(1234).toString(), 0, new ArrayList<>()); NetworkEnvelope responseEnvelope = new NetworkEnvelope(token, response); List allEnvelopesToReceive = List.of(responseEnvelope); @@ -131,13 +132,13 @@ void bannedPeer() throws IOException { ConnectionHandshake.Request request = new ConnectionHandshake.Request(responderCapability, Optional.empty(), new NetworkLoad(), 0); AuthorizationToken token = authorizationService.createToken(request, new NetworkLoad(), - Address.localHost(1234).toString(), + DefaultLocalhostFacade.toLocalHostAddress(1234).toString(), 0, new ArrayList<>()); NetworkEnvelope requestNetworkEnvelope = new NetworkEnvelope(token, request); List allEnvelopesToReceive = List.of(requestNetworkEnvelope); when(networkEnvelopeSocketChannel.receiveNetworkEnvelopes()).thenReturn(allEnvelopesToReceive); - when(banList.isBanned(Address.localHost(1234))).thenReturn(true); + when(banList.isBanned(DefaultLocalhostFacade.toLocalHostAddress(1234))).thenReturn(true); ConnectionException exception = assertThrows(ConnectionException.class, handshakeResponder::verifyAndBuildRespond); assertEquals(exception.getReason(), ConnectionException.Reason.ADDRESS_BANNED); @@ -148,7 +149,7 @@ void invalidPoW() throws IOException { ConnectionHandshake.Request request = new ConnectionHandshake.Request(responderCapability, Optional.empty(), new NetworkLoad(), 0); AuthorizationToken token = authorizationService.createToken(request, new NetworkLoad(), - Address.localHost(1234).toString(), + DefaultLocalhostFacade.toLocalHostAddress(1234).toString(), 5, new ArrayList<>()); NetworkEnvelope requestNetworkEnvelope = new NetworkEnvelope(token, request); List allEnvelopesToReceive = List.of(requestNetworkEnvelope); @@ -163,7 +164,7 @@ void invalidPoW() throws IOException { @Test void correctPoW() throws IOException { - Capability peerCapability = createCapability(Address.localHost(2345), supportedTransportTypes); + Capability peerCapability = createCapability(DefaultLocalhostFacade.toLocalHostAddress(2345), supportedTransportTypes); ConnectionHandshake.Request request = new ConnectionHandshake.Request(peerCapability, Optional.empty(), new NetworkLoad(), 0); AuthorizationToken token = authorizationService.createToken(request, new NetworkLoad(), @@ -181,7 +182,7 @@ void correctPoW() throws IOException { } private NetworkEnvelope createValidRequest() { - Capability peerCapability = createCapability(Address.localHost(2345), supportedTransportTypes); + Capability peerCapability = createCapability(DefaultLocalhostFacade.toLocalHostAddress(2345), supportedTransportTypes); ConnectionHandshake.Request request = new ConnectionHandshake.Request(peerCapability, Optional.empty(), new NetworkLoad(), 0); AuthorizationToken token = authorizationService.createToken(request, new NetworkLoad(), diff --git a/network/network/src/test/java/bisq/network/p2p/InboundConnectionsManagerTests.java b/network/network/src/test/java/bisq/network/p2p/InboundConnectionsManagerTests.java index 17dce05996..e9a9a41853 100644 --- a/network/network/src/test/java/bisq/network/p2p/InboundConnectionsManagerTests.java +++ b/network/network/src/test/java/bisq/network/p2p/InboundConnectionsManagerTests.java @@ -19,9 +19,10 @@ import bisq.common.application.ApplicationVersion; import bisq.common.file.FileUtils; +import bisq.common.network.DefaultLocalhostFacade; import bisq.common.util.NetworkUtils; -import bisq.network.common.Address; -import bisq.network.common.TransportType; +import bisq.common.network.Address; +import bisq.common.network.TransportType; import bisq.network.p2p.message.NetworkEnvelope; import bisq.network.p2p.node.Capability; import bisq.network.p2p.node.Feature; @@ -70,7 +71,7 @@ void validConnections() throws IOException { ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.configureBlocking(false); - Address myAddress = Address.localHost(NetworkUtils.findFreeSystemPort()); + Address myAddress = DefaultLocalhostFacade.toLocalHostAddress(NetworkUtils.findFreeSystemPort()); InetSocketAddress socketAddress = new InetSocketAddress( InetAddress.getLocalHost(), myAddress.getPort() @@ -128,7 +129,7 @@ void validConnections() throws IOException { socketChannel.connect(socketAddress); InetSocketAddress localSocketAddress = (InetSocketAddress) socketChannel.getLocalAddress(); - Address peerAddress = Address.localHost(localSocketAddress.getPort()); + Address peerAddress = DefaultLocalhostFacade.toLocalHostAddress(localSocketAddress.getPort()); bisq.network.protobuf.NetworkEnvelope poWRequest = createPoWRequest(myAddress, peerAddress); byte[] requestInBytes = poWRequest.toByteArray(); @@ -159,7 +160,7 @@ void invalidConnection() throws IOException { ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.configureBlocking(false); - Address myAddress = Address.localHost(NetworkUtils.findFreeSystemPort()); + Address myAddress = DefaultLocalhostFacade.toLocalHostAddress(NetworkUtils.findFreeSystemPort()); InetSocketAddress socketAddress = new InetSocketAddress( InetAddress.getLocalHost(), myAddress.getPort() @@ -217,7 +218,7 @@ void invalidConnection() throws IOException { socketChannel.connect(socketAddress); InetSocketAddress localSocketAddress = (InetSocketAddress) socketChannel.getLocalAddress(); - Address peerAddress = Address.localHost(localSocketAddress.getPort()); + Address peerAddress = DefaultLocalhostFacade.toLocalHostAddress(localSocketAddress.getPort()); bisq.network.protobuf.NetworkEnvelope invalidPoWRequest = createPoWRequest(peerAddress, myAddress); diff --git a/network/network/src/test/java/bisq/network/p2p/ProtoBufMessageLengthTests.java b/network/network/src/test/java/bisq/network/p2p/ProtoBufMessageLengthTests.java index 722ab230a6..d44d301f93 100644 --- a/network/network/src/test/java/bisq/network/p2p/ProtoBufMessageLengthTests.java +++ b/network/network/src/test/java/bisq/network/p2p/ProtoBufMessageLengthTests.java @@ -19,8 +19,9 @@ import bisq.common.application.ApplicationVersion; import bisq.common.file.FileUtils; -import bisq.network.common.Address; -import bisq.network.common.TransportType; +import bisq.common.network.Address; +import bisq.common.network.DefaultLocalhostFacade; +import bisq.common.network.TransportType; import bisq.network.p2p.message.NetworkEnvelope; import bisq.network.p2p.node.Capability; import bisq.network.p2p.node.Feature; @@ -111,11 +112,11 @@ private AuthorizationService createAuthorizationService() { } private bisq.network.protobuf.NetworkEnvelope createValidRequest() { - Capability peerCapability = createCapability(Address.localHost(2345), supportedTransportTypes); + Capability peerCapability = createCapability(DefaultLocalhostFacade.toLocalHostAddress(2345), supportedTransportTypes); ConnectionHandshake.Request request = new ConnectionHandshake.Request(peerCapability, Optional.empty(), new NetworkLoad(), 0); AuthorizationToken token = authorizationService.createToken(request, new NetworkLoad(), - Address.localHost(1234).getFullAddress(), + DefaultLocalhostFacade.toLocalHostAddress(1234).getFullAddress(), 0, new ArrayList<>()); return new NetworkEnvelope(token, request).completeProto(); } diff --git a/network/network/src/test/java/bisq/network/p2p/node/handshake/OnionAddressValidationSignTests.java b/network/network/src/test/java/bisq/network/p2p/node/handshake/OnionAddressValidationSignTests.java index 1cca0985a9..5ac25fbc94 100644 --- a/network/network/src/test/java/bisq/network/p2p/node/handshake/OnionAddressValidationSignTests.java +++ b/network/network/src/test/java/bisq/network/p2p/node/handshake/OnionAddressValidationSignTests.java @@ -17,7 +17,8 @@ package bisq.network.p2p.node.handshake; -import bisq.network.common.Address; +import bisq.common.network.Address; +import bisq.common.network.DefaultLocalhostFacade; import bisq.security.keys.TorKeyGeneration; import bisq.security.keys.TorKeyPair; import org.junit.jupiter.api.Test; @@ -33,15 +34,15 @@ public class OnionAddressValidationSignTests { @Test void testSignNonOnionAddresses() { - Address myAddress = Address.localHost(1234); - Address peerAddress = Address.localHost(4321); + Address myAddress = DefaultLocalhostFacade.toLocalHostAddress(1234); + Address peerAddress = DefaultLocalhostFacade.toLocalHostAddress(4321); Optional signature = OnionAddressValidation.sign(myAddress, peerAddress, signatureDate, myTorKeyPair.getPrivateKey()); assertThat(signature).isEmpty(); } @Test void testSignMyNonOnionAddress() { - Address myAddress = Address.localHost(1234); + Address myAddress = DefaultLocalhostFacade.toLocalHostAddress(1234); Address peerAddress = new Address(peerTorKeyPair.getOnionAddress(), 8888); Optional signature = OnionAddressValidation.sign(myAddress, peerAddress, signatureDate, myTorKeyPair.getPrivateKey()); assertThat(signature).isEmpty(); @@ -50,7 +51,7 @@ void testSignMyNonOnionAddress() { @Test void testSignPeerNonOnionAddress() { Address myAddress = new Address(myTorKeyPair.getOnionAddress(), 8888); - Address peerAddress = Address.localHost(4321); + Address peerAddress = DefaultLocalhostFacade.toLocalHostAddress(4321); Optional signature = OnionAddressValidation.sign(myAddress, peerAddress, signatureDate, myTorKeyPair.getPrivateKey()); assertThat(signature).isEmpty(); } diff --git a/network/network/src/test/java/bisq/network/p2p/node/handshake/OnionAddressValidationVerifyTests.java b/network/network/src/test/java/bisq/network/p2p/node/handshake/OnionAddressValidationVerifyTests.java index 5fa1881ad4..323833563a 100644 --- a/network/network/src/test/java/bisq/network/p2p/node/handshake/OnionAddressValidationVerifyTests.java +++ b/network/network/src/test/java/bisq/network/p2p/node/handshake/OnionAddressValidationVerifyTests.java @@ -17,7 +17,8 @@ package bisq.network.p2p.node.handshake; -import bisq.network.common.Address; +import bisq.common.network.Address; +import bisq.common.network.DefaultLocalhostFacade; import bisq.security.keys.TorKeyGeneration; import bisq.security.keys.TorKeyPair; import org.junit.jupiter.api.Test; @@ -33,15 +34,15 @@ public class OnionAddressValidationVerifyTests { @Test void testVerifyNonOnionAddresses() { - Address myAddress = Address.localHost(1234); - Address peerAddress = Address.localHost(4321); + Address myAddress = DefaultLocalhostFacade.toLocalHostAddress(1234); + Address peerAddress = DefaultLocalhostFacade.toLocalHostAddress(4321); boolean isValid = OnionAddressValidation.verify(myAddress, peerAddress, signatureDate, Optional.empty()); assertThat(isValid).isTrue(); } @Test void testVerifyMyNonOnionAddress() { - Address myAddress = Address.localHost(1234); + Address myAddress = DefaultLocalhostFacade.toLocalHostAddress(1234); Address peerAddress = new Address(peerTorKeyPair.getOnionAddress(), 8888); boolean isValid = OnionAddressValidation.verify(myAddress, peerAddress, signatureDate, Optional.empty()); assertThat(isValid).isTrue(); @@ -50,7 +51,7 @@ void testVerifyMyNonOnionAddress() { @Test void testVerifyPeerNonOnionAddress() { Address myAddress = new Address(myTorKeyPair.getOnionAddress(), 8888); - Address peerAddress = Address.localHost(4321); + Address peerAddress = DefaultLocalhostFacade.toLocalHostAddress(4321); boolean isValid = OnionAddressValidation.verify(myAddress, peerAddress, signatureDate, Optional.empty()); assertThat(isValid).isTrue(); } diff --git a/network/settings.gradle.kts b/network/settings.gradle.kts index b8d972de84..e7711309c6 100644 --- a/network/settings.gradle.kts +++ b/network/settings.gradle.kts @@ -16,7 +16,6 @@ dependencyResolutionManagement { includeBuild("..") includeBuild("tor") -include("network-common") include("i2p") include("i2p-v2") include("network") diff --git a/network/tor/tor-common/src/main/java/bisq/network/tor/common/torrc/TorrcFileGenerator.java b/network/tor/tor-common/src/main/java/bisq/network/tor/common/torrc/TorrcFileGenerator.java index de10fd4a47..23d15747d5 100644 --- a/network/tor/tor-common/src/main/java/bisq/network/tor/common/torrc/TorrcFileGenerator.java +++ b/network/tor/tor-common/src/main/java/bisq/network/tor/common/torrc/TorrcFileGenerator.java @@ -17,8 +17,9 @@ package bisq.network.tor.common.torrc; +import bisq.common.file.FileUtils; + import java.io.IOException; -import java.nio.file.Files; import java.nio.file.Path; import java.util.Map; import java.util.Set; @@ -53,8 +54,9 @@ public void generate() { .append(" ").append(dirAuthority.getRelayFingerprint()) .append("\n")); + try { - Files.writeString(torrcPath, torrcStringBuilder.toString()); + FileUtils.writeToFile(torrcStringBuilder.toString(), torrcPath.toFile()); } catch (IOException e) { throw new IllegalStateException("Couldn't create torrc file: " + torrcPath.toAbsolutePath()); } diff --git a/network/tor/tor/build.gradle.kts b/network/tor/tor/build.gradle.kts index fb80f835c1..ce08bb8d86 100644 --- a/network/tor/tor/build.gradle.kts +++ b/network/tor/tor/build.gradle.kts @@ -32,7 +32,6 @@ dependencies { implementation("bisq:security") - implementation("network:network-common") implementation("network:network-identity") implementation("network:socks5-socket-channel") diff --git a/network/tor/tor/src/main/java/bisq/tor/TorAddressOwnershipProofGenerator.java b/network/tor/tor/src/main/java/bisq/tor/TorAddressOwnershipProofGenerator.java index 7998333586..92efac3622 100644 --- a/network/tor/tor/src/main/java/bisq/tor/TorAddressOwnershipProofGenerator.java +++ b/network/tor/tor/src/main/java/bisq/tor/TorAddressOwnershipProofGenerator.java @@ -17,9 +17,9 @@ package bisq.tor; -import bisq.network.common.Address; -import bisq.network.common.AddressOwnershipProof; -import bisq.network.common.AddressOwnershipProofGenerator; +import bisq.common.network.Address; +import bisq.common.network.AddressOwnershipProof; +import bisq.common.network.AddressOwnershipProofGenerator; import bisq.security.TorSignatureUtil; import bisq.security.keys.TorKeyPair; import org.bouncycastle.crypto.CryptoException; diff --git a/network/tor/tor/src/main/java/bisq/tor/TorService.java b/network/tor/tor/src/main/java/bisq/tor/TorService.java index 2e052f4e89..1126b266be 100644 --- a/network/tor/tor/src/main/java/bisq/tor/TorService.java +++ b/network/tor/tor/src/main/java/bisq/tor/TorService.java @@ -18,6 +18,7 @@ package bisq.tor; import bisq.common.application.Service; +import bisq.common.facades.FacadeProvider; import bisq.common.file.FileUtils; import bisq.common.observable.Observable; import bisq.common.platform.LinuxDistribution; @@ -142,7 +143,7 @@ public CompletableFuture createOnionService(int port, TorKeyPair t try { InetAddress bindAddress = !LinuxDistribution.isWhonix() ? Inet4Address.getLoopbackAddress() : Inet4Address.getByName("0.0.0.0"); - var localServerSocket = new ServerSocket(RANDOM_PORT, 50, bindAddress); + var localServerSocket = new ServerSocket(RANDOM_PORT, 50, bindAddress); String onionAddress = torKeyPair.getOnionAddress(); if (!publishedOnionServices.contains(onionAddress)) { @@ -193,11 +194,7 @@ private Path getTorBinaryPath() { } private boolean isTorRunning(String absoluteTorBinaryPath) { - return ProcessHandle.allProcesses() - .anyMatch(processHandle -> processHandle.info() - .commandLine() - .orElse("") - .startsWith(absoluteTorBinaryPath)); + return FacadeProvider.getJdkFacade().getProcessCommandLineStream().anyMatch(e -> e.startsWith(absoluteTorBinaryPath)); } private void installTorIfNotUpToDate() { diff --git a/network/tor/tor/src/main/java/bisq/tor/TorSocket.java b/network/tor/tor/src/main/java/bisq/tor/TorSocket.java index f6b8b537ba..f472dff537 100644 --- a/network/tor/tor/src/main/java/bisq/tor/TorSocket.java +++ b/network/tor/tor/src/main/java/bisq/tor/TorSocket.java @@ -17,7 +17,7 @@ package bisq.tor; -import bisq.network.common.PeerSocket; +import bisq.common.network.PeerSocket; import lombok.Getter; import java.io.IOException; diff --git a/network/tor/tor/src/main/java/bisq/tor/TorTransportConfig.java b/network/tor/tor/src/main/java/bisq/tor/TorTransportConfig.java index 95459b0203..1b4bd622eb 100644 --- a/network/tor/tor/src/main/java/bisq/tor/TorTransportConfig.java +++ b/network/tor/tor/src/main/java/bisq/tor/TorTransportConfig.java @@ -17,7 +17,7 @@ package bisq.tor; -import bisq.network.common.TransportConfig; +import bisq.common.network.TransportConfig; import bisq.network.tor.common.torrc.DirectoryAuthority; import com.typesafe.config.ConfigList; import com.typesafe.config.ConfigValue; diff --git a/network/tor/tor/src/main/java/bisq/tor/process/NativeTorProcess.java b/network/tor/tor/src/main/java/bisq/tor/process/NativeTorProcess.java index cf45b25577..2a26aaa56e 100644 --- a/network/tor/tor/src/main/java/bisq/tor/process/NativeTorProcess.java +++ b/network/tor/tor/src/main/java/bisq/tor/process/NativeTorProcess.java @@ -27,6 +27,8 @@ import java.util.Optional; import java.util.concurrent.TimeUnit; +import static bisq.common.facades.FacadeProvider.getJdkFacade; + @Slf4j public class NativeTorProcess { public static final String ARG_OWNER_PID = "__OwningControllerProcess"; @@ -46,7 +48,7 @@ public void start() { createTorControlDirectory(); String absoluteTorrcPathAsString = torrcPath.toAbsolutePath().toString(); - String ownerPid = Pid.getMyPid(); + String ownerPid = getJdkFacade().getMyPid(); var processBuilder = new ProcessBuilder( torBinaryPath.toAbsolutePath().toString(), "--torrc-file", absoluteTorrcPathAsString, @@ -59,8 +61,8 @@ public void start() { environment.put("LD_PRELOAD", LdPreload.computeLdPreloadVariable(torDataDirPath)); } - processBuilder.redirectError(ProcessBuilder.Redirect.DISCARD); - processBuilder.redirectOutput(ProcessBuilder.Redirect.DISCARD); + getJdkFacade().redirectError(processBuilder); + getJdkFacade().redirectOutput(processBuilder); try { Process torProcess = processBuilder.start(); diff --git a/network/tor/tor/src/main/java/bisq/tor/process/control_port/ControlPortFileParser.java b/network/tor/tor/src/main/java/bisq/tor/process/control_port/ControlPortFileParser.java index 95930c871c..fbd7a01f24 100644 --- a/network/tor/tor/src/main/java/bisq/tor/process/control_port/ControlPortFileParser.java +++ b/network/tor/tor/src/main/java/bisq/tor/process/control_port/ControlPortFileParser.java @@ -17,8 +17,9 @@ package bisq.tor.process.control_port; +import bisq.common.file.FileUtils; + import java.io.IOException; -import java.nio.file.Files; import java.nio.file.Path; public class ControlPortFileParser { @@ -26,8 +27,7 @@ public class ControlPortFileParser { public static int parse(Path controlPortFilePath) { try { - String fileContent = Files.readString(controlPortFilePath); - + String fileContent = FileUtils.readAsString(controlPortFilePath.toString()); if (isControlPortFileReady(fileContent)) { for (String line : fileContent.split("\n")) { // Lines end on Windows with "\r\n". Previous String.split("\n") removed "\n" already. diff --git a/os-specific/build.gradle.kts b/os-specific/build.gradle.kts new file mode 100644 index 0000000000..746651fb7a --- /dev/null +++ b/os-specific/build.gradle.kts @@ -0,0 +1,11 @@ +plugins { + id("bisq.java-library") +} + +dependencies { + implementation(project(":presentation")) + implementation(project(":persistence")) + implementation(project(":settings")) + + implementation(libs.java.dev.jna) +} diff --git a/presentation/src/main/java/bisq/presentation/notifications/linux/LinuxNotificationDelegate.java b/os-specific/src/main/java/bisq/os_specific/notifications/linux/LinuxNotificationService.java similarity index 56% rename from presentation/src/main/java/bisq/presentation/notifications/linux/LinuxNotificationDelegate.java rename to os-specific/src/main/java/bisq/os_specific/notifications/linux/LinuxNotificationService.java index a77df25d4e..9ed3cba472 100644 --- a/presentation/src/main/java/bisq/presentation/notifications/linux/LinuxNotificationDelegate.java +++ b/os-specific/src/main/java/bisq/os_specific/notifications/linux/LinuxNotificationService.java @@ -14,10 +14,11 @@ * You should have received a copy of the GNU Affero General Public License * along with Bisq. If not, see . */ -package bisq.presentation.notifications.linux; + +package bisq.os_specific.notifications.linux; import bisq.common.file.FileUtils; -import bisq.presentation.notifications.SystemNotificationDelegate; +import bisq.presentation.notifications.OsSpecificNotificationService; import bisq.settings.CookieKey; import bisq.settings.SettingsService; import lombok.extern.slf4j.Slf4j; @@ -28,14 +29,18 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.CompletableFuture; + +import static com.google.common.base.Preconditions.checkArgument; @Slf4j -public class LinuxNotificationDelegate implements SystemNotificationDelegate { +public class LinuxNotificationService implements OsSpecificNotificationService { private final SettingsService settingsService; + private boolean isSupported; @Nullable private String iconPath; - public LinuxNotificationDelegate(Path baseDir, SettingsService settingsService) { + public LinuxNotificationService(Path baseDir, SettingsService settingsService) { this.settingsService = settingsService; String javaHomePath = System.getProperty("java.home"); @@ -63,44 +68,55 @@ public LinuxNotificationDelegate(Path baseDir, SettingsService settingsService) } } - public static boolean isSupported() { + @Override + public CompletableFuture initialize() { try { String[] command = new String[]{"notify-send --help > nil"}; - return Runtime.getRuntime().exec(command).waitFor() == 0; + checkArgument(Runtime.getRuntime().exec(command).waitFor() == 0, "notify-send is not supported"); + + isSupported = true; } catch (Exception e) { - return false; + log.warn("LinuxNotificationService not supported.", e); + isSupported = false; } + return CompletableFuture.completedFuture(true); } + @Override + public CompletableFuture shutdown() { + return CompletableFuture.completedFuture(true); + } @Override public void show(String title, String message) { - Boolean useTransientNotifications = settingsService.getCookie().asBoolean(CookieKey.USE_TRANSIENT_NOTIFICATIONS) - .orElse(true); + if (isSupported) { + Boolean useTransientNotifications = settingsService.getCookie().asBoolean(CookieKey.USE_TRANSIENT_NOTIFICATIONS) + .orElse(true); - List command = new ArrayList<>(); - command.add("notify-send"); + List command = new ArrayList<>(); + command.add("notify-send"); - if (iconPath != null) { - command.add("-i"); - command.add(iconPath); - } + if (iconPath != null) { + command.add("-i"); + command.add(iconPath); + } - // notify-send does not support removing notifications. To avoid that we fill up the notification center we - // can set the notification transient. - if (useTransientNotifications) { - command.add("--hint=int:transient:1"); - } + // notify-send does not support removing notifications. To avoid that we fill up the notification center we + // can set the notification transient. + if (useTransientNotifications) { + command.add("--hint=int:transient:1"); + } - command.add("--app-name"); - command.add("Bisq"); + command.add("--app-name"); + command.add("Bisq"); - command.add(title); - command.add(message); - try { - Runtime.getRuntime().exec(command.toArray(new String[0])); - } catch (IOException e) { - throw new RuntimeException("Unable to notify with Notify OSD", e); + command.add(title); + command.add(message); + try { + Runtime.getRuntime().exec(command.toArray(new String[0])); + } catch (IOException e) { + throw new RuntimeException("Unable to notify with Notify OSD", e); + } } } } diff --git a/os-specific/src/main/java/bisq/os_specific/notifications/osx/OsxNotificationService.java b/os-specific/src/main/java/bisq/os_specific/notifications/osx/OsxNotificationService.java new file mode 100644 index 0000000000..015064ffff --- /dev/null +++ b/os-specific/src/main/java/bisq/os_specific/notifications/osx/OsxNotificationService.java @@ -0,0 +1,71 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.os_specific.notifications.osx; + +import bisq.common.platform.OS; +import bisq.common.platform.Version; +import bisq.os_specific.notifications.osx.foundation.Foundation; +import bisq.os_specific.notifications.osx.foundation.ID; +import bisq.presentation.notifications.OsSpecificNotificationService; +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.CompletableFuture; + +import static com.google.common.base.Preconditions.checkArgument; + +@Slf4j +public class OsxNotificationService implements OsSpecificNotificationService { + private boolean isSupported; + + public OsxNotificationService() { + } + + @Override + public CompletableFuture initialize() { + try { + checkArgument(new Version(OS.getOsVersion()).aboveOrEqual("10.8.0"), + "OSX version must be at least 10.8.0 (Mountain Lion)"); + // If native lib would not be supported it throws an exception + Foundation.init(); + isSupported = true; + } catch (Exception e) { + log.warn("OsxNotificationService not supported.", e); + isSupported = false; + } + return CompletableFuture.completedFuture(true); + } + + @Override + public CompletableFuture shutdown() { + return CompletableFuture.completedFuture(true); + } + + @Override + public void show(String title, String message) { + if (isSupported) { + ID notification = Foundation.invoke(Foundation.getObjcClass("NSUserNotification"), "new"); + Foundation.invoke(notification, "setTitle:", + Foundation.nsString(title)); + Foundation.invoke(notification, "setInformativeText:", + Foundation.nsString(message.replace("\n", "\r"))); + ID center = Foundation.invoke(Foundation.getObjcClass("NSUserNotificationCenter"), + "defaultUserNotificationCenter"); + Foundation.invoke(center, "deliverNotification:", notification); + } + } +} diff --git a/presentation/src/main/java/bisq/presentation/notifications/osx/foundation/Foundation.java b/os-specific/src/main/java/bisq/os_specific/notifications/osx/foundation/Foundation.java similarity index 98% rename from presentation/src/main/java/bisq/presentation/notifications/osx/foundation/Foundation.java rename to os-specific/src/main/java/bisq/os_specific/notifications/osx/foundation/Foundation.java index 3b72598223..45ec1c0302 100644 --- a/presentation/src/main/java/bisq/presentation/notifications/osx/foundation/Foundation.java +++ b/os-specific/src/main/java/bisq/os_specific/notifications/osx/foundation/Foundation.java @@ -30,7 +30,7 @@ * License for the specific language governing permissions and limitations under * the License. */ -package bisq.presentation.notifications.osx.foundation; +package bisq.os_specific.notifications.osx.foundation; import com.sun.jna.*; diff --git a/presentation/src/main/java/bisq/presentation/notifications/osx/foundation/FoundationLibrary.java b/os-specific/src/main/java/bisq/os_specific/notifications/osx/foundation/FoundationLibrary.java similarity index 98% rename from presentation/src/main/java/bisq/presentation/notifications/osx/foundation/FoundationLibrary.java rename to os-specific/src/main/java/bisq/os_specific/notifications/osx/foundation/FoundationLibrary.java index 5c679d44a5..f0267960cb 100644 --- a/presentation/src/main/java/bisq/presentation/notifications/osx/foundation/FoundationLibrary.java +++ b/os-specific/src/main/java/bisq/os_specific/notifications/osx/foundation/FoundationLibrary.java @@ -31,7 +31,7 @@ * the License. */ -package bisq.presentation.notifications.osx.foundation; +package bisq.os_specific.notifications.osx.foundation; import com.sun.jna.Callback; import com.sun.jna.Library; diff --git a/presentation/src/main/java/bisq/presentation/notifications/osx/foundation/ID.java b/os-specific/src/main/java/bisq/os_specific/notifications/osx/foundation/ID.java similarity index 96% rename from presentation/src/main/java/bisq/presentation/notifications/osx/foundation/ID.java rename to os-specific/src/main/java/bisq/os_specific/notifications/osx/foundation/ID.java index d2688aa50e..b4459ad486 100644 --- a/presentation/src/main/java/bisq/presentation/notifications/osx/foundation/ID.java +++ b/os-specific/src/main/java/bisq/os_specific/notifications/osx/foundation/ID.java @@ -30,7 +30,7 @@ * License for the specific language governing permissions and limitations under * the License. */ -package bisq.presentation.notifications.osx.foundation; +package bisq.os_specific.notifications.osx.foundation; import com.sun.jna.NativeLong; /** diff --git a/os-specific/src/main/java/bisq/os_specific/notifications/other/AwtNotificationService.java b/os-specific/src/main/java/bisq/os_specific/notifications/other/AwtNotificationService.java new file mode 100644 index 0000000000..d743b24a3a --- /dev/null +++ b/os-specific/src/main/java/bisq/os_specific/notifications/other/AwtNotificationService.java @@ -0,0 +1,66 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.os_specific.notifications.other; + +import bisq.presentation.notifications.OsSpecificNotificationService; +import lombok.extern.slf4j.Slf4j; + +import javax.swing.ImageIcon; +import java.awt.SystemTray; +import java.awt.TrayIcon; +import java.net.URL; +import java.util.concurrent.CompletableFuture; + +import static com.google.common.base.Preconditions.checkArgument; + +@Slf4j +public class AwtNotificationService implements OsSpecificNotificationService { + private boolean isSupported; + private final TrayIcon trayIcon; + + public AwtNotificationService() { + URL image = getClass().getClassLoader().getResource("images/app_window/icon_128.png"); + trayIcon = new TrayIcon(new ImageIcon(image, "Bisq 2").getImage()); + trayIcon.setImageAutoSize(true); + } + + @Override + public CompletableFuture initialize() { + try { + checkArgument(SystemTray.isSupported(), "SystemTray is not supported"); + SystemTray systemTray = SystemTray.getSystemTray(); + systemTray.add(trayIcon); + isSupported = true; + } catch (Exception e) { + log.warn("AwtNotificationService not supported.", e); + isSupported = false; + } + return CompletableFuture.completedFuture(true); + } + + @Override + public CompletableFuture shutdown() { + return CompletableFuture.completedFuture(true); + } + + public void show(String title, String message) { + if (isSupported) { + trayIcon.displayMessage(title, message, TrayIcon.MessageType.NONE); + } + } +} diff --git a/persistence/src/main/java/bisq/persistence/backup/BackupService.java b/persistence/src/main/java/bisq/persistence/backup/BackupService.java index 2bc522ed5f..14fa25a82c 100644 --- a/persistence/src/main/java/bisq/persistence/backup/BackupService.java +++ b/persistence/src/main/java/bisq/persistence/backup/BackupService.java @@ -107,7 +107,6 @@ public void maybeMigrateLegacyBackupFile() { } public boolean maybeBackup() { - log.error("totalMaxBackupSize {}",totalMaxBackupSize); if (maxBackupSize == MaxBackupSize.ZERO) { return false; } diff --git a/presentation/src/main/java/bisq/presentation/notifications/SystemNotificationDelegate.java b/presentation/src/main/java/bisq/presentation/notifications/OsSpecificNotificationService.java similarity index 87% rename from presentation/src/main/java/bisq/presentation/notifications/SystemNotificationDelegate.java rename to presentation/src/main/java/bisq/presentation/notifications/OsSpecificNotificationService.java index 966dd4051c..ae12a69721 100644 --- a/presentation/src/main/java/bisq/presentation/notifications/SystemNotificationDelegate.java +++ b/presentation/src/main/java/bisq/presentation/notifications/OsSpecificNotificationService.java @@ -17,6 +17,8 @@ package bisq.presentation.notifications; -public interface SystemNotificationDelegate { +import bisq.common.application.Service; + +public interface OsSpecificNotificationService extends Service { void show(String title, String message); } diff --git a/presentation/src/main/java/bisq/presentation/notifications/SystemNotificationService.java b/presentation/src/main/java/bisq/presentation/notifications/SystemNotificationService.java index df36f8c99c..ac6bbcaff6 100644 --- a/presentation/src/main/java/bisq/presentation/notifications/SystemNotificationService.java +++ b/presentation/src/main/java/bisq/presentation/notifications/SystemNotificationService.java @@ -19,69 +19,36 @@ import bisq.common.application.Service; -import bisq.common.platform.OS; -import bisq.presentation.notifications.linux.LinuxNotificationDelegate; -import bisq.presentation.notifications.osx.OsxNotificationDelegate; -import bisq.presentation.notifications.other.AwtNotificationDelegate; -import bisq.settings.SettingsService; import lombok.extern.slf4j.Slf4j; -import java.awt.SystemTray; -import java.nio.file.Path; import java.util.Optional; import java.util.concurrent.CompletableFuture; @Slf4j public class SystemNotificationService implements Service { - private final Path baseDir; - private final SettingsService settingsService; - private SystemNotificationDelegate delegate; + private final Optional systemNotificationDelegate; private boolean isInitialized; - public SystemNotificationService(Path baseDir, SettingsService settingsService) { - this.baseDir = baseDir; - this.settingsService = settingsService; + public SystemNotificationService(Optional systemNotificationDelegate) { + this.systemNotificationDelegate = systemNotificationDelegate; } public CompletableFuture initialize() { isInitialized = true; log.info("initialize"); + systemNotificationDelegate.ifPresent(Service::initialize); return CompletableFuture.completedFuture(true); } public CompletableFuture shutdown() { + systemNotificationDelegate.ifPresent(Service::shutdown); return CompletableFuture.completedFuture(true); } public void show(Notification notification) { if (isInitialized) { - getDelegate().ifPresent(delegate -> delegate.show(notification.getTitle(), notification.getMessage())); + systemNotificationDelegate.ifPresent(service -> service.show(notification.getTitle(), notification.getMessage())); } } - - private Optional getDelegate() { - if (delegate == null) { - if (OS.isLinux() && LinuxNotificationDelegate.isSupported()) { - delegate = new LinuxNotificationDelegate(baseDir, settingsService); - } else if (OS.isMacOs() && OsxNotificationDelegate.isSupported()) { - delegate = new OsxNotificationDelegate(); - } else { - boolean supported = false; - try { - supported = SystemTray.isSupported(); - } catch (Exception e) { - log.warn("SystemTray.isSupported call failed", e); - } - try { - if (supported) { - delegate = new AwtNotificationDelegate(); - } - } catch (Exception e) { - log.warn("Creating AwtNotificationDelegate failed, even SystemTray.isSupported() returned true", e); - } - } - } - return Optional.ofNullable(delegate); - } } diff --git a/presentation/src/main/java/bisq/presentation/notifications/osx/OsxNotificationDelegate.java b/presentation/src/main/java/bisq/presentation/notifications/osx/OsxNotificationDelegate.java deleted file mode 100644 index bc4c1b4eac..0000000000 --- a/presentation/src/main/java/bisq/presentation/notifications/osx/OsxNotificationDelegate.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ -package bisq.presentation.notifications.osx; - -import bisq.common.platform.OS; -import bisq.common.platform.Version; -import bisq.presentation.notifications.SystemNotificationDelegate; -import bisq.presentation.notifications.osx.foundation.Foundation; -import bisq.presentation.notifications.osx.foundation.ID; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class OsxNotificationDelegate implements SystemNotificationDelegate { - public static boolean isSupported() { - try { - // Requires at least Mountain Lion - if (new Version(OS.getOsVersion()).below("10.8.0")) { - return false; - } - - // If native lib would not be supported it throws an exception - Foundation.init(); - return true; - } catch (Throwable t) { - log.error("No native OSX support for notifications. OSX version: {}", OS.getOsVersion(), t); - return false; - } - } - - @Override - public void show(String title, String message) { - ID notification = Foundation.invoke(Foundation.getObjcClass("NSUserNotification"), "new"); - Foundation.invoke(notification, "setTitle:", - Foundation.nsString(title)); - Foundation.invoke(notification, "setInformativeText:", - Foundation.nsString(message.replace("\n", "\r"))); - ID center = Foundation.invoke(Foundation.getObjcClass("NSUserNotificationCenter"), - "defaultUserNotificationCenter"); - Foundation.invoke(center, "deliverNotification:", notification); - } -} diff --git a/presentation/src/main/java/bisq/presentation/notifications/other/AwtNotificationDelegate.java b/presentation/src/main/java/bisq/presentation/notifications/other/AwtNotificationDelegate.java deleted file mode 100644 index 3c3159f74f..0000000000 --- a/presentation/src/main/java/bisq/presentation/notifications/other/AwtNotificationDelegate.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.presentation.notifications.other; - -import bisq.presentation.notifications.SystemNotificationDelegate; -import lombok.extern.slf4j.Slf4j; - -import javax.swing.*; -import java.awt.*; -import java.net.URL; - -@Slf4j -public class AwtNotificationDelegate implements SystemNotificationDelegate { - private final TrayIcon trayIcon; - - public AwtNotificationDelegate() { - URL image = getClass().getClassLoader().getResource("images/app_window/icon_128.png"); - trayIcon = new TrayIcon(new ImageIcon(image, "Bisq 2").getImage()); - trayIcon.setImageAutoSize(true); - SystemTray systemTray = SystemTray.getSystemTray(); - try { - systemTray.add(trayIcon); - } catch (AWTException e) { - throw new RuntimeException(e); - } - } - - public void show(String title, String message) { - trayIcon.displayMessage(title, message, TrayIcon.MessageType.NONE); - } -} diff --git a/security/src/main/java/bisq/security/SecurityService.java b/security/src/main/java/bisq/security/SecurityService.java index c869d791dd..5436972453 100644 --- a/security/src/main/java/bisq/security/SecurityService.java +++ b/security/src/main/java/bisq/security/SecurityService.java @@ -18,17 +18,31 @@ package bisq.security; import bisq.common.application.Service; +import bisq.common.platform.OS; import bisq.persistence.PersistenceService; import bisq.security.keys.KeyBundleService; import bisq.security.pow.equihash.EquihashProofOfWorkService; import bisq.security.pow.hashcash.HashCashProofOfWorkService; import lombok.Getter; import lombok.extern.slf4j.Slf4j; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import java.security.Security; import java.util.concurrent.CompletableFuture; @Slf4j public class SecurityService implements Service { + static { + if (OS.isAndroid()) { + // Androids default BC version does not support all algorithms we need, thus we remove + // it and add our BC provider + Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME); + Security.addProvider(new BouncyCastleProvider()); + } else if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) { + Security.addProvider(new BouncyCastleProvider()); + } + } + @Getter public static class Config { private final com.typesafe.config.Config keyBundle; diff --git a/security/src/main/java/bisq/security/pow/equihash/Equihash.java b/security/src/main/java/bisq/security/pow/equihash/Equihash.java index a7050ae716..e19b343c49 100644 --- a/security/src/main/java/bisq/security/pow/equihash/Equihash.java +++ b/security/src/main/java/bisq/security/pow/equihash/Equihash.java @@ -17,6 +17,7 @@ package bisq.security.pow.equihash; +import bisq.common.platform.OS; import bisq.common.util.ByteArrayUtils; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ListMultimap; @@ -32,6 +33,7 @@ import java.util.stream.IntStream; import java.util.stream.Stream; +import static bisq.common.facades.FacadeProvider.getGuavaFacade; import static com.google.common.base.Preconditions.checkArgument; import static java.math.BigInteger.ONE; @@ -73,7 +75,11 @@ public class Equihash { * Mean solution count per nonce for Equihash puzzles with unit difficulty. */ private static final double MEAN_SOLUTION_COUNT_PER_NONCE = 2.0; + private static final boolean IS_ANDROID = OS.isAndroid(); + // Guava has different APIs for Java SE and Android. + // Thus, we use a facade with Android compatible APIs by default and let the Desktop app set the Java SE facade + // containing APIs only supported for Java SE compatible JDKs. private final int k, N; private final int tableCapacity; private final int inputNum, inputBits; @@ -245,7 +251,7 @@ Stream streamInputsHits() { } return IntStream.range(0, table.numRows) .mapToObj(table::getRow) - .filter(row -> row.stream().distinct().count() == inputNum) + .filter(row -> getGuavaFacade().toIntStream(row).distinct().count() == inputNum) .map(row -> sortInputs(row.toArray())) .filter(this::testDifficultyCondition); } @@ -259,7 +265,9 @@ private XorTable computeAllHashes() { int[] hash = hashInputs(i); return IntStream.range(0, k + 2).map(j -> j <= k ? hash[j] & (N / 2 - 1) : i); }); - return new XorTable(k + 1, 1, ImmutableIntArray.copyOf(tableValues.parallel())); + IntStream parallelIntStream = getGuavaFacade().parallel(tableValues); + ImmutableIntArray immutableIntArray = getGuavaFacade().copyOf(parallelIntStream); + return new XorTable(k + 1, 1, immutableIntArray); } private boolean testDifficultyCondition(int[] inputs) { diff --git a/settings.gradle.kts b/settings.gradle.kts index 42390cf204..af3f1e43dc 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -29,9 +29,12 @@ include("chat") include("common") include("contract") include("daemon") +include("evolution") include("identity") include("i18n") +include("java-se") include("offer") +include("os-specific") include("persistence") include("platform") include("presentation") diff --git a/user/build.gradle.kts b/user/build.gradle.kts index 7c7ef8a2e5..3265664105 100644 --- a/user/build.gradle.kts +++ b/user/build.gradle.kts @@ -12,7 +12,6 @@ dependencies { implementation("network:network") implementation("network:network-identity") - implementation("network:network-common") implementation(libs.google.gson) implementation(libs.typesafe.config) diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/components/cathash/BucketConfig.java b/user/src/main/java/bisq/user/cathash/BucketConfig.java similarity index 95% rename from apps/desktop/desktop/src/main/java/bisq/desktop/components/cathash/BucketConfig.java rename to user/src/main/java/bisq/user/cathash/BucketConfig.java index 159cd6761f..08e713fc89 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/components/cathash/BucketConfig.java +++ b/user/src/main/java/bisq/user/cathash/BucketConfig.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.desktop.components.cathash; +package bisq.user.cathash; import lombok.Getter; import lombok.extern.slf4j.Slf4j; @@ -24,7 +24,7 @@ @Slf4j public abstract class BucketConfig { - static final int CURRENT_VERSION = 0; + public static final int CURRENT_VERSION = 0; static final String DIGIT = "#"; static final String SHAPE_NUMBER = "#SHAPE_NUMBER#"; diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/components/cathash/BucketConfigV0.java b/user/src/main/java/bisq/user/cathash/BucketConfigV0.java similarity index 98% rename from apps/desktop/desktop/src/main/java/bisq/desktop/components/cathash/BucketConfigV0.java rename to user/src/main/java/bisq/user/cathash/BucketConfigV0.java index 4c68e15ba8..725b51e2be 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/components/cathash/BucketConfigV0.java +++ b/user/src/main/java/bisq/user/cathash/BucketConfigV0.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.desktop.components.cathash; +package bisq.user.cathash; import lombok.extern.slf4j.Slf4j; diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/components/cathash/BucketEncoder.java b/user/src/main/java/bisq/user/cathash/BucketEncoder.java similarity index 98% rename from apps/desktop/desktop/src/main/java/bisq/desktop/components/cathash/BucketEncoder.java rename to user/src/main/java/bisq/user/cathash/BucketEncoder.java index ffe941f8ff..ddfcc08b7b 100644 --- a/apps/desktop/desktop/src/main/java/bisq/desktop/components/cathash/BucketEncoder.java +++ b/user/src/main/java/bisq/user/cathash/BucketEncoder.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.desktop.components.cathash; +package bisq.user.cathash; import java.math.BigInteger; import java.util.Optional; diff --git a/user/src/main/java/bisq/user/cathash/CatHashService.java b/user/src/main/java/bisq/user/cathash/CatHashService.java new file mode 100644 index 0000000000..ffe182fb1f --- /dev/null +++ b/user/src/main/java/bisq/user/cathash/CatHashService.java @@ -0,0 +1,190 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.user.cathash; + +import bisq.common.encoding.Hex; +import bisq.common.file.FileUtils; +import bisq.common.util.ByteArrayUtils; +import bisq.user.profile.UserProfile; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; + +import java.io.File; +import java.io.IOException; +import java.math.BigInteger; +import java.nio.file.Path; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +@Slf4j +public abstract class CatHashService { + // Largest size in offerbook is 60px, in reputationListView it is 40px and in chats 30px. + // Larger images are used only rarely and are not cached. + public static final double SIZE_OF_CACHED_ICONS = 60; + + // This is a 120*120 image meaning 14400 pixels. At 4 bytes each, that takes 57.6 KB in memory (and on disk as we use raw format). + // With 5000 images we would get about 288 MB. + private static final int MAX_CACHE_SIZE = 5000; + + private final ConcurrentHashMap cache = new ConcurrentHashMap<>(); + @Setter + private Path baseDir; + + public CatHashService(Path baseDir) { + this.baseDir = baseDir; + } + + protected abstract T composeImage(String[] paths, double size); + + protected abstract void writeRawImage(T image, File iconFile) throws IOException; + + protected abstract T readRawImage(File iconFile) throws IOException; + + public T getImage(UserProfile userProfile, double size) { + return getImage(userProfile.getPubKeyHash(), + userProfile.getProofOfWork().getSolution(), + userProfile.getAvatarVersion(), + size); + } + + public T getImage(byte[] pubKeyHash, byte[] powSolution, int avatarVersion, double size) { + byte[] combined = ByteArrayUtils.concat(powSolution, pubKeyHash); + BigInteger catHashInput = new BigInteger(combined); + String userProfileId = Hex.encode(pubKeyHash); + File iconsDir = Path.of(getCatHashIconsDirectory().toString(), "v" + avatarVersion).toFile(); + File iconFile = Path.of(iconsDir.getAbsolutePath(), userProfileId + ".raw").toFile(); + + boolean useCache = size <= SIZE_OF_CACHED_ICONS; + if (useCache) { + // First approach is to look up the cache + if (cache.containsKey(catHashInput)) { + return cache.get(catHashInput); + } + + + if (!iconsDir.exists()) { + try { + FileUtils.makeDirs(iconsDir); + } catch (IOException e) { + log.error(e.toString()); + } + } + + // Next approach is to read the image from file + if (iconFile.exists()) { + try { + T image = readRawImage(iconFile); + if (cache.size() < MAX_CACHE_SIZE) { + cache.put(catHashInput, image); + } + return image; + } catch (Exception e) { + log.error("Read image failed", e); + } + } + } + + // Image size might be larger as our cached images, or we did not find it in the + // cache and also not from persisted files. We create the image. This is an expensive operation taking + // about 12 ms on a high-end laptop, and it needs to be done on the UI thread. + long ts = System.currentTimeMillis(); + BucketConfig bucketConfig = getBucketConfig(avatarVersion); + int[] buckets = BucketEncoder.encode(catHashInput, bucketConfig.getBucketSizes()); + String[] paths = BucketEncoder.toPaths(buckets, bucketConfig.getPathTemplates()); + // For retina support we scale by 2 + T image = composeImage(paths, 2 * SIZE_OF_CACHED_ICONS); + log.info("Creating user profile icon for {} took {} ms.", userProfileId, System.currentTimeMillis() - ts); + if (useCache && cache.size() < MAX_CACHE_SIZE) { + cache.put(catHashInput, image); + + // We use the MAX_CACHE_SIZE also as limit for files on disk + try { + writeRawImage(image, iconFile); + } catch (IOException e) { + log.error("Write image failed", e); + } + } + return image; + } + + // Remove the user profile icons which are not contained anymore in the current user profile list + public void pruneOutdatedProfileIcons(Collection userProfiles) { + if (userProfiles.isEmpty()) { + return; + } + File iconsDirectory = getCatHashIconsDirectory().toFile(); + File[] versionDirs = iconsDirectory.listFiles(); + if (versionDirs == null) { + return; + } + Map> iconFilesByVersion = Stream.of(versionDirs) + .filter(File::isDirectory) + .filter(dir -> dir.listFiles() != null) + .collect(Collectors.toMap(File::getName, + dir -> Arrays.asList(Objects.requireNonNull(dir.listFiles())))); + + Map> userProfilesByVersion = userProfiles.stream() + .collect(Collectors.groupingBy(UserProfile::getAvatarVersion)); + + iconFilesByVersion.forEach((versionDir, iconFiles) -> { + try { + int version = Integer.parseInt(versionDir + .replace("v", "")); + Set fromDisk = iconFiles.stream() + .map(File::getName) + .collect(Collectors.toSet()); + Set fromData = Optional.of(userProfilesByVersion.get(version).stream() + .map(userProfile -> userProfile.getId() + ".raw") + .collect(Collectors.toSet())) + .orElse(new HashSet<>()); + Set toRemove = new HashSet<>(fromDisk); + toRemove.removeAll(fromData); + log.info("We remove following user profile icons which are not found in the current user profile list:{}", toRemove); + toRemove.forEach(fileName -> { + File file = Path.of(iconsDirectory.getAbsolutePath(), versionDir, fileName).toFile(); + try { + log.error("Remove {}", file); + FileUtils.deleteFile(file); + } catch (IOException e) { + log.error("Failed to remove file {}", file, e); + } + }); + } catch (Exception e) { + log.error("Unexpected versionDir {}", versionDir, e); + } + }); + } + + public int currentAvatarsVersion() { + return BucketConfig.CURRENT_VERSION; + } + + private Path getCatHashIconsDirectory() { + return Path.of(baseDir.toString(), "db", "cache", "cat_hash_icons"); + } + + private BucketConfig getBucketConfig(int avatarVersion) { + if (avatarVersion == 0) { + return new BucketConfigV0(); + } else { + throw new IllegalArgumentException("Provided avatarVersion not supported. avatarVersion=" + avatarVersion); + } + } +} diff --git a/wallets/electrum/build.gradle.kts b/wallets/electrum/build.gradle.kts index 04cb572a97..f530fc80d3 100644 --- a/wallets/electrum/build.gradle.kts +++ b/wallets/electrum/build.gradle.kts @@ -21,6 +21,7 @@ dependencies { api("bitcoind:core") implementation("bitcoind:json-rpc") implementation("bitcoind:regtest") + implementation("bisq:java-se") implementation("wallets:wallet") implementation(project(":process")) diff --git a/wallets/electrum/src/main/java/bisq/wallets/electrum/ElectrumProcess.java b/wallets/electrum/src/main/java/bisq/wallets/electrum/ElectrumProcess.java index e4988b75d0..3db6142457 100644 --- a/wallets/electrum/src/main/java/bisq/wallets/electrum/ElectrumProcess.java +++ b/wallets/electrum/src/main/java/bisq/wallets/electrum/ElectrumProcess.java @@ -95,6 +95,7 @@ public static String getBinarySuffix() { case LINUX -> ElectrumBinaryExtractor.LINUX_BINARY_SUFFIX; case MAC_OS -> ElectrumBinaryExtractor.MAC_OS_BINARY_SUFFIX; case WINDOWS -> ElectrumBinaryExtractor.WINDOWS_BINARY_SUFFIX; + case ANDROID -> throw new RuntimeException("Android not supported"); }; } @@ -118,6 +119,7 @@ private Path resolveBinaryPath() { case MAC_OS -> destDirPath.resolve("Electrum." + binarySuffix) .resolve("Contents/MacOS/run_electrum"); case WINDOWS -> destDirPath.resolve("electrum-" + version + "." + binarySuffix); + case ANDROID -> throw new RuntimeException("Android not supported"); }; } } diff --git a/wallets/electrum/src/main/java/bisq/wallets/electrum/ElectrumRegtestProcess.java b/wallets/electrum/src/main/java/bisq/wallets/electrum/ElectrumRegtestProcess.java index 075ea6f2a3..d839dc6789 100644 --- a/wallets/electrum/src/main/java/bisq/wallets/electrum/ElectrumRegtestProcess.java +++ b/wallets/electrum/src/main/java/bisq/wallets/electrum/ElectrumRegtestProcess.java @@ -17,8 +17,8 @@ package bisq.wallets.electrum; -import bisq.common.file.FileCreationWatcher; import bisq.common.file.FileUtils; +import bisq.java_se.utils.FileCreationWatcher; import bisq.wallets.electrum.rpc.ElectrumDaemon; import bisq.wallets.electrum.rpc.ElectrumProcessConfig; import bisq.wallets.json_rpc.JsonRpcClient;