Fix bug with not rePublished offers. Update offerbook when offer gets removed. Add pref. language and currency to preferences

This commit is contained in:
Manfred Karrer 2015-12-20 23:05:42 +01:00
parent b1c4d7b636
commit 3222019480
13 changed files with 184 additions and 36 deletions

View file

@ -119,7 +119,7 @@ public class CountryUtil {
} }
public static Country getDefaultCountry() { public static Country getDefaultCountry() {
final Locale locale = new Locale(LanguageUtil.getDefaultLanguage(), getDefaultCountryCode()); final Locale locale = Preferences.getDefaultLocale();
String regionCode = getRegionCode(locale.getCountry()); String regionCode = getRegionCode(locale.getCountry());
final Region region = new Region(regionCode, getRegionName(regionCode)); final Region region = new Region(regionCode, getRegionName(regionCode));
return new Country(locale.getCountry(), locale.getDisplayCountry(), region); return new Country(locale.getCountry(), locale.getDisplayCountry(), region);
@ -205,7 +205,6 @@ public class CountryUtil {
} }
} }
public static String getDefaultCountryCode() { public static String getDefaultCountryCode() {
// might be set later in pref or config, so not use Preferences.getDefaultLocale() anywhere in the code // might be set later in pref or config, so not use Preferences.getDefaultLocale() anywhere in the code
return Preferences.getDefaultLocale().getCountry(); return Preferences.getDefaultLocale().getCountry();

View file

@ -205,8 +205,8 @@ public class CurrencyUtil {
} }
} }
public static FiatCurrency getDefaultFiatCurrency() { public static TradeCurrency getDefaultTradeCurrency() {
return new FiatCurrency(getCurrencyByCountryCode(CountryUtil.getDefaultCountryCode()).getCurrency()); return Preferences.getDefaultTradeCurrency();
} }
} }

View file

