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

View file

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