mirror of
https://github.com/bisq-network/bisq.git
synced 2024-11-19 01:41:11 +01:00
Add resync from resources button
We add a second button (displayed as first) to the preferences UI for resync from latest resources. We add a warning to the resync from genesis as it takes very long time and causes heavy network load for seeds. The resync button at the stateMonitor does now a resync from resources, not from genesis. We add handling of the UnconfirmedBsqChangeOutputList file as well. In Filemanager we add a check if file exists.
This commit is contained in:
parent
bc7f570a18
commit
f7dfef253a
@ -165,7 +165,9 @@ public class FileManager<T extends PersistableEnvelope> {
|
||||
log.warn("make dir failed");
|
||||
|
||||
File corruptedFile = new File(Paths.get(dbDir.getAbsolutePath(), backupFolderName, fileName).toString());
|
||||
FileUtil.renameFile(storageFile, corruptedFile);
|
||||
if (storageFile.exists()) {
|
||||
FileUtil.renameFile(storageFile, corruptedFile);
|
||||
}
|
||||
}
|
||||
|
||||
synchronized void removeAndBackupFile(String fileName) throws IOException {
|
||||
|
@ -91,6 +91,7 @@ import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.collections.transformation.FilteredList;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -517,7 +518,10 @@ public class DaoFacade implements DaoSetupService {
|
||||
lockupTxService.publishLockupTx(lockupAmount, lockTime, lockupReason, hash, resultHandler, exceptionHandler);
|
||||
}
|
||||
|
||||
public Tuple2<Coin, Integer> getLockupTxMiningFeeAndTxSize(Coin lockupAmount, int lockTime, LockupReason lockupReason, byte[] hash)
|
||||
public Tuple2<Coin, Integer> getLockupTxMiningFeeAndTxSize(Coin lockupAmount,
|
||||
int lockTime,
|
||||
LockupReason lockupReason,
|
||||
byte[] hash)
|
||||
throws InsufficientMoneyException, IOException, TransactionVerificationException, WalletException {
|
||||
return lockupTxService.getMiningFeeAndTxSize(lockupAmount, lockTime, lockupReason, hash);
|
||||
}
|
||||
@ -700,8 +704,12 @@ public class DaoFacade implements DaoSetupService {
|
||||
return daoStateService.getParamValue(param, blockHeight);
|
||||
}
|
||||
|
||||
public void resyncDao(Runnable resultHandler) {
|
||||
daoStateStorageService.resetDaoState(resultHandler);
|
||||
public void resyncDaoStateFromGenesis(Runnable resultHandler) {
|
||||
daoStateStorageService.resyncDaoStateFromGenesis(resultHandler);
|
||||
}
|
||||
|
||||
public void resyncDaoStateFromResources(File storageDir) throws IOException {
|
||||
daoStateStorageService.resyncDaoStateFromResources(storageDir);
|
||||
}
|
||||
|
||||
public boolean isMyRole(Role role) {
|
||||
|
@ -26,12 +26,14 @@ import bisq.network.p2p.storage.persistence.StoreService;
|
||||
|
||||
import bisq.common.UserThread;
|
||||
import bisq.common.config.Config;
|
||||
import bisq.common.storage.FileManager;
|
||||
import bisq.common.storage.Storage;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -101,11 +103,33 @@ public class DaoStateStorageService extends StoreService<DaoStateStore> {
|
||||
return store.getDaoStateHashChain();
|
||||
}
|
||||
|
||||
public void resetDaoState(Runnable resultHandler) {
|
||||
public void resyncDaoStateFromGenesis(Runnable resultHandler) {
|
||||
persist(new DaoState(), new LinkedList<>(), 1);
|
||||
UserThread.runAfter(resultHandler, 300, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
public void resyncDaoStateFromResources(File storageDir) throws IOException {
|
||||
// We delete all DAO consensus payload data and remove the daoState so it will rebuild from latest
|
||||
// resource files.
|
||||
long currentTime = System.currentTimeMillis();
|
||||
String backupDirName = "out_of_sync_dao_data";
|
||||
String newFileName = "BlindVoteStore_" + currentTime;
|
||||
FileManager.removeAndBackupFile(storageDir, new File(storageDir, "BlindVoteStore"), newFileName, backupDirName);
|
||||
|
||||
newFileName = "ProposalStore_" + currentTime;
|
||||
FileManager.removeAndBackupFile(storageDir, new File(storageDir, "ProposalStore"), newFileName, backupDirName);
|
||||
|
||||
// We also need to remove ballot list as it contains the proposals as well. It will be recreated at resync
|
||||
newFileName = "BallotList_" + currentTime;
|
||||
FileManager.removeAndBackupFile(storageDir, new File(storageDir, "BallotList"), newFileName, backupDirName);
|
||||
|
||||
newFileName = "UnconfirmedBsqChangeOutputList_" + currentTime;
|
||||
FileManager.removeAndBackupFile(storageDir, new File(storageDir, "UnconfirmedBsqChangeOutputList"), newFileName, backupDirName);
|
||||
|
||||
newFileName = "DaoStateStore_" + currentTime;
|
||||
FileManager.removeAndBackupFile(storageDir, new File(storageDir, "DaoStateStore"), newFileName, backupDirName);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Protected
|
||||
|
@ -1074,10 +1074,15 @@ settings.preferences.languageChange=To apply the language change to all screens
|
||||
settings.preferences.supportLanguageWarning=In case of a dispute, please note that mediation is handled in {0} and arbitration in {1}.
|
||||
settings.preferences.selectCurrencyNetwork=Select network
|
||||
setting.preferences.daoOptions=DAO options
|
||||
setting.preferences.dao.resync.label=Rebuild DAO state from genesis tx
|
||||
setting.preferences.dao.resync.button=Resync
|
||||
setting.preferences.dao.resync.popup=After an application restart the Bisq network governance data will be reloaded from \
|
||||
setting.preferences.dao.resyncFromGenesis.label=Rebuild DAO state from genesis tx
|
||||
setting.preferences.dao.resyncFromResources.label=Rebuild DAO state from resources
|
||||
setting.preferences.dao.resyncFromResources.popup=After an application restart the Bisq network governance data will be reloaded from \
|
||||
the seed nodes and the BSQ consensus state will be rebuilt from the latest resource files.
|
||||
setting.preferences.dao.resyncFromGenesis.popup=A resync from genesis transaction can take considerable time and CPU \
|
||||
resources. Are you sure you want to do that? Mostly a resync from latest resource files is sufficient and much faster.\n\n\
|
||||
If you proceed, after an application restart the Bisq network governance data will be reloaded from \
|
||||
the seed nodes and the BSQ consensus state will be rebuilt from the genesis transaction.
|
||||
setting.preferences.dao.resyncFromGenesis.resync=Resync from genesis and shutdown
|
||||
setting.preferences.dao.isDaoFullNode=Run Bisq as DAO full node
|
||||
setting.preferences.dao.rpcUser=RPC username
|
||||
setting.preferences.dao.rpcPw=RPC password
|
||||
|
@ -18,7 +18,6 @@
|
||||
package bisq.desktop.main.dao.monitor;
|
||||
|
||||
import bisq.desktop.common.view.ActivatableView;
|
||||
import bisq.desktop.common.view.FxmlView;
|
||||
import bisq.desktop.components.AutoTooltipButton;
|
||||
import bisq.desktop.components.AutoTooltipLabel;
|
||||
import bisq.desktop.components.AutoTooltipTableColumn;
|
||||
@ -40,8 +39,6 @@ import bisq.core.locale.Res;
|
||||
import bisq.network.p2p.NodeAddress;
|
||||
import bisq.network.p2p.seed.SeedNodeRepository;
|
||||
|
||||
import bisq.common.storage.FileManager;
|
||||
|
||||
import de.jensd.fx.fontawesome.AwesomeIcon;
|
||||
|
||||
import javafx.scene.control.Button;
|
||||
@ -140,33 +137,7 @@ public abstract class StateMonitorView<StH extends StateHash,
|
||||
resyncButton.visibleProperty().bind(isInConflictWithSeedNode);
|
||||
resyncButton.managedProperty().bind(isInConflictWithSeedNode);
|
||||
|
||||
resyncButton.setOnAction(ev -> {
|
||||
try {
|
||||
// We delete all consensus payload data and reset the daoState so it will rebuild from genesis.
|
||||
// Deleting the daoState would cause to read the file from the resources and we would not rebuild from
|
||||
// genesis if a snapshot exist!
|
||||
long currentTime = System.currentTimeMillis();
|
||||
String backupDirName = "out_of_sync_dao_data";
|
||||
String newFileName = "BlindVoteStore_" + currentTime;
|
||||
FileManager.removeAndBackupFile(storageDir, new File(storageDir, "BlindVoteStore"), newFileName, backupDirName);
|
||||
|
||||
newFileName = "ProposalStore_" + currentTime;
|
||||
FileManager.removeAndBackupFile(storageDir, new File(storageDir, "ProposalStore"), newFileName, backupDirName);
|
||||
|
||||
// We also need to remove ballot list as it contains the proposals as well. It will be recreated at resync
|
||||
newFileName = "BallotList_" + currentTime;
|
||||
FileManager.removeAndBackupFile(storageDir, new File(storageDir, "BallotList"), newFileName, backupDirName);
|
||||
|
||||
daoFacade.resyncDao(() -> new Popup().attention(Res.get("setting.preferences.dao.resync.popup"))
|
||||
.useShutDownButton()
|
||||
.hideCloseButton()
|
||||
.show());
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
log.error(t.toString());
|
||||
new Popup().error(t.toString()).show();
|
||||
}
|
||||
});
|
||||
resyncButton.setOnAction(ev -> resyncDaoState());
|
||||
|
||||
if (daoStateService.isParseBlockChainComplete()) {
|
||||
onDataUpdate();
|
||||
@ -294,7 +265,9 @@ public abstract class StateMonitorView<StH extends StateHash,
|
||||
|
||||
protected void onDataUpdate() {
|
||||
if (isInConflictWithSeedNode.get()) {
|
||||
statusTextField.setText(Res.get("dao.monitor.isInConflictWithSeedNode"));
|
||||
String msg = Res.get("dao.monitor.isInConflictWithSeedNode");
|
||||
log.warn(msg);
|
||||
statusTextField.setText(msg);
|
||||
statusTextField.getStyleClass().add("dao-inConflict");
|
||||
} else if (isInConflictWithNonSeedNode.get()) {
|
||||
statusTextField.setText(Res.get("dao.monitor.isInConflictWithNonSeedNode"));
|
||||
@ -307,6 +280,20 @@ public abstract class StateMonitorView<StH extends StateHash,
|
||||
GUIUtil.setFitToRowsForTableView(tableView, 25, 28, 2, 5);
|
||||
}
|
||||
|
||||
private void resyncDaoState() {
|
||||
try {
|
||||
daoFacade.resyncDaoStateFromResources(storageDir);
|
||||
new Popup().attention(Res.get("setting.preferences.dao.resyncFromResources.popup"))
|
||||
.useShutDownButton()
|
||||
.hideCloseButton()
|
||||
.show();
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
log.error(t.toString());
|
||||
new Popup().error(t.toString()).show();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// TableColumns
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
package bisq.desktop.main.settings.preferences;
|
||||
|
||||
import bisq.desktop.app.BisqApp;
|
||||
import bisq.desktop.common.view.ActivatableViewAndModel;
|
||||
import bisq.desktop.common.view.FxmlView;
|
||||
import bisq.desktop.components.AutoTooltipButton;
|
||||
@ -88,6 +89,8 @@ import javafx.collections.ObservableList;
|
||||
import javafx.util.Callback;
|
||||
import javafx.util.StringConverter;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -123,12 +126,13 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
|
||||
private final AssetService assetService;
|
||||
private final FilterManager filterManager;
|
||||
private final DaoFacade daoFacade;
|
||||
private final File storageDir;
|
||||
|
||||
private ListView<FiatCurrency> fiatCurrenciesListView;
|
||||
private ComboBox<FiatCurrency> fiatCurrenciesComboBox;
|
||||
private ListView<CryptoCurrency> cryptoCurrenciesListView;
|
||||
private ComboBox<CryptoCurrency> cryptoCurrenciesComboBox;
|
||||
private Button resetDontShowAgainButton, resyncDaoButton;
|
||||
private Button resetDontShowAgainButton, resyncDaoFromGenesisButton, resyncDaoFromResourcesButton;
|
||||
// private ListChangeListener<TradeCurrency> displayCurrenciesListChangeListener;
|
||||
private ObservableList<BlockChainExplorer> blockExplorers;
|
||||
private ObservableList<BlockChainExplorer> bsqBlockChainExplorers;
|
||||
@ -162,13 +166,15 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
|
||||
Config config,
|
||||
@Named(Config.RPC_USER) String rpcUser,
|
||||
@Named(Config.RPC_PASSWORD) String rpcPassword,
|
||||
@Named(Config.RPC_BLOCK_NOTIFICATION_PORT) int rpcBlockNotificationPort) {
|
||||
@Named(Config.RPC_BLOCK_NOTIFICATION_PORT) int rpcBlockNotificationPort,
|
||||
@Named(Config.STORAGE_DIR) File storageDir) {
|
||||
super(model);
|
||||
this.preferences = preferences;
|
||||
this.feeService = feeService;
|
||||
this.assetService = assetService;
|
||||
this.filterManager = filterManager;
|
||||
this.daoFacade = daoFacade;
|
||||
this.storageDir = storageDir;
|
||||
daoOptionsSet = config.fullDaoNodeOptionSetExplicitly &&
|
||||
!rpcUser.isEmpty() &&
|
||||
!rpcPassword.isEmpty() &&
|
||||
@ -600,10 +606,14 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
|
||||
}
|
||||
|
||||
private void initializeDaoOptions() {
|
||||
daoOptionsTitledGroupBg = addTitledGroupBg(root, ++gridRow, 1, Res.get("setting.preferences.daoOptions"), Layout.GROUP_DISTANCE);
|
||||
resyncDaoButton = addButton(root, gridRow, Res.get("setting.preferences.dao.resync.label"), Layout.TWICE_FIRST_ROW_AND_GROUP_DISTANCE);
|
||||
resyncDaoButton.setMaxWidth(Double.MAX_VALUE);
|
||||
GridPane.setHgrow(resyncDaoButton, Priority.ALWAYS);
|
||||
daoOptionsTitledGroupBg = addTitledGroupBg(root, ++gridRow, 2, Res.get("setting.preferences.daoOptions"), Layout.GROUP_DISTANCE);
|
||||
resyncDaoFromResourcesButton = addButton(root, gridRow, Res.get("setting.preferences.dao.resyncFromResources.label"), Layout.TWICE_FIRST_ROW_AND_GROUP_DISTANCE);
|
||||
resyncDaoFromResourcesButton.setMaxWidth(Double.MAX_VALUE);
|
||||
GridPane.setHgrow(resyncDaoFromResourcesButton, Priority.ALWAYS);
|
||||
|
||||
resyncDaoFromGenesisButton = addButton(root, ++gridRow, Res.get("setting.preferences.dao.resyncFromGenesis.label"));
|
||||
resyncDaoFromGenesisButton.setMaxWidth(Double.MAX_VALUE);
|
||||
GridPane.setHgrow(resyncDaoFromGenesisButton, Priority.ALWAYS);
|
||||
|
||||
isDaoFullNodeToggleButton = addSlideToggleButton(root, ++gridRow, Res.get("setting.preferences.dao.isDaoFullNode"));
|
||||
rpcUserTextField = addInputTextField(root, ++gridRow, Res.get("setting.preferences.dao.rpcUser"));
|
||||
@ -865,11 +875,26 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
|
||||
blockNotifyPortTextField.setText(blockNotifyPort > 0 ? String.valueOf(blockNotifyPort) : "");
|
||||
updateDaoFields();
|
||||
|
||||
resyncDaoButton.setOnAction(e -> daoFacade.resyncDao(() ->
|
||||
new Popup().attention(Res.get("setting.preferences.dao.resync.popup"))
|
||||
resyncDaoFromResourcesButton.setOnAction(e -> {
|
||||
try {
|
||||
daoFacade.resyncDaoStateFromResources(storageDir);
|
||||
new Popup().attention(Res.get("setting.preferences.dao.resyncFromResources.popup"))
|
||||
.useShutDownButton()
|
||||
.hideCloseButton()
|
||||
.show()));
|
||||
.show();
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
log.error(t.toString());
|
||||
new Popup().error(t.toString()).show();
|
||||
}
|
||||
});
|
||||
|
||||
resyncDaoFromGenesisButton.setOnAction(e ->
|
||||
new Popup().attention(Res.get("setting.preferences.dao.resyncFromGenesis.popup"))
|
||||
.actionButtonText(Res.get("setting.preferences.dao.resyncFromGenesis.resync"))
|
||||
.onAction(() -> daoFacade.resyncDaoStateFromGenesis(() -> BisqApp.getShutDownHandler().run()))
|
||||
.closeButtonText(Res.get("shared.cancel"))
|
||||
.show());
|
||||
|
||||
isDaoFullNodeToggleButton.setOnAction(e -> {
|
||||
String key = "daoFullModeInfoShown";
|
||||
@ -973,7 +998,8 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
|
||||
}
|
||||
|
||||
private void deactivateDaoPreferences() {
|
||||
resyncDaoButton.setOnAction(null);
|
||||
resyncDaoFromResourcesButton.setOnAction(null);
|
||||
resyncDaoFromGenesisButton.setOnAction(null);
|
||||
isDaoFullNodeToggleButton.setOnAction(null);
|
||||
rpcUserTextField.textProperty().removeListener(rpcUserListener);
|
||||
rpcPwTextField.textProperty().removeListener(rpcPwListener);
|
||||
|
Loading…
Reference in New Issue
Block a user