Merge 022ea3c93f91aea6cbbc95d8e33f8c5dfeccfc09 into c87b8a5b45c0ff513c07cd0562dbf66fc61eb58b

This commit is contained in:
woodser 2025-04-16 15:15:27 +00:00 committed by GitHub
commit 3ac3a4d63f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 28 additions and 29 deletions

View File

@ -149,6 +149,20 @@ public class OfferBookService {
Offer offer = new Offer(offerPayload);
offer.setPriceFeedService(priceFeedService);
announceOfferRemoved(offer);
// check if invalid offers are now valid
synchronized (invalidOffers) {
for (Offer invalidOffer : new ArrayList<Offer>(invalidOffers)) {
try {
validateOfferPayload(invalidOffer.getOfferPayload());
removeInvalidOffer(invalidOffer.getId());
replaceValidOffer(invalidOffer);
announceOfferAdded(invalidOffer);
} catch (Exception e) {
// ignore
}
}
}
}
});
}, OfferBookService.class.getSimpleName());
@ -298,20 +312,6 @@ public class OfferBookService {
synchronized (offerBookChangedListeners) {
offerBookChangedListeners.forEach(listener -> listener.onRemoved(offer));
}
// check if invalid offers are now valid
synchronized (invalidOffers) {
for (Offer invalidOffer : new ArrayList<Offer>(invalidOffers)) {
try {
validateOfferPayload(invalidOffer.getOfferPayload());
removeInvalidOffer(invalidOffer.getId());
replaceValidOffer(invalidOffer);
announceOfferAdded(invalidOffer);
} catch (Exception e) {
// ignore
}
}
}
}
private boolean hasValidOffer(String offerId) {

View File

@ -1574,14 +1574,6 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
}
}
// verify the max version number
if (Version.compare(request.getOfferPayload().getVersionNr(), Version.VERSION) > 0) {
errorMessage = "Offer version number is too high: " + request.getOfferPayload().getVersionNr() + " > " + Version.VERSION;
log.warn(errorMessage);
sendAckMessage(request.getClass(), peer, request.getPubKeyRing(), request.getOfferId(), request.getUid(), false, errorMessage);
return;
}
// verify maker and taker fees
boolean hasBuyerAsTakerWithoutDeposit = offer.getDirection() == OfferDirection.SELL && offer.isPrivateOffer() && offer.getChallengeHash() != null && offer.getChallengeHash().length() > 0 && offer.getTakerFeePct() == 0;
if (hasBuyerAsTakerWithoutDeposit) {

View File

@ -144,7 +144,6 @@ public class XmrKeyImagePoller {
if (!keyImageGroups.containsKey(groupId)) keyImageGroups.put(groupId, new HashSet<String>());
Set<String> keyImagesGroup = keyImageGroups.get(groupId);
keyImagesGroup.addAll(keyImages);
refreshPolling();
}
}
@ -159,8 +158,13 @@ public class XmrKeyImagePoller {
if (keyImagesGroup == null) return;
keyImagesGroup.removeAll(keyImages);
if (keyImagesGroup.isEmpty()) keyImageGroups.remove(groupId);
Set<String> allKeyImages = getKeyImages();
synchronized (lastStatuses) {
for (String lastKeyImage : new HashSet<>(lastStatuses.keySet())) lastStatuses.remove(lastKeyImage);
for (String keyImage : keyImages) {
if (lastStatuses.containsKey(keyImage) && !allKeyImages.contains(keyImage)) {
lastStatuses.remove(keyImage);
}
}
}
refreshPolling();
}
@ -171,10 +175,10 @@ public class XmrKeyImagePoller {
Set<String> keyImagesGroup = keyImageGroups.get(groupId);
if (keyImagesGroup == null) return;
keyImageGroups.remove(groupId);
Set<String> keyImages = getKeyImages();
Set<String> allKeyImages = getKeyImages();
synchronized (lastStatuses) {
for (String keyImage : keyImagesGroup) {
if (lastStatuses.containsKey(keyImage) && !keyImages.contains(keyImage)) {
if (lastStatuses.containsKey(keyImage) && !allKeyImages.contains(keyImage)) {
lastStatuses.remove(keyImage);
}
}
@ -265,6 +269,7 @@ public class XmrKeyImagePoller {
// announce changes
if (!changedStatuses.isEmpty()) {
log.info("Announcing " + changedStatuses.size() + " key image spent status changes");
for (XmrKeyImageListener listener : new ArrayList<XmrKeyImageListener>(listeners)) {
listener.onSpentStatusChanged(changedStatuses);
}

View File

@ -174,9 +174,11 @@ abstract class OfferBookViewModel extends ActivatableViewModel {
tradeCurrencyListChangeListener = c -> fillCurrencies();
// refresh filter on changes
offerBook.getOfferBookListItems().addListener((ListChangeListener<OfferBookListItem>) c -> {
filterOffers();
});
// TODO: This is removed because it's expensive to re-filter offers for every change (high cpu for many offers).
// This was used to ensure offer list is fully refreshed, but is unnecessary after refactoring OfferBookService to clone offers?
// offerBook.getOfferBookListItems().addListener((ListChangeListener<OfferBookListItem>) c -> {
// filterOffers();
// });
filterItemsListener = c -> {
final Optional<OfferBookListItem> highestAmountOffer = filteredItems.stream()