add and remove offers on user thread to fix illegal state #1031

This commit is contained in:
woodser 2024-06-20 11:53:15 -04:00
parent 26a5ffcb31
commit cb0b6665f7
2 changed files with 30 additions and 24 deletions

View File

@ -115,6 +115,7 @@ public class OfferBookService {
p2PService.addHashSetChangedListener(new HashMapChangedListener() { p2PService.addHashSetChangedListener(new HashMapChangedListener() {
@Override @Override
public void onAdded(Collection<ProtectedStorageEntry> protectedStorageEntries) { public void onAdded(Collection<ProtectedStorageEntry> protectedStorageEntries) {
UserThread.execute(() -> {
protectedStorageEntries.forEach(protectedStorageEntry -> { protectedStorageEntries.forEach(protectedStorageEntry -> {
if (protectedStorageEntry.getProtectedStoragePayload() instanceof OfferPayload) { if (protectedStorageEntry.getProtectedStoragePayload() instanceof OfferPayload) {
OfferPayload offerPayload = (OfferPayload) protectedStorageEntry.getProtectedStoragePayload(); OfferPayload offerPayload = (OfferPayload) protectedStorageEntry.getProtectedStoragePayload();
@ -128,22 +129,25 @@ public class OfferBookService {
} }
} }
}); });
});
} }
@Override @Override
public void onRemoved(Collection<ProtectedStorageEntry> protectedStorageEntries) { public void onRemoved(Collection<ProtectedStorageEntry> protectedStorageEntries) {
protectedStorageEntries.forEach(protectedStorageEntry -> { UserThread.execute(() -> {
if (protectedStorageEntry.getProtectedStoragePayload() instanceof OfferPayload) { protectedStorageEntries.forEach(protectedStorageEntry -> {
OfferPayload offerPayload = (OfferPayload) protectedStorageEntry.getProtectedStoragePayload(); if (protectedStorageEntry.getProtectedStoragePayload() instanceof OfferPayload) {
maybeInitializeKeyImagePoller(); OfferPayload offerPayload = (OfferPayload) protectedStorageEntry.getProtectedStoragePayload();
keyImagePoller.removeKeyImages(offerPayload.getReserveTxKeyImages()); maybeInitializeKeyImagePoller();
Offer offer = new Offer(offerPayload); keyImagePoller.removeKeyImages(offerPayload.getReserveTxKeyImages());
offer.setPriceFeedService(priceFeedService); Offer offer = new Offer(offerPayload);
setReservedFundsSpent(offer); offer.setPriceFeedService(priceFeedService);
synchronized (offerBookChangedListeners) { setReservedFundsSpent(offer);
offerBookChangedListeners.forEach(listener -> listener.onRemoved(offer)); synchronized (offerBookChangedListeners) {
offerBookChangedListeners.forEach(listener -> listener.onRemoved(offer));
}
} }
} });
}); });
} }
}); });
@ -278,9 +282,11 @@ public class OfferBookService {
keyImagePoller.addListener(new XmrKeyImageListener() { keyImagePoller.addListener(new XmrKeyImageListener() {
@Override @Override
public void onSpentStatusChanged(Map<String, MoneroKeyImageSpentStatus> spentStatuses) { public void onSpentStatusChanged(Map<String, MoneroKeyImageSpentStatus> spentStatuses) {
for (String keyImage : spentStatuses.keySet()) { UserThread.execute(() -> {
updateAffectedOffers(keyImage); for (String keyImage : spentStatuses.keySet()) {
} updateAffectedOffers(keyImage);
}
});
} }
}); });
@ -301,12 +307,8 @@ public class OfferBookService {
if (offer.getOfferPayload().getReserveTxKeyImages().contains(keyImage)) { if (offer.getOfferPayload().getReserveTxKeyImages().contains(keyImage)) {
synchronized (offerBookChangedListeners) { synchronized (offerBookChangedListeners) {
offerBookChangedListeners.forEach(listener -> { offerBookChangedListeners.forEach(listener -> {
listener.onRemoved(offer);
// notify off thread to avoid deadlocking listener.onAdded(offer);
new Thread(() -> {
listener.onRemoved(offer);
listener.onAdded(offer);
}).start();
}); });
} }
} }

View File

@ -19,6 +19,8 @@ package haveno.desktop.main.market.offerbook;
import com.google.common.math.LongMath; import com.google.common.math.LongMath;
import com.google.inject.Inject; import com.google.inject.Inject;
import haveno.common.UserThread;
import haveno.core.account.witness.AccountAgeWitnessService; import haveno.core.account.witness.AccountAgeWitnessService;
import haveno.core.locale.CurrencyUtil; import haveno.core.locale.CurrencyUtil;
import haveno.core.locale.GlobalSettings; import haveno.core.locale.GlobalSettings;
@ -135,10 +137,12 @@ class OfferBookChartViewModel extends ActivatableViewModel {
currenciesUpdatedListener = (observable, oldValue, newValue) -> { currenciesUpdatedListener = (observable, oldValue, newValue) -> {
if (!isAnyPriceAbsent()) { if (!isAnyPriceAbsent()) {
offerBook.fillOfferBookListItems(); UserThread.execute(() -> {
updateChartData(); offerBook.fillOfferBookListItems();
var self = this; updateChartData();
priceFeedService.updateCounterProperty().removeListener(self.currenciesUpdatedListener); var self = this;
priceFeedService.updateCounterProperty().removeListener(self.currenciesUpdatedListener);
});
} }
}; };