mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-08-24 14:29:23 -04:00
Handle offer removal on disconnect (WIP)
This commit is contained in:
parent
92ad387d70
commit
db363fac48
12 changed files with 199 additions and 55 deletions
|
@ -25,6 +25,7 @@ import io.bitsquare.common.handlers.ResultHandler;
|
|||
import io.bitsquare.common.util.JsonExclude;
|
||||
import io.bitsquare.locale.Country;
|
||||
import io.bitsquare.p2p.NodeAddress;
|
||||
import io.bitsquare.p2p.storage.data.RequiresLiveOwner;
|
||||
import io.bitsquare.p2p.storage.data.StorageMessage;
|
||||
import io.bitsquare.payment.PaymentMethod;
|
||||
import io.bitsquare.trade.protocol.availability.OfferAvailabilityModel;
|
||||
|
@ -46,18 +47,22 @@ import java.util.concurrent.TimeUnit;
|
|||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public final class Offer implements StorageMessage {
|
||||
public final class Offer implements StorageMessage, RequiresLiveOwner {
|
||||
// That object is sent over the wire, so we need to take care of version compatibility.
|
||||
@JsonExclude
|
||||
private static final long serialVersionUID = Version.P2P_NETWORK_VERSION;
|
||||
@JsonExclude
|
||||
private static final Logger log = LoggerFactory.getLogger(Offer.class);
|
||||
|
||||
public static final long TTL = TimeUnit.MINUTES.toMillis(10);
|
||||
//public static final long TTL = TimeUnit.MINUTES.toMillis(10);
|
||||
//TODO
|
||||
public static final long TTL = TimeUnit.SECONDS.toMillis(10);
|
||||
|
||||
public final static String TAC_OFFERER = "When placing that offer I accept that anyone who fulfills my conditions can " +
|
||||
"take that offer.";
|
||||
public static final String TAC_TAKER = "With taking the offer I commit to the trade conditions as defined.";
|
||||
|
||||
|
||||
public enum Direction {BUY, SELL}
|
||||
|
||||
public enum State {
|
||||
|
@ -154,6 +159,11 @@ public final class Offer implements StorageMessage {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeAddress getOwnerNodeAddress() {
|
||||
return offererNodeAddress;
|
||||
}
|
||||
|
||||
public void validate() {
|
||||
checkNotNull(getAmount(), "Amount is null");
|
||||
checkNotNull(getArbitratorNodeAddresses(), "Arbitrator is null");
|
||||
|
|
|
@ -21,10 +21,13 @@ import io.bitsquare.common.handlers.ErrorMessageHandler;
|
|||
import io.bitsquare.common.handlers.ResultHandler;
|
||||
import io.bitsquare.p2p.P2PService;
|
||||
import io.bitsquare.p2p.storage.HashMapChangedListener;
|
||||
import io.bitsquare.p2p.storage.data.ProtectedData;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
@ -35,8 +38,14 @@ import java.util.stream.Collectors;
|
|||
public class OfferBookService {
|
||||
private static final Logger log = LoggerFactory.getLogger(OfferBookService.class);
|
||||
|
||||
private final P2PService p2PService;
|
||||
public interface OfferBookChangedListener {
|
||||
void onAdded(Offer offer);
|
||||
|
||||
void onRemoved(Offer offer);
|
||||
}
|
||||
|
||||
private final P2PService p2PService;
|
||||
private final List<OfferBookChangedListener> offerBookChangedListeners = new LinkedList<>();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
|
@ -45,12 +54,37 @@ public class OfferBookService {
|
|||
@Inject
|
||||
public OfferBookService(P2PService p2PService) {
|
||||
this.p2PService = p2PService;
|
||||
|
||||
p2PService.addHashSetChangedListener(new HashMapChangedListener() {
|
||||
@Override
|
||||
public void onAdded(ProtectedData entry) {
|
||||
log.debug("OfferBookService.onAdded " + entry);
|
||||
offerBookChangedListeners.stream().forEach(listener -> {
|
||||
if (entry.expirableMessage instanceof Offer)
|
||||
listener.onAdded((Offer) entry.expirableMessage);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemoved(ProtectedData entry) {
|
||||
offerBookChangedListeners.stream().forEach(listener -> {
|
||||
log.debug("OfferBookService.onRemoved " + entry);
|
||||
if (entry.expirableMessage instanceof Offer)
|
||||
listener.onRemoved((Offer) entry.expirableMessage);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void addHashSetChangedListener(HashMapChangedListener hashMapChangedListener) {
|
||||
p2PService.addHashSetChangedListener(hashMapChangedListener);
|
||||
public void addOfferBookChangedListener(OfferBookChangedListener offerBookChangedListener) {
|
||||
offerBookChangedListeners.add(offerBookChangedListener);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// API
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void addOffer(Offer offer, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
|
||||
doAddOffer(offer, resultHandler, errorMessageHandler, false);
|
||||
}
|
||||
|
@ -74,25 +108,27 @@ public class OfferBookService {
|
|||
}
|
||||
}
|
||||
|
||||
public void removeOffer(Offer offer, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
|
||||
public void removeOffer(Offer offer, @Nullable ResultHandler resultHandler, @Nullable ErrorMessageHandler errorMessageHandler) {
|
||||
if (p2PService.removeData(offer)) {
|
||||
log.trace("Remove offer from network was successful. Offer = " + offer);
|
||||
if (resultHandler != null) resultHandler.handleResult();
|
||||
if (resultHandler != null)
|
||||
resultHandler.handleResult();
|
||||
} else {
|
||||
if (errorMessageHandler != null) errorMessageHandler.handleErrorMessage("Remove offer failed");
|
||||
if (errorMessageHandler != null)
|
||||
errorMessageHandler.handleErrorMessage("Remove offer failed");
|
||||
}
|
||||
}
|
||||
|
||||
public List<Offer> getOffers() {
|
||||
final List<Offer> offers = p2PService.getDataMap().values().stream()
|
||||
return p2PService.getDataMap().values().stream()
|
||||
.filter(e -> e.expirableMessage instanceof Offer)
|
||||
.map(e -> (Offer) e.expirableMessage)
|
||||
.collect(Collectors.toList());
|
||||
return offers;
|
||||
}
|
||||
|
||||
public void removeOfferAtShutDown(Offer offer) {
|
||||
log.debug("removeOfferAtShutDown " + offer);
|
||||
removeOffer(offer, null, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -71,6 +71,7 @@ public class OpenOfferManager {
|
|||
private BootstrapListener bootstrapListener;
|
||||
private final Timer timer = new Timer();
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -153,6 +154,18 @@ public class OpenOfferManager {
|
|||
}
|
||||
};
|
||||
timer.scheduleAtFixedRate(timerTask, 500, period);
|
||||
|
||||
p2PService.getNumConnectedPeers().addListener((observable, oldValue, newValue) -> {
|
||||
if ((int) oldValue == 0 && (int) newValue > 0) {
|
||||
rePublishOffers();
|
||||
|
||||
// We repeat a rePublishOffers call after 10 seconds if we have more than 3 peers
|
||||
UserThread.runAfter(() -> {
|
||||
if (p2PService.getNumConnectedPeers().get() > 3)
|
||||
rePublishOffers();
|
||||
}, 10);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void rePublishOffers() {
|
||||
|
@ -161,7 +174,6 @@ public class OpenOfferManager {
|
|||
offerBookService.republishOffer(openOffer.getOffer(),
|
||||
() -> log.debug("Successful added offer to P2P network"),
|
||||
errorMessage -> log.error("Add offer to P2P network failed. " + errorMessage));
|
||||
//setupDepositPublishedListener(openOffer);
|
||||
openOffer.setStorage(openOffersStorage);
|
||||
}
|
||||
}
|
||||
|
@ -175,14 +187,14 @@ public class OpenOfferManager {
|
|||
timer.cancel();
|
||||
|
||||
if (!shutDownRequested) {
|
||||
log.debug("shutDown");
|
||||
log.info("remove all open offers at shutDown");
|
||||
shutDownRequested = true;
|
||||
int numOffers = openOffers.size();
|
||||
// we remove own offers from offerbook when we go offline
|
||||
openOffers.forEach(openOffer -> offerBookService.removeOfferAtShutDown(openOffer.getOffer()));
|
||||
//TODO
|
||||
// openOffers.forEach(openOffer -> offerBookService.removeOfferAtShutDown(openOffer.getOffer()));
|
||||
|
||||
if (completeHandler != null)
|
||||
UserThread.runAfter(completeHandler::run, numOffers * 200 + 300, TimeUnit.MILLISECONDS);
|
||||
UserThread.runAfter(completeHandler::run, openOffers.size() * 200 + 300, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue