mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-07-23 07:00:49 -04:00
Support leaving and re-joining taker
This commit is contained in:
parent
62cb8d7683
commit
23a868f8fc
7 changed files with 49 additions and 102 deletions
|
@ -23,14 +23,14 @@ import io.bitsquare.common.handlers.ErrorMessageHandler;
|
||||||
import io.bitsquare.common.handlers.ResultHandler;
|
import io.bitsquare.common.handlers.ResultHandler;
|
||||||
import io.bitsquare.crypto.SignatureService;
|
import io.bitsquare.crypto.SignatureService;
|
||||||
import io.bitsquare.fiat.FiatAccount;
|
import io.bitsquare.fiat.FiatAccount;
|
||||||
|
import io.bitsquare.offer.Direction;
|
||||||
|
import io.bitsquare.offer.Offer;
|
||||||
|
import io.bitsquare.offer.OfferBookService;
|
||||||
import io.bitsquare.p2p.AddressService;
|
import io.bitsquare.p2p.AddressService;
|
||||||
import io.bitsquare.p2p.Message;
|
import io.bitsquare.p2p.Message;
|
||||||
import io.bitsquare.p2p.MessageService;
|
import io.bitsquare.p2p.MessageService;
|
||||||
import io.bitsquare.p2p.Peer;
|
import io.bitsquare.p2p.Peer;
|
||||||
import io.bitsquare.p2p.listener.SendMessageListener;
|
import io.bitsquare.p2p.listener.SendMessageListener;
|
||||||
import io.bitsquare.offer.Direction;
|
|
||||||
import io.bitsquare.offer.Offer;
|
|
||||||
import io.bitsquare.offer.OfferBookService;
|
|
||||||
import io.bitsquare.persistence.Persistence;
|
import io.bitsquare.persistence.Persistence;
|
||||||
import io.bitsquare.trade.handlers.TradeResultHandler;
|
import io.bitsquare.trade.handlers.TradeResultHandler;
|
||||||
import io.bitsquare.trade.handlers.TransactionResultHandler;
|
import io.bitsquare.trade.handlers.TransactionResultHandler;
|
||||||
|
@ -134,11 +134,34 @@ public class TradeManager {
|
||||||
}
|
}
|
||||||
for (Map.Entry<String, Trade> entry : pendingTrades.entrySet()) {
|
for (Map.Entry<String, Trade> entry : pendingTrades.entrySet()) {
|
||||||
Trade trade = entry.getValue();
|
Trade trade = entry.getValue();
|
||||||
if (trade.getState() == Trade.State.FAULT)
|
if (trade.getState() == Trade.State.FAULT) {
|
||||||
closeTrade(trade);
|
closeTrade(trade);
|
||||||
|
|
||||||
createBuyerAcceptsOfferProtocol(trade.getOffer());
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
Offer offer = trade.getOffer();
|
||||||
|
if (isMyOffer(offer)) {
|
||||||
|
createBuyerAcceptsOfferProtocol(offer);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
CheckOfferAvailabilityModel model = new CheckOfferAvailabilityModel(offer, messageService, addressService);
|
||||||
|
CheckOfferAvailabilityProtocol protocol = new CheckOfferAvailabilityProtocol(model,
|
||||||
|
() -> {
|
||||||
|
disposeCheckOfferAvailabilityRequest(offer);
|
||||||
|
// TODO need to check that trade hijacking is not possible (taking trades form other peers)
|
||||||
|
if (offer.getState() == Offer.State.AVAILABLE || offer.getState() == Offer.State.RESERVED) {
|
||||||
|
createSellerAsTakerProtocol(trade, model.getPeer());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(errorMessage) -> disposeCheckOfferAvailabilityRequest(offer));
|
||||||
|
checkOfferAvailabilityProtocolMap.put(offer.getId(), protocol);
|
||||||
|
protocol.checkOfferAvailability();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isMyOffer(Offer offer) {
|
||||||
|
return offer.getMessagePublicKey().equals(user.getMessagePubKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -233,6 +256,12 @@ public class TradeManager {
|
||||||
Trade trade = createTrade(offer);
|
Trade trade = createTrade(offer);
|
||||||
trade.setTradeAmount(amount);
|
trade.setTradeAmount(amount);
|
||||||
|
|
||||||
|
SellerAsTakerProtocol sellerTakesOfferProtocol = createSellerAsTakerProtocol(trade, peer);
|
||||||
|
sellerTakesOfferProtocol.takeAvailableOffer();
|
||||||
|
return trade;
|
||||||
|
}
|
||||||
|
|
||||||
|
private SellerAsTakerProtocol createSellerAsTakerProtocol(Trade trade, Peer peer) {
|
||||||
trade.stateProperty().addListener((ov, oldValue, newValue) -> {
|
trade.stateProperty().addListener((ov, oldValue, newValue) -> {
|
||||||
log.debug("trade state = " + newValue);
|
log.debug("trade state = " + newValue);
|
||||||
switch (newValue) {
|
switch (newValue) {
|
||||||
|
@ -268,9 +297,7 @@ public class TradeManager {
|
||||||
|
|
||||||
SellerAsTakerProtocol sellerTakesOfferProtocol = new SellerAsTakerProtocol(model);
|
SellerAsTakerProtocol sellerTakesOfferProtocol = new SellerAsTakerProtocol(model);
|
||||||
sellerAsTakerProtocolMap.put(trade.getId(), sellerTakesOfferProtocol);
|
sellerAsTakerProtocolMap.put(trade.getId(), sellerTakesOfferProtocol);
|
||||||
sellerTakesOfferProtocol.takeAvailableOffer();
|
return sellerTakesOfferProtocol;
|
||||||
|
|
||||||
return trade;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onFiatPaymentStarted(String tradeId) {
|
public void onFiatPaymentStarted(String tradeId) {
|
||||||
|
|
|
@ -93,7 +93,7 @@ public class CheckOfferAvailabilityProtocol {
|
||||||
|
|
||||||
private void handleMessage(Message message, Peer sender) {
|
private void handleMessage(Message message, Peer sender) {
|
||||||
if (!isCanceled) {
|
if (!isCanceled) {
|
||||||
if (message instanceof ReportOfferAvailabilityMessage)
|
if (message instanceof ReportOfferAvailabilityMessage && model.offer.getId().equals(((ReportOfferAvailabilityMessage) message).offerId))
|
||||||
handleReportOfferAvailabilityMessage((ReportOfferAvailabilityMessage) message);
|
handleReportOfferAvailabilityMessage((ReportOfferAvailabilityMessage) message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,8 +26,6 @@ import io.bitsquare.trade.protocol.availability.messages.ReportOfferAvailability
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import static com.google.inject.internal.util.$Preconditions.checkState;
|
|
||||||
|
|
||||||
public class ProcessReportOfferAvailabilityMessage extends Task<CheckOfferAvailabilityModel> {
|
public class ProcessReportOfferAvailabilityMessage extends Task<CheckOfferAvailabilityModel> {
|
||||||
private static final Logger log = LoggerFactory.getLogger(ProcessReportOfferAvailabilityMessage.class);
|
private static final Logger log = LoggerFactory.getLogger(ProcessReportOfferAvailabilityMessage.class);
|
||||||
|
|
||||||
|
@ -39,7 +37,6 @@ public class ProcessReportOfferAvailabilityMessage extends Task<CheckOfferAvaila
|
||||||
protected void doRun() {
|
protected void doRun() {
|
||||||
try {
|
try {
|
||||||
ReportOfferAvailabilityMessage reportOfferAvailabilityMessage = (ReportOfferAvailabilityMessage) model.getMessage();
|
ReportOfferAvailabilityMessage reportOfferAvailabilityMessage = (ReportOfferAvailabilityMessage) model.getMessage();
|
||||||
checkState(model.offer.getId().equals(reportOfferAvailabilityMessage.offerId));
|
|
||||||
|
|
||||||
if (model.offer.getState() != Offer.State.REMOVED) {
|
if (model.offer.getState() != Offer.State.REMOVED) {
|
||||||
if (reportOfferAvailabilityMessage.isOfferOpen)
|
if (reportOfferAvailabilityMessage.isOfferOpen)
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
package io.bitsquare.trade.protocol.trade.offerer;
|
package io.bitsquare.trade.protocol.trade.offerer;
|
||||||
|
|
||||||
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
import io.bitsquare.p2p.Message;
|
import io.bitsquare.p2p.Message;
|
||||||
import io.bitsquare.p2p.MessageHandler;
|
import io.bitsquare.p2p.MessageHandler;
|
||||||
import io.bitsquare.p2p.Peer;
|
import io.bitsquare.p2p.Peer;
|
||||||
|
@ -98,7 +99,7 @@ public class BuyerAsOffererProtocol {
|
||||||
model.setTradeMessage(tradeMessage);
|
model.setTradeMessage(tradeMessage);
|
||||||
model.taker.peer = taker;
|
model.taker.peer = taker;
|
||||||
|
|
||||||
BuyerAsOffererTaskRunner<BuyerAsOffererModel> taskRunner = new BuyerAsOffererTaskRunner<>(model,
|
TaskRunner<BuyerAsOffererModel> taskRunner = new TaskRunner<>(model,
|
||||||
() -> {
|
() -> {
|
||||||
log.debug("sequence at handleTakeOfferFeePayedMessage completed");
|
log.debug("sequence at handleTakeOfferFeePayedMessage completed");
|
||||||
},
|
},
|
||||||
|
@ -117,7 +118,7 @@ public class BuyerAsOffererProtocol {
|
||||||
private void handleRequestOffererPublishDepositTxMessage(RequestOffererPublishDepositTxMessage tradeMessage) {
|
private void handleRequestOffererPublishDepositTxMessage(RequestOffererPublishDepositTxMessage tradeMessage) {
|
||||||
model.setTradeMessage(tradeMessage);
|
model.setTradeMessage(tradeMessage);
|
||||||
|
|
||||||
BuyerAsOffererTaskRunner<BuyerAsOffererModel> taskRunner = new BuyerAsOffererTaskRunner<>(model,
|
TaskRunner<BuyerAsOffererModel> taskRunner = new TaskRunner<>(model,
|
||||||
() -> {
|
() -> {
|
||||||
log.debug("taskRunner at handleRequestOffererPublishDepositTxMessage completed");
|
log.debug("taskRunner at handleRequestOffererPublishDepositTxMessage completed");
|
||||||
transactionConfidenceListener = (tx, reason) -> {
|
transactionConfidenceListener = (tx, reason) -> {
|
||||||
|
@ -153,7 +154,7 @@ public class BuyerAsOffererProtocol {
|
||||||
|
|
||||||
// User clicked the "bank transfer started" button
|
// User clicked the "bank transfer started" button
|
||||||
public void onFiatPaymentStarted() {
|
public void onFiatPaymentStarted() {
|
||||||
BuyerAsOffererTaskRunner<BuyerAsOffererModel> taskRunner = new BuyerAsOffererTaskRunner<>(model,
|
TaskRunner<BuyerAsOffererModel> taskRunner = new TaskRunner<>(model,
|
||||||
() -> {
|
() -> {
|
||||||
log.debug("sequence at handleBankTransferStartedUIEvent completed");
|
log.debug("sequence at handleBankTransferStartedUIEvent completed");
|
||||||
},
|
},
|
||||||
|
@ -177,7 +178,7 @@ public class BuyerAsOffererProtocol {
|
||||||
private void handlePayoutTxPublishedMessage(PayoutTxPublishedMessage tradeMessage) {
|
private void handlePayoutTxPublishedMessage(PayoutTxPublishedMessage tradeMessage) {
|
||||||
model.setTradeMessage(tradeMessage);
|
model.setTradeMessage(tradeMessage);
|
||||||
|
|
||||||
BuyerAsOffererTaskRunner<BuyerAsOffererModel> taskRunner = new BuyerAsOffererTaskRunner<>(model,
|
TaskRunner<BuyerAsOffererModel> taskRunner = new TaskRunner<>(model,
|
||||||
() -> {
|
() -> {
|
||||||
log.debug("sequence at handlePayoutTxPublishedMessage completed");
|
log.debug("sequence at handlePayoutTxPublishedMessage completed");
|
||||||
|
|
||||||
|
|
|
@ -1,40 +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;
|
|
||||||
|
|
||||||
import io.bitsquare.common.handlers.ErrorMessageHandler;
|
|
||||||
import io.bitsquare.common.handlers.ResultHandler;
|
|
||||||
import io.bitsquare.common.taskrunner.TaskRunner;
|
|
||||||
import io.bitsquare.trade.protocol.trade.offerer.models.BuyerAsOffererModel;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
class BuyerAsOffererTaskRunner<T extends BuyerAsOffererModel> extends TaskRunner<BuyerAsOffererModel> {
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(BuyerAsOffererTaskRunner.class);
|
|
||||||
|
|
||||||
public BuyerAsOffererTaskRunner(T sharedModel, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
|
|
||||||
super(sharedModel, resultHandler, errorMessageHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* @Override
|
|
||||||
public void handleFault(String message, @NotNull Throwable throwable) {
|
|
||||||
sharedModel.trade.setState(Trade.State.FAILED);
|
|
||||||
super.handleFault(message, throwable);
|
|
||||||
}*/
|
|
||||||
}
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
package io.bitsquare.trade.protocol.trade.taker;
|
package io.bitsquare.trade.protocol.trade.taker;
|
||||||
|
|
||||||
|
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
import io.bitsquare.p2p.Message;
|
import io.bitsquare.p2p.Message;
|
||||||
import io.bitsquare.p2p.MessageHandler;
|
import io.bitsquare.p2p.MessageHandler;
|
||||||
import io.bitsquare.p2p.Peer;
|
import io.bitsquare.p2p.Peer;
|
||||||
|
@ -82,7 +83,7 @@ public class SellerAsTakerProtocol {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void takeAvailableOffer() {
|
public void takeAvailableOffer() {
|
||||||
SellerAsTakerTaskRunner<SellerAsTakerModel> taskRunner = new SellerAsTakerTaskRunner<>(model,
|
TaskRunner<SellerAsTakerModel> taskRunner = new TaskRunner<>(model,
|
||||||
() -> {
|
() -> {
|
||||||
log.debug("taskRunner at takeAvailableOffer completed");
|
log.debug("taskRunner at takeAvailableOffer completed");
|
||||||
},
|
},
|
||||||
|
@ -98,6 +99,7 @@ public class SellerAsTakerProtocol {
|
||||||
taskRunner.run();
|
taskRunner.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Incoming message handling
|
// Incoming message handling
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -105,7 +107,7 @@ public class SellerAsTakerProtocol {
|
||||||
private void handleRequestDepositPaymentMessage(RequestDepositPaymentMessage tradeMessage) {
|
private void handleRequestDepositPaymentMessage(RequestDepositPaymentMessage tradeMessage) {
|
||||||
model.setTradeMessage(tradeMessage);
|
model.setTradeMessage(tradeMessage);
|
||||||
|
|
||||||
SellerAsTakerTaskRunner<SellerAsTakerModel> taskRunner = new SellerAsTakerTaskRunner<>(model,
|
TaskRunner<SellerAsTakerModel> taskRunner = new TaskRunner<>(model,
|
||||||
() -> {
|
() -> {
|
||||||
log.debug("taskRunner at handleTakerDepositPaymentRequestMessage completed");
|
log.debug("taskRunner at handleTakerDepositPaymentRequestMessage completed");
|
||||||
},
|
},
|
||||||
|
@ -126,7 +128,7 @@ public class SellerAsTakerProtocol {
|
||||||
private void handleDepositTxPublishedMessage(DepositTxPublishedMessage tradeMessage) {
|
private void handleDepositTxPublishedMessage(DepositTxPublishedMessage tradeMessage) {
|
||||||
model.setTradeMessage(tradeMessage);
|
model.setTradeMessage(tradeMessage);
|
||||||
|
|
||||||
SellerAsTakerTaskRunner<SellerAsTakerModel> taskRunner = new SellerAsTakerTaskRunner<>(model,
|
TaskRunner<SellerAsTakerModel> taskRunner = new TaskRunner<>(model,
|
||||||
() -> {
|
() -> {
|
||||||
log.debug("taskRunner at handleDepositTxPublishedMessage completed");
|
log.debug("taskRunner at handleDepositTxPublishedMessage completed");
|
||||||
},
|
},
|
||||||
|
@ -144,7 +146,7 @@ public class SellerAsTakerProtocol {
|
||||||
private void handleBankTransferStartedMessage(BankTransferStartedMessage tradeMessage) {
|
private void handleBankTransferStartedMessage(BankTransferStartedMessage tradeMessage) {
|
||||||
model.setTradeMessage(tradeMessage);
|
model.setTradeMessage(tradeMessage);
|
||||||
|
|
||||||
SellerAsTakerTaskRunner<SellerAsTakerModel> taskRunner = new SellerAsTakerTaskRunner<>(model,
|
TaskRunner<SellerAsTakerModel> taskRunner = new TaskRunner<>(model,
|
||||||
() -> {
|
() -> {
|
||||||
log.debug("taskRunner at handleBankTransferInitedMessage completed");
|
log.debug("taskRunner at handleBankTransferInitedMessage completed");
|
||||||
model.trade.setState(Trade.State.FIAT_PAYMENT_STARTED);
|
model.trade.setState(Trade.State.FIAT_PAYMENT_STARTED);
|
||||||
|
@ -163,7 +165,7 @@ public class SellerAsTakerProtocol {
|
||||||
|
|
||||||
// User clicked the "bank transfer received" button, so we release the funds for pay out
|
// User clicked the "bank transfer received" button, so we release the funds for pay out
|
||||||
public void onFiatPaymentReceived() {
|
public void onFiatPaymentReceived() {
|
||||||
SellerAsTakerTaskRunner<SellerAsTakerModel> taskRunner = new SellerAsTakerTaskRunner<>(model,
|
TaskRunner<SellerAsTakerModel> taskRunner = new TaskRunner<>(model,
|
||||||
() -> {
|
() -> {
|
||||||
log.debug("taskRunner at handleFiatReceivedUIEvent completed");
|
log.debug("taskRunner at handleFiatReceivedUIEvent completed");
|
||||||
|
|
||||||
|
|
|
@ -1,40 +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.common.handlers.ErrorMessageHandler;
|
|
||||||
import io.bitsquare.common.handlers.ResultHandler;
|
|
||||||
import io.bitsquare.common.taskrunner.TaskRunner;
|
|
||||||
import io.bitsquare.trade.protocol.trade.taker.models.SellerAsTakerModel;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
class SellerAsTakerTaskRunner<T extends SellerAsTakerModel> extends TaskRunner<SellerAsTakerModel> {
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(SellerAsTakerTaskRunner.class);
|
|
||||||
|
|
||||||
public SellerAsTakerTaskRunner(T sharedModel, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
|
|
||||||
super(sharedModel, resultHandler, errorMessageHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* @Override
|
|
||||||
public void handleErrorMessage(String errorMessage) {
|
|
||||||
sharedModel.trade.setState(Trade.State.FAILED);
|
|
||||||
super.handleErrorMessage(errorMessage);
|
|
||||||
}*/
|
|
||||||
}
|
|
Loading…
Add table
Add a link
Reference in a new issue