Merge pull request #4829 from chimp1984/prevent-downgrade

Check if user has downgraded to an older version
This commit is contained in:
Christoph Atteneder 2020-11-24 09:15:47 +01:00 committed by GitHub
commit 94453cf27c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 129 additions and 16 deletions

View file

@ -68,6 +68,7 @@ public abstract class BisqExecutable implements GracefulShutDownHandler, BisqSet
protected AppModule module;
protected Config config;
private boolean isShutdownInProgress;
private boolean hasDowngraded;
public BisqExecutable(String fullName, String scriptName, String appName, String version) {
this.fullName = fullName;
@ -133,9 +134,17 @@ public abstract class BisqExecutable implements GracefulShutDownHandler, BisqSet
CommonSetup.setupUncaughtExceptionHandler(this);
setupGuice();
setupAvoidStandbyMode();
readAllPersisted(this::startApplication);
}
hasDowngraded = BisqSetup.hasDowngraded();
if (hasDowngraded) {
// If user tried to downgrade we do not read the persisted data to avoid data corruption
// We call startApplication to enable UI to show popup. We prevent in BisqSetup to go further
// in the process and require a shut down.
startApplication();
} else {
readAllPersisted(this::startApplication);
}
}
///////////////////////////////////////////////////////////////////////////////////////////
// We continue with a series of synchronous execution tasks
@ -236,11 +245,16 @@ public abstract class BisqExecutable implements GracefulShutDownHandler, BisqSet
injector.getInstance(P2PService.class).shutDown(() -> {
log.info("P2PService shutdown completed");
module.close(injector);
PersistenceManager.flushAllDataToDisk(() -> {
log.info("Graceful shutdown completed. Exiting now.");
resultHandler.handleResult();
if (!hasDowngraded) {
// If user tried to downgrade we do not write the persistable data to avoid data corruption
PersistenceManager.flushAllDataToDisk(() -> {
log.info("Graceful shutdown completed. Exiting now.");
resultHandler.handleResult();
System.exit(EXIT_SUCCESS);
});
} else {
System.exit(EXIT_SUCCESS);
});
}
});
});
walletsSetup.shutDown();
@ -250,20 +264,31 @@ public abstract class BisqExecutable implements GracefulShutDownHandler, BisqSet
// Wait max 20 sec.
UserThread.runAfter(() -> {
log.warn("Timeout triggered resultHandler");
PersistenceManager.flushAllDataToDisk(() -> {
log.info("Graceful shutdown resulted in a timeout. Exiting now.");
resultHandler.handleResult();
if (!hasDowngraded) {
// If user tried to downgrade we do not write the persistable data to avoid data corruption
PersistenceManager.flushAllDataToDisk(() -> {
log.info("Graceful shutdown resulted in a timeout. Exiting now.");
resultHandler.handleResult();
System.exit(EXIT_SUCCESS);
});
} else {
System.exit(EXIT_SUCCESS);
});
}
}, 20);
} catch (Throwable t) {
log.error("App shutdown failed with exception {}", t.toString());
t.printStackTrace();
PersistenceManager.flushAllDataToDisk(() -> {
log.info("Graceful shutdown resulted in an error. Exiting now.");
resultHandler.handleResult();
if (!hasDowngraded) {
// If user tried to downgrade we do not write the persistable data to avoid data corruption
PersistenceManager.flushAllDataToDisk(() -> {
log.info("Graceful shutdown resulted in an error. Exiting now.");
resultHandler.handleResult();
System.exit(EXIT_FAILURE);
});
} else {
System.exit(EXIT_FAILURE);
});
}
}
}

View file