@ -52,7 +52,20 @@ public class OfferBookService {
} }
public void addOffer(Offer offer, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) { public void addOffer(Offer offer, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
boolean result = p2PService.addData(offer); doAddOffer(offer, resultHandler, errorMessageHandler, false);
}
public void republishOffer(Offer offer, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
doAddOffer(offer, resultHandler, errorMessageHandler, true);
}
private void doAddOffer(Offer offer, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler, boolean rePublish) {
boolean result;
if (rePublish)
result = p2PService.republishData(offer);
else
result = p2PService.addData(offer);
if (result) { if (result) {
log.trace("Add offer to network was successful. Offer = " + offer); log.trace("Add offer to network was successful. Offer = " + offer);
resultHandler.handleResult(); resultHandler.handleResult();

View file

@ -146,7 +146,7 @@ public class OpenOfferManager {
if (p2PNetworkReadyListener != null) if (p2PNetworkReadyListener != null)
p2PService.removeP2PServiceListener(p2PNetworkReadyListener); p2PService.removeP2PServiceListener(p2PNetworkReadyListener);
long period = (long) (Offer.TTL * 0.8); long period = (long) (Offer.TTL * 0.8); // republish sufficiently before offer would expires
TimerTask timerTask = new TimerTask() { TimerTask timerTask = new TimerTask() {
@Override @Override
public void run() { public void run() {
@ -165,7 +165,7 @@ public class OpenOfferManager {
private void rePublishOffers() { private void rePublishOffers() {
if (!openOffers.isEmpty()) log.trace("rePublishOffers"); if (!openOffers.isEmpty()) log.trace("rePublishOffers");
for (OpenOffer openOffer : openOffers) { for (OpenOffer openOffer : openOffers) {
offerBookService.addOffer(openOffer.getOffer(), offerBookService.republishOffer(openOffer.getOffer(),
() -> log.debug("Successful added offer to P2P network"), () -> log.debug("Successful added offer to P2P network"),
errorMessage -> log.error("Add offer to P2P network failed. " + errorMessage)); errorMessage -> log.error("Add offer to P2P network failed. " + errorMessage));
//setupDepositPublishedListener(openOffer); //setupDepositPublishedListener(openOffer);

View file

@ -20,6 +20,7 @@ package io.bitsquare.user;
import io.bitsquare.app.BitsquareEnvironment; import io.bitsquare.app.BitsquareEnvironment;
import io.bitsquare.app.Version; import io.bitsquare.app.Version;
import io.bitsquare.btc.BitcoinNetwork; import io.bitsquare.btc.BitcoinNetwork;
import io.bitsquare.locale.CountryUtil;
import io.bitsquare.locale.CurrencyUtil; import io.bitsquare.locale.CurrencyUtil;
import io.bitsquare.locale.TradeCurrency; import io.bitsquare.locale.TradeCurrency;
import io.bitsquare.storage.Storage; import io.bitsquare.storage.Storage;
@ -67,9 +68,16 @@ public class Preferences implements Serializable {
return BTC_DENOMINATIONS; return BTC_DENOMINATIONS;
} }
private transient static Locale defaultLocale = Locale.getDefault();
public static Locale getDefaultLocale() { public static Locale getDefaultLocale() {
//return new Locale("EN", "US"); return defaultLocale;
return Locale.getDefault(); }
private transient static TradeCurrency defaultTradeCurrency = new TradeCurrency(CurrencyUtil.getCurrencyByCountryCode(CountryUtil.getDefaultCountryCode()).getCurrency().getCurrencyCode());
public static TradeCurrency getDefaultTradeCurrency() {
return defaultTradeCurrency;
} }
transient private final Storage<Preferences> storage; transient private final Storage<Preferences> storage;
@ -92,6 +100,8 @@ public class Preferences implements Serializable {
private boolean autoSelectArbitrators = true; private boolean autoSelectArbitrators = true;
private Map<String, Boolean> showAgainMap; private Map<String, Boolean> showAgainMap;
private boolean tacAccepted; private boolean tacAccepted;
private Locale preferredLocale;
private TradeCurrency preferredTradeCurrency;
// Observable wrappers // Observable wrappers
transient private final StringProperty btcDenominationProperty = new SimpleStringProperty(btcDenomination); transient private final StringProperty btcDenominationProperty = new SimpleStringProperty(btcDenomination);
@ -134,6 +144,11 @@ public class Preferences implements Serializable {
autoSelectArbitrators = persisted.getAutoSelectArbitrators(); autoSelectArbitrators = persisted.getAutoSelectArbitrators();
showAgainMap = persisted.getShowAgainMap(); showAgainMap = persisted.getShowAgainMap();
tacAccepted = persisted.getTacAccepted(); tacAccepted = persisted.getTacAccepted();
preferredLocale = persisted.getPreferredLocale();
defaultLocale = preferredLocale;
preferredTradeCurrency = persisted.getPreferredTradeCurrency();
defaultTradeCurrency = preferredTradeCurrency;
} else { } else {
setTradeCurrencies(CurrencyUtil.getAllSortedCurrencies()); setTradeCurrencies(CurrencyUtil.getAllSortedCurrencies());
tradeCurrencies = new ArrayList<>(tradeCurrenciesAsObservable); tradeCurrencies = new ArrayList<>(tradeCurrenciesAsObservable);
@ -148,6 +163,8 @@ public class Preferences implements Serializable {
showAgainMap.put(PopupId.PAYMENT_SENT, true); showAgainMap.put(PopupId.PAYMENT_SENT, true);
showAgainMap.put(PopupId.PAYMENT_RECEIVED, true); showAgainMap.put(PopupId.PAYMENT_RECEIVED, true);
preferredLocale = getDefaultLocale();
preferredTradeCurrency = getDefaultTradeCurrency();
storage.queueUpForSave(); storage.queueUpForSave();
} }
@ -250,6 +267,19 @@ public class Preferences implements Serializable {
storage.queueUpForSave(); storage.queueUpForSave();
} }
public void setPreferredLocale(Locale preferredLocale) {
this.preferredLocale = preferredLocale;
defaultLocale = preferredLocale;
storage.queueUpForSave();
}
public void setPreferredTradeCurrency(TradeCurrency preferredTradeCurrency) {
this.preferredTradeCurrency = preferredTradeCurrency;
defaultTradeCurrency = preferredTradeCurrency;
storage.queueUpForSave();
}
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Getter // Getter
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@ -360,4 +390,12 @@ public class Preferences implements Serializable {
public boolean getTacAccepted() { public boolean getTacAccepted() {
return tacAccepted; return tacAccepted;
} }
public Locale getPreferredLocale() {
return preferredLocale;
}
public TradeCurrency getPreferredTradeCurrency() {
return preferredTradeCurrency;
}
} }

View file

@ -102,8 +102,11 @@ public class User implements Serializable {
} else { } else {
accountID = String.valueOf(Math.abs(keyRing.getPubKeyRing().hashCode())); accountID = String.valueOf(Math.abs(keyRing.getPubKeyRing().hashCode()));
acceptedLanguageLocaleCodes = new ArrayList<>(Arrays.asList(LanguageUtil.getDefaultLanguageLocaleAsCode(), acceptedLanguageLocaleCodes.add(LanguageUtil.getDefaultLanguageLocaleAsCode());
LanguageUtil.getEnglishLanguageLocaleCode())); String english = LanguageUtil.getEnglishLanguageLocaleCode();
if (!acceptedLanguageLocaleCodes.contains(english))
acceptedLanguageLocaleCodes.add(english);
acceptedArbitrators = new ArrayList<>(); acceptedArbitrators = new ArrayList<>();
} }
storage.queueUpForSave(); storage.queueUpForSave();

View file

@ -42,7 +42,7 @@ class MarketViewModel extends ActivatableViewModel {
private final OfferBook offerBook; private final OfferBook offerBook;
private final Preferences preferences; private final Preferences preferences;
final ObjectProperty<TradeCurrency> tradeCurrency = new SimpleObjectProperty<>(CurrencyUtil.getDefaultFiatCurrency()); final ObjectProperty<TradeCurrency> tradeCurrency = new SimpleObjectProperty<>(CurrencyUtil.getDefaultTradeCurrency());
private final List<XYChart.Data> buyData = new ArrayList(); private final List<XYChart.Data> buyData = new ArrayList();
private final List<XYChart.Data> sellData = new ArrayList(); private final List<XYChart.Data> sellData = new ArrayList();
private final ObservableList<OfferBookListItem> offerBookListItems; private final ObservableList<OfferBookListItem> offerBookListItems;

View file

@ -89,7 +89,7 @@ public abstract class OfferView extends ActivatableView<TabPane, Void> {
} }
}); });
tradeCurrency = CurrencyUtil.getDefaultFiatCurrency(); tradeCurrency = CurrencyUtil.getDefaultTradeCurrency();
navigation.addListener(listener); navigation.addListener(listener);
navigation.navigateTo(MainView.class, this.getClass(), OfferBookView.class); navigation.navigateTo(MainView.class, this.getClass(), OfferBookView.class);

View file

@ -88,7 +88,7 @@ class OfferBookViewModel extends ActivatableViewModel {
this.filteredItems = new FilteredList<>(offerBookListItems); this.filteredItems = new FilteredList<>(offerBookListItems);
this.sortedItems = new SortedList<>(filteredItems); this.sortedItems = new SortedList<>(filteredItems);
tradeCurrency = CurrencyUtil.getDefaultFiatCurrency(); tradeCurrency = CurrencyUtil.getDefaultTradeCurrency();
tradeCurrencyCode.set(tradeCurrency.getCode()); tradeCurrencyCode.set(tradeCurrency.getCode());
} }

View file

@ -20,6 +20,8 @@ package io.bitsquare.gui.main.settings.application;
import io.bitsquare.gui.common.view.ActivatableViewAndModel; import io.bitsquare.gui.common.view.ActivatableViewAndModel;
import io.bitsquare.gui.common.view.FxmlView; import io.bitsquare.gui.common.view.FxmlView;
import io.bitsquare.gui.util.Layout; import io.bitsquare.gui.util.Layout;
import io.bitsquare.locale.LanguageUtil;
import io.bitsquare.locale.TradeCurrency;
import io.bitsquare.user.BlockChainExplorer; import io.bitsquare.user.BlockChainExplorer;
import javafx.scene.control.CheckBox; import javafx.scene.control.CheckBox;
import javafx.scene.control.ComboBox; import javafx.scene.control.ComboBox;
@ -33,8 +35,11 @@ import static io.bitsquare.gui.util.FormBuilder.*;
@FxmlView @FxmlView
public class PreferencesView extends ActivatableViewAndModel<GridPane, PreferencesViewModel> { public class PreferencesView extends ActivatableViewAndModel<GridPane, PreferencesViewModel> {
private ComboBox<String> btcDenominationComboBox; // not supported yet
//private ComboBox<String> btcDenominationComboBox;
private ComboBox<BlockChainExplorer> blockExplorerComboBox; private ComboBox<BlockChainExplorer> blockExplorerComboBox;
private ComboBox<String> languageComboBox;
private ComboBox<TradeCurrency> tradeCurrencyComboBox;
private CheckBox useAnimationsCheckBox, useEffectsCheckBox, showPlaceOfferConfirmationCheckBox, showTakeOfferConfirmationCheckBox, private CheckBox useAnimationsCheckBox, useEffectsCheckBox, showPlaceOfferConfirmationCheckBox, showTakeOfferConfirmationCheckBox,
autoSelectArbitratorsCheckBox; autoSelectArbitratorsCheckBox;
@ -47,9 +52,11 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
@Override @Override
public void initialize() { public void initialize() {
addTitledGroupBg(root, gridRow, 7, "Preferences"); addTitledGroupBg(root, gridRow, 9, "Preferences");
btcDenominationComboBox = addLabelComboBox(root, gridRow, "Bitcoin denomination:", Layout.FIRST_ROW_DISTANCE).second; tradeCurrencyComboBox = addLabelComboBox(root, ++gridRow, "Preferred currency:", Layout.FIRST_ROW_DISTANCE).second;
languageComboBox = addLabelComboBox(root, ++gridRow, "Language:").second;
// btcDenominationComboBox = addLabelComboBox(root, gridRow, "Bitcoin denomination:", Layout.FIRST_ROW_DISTANCE).second;
blockExplorerComboBox = addLabelComboBox(root, ++gridRow, "Bitcoin block explorer:").second; blockExplorerComboBox = addLabelComboBox(root, ++gridRow, "Bitcoin block explorer:").second;
useAnimationsCheckBox = addLabelCheckBox(root, ++gridRow, "Use animations:", "").second; useAnimationsCheckBox = addLabelCheckBox(root, ++gridRow, "Use animations:", "").second;
useEffectsCheckBox = addLabelCheckBox(root, ++gridRow, "Use effects:", "").second; useEffectsCheckBox = addLabelCheckBox(root, ++gridRow, "Use effects:", "").second;
@ -60,10 +67,41 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
@Override @Override
protected void activate() { protected void activate() {
btcDenominationComboBox.setDisable(true); /* btcDenominationComboBox.setDisable(true);
btcDenominationComboBox.setItems(model.btcDenominations); btcDenominationComboBox.setItems(model.btcDenominations);
btcDenominationComboBox.getSelectionModel().select(model.getBtcDenomination()); btcDenominationComboBox.getSelectionModel().select(model.getBtcDenomination());
btcDenominationComboBox.setOnAction(e -> model.onSelectBtcDenomination(btcDenominationComboBox.getSelectionModel().getSelectedItem())); btcDenominationComboBox.setOnAction(e -> model.onSelectBtcDenomination(btcDenominationComboBox.getSelectionModel().getSelectedItem()));*/
tradeCurrencyComboBox.setItems(model.tradeCurrencies);
tradeCurrencyComboBox.getSelectionModel().select(model.getTradeCurrency());
tradeCurrencyComboBox.setConverter(new StringConverter<TradeCurrency>() {
@Override
public String toString(TradeCurrency tradeCurrency) {
return tradeCurrency.getCodeAndName();
}
@Override
public TradeCurrency fromString(String string) {
return null;
}
});
tradeCurrencyComboBox.setOnAction(e -> model.onSelectTradeCurrency(tradeCurrencyComboBox.getSelectionModel().getSelectedItem()));
languageComboBox.setItems(model.languageCodes);
languageComboBox.getSelectionModel().select(model.getLanguageCode());
languageComboBox.setConverter(new StringConverter<String>() {
@Override
public String toString(String code) {
return LanguageUtil.getDisplayName(code);
}
@Override
public String fromString(String string) {
return null;
}
});
languageComboBox.setOnAction(e -> model.onSelectLanguageCode(languageComboBox.getSelectionModel().getSelectedItem()));
blockExplorerComboBox.setItems(model.blockExplorers); blockExplorerComboBox.setItems(model.blockExplorers);
blockExplorerComboBox.getSelectionModel().select(model.getBlockExplorer()); blockExplorerComboBox.getSelectionModel().select(model.getBlockExplorer());
@ -80,6 +118,7 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
}); });
blockExplorerComboBox.setOnAction(e -> model.onSelectBlockExplorer(blockExplorerComboBox.getSelectionModel().getSelectedItem())); blockExplorerComboBox.setOnAction(e -> model.onSelectBlockExplorer(blockExplorerComboBox.getSelectionModel().getSelectedItem()));
useAnimationsCheckBox.setSelected(model.getUseAnimations()); useAnimationsCheckBox.setSelected(model.getUseAnimations());
useAnimationsCheckBox.setOnAction(e -> model.onSelectUseAnimations(useAnimationsCheckBox.isSelected())); useAnimationsCheckBox.setOnAction(e -> model.onSelectUseAnimations(useAnimationsCheckBox.isSelected()));
@ -94,12 +133,14 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Preferenc
autoSelectArbitratorsCheckBox.setSelected(model.getAutoSelectArbitrators()); autoSelectArbitratorsCheckBox.setSelected(model.getAutoSelectArbitrators());
autoSelectArbitratorsCheckBox.setOnAction(e -> model.onSelectAutoSelectArbitratorsCheckBox(autoSelectArbitratorsCheckBox.isSelected())); autoSelectArbitratorsCheckBox.setOnAction(e -> model.onSelectAutoSelectArbitratorsCheckBox(autoSelectArbitratorsCheckBox.isSelected()));
} }
@Override @Override
protected void deactivate() { protected void deactivate() {
btcDenominationComboBox.setOnAction(null); //btcDenominationComboBox.setOnAction(null);
languageComboBox.setOnAction(null);
tradeCurrencyComboBox.setOnAction(null);
blockExplorerComboBox.setOnAction(null);
useAnimationsCheckBox.setOnAction(null); useAnimationsCheckBox.setOnAction(null);
useEffectsCheckBox.setOnAction(null); useEffectsCheckBox.setOnAction(null);
showPlaceOfferConfirmationCheckBox.setOnAction(null); showPlaceOfferConfirmationCheckBox.setOnAction(null);

View file

@ -19,16 +19,22 @@ package io.bitsquare.gui.main.settings.application;
import com.google.inject.Inject; import com.google.inject.Inject;
import io.bitsquare.gui.common.model.ActivatableViewModel; import io.bitsquare.gui.common.model.ActivatableViewModel;
import io.bitsquare.locale.LanguageUtil;
import io.bitsquare.locale.TradeCurrency;
import io.bitsquare.user.BlockChainExplorer; import io.bitsquare.user.BlockChainExplorer;
import io.bitsquare.user.Preferences; import io.bitsquare.user.Preferences;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import java.util.Locale;
class PreferencesViewModel extends ActivatableViewModel { class PreferencesViewModel extends ActivatableViewModel {
private final Preferences preferences; private final Preferences preferences;
final ObservableList<String> btcDenominations = FXCollections.observableArrayList(Preferences.getBtcDenominations()); final ObservableList<String> btcDenominations = FXCollections.observableArrayList(Preferences.getBtcDenominations());
final ObservableList<BlockChainExplorer> blockExplorers; final ObservableList<BlockChainExplorer> blockExplorers;
final ObservableList<TradeCurrency> tradeCurrencies;
final ObservableList<String> languageCodes;
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@ -38,7 +44,10 @@ class PreferencesViewModel extends ActivatableViewModel {
@Inject @Inject
public PreferencesViewModel(Preferences preferences) { public PreferencesViewModel(Preferences preferences) {
this.preferences = preferences; this.preferences = preferences;
blockExplorers = FXCollections.observableArrayList(preferences.getBlockChainExplorers()); blockExplorers = FXCollections.observableArrayList(preferences.getBlockChainExplorers());
tradeCurrencies = preferences.getTradeCurrenciesAsObservable();
languageCodes = FXCollections.observableArrayList(LanguageUtil.getAllLanguageCodes());
} }
@Override @Override
@ -78,6 +87,18 @@ class PreferencesViewModel extends ActivatableViewModel {
preferences.setAutoSelectArbitrators(selected); preferences.setAutoSelectArbitrators(selected);
} }
public void onSelectBlockExplorer(BlockChainExplorer selectedItem) {
preferences.setBlockChainExplorer(selectedItem);
}
public void onSelectTradeCurrency(TradeCurrency selectedItem) {
preferences.setPreferredTradeCurrency(selectedItem);
}
public void onSelectLanguageCode(String code) {
preferences.setPreferredLocale(new Locale(code, preferences.getPreferredLocale().getCountry()));
}
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Getters // Getters
@ -111,7 +132,11 @@ class PreferencesViewModel extends ActivatableViewModel {
return preferences.getBlockChainExplorer(); return preferences.getBlockChainExplorer();
} }
public void onSelectBlockExplorer(BlockChainExplorer selectedItem) { public String getLanguageCode() {
preferences.setBlockChainExplorer(selectedItem); return preferences.getPreferredLocale().getLanguage();
}
public TradeCurrency getTradeCurrency() {
return preferences.getPreferredTradeCurrency();
} }
} }

View file

@ -53,6 +53,7 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
private final boolean useLocalhost; private final boolean useLocalhost;
@Nullable @Nullable
private final EncryptionService encryptionService; private final EncryptionService encryptionService;
@Nullable
private final KeyRing keyRing; private final KeyRing keyRing;
// set in init // set in init
@ -91,15 +92,14 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
@Named(ProgramArguments.NETWORK_ID) int networkId, @Named(ProgramArguments.NETWORK_ID) int networkId,
@Named("storage.dir") File storageDir, @Named("storage.dir") File storageDir,
@Nullable EncryptionService encryptionService, @Nullable EncryptionService encryptionService,
@Nullable KeyRing keyRing @Nullable KeyRing keyRing) {
) {
Log.traceCall();
this.seedNodesRepository = seedNodesRepository; this.seedNodesRepository = seedNodesRepository;
this.port = port; this.port = port;
this.torDir = torDir; this.torDir = torDir;
this.useLocalhost = useLocalhost; this.useLocalhost = useLocalhost;
this.encryptionService = encryptionService; this.encryptionService = encryptionService;
this.keyRing = keyRing; this.keyRing = keyRing;
dbStorage = new Storage<>(storageDir); dbStorage = new Storage<>(storageDir);
init(networkId, storageDir); init(networkId, storageDir);
@ -568,12 +568,25 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
public boolean addData(ExpirablePayload expirablePayload) { public boolean addData(ExpirablePayload expirablePayload) {
Log.traceCall();
return doAddData(expirablePayload, false);
}
public boolean republishData(ExpirablePayload expirablePayload) {
Log.traceCall();
return doAddData(expirablePayload, true);
}
private boolean doAddData(ExpirablePayload expirablePayload, boolean rePublish) {
Log.traceCall(); Log.traceCall();
checkAuthentication(); checkAuthentication();
try { try {
ProtectedData protectedData = dataStorage.getDataWithSignedSeqNr(expirablePayload, keyRing.getSignatureKeyPair()); ProtectedData protectedData = dataStorage.getDataWithSignedSeqNr(expirablePayload, keyRing.getSignatureKeyPair());
return dataStorage.add(protectedData, networkNode.getAddress()); if (rePublish)
return dataStorage.rePublish(protectedData, networkNode.getAddress());
else
return dataStorage.add(protectedData, networkNode.getAddress());
} catch (CryptoException e) { } catch (CryptoException e) {
log.error("Signing at getDataWithSignedSeqNr failed. That should never happen."); log.error("Signing at getDataWithSignedSeqNr failed. That should never happen.");
return false; return false;

View file

@ -28,10 +28,7 @@ import javax.annotation.Nullable;
import java.io.File; import java.io.File;
import java.security.KeyPair; import java.security.KeyPair;
import java.security.PublicKey; import java.security.PublicKey;
import java.util.HashMap; import java.util.*;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.CopyOnWriteArraySet;
// Run in UserThread // Run in UserThread
@ -90,15 +87,25 @@ public class ProtectedExpirableDataStorage implements MessageListener {
private void removeExpiredEntries() { private void removeExpiredEntries() {
Log.traceCall(); Log.traceCall();
// The moment when an object becomes expired will not be synchrone in the network and we could // The moment when an object becomes expired will not be synchronous in the network and we could
// get add messages after the object has expired. To avoid repeated additions of already expired // get add messages after the object has expired. To avoid repeated additions of already expired
// object when we get it sent from new peers, we dont remove the sequence number from the map. // object when we get it sent from new peers, we dont remove the sequence number from the map.
// That way a add message for an already expired data will fail because the sequence number // That way an ADD message for an already expired data will fail because the sequence number
// is equal and not larger. // is equal and not larger.
Map<ByteArray, ProtectedData> temp = new HashMap<>(map); Map<ByteArray, ProtectedData> temp = new HashMap<>(map);
Set<ProtectedData> protectedDataToRemoveSet = new HashSet<>();
temp.entrySet().stream() temp.entrySet().stream()
.filter(entry -> entry.getValue().isExpired()) .filter(entry -> entry.getValue().isExpired())
.forEach(entry -> map.remove(entry.getKey())); .forEach(entry -> {
ByteArray hashOfPayload = entry.getKey();
ProtectedData protectedDataToRemove = map.get(hashOfPayload);
protectedDataToRemoveSet.add(protectedDataToRemove);
map.remove(hashOfPayload);
});
protectedDataToRemoveSet.stream().forEach(
protectedDataToRemove -> hashMapChangedListeners.stream().forEach(
listener -> listener.onRemoved(protectedDataToRemove)));
} }
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@ -142,6 +149,14 @@ public class ProtectedExpirableDataStorage implements MessageListener {
} }
public boolean add(ProtectedData protectedData, @Nullable Address sender) { public boolean add(ProtectedData protectedData, @Nullable Address sender) {
return doAdd(protectedData, sender, false);
}
public boolean rePublish(ProtectedData protectedData, @Nullable Address sender) {
return doAdd(protectedData, sender, true);
}
private boolean doAdd(ProtectedData protectedData, @Nullable Address sender, boolean rePublish) {
Log.traceCall(); Log.traceCall();
ByteArray hashOfPayload = getHashAsByteArray(protectedData.expirablePayload); ByteArray hashOfPayload = getHashAsByteArray(protectedData.expirablePayload);
boolean result = checkPublicKeys(protectedData, true) boolean result = checkPublicKeys(protectedData, true)
@ -162,7 +177,7 @@ public class ProtectedExpirableDataStorage implements MessageListener {
sb.append("\n------------------------------------------------------------\n"); sb.append("\n------------------------------------------------------------\n");
log.info(sb.toString()); log.info(sb.toString());
if (!containsKey) if (rePublish || !containsKey)
broadcast(new AddDataMessage(protectedData), sender); broadcast(new AddDataMessage(protectedData), sender);
storage.queueUpForSave(); storage.queueUpForSave();
@ -273,6 +288,7 @@ public class ProtectedExpirableDataStorage implements MessageListener {
Log.traceCall(); Log.traceCall();
map.remove(hashOfPayload); map.remove(hashOfPayload);
log.trace("Data removed from our map. We broadcast the message to our peers."); log.trace("Data removed from our map. We broadcast the message to our peers.");
storage.queueUpForSave();
hashMapChangedListeners.stream().forEach(e -> e.onRemoved(protectedData)); hashMapChangedListeners.stream().forEach(e -> e.onRemoved(protectedData));
StringBuilder sb = new StringBuilder("\n\n------------------------------------------------------------\n" + StringBuilder sb = new StringBuilder("\n\n------------------------------------------------------------\n" +