From a54298690f6f831284ee84699f95e0d5c510c668 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Tue, 11 Dec 2018 12:10:28 +0100 Subject: [PATCH 1/2] Update display string - Remove info that you cannot import seeds from pre v0.5.0 wallets --- core/src/main/resources/i18n/displayStrings.properties | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/core/src/main/resources/i18n/displayStrings.properties b/core/src/main/resources/i18n/displayStrings.properties index dd581cf0b9d..b6c373746ba 100644 --- a/core/src/main/resources/i18n/displayStrings.properties +++ b/core/src/main/resources/i18n/displayStrings.properties @@ -1106,11 +1106,10 @@ account.seed.warn.noPw.msg=You have not setup a wallet password which would prot Do you want to display the seed words? account.seed.warn.noPw.yes=Yes, and don't ask me again account.seed.enterPw=Enter password to view seed words -account.seed.restore.info=Please note that you cannot import a wallet from an old Bisq version (any version before 0.5.0), \ - because the wallet format has changed!\n\n\ - If you want to move the funds from the old version to the new Bisq application send it with a bitcoin transaction.\n\n\ - Also be aware that wallet restore is only for emergency cases and might cause problems with the internal wallet database.\n\ - It is not a way for applying a backup! Please use a backup from the application data directory for restoring a previous application state. +account.seed.restore.info=Please make a backup before applying restore from seed words. Be aware that wallet restore is \ + only for emergency cases and might cause problems with the internal wallet database.\n\ + It is not a way for applying a backup! Please use a backup from the application data directory for restoring a \ + previous application state. account.seed.restore.ok=Ok, I understand and want to restore From 5bf7ba46a7a0cb97c7552a883689a8522b447557 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Wed, 12 Dec 2018 13:35:13 +0100 Subject: [PATCH 2/2] Handle cycles in case of applying a empty snapshot --- .../dao/governance/period/CycleService.java | 42 ++++++++++--------- .../dao/state/DaoStateSnapshotService.java | 23 ++++++---- 2 files changed, 38 insertions(+), 27 deletions(-) diff --git a/core/src/main/java/bisq/core/dao/governance/period/CycleService.java b/core/src/main/java/bisq/core/dao/governance/period/CycleService.java index 0300201dad9..4276c448e48 100644 --- a/core/src/main/java/bisq/core/dao/governance/period/CycleService.java +++ b/core/src/main/java/bisq/core/dao/governance/period/CycleService.java @@ -68,7 +68,7 @@ public void addListeners() { @Override public void start() { - daoStateService.getCycles().add(getFirstCycle()); + addFirstCycle(); } @@ -96,6 +96,28 @@ public void onParseBlockChainComplete() { // API /////////////////////////////////////////////////////////////////////////////////////////// + public void addFirstCycle() { + daoStateService.getCycles().add(getFirstCycle()); + } + + public int getCycleIndex(Cycle cycle) { + return (cycle.getHeightOfFirstBlock() - genesisBlockHeight) / cycle.getDuration(); + } + + public boolean isTxInCycle(Cycle cycle, String txId) { + return daoStateService.getTx(txId).filter(tx -> isBlockHeightInCycle(tx.getBlockHeight(), cycle)).isPresent(); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Private + /////////////////////////////////////////////////////////////////////////////////////////// + + private boolean isBlockHeightInCycle(int blockHeight, Cycle cycle) { + return blockHeight >= cycle.getHeightOfFirstBlock() && + blockHeight <= cycle.getHeightOfLastBlock(); + } + private Optional maybeCreateNewCycle(int blockHeight, LinkedList cycles) { // We want to set the correct phase and cycle before we start parsing a new block. // For Genesis block we did it already in the start method. @@ -128,24 +150,6 @@ private Cycle getFirstCycle() { return new Cycle(genesisBlockHeight, ImmutableList.copyOf(daoPhasesWithDefaultDuration)); } - public int getCycleIndex(Cycle cycle) { - return (cycle.getHeightOfFirstBlock() - genesisBlockHeight) / cycle.getDuration(); - } - - public boolean isTxInCycle(Cycle cycle, String txId) { - return daoStateService.getTx(txId).filter(tx -> isBlockHeightInCycle(tx.getBlockHeight(), cycle)).isPresent(); - } - - private boolean isBlockHeightInCycle(int blockHeight, Cycle cycle) { - return blockHeight >= cycle.getHeightOfFirstBlock() && - blockHeight <= cycle.getHeightOfLastBlock(); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Private - /////////////////////////////////////////////////////////////////////////////////////////// - private Cycle createNewCycle(int blockHeight, Cycle previousCycle) { List daoPhaseList = previousCycle.getDaoPhaseList().stream() .map(daoPhase -> { diff --git a/core/src/main/java/bisq/core/dao/state/DaoStateSnapshotService.java b/core/src/main/java/bisq/core/dao/state/DaoStateSnapshotService.java index fe20b7de82d..091a331098e 100644 --- a/core/src/main/java/bisq/core/dao/state/DaoStateSnapshotService.java +++ b/core/src/main/java/bisq/core/dao/state/DaoStateSnapshotService.java @@ -17,6 +17,7 @@ package bisq.core.dao.state; +import bisq.core.dao.governance.period.CycleService; import bisq.core.dao.state.model.DaoState; import bisq.core.dao.state.model.blockchain.Block; @@ -41,6 +42,7 @@ public class DaoStateSnapshotService implements DaoStateListener { private final DaoStateService daoStateService; private final GenesisTxInfo genesisTxInfo; + private final CycleService cycleService; private final DaoStateStorageService daoStateStorageService; private DaoState snapshotCandidate; @@ -53,9 +55,11 @@ public class DaoStateSnapshotService implements DaoStateListener { @Inject public DaoStateSnapshotService(DaoStateService daoStateService, GenesisTxInfo genesisTxInfo, + CycleService cycleService, DaoStateStorageService daoStateStorageService) { this.daoStateService = daoStateService; this.genesisTxInfo = genesisTxInfo; + this.cycleService = cycleService; this.daoStateStorageService = daoStateStorageService; this.daoStateService.addBsqStateListener(this); @@ -128,19 +132,13 @@ public void applySnapshot(boolean fromReorg) { log.warn("We applied already a snapshot with chainHeight {}. We will reset the daoState and " + "start over from the genesis transaction again.", chainHeightOfLastApplySnapshot); persisted = new DaoState(); - int genesisBlockHeight = genesisTxInfo.getGenesisBlockHeight(); - persisted.setChainHeight(genesisBlockHeight); - chainHeightOfLastApplySnapshot = genesisBlockHeight; - daoStateService.applySnapshot(persisted); + applyEmptySnapshot(persisted); } } } else if (fromReorg) { log.info("We got a reorg and we want to apply the snapshot but it is empty. That is expected in the first blocks until the " + "first snapshot has been created. We use our applySnapshot method and restart from the genesis tx"); - int genesisBlockHeight = genesisTxInfo.getGenesisBlockHeight(); - persisted.setChainHeight(genesisBlockHeight); - chainHeightOfLastApplySnapshot = genesisBlockHeight; - daoStateService.applySnapshot(persisted); + applyEmptySnapshot(persisted); } } else { log.info("Try to apply snapshot but no stored snapshot available. That is expected at first blocks."); @@ -152,6 +150,15 @@ public void applySnapshot(boolean fromReorg) { // Private /////////////////////////////////////////////////////////////////////////////////////////// + private void applyEmptySnapshot(DaoState persisted) { + int genesisBlockHeight = genesisTxInfo.getGenesisBlockHeight(); + persisted.setChainHeight(genesisBlockHeight); + chainHeightOfLastApplySnapshot = genesisBlockHeight; + daoStateService.applySnapshot(persisted); + // In case we apply an empty snapshot we need to trigger the cycleService.addFirstCycle method + cycleService.addFirstCycle(); + } + @VisibleForTesting int getSnapshotHeight(int genesisHeight, int height, int grid) { return Math.round(Math.max(genesisHeight + 3 * grid, height) / grid) * grid - grid;