@ -20,6 +20,7 @@ package bisq.core.app;
import bisq.core.trade.TradeManager;
import bisq.common.UserThread;
import bisq.common.app.Version;
import bisq.common.file.CorruptedStorageFileHandler;
import bisq.common.setup.GracefulShutDownHandler;
@ -94,6 +95,8 @@ public class BisqHeadlessApp implements HeadlessApp {
bisqSetup.setRevolutAccountsUpdateHandler(revolutAccountList -> log.info("setRevolutAccountsUpdateHandler: revolutAccountList={}", revolutAccountList));
bisqSetup.setOsxKeyLoggerWarningHandler(() -> log.info("setOsxKeyLoggerWarningHandler"));
bisqSetup.setQubesOSInfoHandler(() -> log.info("setQubesOSInfoHandler"));
bisqSetup.setDownGradePreventionHandler(lastVersion -> log.info("Downgrade from version {} to version {} is not supported",
lastVersion, Version.VERSION));
corruptedStorageFileHandler.getFiles().ifPresent(files -> log.warn("getCorruptedDatabaseFiles. files={}", files));
tradeManager.setTakeOfferRequestErrorMessageHandler(errorMessage -> log.error("onTakeOfferRequestErrorMessageHandler"));

View file

@ -48,6 +48,7 @@ import bisq.common.Timer;
import bisq.common.UserThread;
import bisq.common.app.DevEnv;
import bisq.common.app.Log;
import bisq.common.app.Version;
import bisq.common.config.Config;
import bisq.common.util.InvalidVersionException;
import bisq.common.util.Utilities;
@ -71,11 +72,15 @@ import javafx.collections.SetChangeListener;
import org.bouncycastle.crypto.params.KeyParameter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
@ -92,6 +97,7 @@ import javax.annotation.Nullable;
@Slf4j
@Singleton
public class BisqSetup {
private static final String VERSION_FILE_NAME = "version";
public interface BisqSetupListener {
default void onInitP2pNetwork() {
@ -172,6 +178,9 @@ public class BisqSetup {
@Setter
@Nullable
private Runnable qubesOSInfoHandler;
@Setter
@Nullable
private Consumer<String> downGradePreventionHandler;
@Getter
final BooleanProperty newVersionAvailableProperty = new SimpleBooleanProperty(false);
@ -255,6 +264,12 @@ public class BisqSetup {
}
public void start() {
// If user tried to downgrade we require a shutdown
if (hasDowngraded(downGradePreventionHandler)) {
return;
}
persistBisqVersion();
maybeReSyncSPVChain();
maybeShowTac(this::step2);
}
@ -387,7 +402,7 @@ public class BisqSetup {
requestWalletPasswordHandler.accept(aesKey -> {
walletsManager.setAesKey(aesKey);
walletsSetup.getWalletConfig().maybeAddSegwitKeychain(walletsSetup.getWalletConfig().btcWallet(),
aesKey);
aesKey);
if (preferences.isResyncSpvRequested()) {
if (showFirstPopupIfResyncSPVRequestedHandler != null)
showFirstPopupIfResyncSPVRequestedHandler.run();
@ -487,6 +502,68 @@ public class BisqSetup {
});
}
@Nullable
public static String getLastBisqVersion() {
File versionFile = getVersionFile();
if (!versionFile.exists()) {
return null;
}
try (Scanner scanner = new Scanner(versionFile)) {
// We only expect 1 line
if (scanner.hasNextLine()) {
return scanner.nextLine();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return null;
}
private static File getVersionFile() {
return new File(Config.appDataDir(), VERSION_FILE_NAME);
}
public static boolean hasDowngraded() {
return hasDowngraded(getLastBisqVersion());
}
public static boolean hasDowngraded(String lastVersion) {
return lastVersion != null && Version.isNewVersion(lastVersion, Version.VERSION);
}
public static boolean hasDowngraded(@Nullable Consumer<String> downGradePreventionHandler) {
String lastVersion = getLastBisqVersion();
boolean hasDowngraded = hasDowngraded(lastVersion);
if (hasDowngraded) {
log.error("Downgrade from version {} to version {} is not supported", lastVersion, Version.VERSION);
if (downGradePreventionHandler != null) {
downGradePreventionHandler.accept(lastVersion);
}
}
return hasDowngraded;
}
public static void persistBisqVersion() {
File versionFile = getVersionFile();
if (!versionFile.exists()) {
try {
if (!versionFile.createNewFile()) {
log.error("Version file could not be created");
}
} catch (IOException e) {
e.printStackTrace();
log.error("Version file could not be created. {}", e.toString());
}
}
try (FileWriter fileWriter = new FileWriter(versionFile, false)) {
fileWriter.write(Version.VERSION);
} catch (IOException e) {
e.printStackTrace();
log.error("Writing Version failed. {}", e.toString());
}
}
private void checkForCorrectOSArchitecture() {
if (!Utilities.isCorrectOSArchitecture() && wrongOSArchitectureHandler != null) {
String osArchitecture = Utilities.getOSArchitecture();

View file

@ -2819,6 +2819,7 @@ popup.info.shutDownWithOpenOffers=Bisq is being shut down, but there are open of
(i.e., make sure it doesn't go into standby mode...monitor standby is not a problem).
popup.info.qubesOSSetupInfo=It appears you are running Bisq on Qubes OS. \n\n\
Please make sure your Bisq qube is setup according to our Setup Guide at [HYPERLINK:https://bisq.wiki/Running_Bisq_on_Qubes].
popup.warn.downGradePrevention=Downgrade from version {0} to version {1} is not supported. Please use the latest Bisq version.
popup.privateNotification.headline=Important private notification!

View file

@ -809,7 +809,7 @@ public class MainView extends InitializableView<StackPane, MainViewModel>
this.setToggleGroup(navButtons);
this.getStyleClass().add("nav-button");
// Japanese fonts are dense, increase top nav button text size
if (model.getPreferences().getUserLanguage().equals("ja")) {
if (model.getPreferences() != null && "ja".equals(model.getPreferences().getUserLanguage())) {
this.getStyleClass().add("nav-button-japanese");
}

View file

@ -403,6 +403,13 @@ public class MainViewModel implements ViewModel, BisqSetup.BisqSetupListener {
}
});
bisqSetup.setDownGradePreventionHandler(lastVersion -> {
new Popup().warning(Res.get("popup.warn.downGradePrevention", lastVersion, Version.VERSION))
.useShutDownButton()
.hideCloseButton()
.show();
});
corruptedStorageFileHandler.getFiles().ifPresent(files -> new Popup()
.warning(Res.get("popup.warning.incompatibleDB", files.toString(), config.appDataDir))
.useShutDownButton()