mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-04-21 08:06:33 -04:00
Refactor check offer availability
This commit is contained in:
parent
6888eacc24
commit
87539db93d
gui/src/main/java/io/bitsquare
gui/main/trade/takeoffer
trade
TradeManager.java
protocol
util/tasks
@ -134,7 +134,7 @@ class TakeOfferDataModel implements Activatable, DataModel {
|
||||
offer.getStateProperty().addListener((observable, oldValue, newValue) -> {
|
||||
offerIsAvailable.set(newValue);
|
||||
});
|
||||
tradeManager.onGetOfferAvailableStateRequested(offer);
|
||||
tradeManager.onCheckOfferAvailability(offer);
|
||||
}
|
||||
|
||||
void takeOffer() {
|
||||
|
@ -30,16 +30,16 @@ import io.bitsquare.offer.OfferBookService;
|
||||
import io.bitsquare.offer.OpenOffer;
|
||||
import io.bitsquare.persistence.Persistence;
|
||||
import io.bitsquare.trade.handlers.TransactionResultHandler;
|
||||
import io.bitsquare.trade.listeners.SendMessageListener;
|
||||
import io.bitsquare.trade.protocol.offer.CheckOfferAvailabilityModel;
|
||||
import io.bitsquare.trade.protocol.offer.CheckOfferAvailabilityProtocol;
|
||||
import io.bitsquare.trade.protocol.offer.messages.ReportOfferAvailabilityMessage;
|
||||
import io.bitsquare.trade.protocol.offer.messages.RequestIsOfferAvailableMessage;
|
||||
import io.bitsquare.trade.protocol.placeoffer.PlaceOfferProtocol;
|
||||
import io.bitsquare.trade.protocol.trade.OfferMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.BuyerAsOffererModel;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.BuyerAsOffererProtocol;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.messages.IsOfferAvailableResponseMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.IsOfferAvailableResponse;
|
||||
import io.bitsquare.trade.protocol.trade.taker.RequestIsOfferAvailableProtocol;
|
||||
import io.bitsquare.trade.protocol.trade.taker.SellerAsTakerModel;
|
||||
import io.bitsquare.trade.protocol.trade.taker.SellerAsTakerProtocol;
|
||||
import io.bitsquare.trade.protocol.trade.taker.messages.RequestIsOfferAvailableMessage;
|
||||
import io.bitsquare.user.User;
|
||||
import io.bitsquare.util.handlers.ErrorMessageHandler;
|
||||
import io.bitsquare.util.handlers.ResultHandler;
|
||||
@ -55,8 +55,6 @@ import javax.inject.Inject;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableMap;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -81,7 +79,7 @@ public class TradeManager {
|
||||
//TODO store TakerAsSellerProtocol in trade
|
||||
private final Map<String, SellerAsTakerProtocol> takerAsSellerProtocolMap = new HashMap<>();
|
||||
private final Map<String, BuyerAsOffererProtocol> offererAsBuyerProtocolMap = new HashMap<>();
|
||||
private final Map<String, RequestIsOfferAvailableProtocol> requestIsOfferAvailableProtocolMap = new HashMap<>();
|
||||
private final Map<String, CheckOfferAvailabilityProtocol> checkOfferAvailabilityProtocolMap = new HashMap<>();
|
||||
|
||||
private final ObservableMap<String, OpenOffer> openOffers = FXCollections.observableHashMap();
|
||||
private final ObservableMap<String, Trade> pendingTrades = FXCollections.observableHashMap();
|
||||
@ -124,16 +122,7 @@ public class TradeManager {
|
||||
closedTrades.putAll((Map<String, Trade>) closedTradesObject);
|
||||
}
|
||||
|
||||
tradeMessageService.addMessageHandler(this::handleNewMessage);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Public Methods
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void cleanup() {
|
||||
tradeMessageService.removeMessageHandler(this::handleNewMessage);
|
||||
tradeMessageService.addMessageHandler(this::handleMessage);
|
||||
}
|
||||
|
||||
|
||||
@ -141,20 +130,23 @@ public class TradeManager {
|
||||
// Called from UI
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void onGetOfferAvailableStateRequested(Offer offer) {
|
||||
if (!requestIsOfferAvailableProtocolMap.containsKey(offer.getId())) {
|
||||
RequestIsOfferAvailableProtocol protocol = new RequestIsOfferAvailableProtocol(offer, tradeMessageService);
|
||||
requestIsOfferAvailableProtocolMap.put(offer.getId(), protocol);
|
||||
protocol.start();
|
||||
public void onCheckOfferAvailability(Offer offer) {
|
||||
if (!checkOfferAvailabilityProtocolMap.containsKey(offer.getId())) {
|
||||
|
||||
CheckOfferAvailabilityModel model = new CheckOfferAvailabilityModel(offer, tradeMessageService, () -> {
|
||||
});
|
||||
CheckOfferAvailabilityProtocol protocol = new CheckOfferAvailabilityProtocol(model);
|
||||
checkOfferAvailabilityProtocolMap.put(offer.getId(), protocol);
|
||||
protocol.onCheckOfferAvailability();
|
||||
}
|
||||
else {
|
||||
log.warn("requestIsOfferAvailable already called for offer with ID:" + offer.getId());
|
||||
log.error("onGetOfferAvailableStateRequested already called for offer with ID:" + offer.getId());
|
||||
}
|
||||
}
|
||||
|
||||
// When closing take offer view, we are not interested in the requestIsOfferAvailable result anymore, so remove from the map
|
||||
public void onGetOfferAvailableStateRequestCanceled(Offer offer) {
|
||||
requestIsOfferAvailableProtocolMap.remove(offer.getId());
|
||||
cleanupCheckOfferAvailabilityProtocolMap(offer);
|
||||
}
|
||||
|
||||
public void onPlaceOfferRequested(String id,
|
||||
@ -201,7 +193,6 @@ public class TradeManager {
|
||||
removeOpenOffer(offerId, resultHandler, errorMessageHandler, true);
|
||||
}
|
||||
|
||||
|
||||
public Trade onTakeOfferRequested(Coin amount, Offer offer) {
|
||||
Trade trade = createTrade(offer);
|
||||
trade.setTradeAmount(amount);
|
||||
@ -263,16 +254,42 @@ public class TradeManager {
|
||||
closeTrade(trade, false);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Called from Offerbook (DHT)
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Called from Offerbook when offer gets removed from DHT
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void onOfferRemovedFromRemoteOfferBook(Offer offer) {
|
||||
requestIsOfferAvailableProtocolMap.remove(offer.getId());
|
||||
cleanupCheckOfferAvailabilityProtocolMap(offer);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Process new tradeMessages
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Routes the incoming messages to the responsible protocol
|
||||
private void handleMessage(Message message, Peer sender) {
|
||||
if (message instanceof RequestIsOfferAvailableMessage) {
|
||||
String offerId = ((RequestIsOfferAvailableMessage) message).getOfferId();
|
||||
checkNotNull(offerId);
|
||||
|
||||
ReportOfferAvailabilityMessage reportOfferAvailabilityMessage = new ReportOfferAvailabilityMessage(offerId, isOfferOpen(offerId));
|
||||
tradeMessageService.sendMessage(sender, reportOfferAvailabilityMessage, new SendMessageListener() {
|
||||
@Override
|
||||
public void handleResult() {
|
||||
log.trace("ReportOfferAvailabilityMessage successfully arrived at peer");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleFault() {
|
||||
log.warn("Sending ReportOfferAvailabilityMessage failed.");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Private
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -291,12 +308,14 @@ public class TradeManager {
|
||||
offerBookService.removeOffer(openOffers.get(offerId).getOffer(),
|
||||
() -> {
|
||||
if (openOffers.containsKey(offerId)) {
|
||||
openOffers.remove(offerId);
|
||||
OpenOffer openOffer = openOffers.remove(offerId);
|
||||
cleanupCheckOfferAvailabilityProtocolMap(openOffer.getOffer());
|
||||
persistOpenOffers();
|
||||
if (removeFromOffererAsBuyerProtocolMap && offererAsBuyerProtocolMap.containsKey(offerId)) {
|
||||
offererAsBuyerProtocolMap.get(offerId).cleanup();
|
||||
offererAsBuyerProtocolMap.remove(offerId);
|
||||
}
|
||||
|
||||
resultHandler.handleResult();
|
||||
}
|
||||
else {
|
||||
@ -400,7 +419,6 @@ public class TradeManager {
|
||||
offererAsBuyerProtocolMap.remove(trade.getId());
|
||||
}
|
||||
|
||||
|
||||
if (!failed) {
|
||||
closedTrades.put(trade.getId(), trade);
|
||||
persistClosedTrades();
|
||||
@ -410,51 +428,19 @@ public class TradeManager {
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Process new tradeMessages
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// TODO remove
|
||||
// Routes the incoming messages to the responsible protocol
|
||||
private void handleNewMessage(Message message, Peer sender) {
|
||||
log.trace("handleNewMessage: message = " + message.getClass().getSimpleName());
|
||||
log.trace("handleNewMessage: sender = " + sender);
|
||||
|
||||
|
||||
if (message instanceof OfferMessage) {
|
||||
OfferMessage offerMessage = (OfferMessage) message;
|
||||
// Before starting any take offer activity we check if the offer is still available.
|
||||
if (offerMessage instanceof RequestIsOfferAvailableMessage) {
|
||||
// That message arrives at the offerer and he returns if the offer is still available (if there is no trade already created with that offerId).
|
||||
String offerId = offerMessage.getOfferId();
|
||||
checkNotNull(offerId);
|
||||
boolean isOfferOpen = getTrade(offerId) == null;
|
||||
// no handling of results or faults needed
|
||||
IsOfferAvailableResponse.run(sender, tradeMessageService, offerId, isOfferOpen);
|
||||
}
|
||||
else if (offerMessage instanceof IsOfferAvailableResponseMessage) {
|
||||
// That message arrives at the taker in response to a previous requestIsOfferAvailable call.
|
||||
// It might be that the offer got removed form the offer book, so lets check if its still there.
|
||||
if (requestIsOfferAvailableProtocolMap.containsKey(offerMessage.getOfferId())) {
|
||||
RequestIsOfferAvailableProtocol protocol = requestIsOfferAvailableProtocolMap.get(offerMessage.getOfferId());
|
||||
protocol.handleIsOfferAvailableResponseMessage((IsOfferAvailableResponseMessage) offerMessage);
|
||||
requestIsOfferAvailableProtocolMap.remove(offerMessage.getOfferId());
|
||||
}
|
||||
else {
|
||||
log.info("Offer might have been removed in the meantime. No protocol found for offer with ID:" + offerMessage.getOfferId());
|
||||
}
|
||||
}
|
||||
else {
|
||||
log.error("Incoming offerMessage not supported. " + offerMessage);
|
||||
}
|
||||
private void cleanupCheckOfferAvailabilityProtocolMap(Offer offer) {
|
||||
if (checkOfferAvailabilityProtocolMap.containsKey(offer.getId())) {
|
||||
CheckOfferAvailabilityProtocol protocol = checkOfferAvailabilityProtocolMap.get(offer.getId());
|
||||
protocol.cancel();
|
||||
protocol.cleanup();
|
||||
checkOfferAvailabilityProtocolMap.remove(offer.getId());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Setters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public boolean isOfferOpen(String offerId) {
|
||||
// Don't use openOffers as the offer gets removed async from DHT, but is added sync to pendingTrades
|
||||
return !pendingTrades.containsKey(offerId) && !closedTrades.containsKey(offerId);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Getters
|
||||
@ -493,16 +479,4 @@ public class TradeManager {
|
||||
persistence.write(this, "closedTrades", (Map<String, Trade>) new HashMap<>(closedTrades));
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public Trade getTrade(String tradeId) {
|
||||
if (pendingTrades.containsKey(tradeId)) {
|
||||
return pendingTrades.get(tradeId);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.trade.protocol.offer;
|
||||
|
||||
import io.bitsquare.network.Peer;
|
||||
import io.bitsquare.offer.Offer;
|
||||
import io.bitsquare.trade.TradeMessageService;
|
||||
import io.bitsquare.trade.protocol.trade.OfferMessage;
|
||||
import io.bitsquare.util.handlers.ResultHandler;
|
||||
import io.bitsquare.util.tasks.SharedModel;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class CheckOfferAvailabilityModel extends SharedModel {
|
||||
private static final Logger log = LoggerFactory.getLogger(CheckOfferAvailabilityModel.class);
|
||||
|
||||
private final Offer offer;
|
||||
private final TradeMessageService tradeMessageService;
|
||||
private final ResultHandler resultHandler;
|
||||
|
||||
private Peer peer;
|
||||
private OfferMessage message;
|
||||
|
||||
public CheckOfferAvailabilityModel(Offer offer, TradeMessageService tradeMessageService, ResultHandler resultHandler) {
|
||||
this.offer = offer;
|
||||
this.tradeMessageService = tradeMessageService;
|
||||
this.resultHandler = resultHandler;
|
||||
}
|
||||
|
||||
// getter/setter
|
||||
public Offer getOffer() {
|
||||
return offer;
|
||||
}
|
||||
|
||||
public TradeMessageService getTradeMessageService() {
|
||||
return tradeMessageService;
|
||||
}
|
||||
|
||||
public Peer getPeer() {
|
||||
return peer;
|
||||
}
|
||||
|
||||
public void setPeer(Peer peer) {
|
||||
this.peer = peer;
|
||||
}
|
||||
|
||||
public void setMessage(OfferMessage message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public OfferMessage getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public ResultHandler getResultHandler() {
|
||||
return resultHandler;
|
||||
}
|
||||
}
|
102
gui/src/main/java/io/bitsquare/trade/protocol/offer/CheckOfferAvailabilityProtocol.java
Normal file
102
gui/src/main/java/io/bitsquare/trade/protocol/offer/CheckOfferAvailabilityProtocol.java
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.trade.protocol.offer;
|
||||
|
||||
import io.bitsquare.network.Message;
|
||||
import io.bitsquare.network.Peer;
|
||||
import io.bitsquare.offer.Offer;
|
||||
import io.bitsquare.trade.protocol.offer.messages.ReportOfferAvailabilityMessage;
|
||||
import io.bitsquare.trade.protocol.offer.tasks.GetPeerAddress;
|
||||
import io.bitsquare.trade.protocol.offer.tasks.RequestIsOfferAvailable;
|
||||
import io.bitsquare.util.tasks.TaskRunner;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static io.bitsquare.util.Validator.nonEmptyStringOf;
|
||||
|
||||
public class CheckOfferAvailabilityProtocol {
|
||||
private static final Logger log = LoggerFactory.getLogger(CheckOfferAvailabilityProtocol.class);
|
||||
|
||||
private CheckOfferAvailabilityModel model;
|
||||
private boolean isCanceled;
|
||||
private TaskRunner<CheckOfferAvailabilityModel> sequence;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public CheckOfferAvailabilityProtocol(CheckOfferAvailabilityModel model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public void cleanup() {
|
||||
model.getTradeMessageService().removeMessageHandler(this::handleMessage);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Called from UI
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void onCheckOfferAvailability() {
|
||||
model.getTradeMessageService().addMessageHandler(this::handleMessage);
|
||||
|
||||
sequence = new TaskRunner<>(model,
|
||||
() -> {
|
||||
log.debug("sequence at onCheckOfferAvailability completed");
|
||||
},
|
||||
(message, throwable) -> {
|
||||
log.error(message);
|
||||
}
|
||||
);
|
||||
sequence.addTasks(
|
||||
GetPeerAddress.class,
|
||||
RequestIsOfferAvailable.class
|
||||
);
|
||||
sequence.run();
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
isCanceled = true;
|
||||
sequence.cancel();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Incoming message handling
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void handleMessage(Message message, Peer sender) {
|
||||
if (!isCanceled) {
|
||||
if (message instanceof ReportOfferAvailabilityMessage) {
|
||||
ReportOfferAvailabilityMessage reportOfferAvailabilityMessage = (ReportOfferAvailabilityMessage) message;
|
||||
nonEmptyStringOf(reportOfferAvailabilityMessage.getOfferId());
|
||||
|
||||
if (model.getOffer().getState() != Offer.State.OFFER_REMOVED) {
|
||||
if (reportOfferAvailabilityMessage.isOfferOpen())
|
||||
model.getOffer().setState(Offer.State.OFFER_AVAILABLE);
|
||||
else
|
||||
model.getOffer().setState(Offer.State.OFFER_NOT_AVAILABLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
model.getResultHandler().handleResult();
|
||||
}
|
||||
}
|
@ -15,18 +15,18 @@
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.trade.protocol.trade.offerer.messages;
|
||||
package io.bitsquare.trade.protocol.offer.messages;
|
||||
|
||||
import io.bitsquare.trade.protocol.trade.OfferMessage;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class IsOfferAvailableResponseMessage implements Serializable, OfferMessage {
|
||||
public class ReportOfferAvailabilityMessage implements Serializable, OfferMessage {
|
||||
private static final long serialVersionUID = 6177387534187739018L;
|
||||
private final String offerId;
|
||||
private final boolean isOfferOpen;
|
||||
|
||||
public IsOfferAvailableResponseMessage(String offerId, boolean isOfferOpen) {
|
||||
public ReportOfferAvailabilityMessage(String offerId, boolean isOfferOpen) {
|
||||
this.offerId = offerId;
|
||||
this.isOfferOpen = isOfferOpen;
|
||||
}
|
@ -15,7 +15,7 @@
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.trade.protocol.trade.taker.messages;
|
||||
package io.bitsquare.trade.protocol.offer.messages;
|
||||
|
||||
import io.bitsquare.trade.protocol.trade.OfferMessage;
|
||||
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.trade.protocol.offer.tasks;
|
||||
|
||||
import io.bitsquare.network.Peer;
|
||||
import io.bitsquare.trade.listeners.GetPeerAddressListener;
|
||||
import io.bitsquare.trade.protocol.offer.CheckOfferAvailabilityModel;
|
||||
import io.bitsquare.util.tasks.Task;
|
||||
import io.bitsquare.util.tasks.TaskRunner;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class GetPeerAddress extends Task<CheckOfferAvailabilityModel> {
|
||||
private static final Logger log = LoggerFactory.getLogger(GetPeerAddress.class);
|
||||
|
||||
public GetPeerAddress(TaskRunner taskHandler, CheckOfferAvailabilityModel model) {
|
||||
super(taskHandler, model);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void run() {
|
||||
model.getTradeMessageService().getPeerAddress(model.getOffer().getMessagePublicKey(), new GetPeerAddressListener() {
|
||||
@Override
|
||||
public void onResult(Peer peer) {
|
||||
log.trace("Found peer: " + peer.toString());
|
||||
|
||||
model.setPeer(peer);
|
||||
|
||||
complete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed() {
|
||||
failed("DHT lookup for peer address failed.");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -15,36 +15,37 @@
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.trade.protocol.trade.taker.tasks;
|
||||
package io.bitsquare.trade.protocol.offer.tasks;
|
||||
|
||||
import io.bitsquare.network.Peer;
|
||||
import io.bitsquare.trade.TradeMessageService;
|
||||
import io.bitsquare.trade.listeners.SendMessageListener;
|
||||
import io.bitsquare.trade.protocol.trade.taker.messages.RequestIsOfferAvailableMessage;
|
||||
import io.bitsquare.util.handlers.ErrorMessageHandler;
|
||||
import io.bitsquare.trade.protocol.offer.CheckOfferAvailabilityModel;
|
||||
import io.bitsquare.trade.protocol.offer.messages.RequestIsOfferAvailableMessage;
|
||||
import io.bitsquare.util.tasks.Task;
|
||||
import io.bitsquare.util.tasks.TaskRunner;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class RequestIsOfferAvailable {
|
||||
public class RequestIsOfferAvailable extends Task<CheckOfferAvailabilityModel> {
|
||||
private static final Logger log = LoggerFactory.getLogger(RequestIsOfferAvailable.class);
|
||||
|
||||
public static void run(ErrorMessageHandler errorMessageHandler,
|
||||
Peer peer, TradeMessageService tradeMessageService, String offerId) {
|
||||
log.trace("Run RequestIsOfferAvailable task");
|
||||
public RequestIsOfferAvailable(TaskRunner taskHandler, CheckOfferAvailabilityModel model) {
|
||||
super(taskHandler, model);
|
||||
}
|
||||
|
||||
tradeMessageService.sendMessage(peer, new RequestIsOfferAvailableMessage(offerId),
|
||||
@Override
|
||||
protected void run() {
|
||||
model.getTradeMessageService().sendMessage(model.getPeer(), new RequestIsOfferAvailableMessage(model.getOffer().getId()),
|
||||
new SendMessageListener() {
|
||||
@Override
|
||||
public void handleResult() {
|
||||
log.trace("RequestIsOfferAvailableMessage successfully arrived at peer");
|
||||
// nothing to do
|
||||
complete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleFault() {
|
||||
log.error("RequestIsOfferAvailableMessage did not arrive at peer");
|
||||
errorMessageHandler.handleErrorMessage("RequestIsOfferAvailableMessage did not arrive at peer");
|
||||
failed("Sending RequestIsOfferAvailableMessage failed.");
|
||||
}
|
||||
});
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.trade.protocol.trade.offerer.tasks;
|
||||
|
||||
import io.bitsquare.network.Peer;
|
||||
import io.bitsquare.trade.TradeMessageService;
|
||||
import io.bitsquare.trade.listeners.SendMessageListener;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.messages.IsOfferAvailableResponseMessage;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class IsOfferAvailableResponse {
|
||||
private static final Logger log = LoggerFactory.getLogger(IsOfferAvailableResponse.class);
|
||||
|
||||
public static void run(Peer peer,
|
||||
TradeMessageService tradeMessageService,
|
||||
String offerId,
|
||||
boolean isOfferOpen) {
|
||||
log.trace("Run RespondToIsOfferAvailable task");
|
||||
IsOfferAvailableResponseMessage message = new IsOfferAvailableResponseMessage(offerId, isOfferOpen);
|
||||
tradeMessageService.sendMessage(peer, message, new SendMessageListener() {
|
||||
@Override
|
||||
public void handleResult() {
|
||||
log.trace("RespondToIsOfferAvailableMessage successfully arrived at peer");
|
||||
// Nothing to do. Taker knows now offer available state.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleFault() {
|
||||
log.error("RespondToIsOfferAvailableMessage did not arrive at peer");
|
||||
// Ignore that. Taker might have gone offline
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -1,116 +0,0 @@
|
||||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.trade.protocol.trade.taker;
|
||||
|
||||
import io.bitsquare.network.Peer;
|
||||
import io.bitsquare.offer.Offer;
|
||||
import io.bitsquare.trade.TradeMessageService;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.messages.IsOfferAvailableResponseMessage;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.GetPeerAddress;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.RequestIsOfferAvailable;
|
||||
|
||||
import java.security.PublicKey;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Responsible for the correct execution of the sequence of tasks, message passing to the peer and message processing
|
||||
* from the peer.
|
||||
* That class handles the role of the taker as the Bitcoin seller.
|
||||
* It uses sub tasks to not pollute the main class too much with all the async result/fault handling.
|
||||
* Any data from incoming messages as well data used to send to the peer need to be validated before further processing.
|
||||
*/
|
||||
public class RequestIsOfferAvailableProtocol {
|
||||
private static final Logger log = LoggerFactory.getLogger(RequestIsOfferAvailableProtocol.class);
|
||||
|
||||
|
||||
// provided data
|
||||
private final Offer offer;
|
||||
private final TradeMessageService tradeMessageService;
|
||||
|
||||
// derived
|
||||
private final String offerId;
|
||||
private final PublicKey offererMessagePublicKey;
|
||||
|
||||
// written/read by task
|
||||
private Peer peer;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public RequestIsOfferAvailableProtocol(Offer offer,
|
||||
TradeMessageService tradeMessageService) {
|
||||
this.offer = offer;
|
||||
this.tradeMessageService = tradeMessageService;
|
||||
offerId = offer.getId();
|
||||
offererMessagePublicKey = offer.getMessagePublicKey();
|
||||
}
|
||||
|
||||
public void start() {
|
||||
getPeerAddress();
|
||||
}
|
||||
|
||||
// 1. GetPeerAddress
|
||||
// Async
|
||||
// In case of an error: Don't repeat call for now, maybe in production repeat once.
|
||||
private void getPeerAddress() {
|
||||
log.debug("getPeerAddress called");
|
||||
GetPeerAddress.run(this::onResultGetPeerAddress, this::handleErrorMessage, tradeMessageService, offererMessagePublicKey);
|
||||
}
|
||||
|
||||
/* private void onGetPeerAddressFault(String errorMessage) {
|
||||
GetPeerAddress.run(this::onResultGetPeerAddress, this::handleErrorMessage, tradeMessageService, offererMessagePublicKey);
|
||||
}*/
|
||||
|
||||
|
||||
// 2. RequestTakeOffer
|
||||
// Async
|
||||
// In case of an error: Don't repeat call for now, maybe in production repeat once.
|
||||
public void onResultGetPeerAddress(Peer peer) {
|
||||
log.debug("onResultGetPeerAddress called");
|
||||
this.peer = peer;
|
||||
|
||||
RequestIsOfferAvailable.run(this::handleErrorMessage, peer, tradeMessageService, offerId);
|
||||
}
|
||||
|
||||
/* private void onRequestIsOfferAvailableFault(String errorMessage) {
|
||||
RequestIsOfferAvailable.run(this::handleErrorMessage, peer, tradeMessageService, offerId);
|
||||
}*/
|
||||
|
||||
// generic
|
||||
private void handleErrorMessage(String errorMessage) {
|
||||
offer.setState(Offer.State.OFFER_NOT_AVAILABLE);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Incoming message from peer
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void handleIsOfferAvailableResponseMessage(IsOfferAvailableResponseMessage offerMessage) {
|
||||
if (offer.getState() != Offer.State.OFFER_REMOVED) {
|
||||
if (offerMessage.isOfferOpen())
|
||||
offer.setState(Offer.State.OFFER_AVAILABLE);
|
||||
else
|
||||
offer.setState(Offer.State.OFFER_NOT_AVAILABLE);
|
||||
}
|
||||
}
|
||||
}
|
@ -47,7 +47,6 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import static io.bitsquare.util.Validator.nonEmptyStringOf;
|
||||
|
||||
|
||||
public class SellerAsTakerProtocol {
|
||||
private static final Logger log = LoggerFactory.getLogger(SellerAsTakerProtocol.class);
|
||||
|
||||
|
@ -18,15 +18,11 @@
|
||||
package io.bitsquare.trade.protocol.trade.taker.tasks;
|
||||
|
||||
import io.bitsquare.network.Peer;
|
||||
import io.bitsquare.trade.TradeMessageService;
|
||||
import io.bitsquare.trade.listeners.GetPeerAddressListener;
|
||||
import io.bitsquare.trade.protocol.trade.taker.SellerAsTakerModel;
|
||||
import io.bitsquare.util.handlers.ErrorMessageHandler;
|
||||
import io.bitsquare.util.tasks.Task;
|
||||
import io.bitsquare.util.tasks.TaskRunner;
|
||||
|
||||
import java.security.PublicKey;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -49,32 +45,9 @@ public class GetPeerAddress extends Task<SellerAsTakerModel> {
|
||||
|
||||
@Override
|
||||
public void onFailed() {
|
||||
failed("DHT lookup for peer address failed.", null);
|
||||
failed("DHT lookup for peer address failed.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public static void run(ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler,
|
||||
TradeMessageService tradeMessageService, PublicKey messagePublicKey) {
|
||||
log.trace("Run GetPeerAddress task");
|
||||
tradeMessageService.getPeerAddress(messagePublicKey, new GetPeerAddressListener() {
|
||||
@Override
|
||||
public void onResult(Peer peer) {
|
||||
log.trace("Received peer = " + peer.toString());
|
||||
resultHandler.onResult(peer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed() {
|
||||
log.error("DHT lookup for peer address failed.");
|
||||
errorMessageHandler.handleErrorMessage("DHT lookup for peer address failed.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public interface ResultHandler {
|
||||
void onResult(Peer peer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,8 @@ public class TaskRunner<T extends SharedModel> {
|
||||
private Class<? extends Task> currentTask;
|
||||
private Class<? extends Task> previousTask;
|
||||
|
||||
private boolean isCanceled;
|
||||
|
||||
public TaskRunner(T sharedModel, ResultHandler resultHandler, FaultHandler faultHandler) {
|
||||
this.sharedModel = sharedModel;
|
||||
this.resultHandler = resultHandler;
|
||||
@ -56,7 +58,7 @@ public class TaskRunner<T extends SharedModel> {
|
||||
}
|
||||
|
||||
protected void next() {
|
||||
if (!failed) {
|
||||
if (!failed && !isCanceled) {
|
||||
if (tasks.size() > 0) {
|
||||
try {
|
||||
setCurrentTask(tasks.poll());
|
||||
@ -74,6 +76,10 @@ public class TaskRunner<T extends SharedModel> {
|
||||
}
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
isCanceled = true;
|
||||
}
|
||||
|
||||
protected void setPreviousTask(Class<? extends Task> task) {
|
||||
previousTask = task;
|
||||
}
|
||||
@ -103,4 +109,5 @@ public class TaskRunner<T extends SharedModel> {
|
||||
failed = true;
|
||||
faultHandler.handleFault(message, throwable);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user