From 4f6981b86943984f385c5549deb002e5d4e356ac Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Wed, 15 Mar 2023 08:44:53 +0200 Subject: [PATCH] change wallet gap limit and subscribe to new addresses if an address beyond gap limit range is requested --- .../event/WalletGapLimitChangedEvent.java | 26 ++++++++++++++++++- .../sparrow/wallet/ReceiveController.java | 14 ++++++++++ .../sparrow/wallet/SettingsController.java | 7 +++++ .../sparrow/wallet/SettingsWalletForm.java | 4 +++ .../sparrow/wallet/WalletForm.java | 4 ++- .../dataSource/SparrowIndexHandler.java | 11 +++++++- 6 files changed, 63 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/sparrowwallet/sparrow/event/WalletGapLimitChangedEvent.java b/src/main/java/com/sparrowwallet/sparrow/event/WalletGapLimitChangedEvent.java index be54412f..8c87afb4 100644 --- a/src/main/java/com/sparrowwallet/sparrow/event/WalletGapLimitChangedEvent.java +++ b/src/main/java/com/sparrowwallet/sparrow/event/WalletGapLimitChangedEvent.java @@ -1,17 +1,41 @@ package com.sparrowwallet.sparrow.event; import com.sparrowwallet.drongo.wallet.Wallet; +import com.sparrowwallet.drongo.wallet.WalletNode; /** * This event is posted if the wallet's gap limit has changed, and triggers a history fetch for the new nodes. * */ public class WalletGapLimitChangedEvent extends WalletChangedEvent { - public WalletGapLimitChangedEvent(Wallet wallet) { + private final String walletId; + private final int previousGapLimit; + + public WalletGapLimitChangedEvent(String walletId, Wallet wallet, int previousGapLimit) { super(wallet); + this.walletId = walletId; + this.previousGapLimit = previousGapLimit; + } + + public String getWalletId() { + return walletId; } public int getGapLimit() { return getWallet().getGapLimit(); } + + public int getPreviousGapLimit() { + return previousGapLimit; + } + + public int getPreviousLookAheadIndex(WalletNode node) { + int lookAheadIndex = getPreviousGapLimit() - 1; + Integer highestUsed = node.getHighestUsedIndex(); + if(highestUsed != null) { + lookAheadIndex = highestUsed + getPreviousGapLimit(); + } + + return lookAheadIndex; + } } diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/ReceiveController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/ReceiveController.java index 9141bf79..72c0a148 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/ReceiveController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/ReceiveController.java @@ -189,6 +189,9 @@ public class ReceiveController extends WalletFormController implements Initializ public void getNewAddress(ActionEvent event) { refreshAddress(); + if(currentEntry != null) { + ensureSufficientGapLimit(currentEntry.getNode().getIndex()); + } } public void refreshAddress() { @@ -196,6 +199,17 @@ public class ReceiveController extends WalletFormController implements Initializ setNodeEntry(freshEntry); } + private void ensureSufficientGapLimit(int index) { + Wallet wallet = getWalletForm().getWallet(); + Integer highestIndex = wallet.getNode(KeyPurpose.RECEIVE).getHighestUsedIndex(); + int highestUsedIndex = highestIndex == null ? -1 : highestIndex; + int existingGapLimit = wallet.getGapLimit(); + if(index > highestUsedIndex + existingGapLimit) { + wallet.setGapLimit(Math.max(wallet.getGapLimit(), index - highestUsedIndex)); + EventManager.get().post(new WalletGapLimitChangedEvent(getWalletForm().getWalletId(), wallet, existingGapLimit)); + } + } + @SuppressWarnings("unchecked") public void displayAddress(ActionEvent event) { Wallet wallet = getWalletForm().getWallet(); diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/SettingsController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/SettingsController.java index f114f2e3..9103c1bb 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/SettingsController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/SettingsController.java @@ -730,6 +730,13 @@ public class SettingsController extends WalletFormController implements Initiali } } + @Subscribe + public void walletGapLimitChanged(WalletGapLimitChangedEvent event) { + if(walletForm.getWalletId().equals(event.getWalletId())) { + ((SettingsWalletForm)walletForm).gapLimitChanged(event.getGapLimit()); + } + } + @Subscribe public void existingWalletImported(ExistingWalletImportedEvent event) { if(event.getExistingWalletId().equals(getWalletForm().getWalletId())) { diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/SettingsWalletForm.java b/src/main/java/com/sparrowwallet/sparrow/wallet/SettingsWalletForm.java index 37685cf8..fc5dbbb1 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/SettingsWalletForm.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/SettingsWalletForm.java @@ -253,4 +253,8 @@ public class SettingsWalletForm extends WalletForm { masterWalletCopy.getChildWallets().add(childWallet.copy()); } } + + public void gapLimitChanged(int gapLimit) { + walletCopy.setGapLimit(gapLimit); + } } diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/WalletForm.java b/src/main/java/com/sparrowwallet/sparrow/wallet/WalletForm.java index 6510d633..2a850d2d 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/WalletForm.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/WalletForm.java @@ -604,7 +604,9 @@ public class WalletForm { Optional optPurposeNode = wallet.getPurposeNodes().stream().filter(node -> node.getKeyPurpose() == keyPurpose).findFirst(); if(optPurposeNode.isPresent()) { WalletNode purposeNode = optPurposeNode.get(); - newNodes.addAll(purposeNode.fillToIndex(wallet, wallet.getLookAheadIndex(purposeNode))); + purposeNode.fillToIndex(wallet, wallet.getLookAheadIndex(purposeNode)); + int previousLookAheadIndex = event.getPreviousLookAheadIndex(purposeNode); + newNodes.addAll(purposeNode.getChildren().stream().filter(node -> node.getIndex() > previousLookAheadIndex).collect(Collectors.toList())); } } diff --git a/src/main/java/com/sparrowwallet/sparrow/whirlpool/dataSource/SparrowIndexHandler.java b/src/main/java/com/sparrowwallet/sparrow/whirlpool/dataSource/SparrowIndexHandler.java index db635ee0..e7bc9ead 100644 --- a/src/main/java/com/sparrowwallet/sparrow/whirlpool/dataSource/SparrowIndexHandler.java +++ b/src/main/java/com/sparrowwallet/sparrow/whirlpool/dataSource/SparrowIndexHandler.java @@ -4,6 +4,7 @@ import com.samourai.wallet.client.indexHandler.AbstractIndexHandler; import com.sparrowwallet.drongo.KeyPurpose; import com.sparrowwallet.drongo.wallet.Wallet; import com.sparrowwallet.drongo.wallet.WalletNode; +import com.sparrowwallet.sparrow.AppServices; import com.sparrowwallet.sparrow.EventManager; import com.sparrowwallet.sparrow.event.WalletGapLimitChangedEvent; import com.sparrowwallet.sparrow.event.WalletMixConfigChangedEvent; @@ -75,7 +76,15 @@ public class SparrowIndexHandler extends AbstractIndexHandler { int existingGapLimit = wallet.getGapLimit(); if(index > highestUsedIndex + existingGapLimit) { wallet.setGapLimit(Math.max(wallet.getGapLimit(), index - highestUsedIndex)); - EventManager.get().post(new WalletGapLimitChangedEvent(wallet)); + EventManager.get().post(new WalletGapLimitChangedEvent(getWalletId(), wallet, existingGapLimit)); + } + } + + private String getWalletId() { + try { + return AppServices.get().getOpenWallets().get(wallet).getWalletId(wallet); + } catch(Exception e) { + return null; } } }