mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-04-14 04:53:00 -04:00
Refactor payment process
This commit is contained in:
parent
397aedc099
commit
aee5addacf
@ -39,7 +39,6 @@ import org.bitcoinj.core.TransactionInput;
|
||||
import org.bitcoinj.core.TransactionOutPoint;
|
||||
import org.bitcoinj.core.TransactionOutput;
|
||||
import org.bitcoinj.core.Utils;
|
||||
import org.bitcoinj.core.VerificationException;
|
||||
import org.bitcoinj.core.Wallet;
|
||||
import org.bitcoinj.core.WalletEventListener;
|
||||
import org.bitcoinj.crypto.DeterministicKey;
|
||||
@ -624,11 +623,11 @@ public class WalletService {
|
||||
log.trace("offererPubKey=" + offererPubKey);
|
||||
log.trace("takerPubKey=" + takerPubKey);
|
||||
log.trace("arbitratorPubKey=" + arbitratorPubKey);
|
||||
log.trace("offererInputAmount=" + offererInputAmount.toFriendlyString());
|
||||
log.trace("tradeId=" + tradeId);
|
||||
|
||||
// we need to subtract the fee as it will go to the miners
|
||||
Coin amountToPay = offererInputAmount.subtract(FeePolicy.TX_FEE);
|
||||
log.trace("amountToPay=" + amountToPay.toFriendlyString());
|
||||
// We need to subtract the fee as it will go to the miners
|
||||
Coin offererInput = offererInputAmount.subtract(FeePolicy.TX_FEE);
|
||||
log.trace("amountToPay=" + offererInput.toFriendlyString());
|
||||
|
||||
// We pay the offererInputAmount to a temporary MS output which will be changed later to the correct value.
|
||||
// With the usage of completeTx() we get all the work done with fee calculation, validation and coin selection.
|
||||
@ -638,7 +637,7 @@ public class WalletService {
|
||||
// The btc tx fee will be included by the completeTx() call, so we don't need to add it manually.
|
||||
Transaction tx = new Transaction(params);
|
||||
Script multiSigOutputScript = getMultiSigScript(offererPubKey, takerPubKey, arbitratorPubKey);
|
||||
tx.addOutput(amountToPay, multiSigOutputScript);
|
||||
tx.addOutput(offererInput, multiSigOutputScript); // that output is just a dummy for input calculation
|
||||
|
||||
Wallet.SendRequest sendRequest = Wallet.SendRequest.forTx(tx);
|
||||
sendRequest.shuffleOutputs = false;
|
||||
@ -660,8 +659,7 @@ public class WalletService {
|
||||
/*
|
||||
IN[0] any input > offererInputAmount + fee (unsigned)
|
||||
OUT[0] MS offererInputAmount
|
||||
OUT[1] Change = input - offererInputAmount - fee
|
||||
btc tx fee
|
||||
OUT[1] Optional Change = input - offererInputAmount - fee btc tx fee
|
||||
*/
|
||||
|
||||
log.trace("Check if wallet is consistent: result=" + wallet.isConsistent());
|
||||
@ -688,6 +686,7 @@ public class WalletService {
|
||||
log.trace("takerPubKey=" + takerPubKey);
|
||||
log.trace("arbitratorPubKey=" + arbitratorPubKey);
|
||||
log.trace("offerersPartialDepositTxAsHex=" + offerersPartialDepositTxAsHex);
|
||||
log.trace("tradeId=" + tradeId);
|
||||
|
||||
// We pay the btc tx fee 2 times to the deposit tx:
|
||||
// 1. will be spent to miners when publishing the deposit tx
|
||||
@ -718,8 +717,7 @@ public class WalletService {
|
||||
/*
|
||||
IN[0] any input taker > takerInputAmount + fee (signed)
|
||||
OUT[0] MS takerInputAmount
|
||||
OUT[1] Change = input taker - takerInputAmount - fee
|
||||
btc tx fee
|
||||
OUT[1] Optional change = input taker - takerInputAmount - fee btc tx fee
|
||||
*/
|
||||
|
||||
|
||||
@ -736,7 +734,9 @@ public class WalletService {
|
||||
*/
|
||||
|
||||
// Now we add the inputs and outputs from our temp tx and change the multiSig amount to the correct value
|
||||
// TODO multiple inputs not supported yet
|
||||
tx.addInput(tempTx.getInput(0));
|
||||
// handle optional change output
|
||||
if (tempTx.getOutputs().size() == 2) {
|
||||
tx.addOutput(tempTx.getOutput(1));
|
||||
}
|
||||
@ -745,11 +745,10 @@ public class WalletService {
|
||||
msOutputAmount = msOutputAmount.add(FeePolicy.TX_FEE);
|
||||
tx.getOutput(0).setValue(msOutputAmount);
|
||||
|
||||
// Now we sign our input
|
||||
// Now we sign our input (index 1)
|
||||
TransactionInput input = tx.getInput(1);
|
||||
if (input == null || input.getConnectedOutput() == null) {
|
||||
log.error("input or input.getConnectedOutput() is null: " + input);
|
||||
}
|
||||
if (input == null || input.getConnectedOutput() == null)
|
||||
log.error("Must not happen - input or input.getConnectedOutput() is null: " + input);
|
||||
|
||||
Script scriptPubKey = input.getConnectedOutput().getScriptPubKey();
|
||||
ECKey sigKey = input.getOutpoint().getConnectedKey(wallet);
|
||||
@ -778,8 +777,7 @@ public class WalletService {
|
||||
IN[1] any input taker > takerInputAmount + fee (signed) e.g.: 1.1001
|
||||
OUT[0] MS offererInputAmount e.g.: 1.2001
|
||||
OUT[1] Change = input offerer - offererInputAmount - fee e.g.: 0 if input is matching correct value
|
||||
OUT[2] Change = input taker - takerInputAmount - fee e.g.: 0 if input is matching correct value
|
||||
btc tx fee e.g.: 0.1001
|
||||
OUT[2] Change = input taker - takerInputAmount - fee e.g.: 0 if input is matching correct value btc tx fee e.g.: 0.1001
|
||||
*/
|
||||
|
||||
// We must not commit that tx to the wallet as we will get it over the network when the offerer
|
||||
@ -926,13 +924,9 @@ public class WalletService {
|
||||
// boolean isAlreadyInWallet = wallet.maybeCommitTx(depositTx);
|
||||
//log.trace("isAlreadyInWallet=" + isAlreadyInWallet);
|
||||
|
||||
try {
|
||||
// Manually add the multisigContract to the wallet, overriding the isRelevant checks so we can track
|
||||
// it and check for double-spends later
|
||||
wallet.receivePending(depositTx, null, true);
|
||||
} catch (VerificationException e) {
|
||||
throw new RuntimeException(e); // Cannot happen, we already called multisigContract.verify()
|
||||
}
|
||||
// Manually add the multisigContract to the wallet, overriding the isRelevant checks so we can track
|
||||
// it and check for double-spends later
|
||||
wallet.receivePending(depositTx, null, true);
|
||||
|
||||
return depositTx;
|
||||
|
||||
|
@ -548,7 +548,7 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
|
||||
setGraphic(iconView);
|
||||
}
|
||||
else {
|
||||
if (stateProperty != null) {
|
||||
if (stateProperty != null && stateChangeListener != null) {
|
||||
stateProperty.removeListener(stateChangeListener);
|
||||
stateChangeListener = null;
|
||||
}
|
||||
|
@ -142,9 +142,16 @@ class TakeOfferDataModel implements Activatable, DataModel {
|
||||
trade.stateProperty().addListener((ov, oldValue, newValue) -> {
|
||||
log.debug("trade state = " + newValue);
|
||||
switch (newValue) {
|
||||
// TODO Check why DEPOSIT_CONFIRMED can happen, refactor state handling
|
||||
case OPEN:
|
||||
break;
|
||||
case OFFERER_ACCEPTED:
|
||||
break;
|
||||
case OFFERER_REJECTED:
|
||||
requestTakeOfferErrorMessage.set("Take offer request got rejected. Maybe another trader has taken the offer in the meantime.");
|
||||
break;
|
||||
case DEPOSIT_PUBLISHED:
|
||||
case DEPOSIT_CONFIRMED:
|
||||
// TODO Check why DEPOSIT_CONFIRMED can happen, refactor state handling
|
||||
// TODO null pointer happened here!
|
||||
if (trade.getDepositTx() != null) {
|
||||
transactionId.set(trade.getDepositTx().getHashAsString());
|
||||
@ -155,14 +162,15 @@ class TakeOfferDataModel implements Activatable, DataModel {
|
||||
" That should not happen and needs more investigation why it can happen.");
|
||||
}
|
||||
break;
|
||||
case PAYMENT_STARTED:
|
||||
break;
|
||||
case FAILED:
|
||||
requestTakeOfferErrorMessage.set("An error occurred. Error: " + trade.getFault().getMessage());
|
||||
break;
|
||||
case OFFERER_REJECTED:
|
||||
requestTakeOfferErrorMessage.set("Take offer request got rejected.");
|
||||
case COMPLETED:
|
||||
break;
|
||||
default:
|
||||
log.warn("Unhandled trade state: " + newValue);
|
||||
log.error("Unhandled trade state: " + newValue);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
@ -163,13 +163,11 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
||||
showPaymentInfoScreenButton.setVisible(true);
|
||||
}
|
||||
else if ((state == Offer.State.OFFER_NOT_AVAILABLE)) {
|
||||
Popups.openWarningPopup("You cannot take that offer",
|
||||
"The offerer is either offline or the offer was already taken by another trader.");
|
||||
Popups.openWarningPopup("You cannot take that offer", "The offerer is either offline or the offer was already taken by another trader.");
|
||||
close();
|
||||
}
|
||||
else if ((state == Offer.State.OFFER_REMOVED)) {
|
||||
Popups.openWarningPopup("You cannot take that offer",
|
||||
"The offerer has been removed in the meantime.");
|
||||
Popups.openWarningPopup("You cannot take that offer", "The offerer has been removed in the meantime.");
|
||||
close();
|
||||
}
|
||||
}
|
||||
@ -196,8 +194,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
||||
}
|
||||
});
|
||||
Popups.openInfoPopup("To ensure that both traders behave fair they need to pay a security deposit.",
|
||||
"The deposit will stay in your local trading wallet until the offer gets accepted by " +
|
||||
"another trader. " +
|
||||
"The deposit will stay in your local trading wallet until the offer gets accepted by another trader. " +
|
||||
"\nIt will be refunded to you after the trade has successfully completed.",
|
||||
actions);
|
||||
|
||||
|
@ -53,7 +53,7 @@ public class Trade implements Serializable {
|
||||
private String takeOfferFeeTxID;
|
||||
private Contract contract;
|
||||
private String contractAsJson;
|
||||
private String takerSignature;
|
||||
private String takerContractSignature;
|
||||
private Transaction depositTx;
|
||||
private Transaction payoutTx;
|
||||
|
||||
@ -86,8 +86,8 @@ public class Trade implements Serializable {
|
||||
// Setters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void setContractTakerSignature(String takerSignature) {
|
||||
this.takerSignature = takerSignature;
|
||||
public void setTakerContractSignature(String takerSignature) {
|
||||
this.takerContractSignature = takerSignature;
|
||||
}
|
||||
|
||||
public void setTakeOfferFeeTxID(String takeOfferFeeTxID) {
|
||||
@ -143,8 +143,8 @@ public class Trade implements Serializable {
|
||||
return offer.getVolumeByAmount(tradeAmount);
|
||||
}
|
||||
|
||||
public String getTakerSignature() {
|
||||
return takerSignature;
|
||||
public String getTakerContractSignature() {
|
||||
return takerContractSignature;
|
||||
}
|
||||
|
||||
public Transaction getDepositTx() {
|
||||
|
@ -30,20 +30,20 @@ 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.BuyerAcceptsOfferProtocolListener;
|
||||
import io.bitsquare.trade.listeners.SellerTakesOfferProtocolListener;
|
||||
import io.bitsquare.trade.protocol.placeoffer.PlaceOfferProtocol;
|
||||
import io.bitsquare.trade.protocol.trade.OfferMessage;
|
||||
import io.bitsquare.trade.protocol.trade.TradeMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.BuyerAcceptsOfferProtocol;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.BuyerAcceptsOfferProtocolListener;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.messages.BankTransferInitedMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.messages.DepositTxPublishedMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.messages.IsOfferAvailableResponseMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.messages.RequestTakerDepositPaymentMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.messages.RespondToTakeOfferRequestMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.messages.TakerDepositPaymentRequestMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.IsOfferAvailableResponse;
|
||||
import io.bitsquare.trade.protocol.trade.taker.RequestIsOfferAvailableProtocol;
|
||||
import io.bitsquare.trade.protocol.trade.taker.SellerTakesOfferProtocol;
|
||||
import io.bitsquare.trade.protocol.trade.taker.SellerTakesOfferProtocolListener;
|
||||
import io.bitsquare.trade.protocol.trade.taker.messages.PayoutTxPublishedMessage;
|
||||
import io.bitsquare.trade.protocol.trade.taker.messages.RequestIsOfferAvailableMessage;
|
||||
import io.bitsquare.trade.protocol.trade.taker.messages.RequestOffererPublishDepositTxMessage;
|
||||
@ -227,6 +227,8 @@ public class TradeManager {
|
||||
pendingTrades.put(offer.getId(), trade);
|
||||
persistPendingTrades();
|
||||
|
||||
currentPendingTrade = trade;
|
||||
|
||||
return trade;
|
||||
}
|
||||
|
||||
@ -241,6 +243,14 @@ public class TradeManager {
|
||||
persistClosedTrades();
|
||||
}
|
||||
|
||||
private void removeFailedTrade(Trade trade) {
|
||||
if (!pendingTrades.containsKey(trade.getId()))
|
||||
log.error("trades does not contain the trade with the ID " + trade.getId());
|
||||
|
||||
pendingTrades.remove(trade.getId());
|
||||
persistPendingTrades();
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Trading protocols
|
||||
@ -251,7 +261,6 @@ public class TradeManager {
|
||||
if (openOffers.containsKey(offerId)) {
|
||||
Offer offer = openOffers.get(offerId).getOffer();
|
||||
Trade trade = createTrade(offer);
|
||||
currentPendingTrade = trade;
|
||||
|
||||
BuyerAcceptsOfferProtocol buyerAcceptsOfferProtocol = new BuyerAcceptsOfferProtocol(trade,
|
||||
sender,
|
||||
@ -263,10 +272,10 @@ public class TradeManager {
|
||||
new BuyerAcceptsOfferProtocolListener() {
|
||||
@Override
|
||||
public void onOfferAccepted(Offer offer) {
|
||||
trade.setState(Trade.State.OFFERER_ACCEPTED);
|
||||
persistPendingTrades();
|
||||
//TODO do that later
|
||||
requestRemoveOpenOffer(offer.getId(),
|
||||
() -> log.debug("remove was successful"),
|
||||
() -> log.debug("remove offer was successful"),
|
||||
(message) -> log.error(message));
|
||||
}
|
||||
|
||||
@ -298,21 +307,11 @@ public class TradeManager {
|
||||
@Override
|
||||
public void onFault(Throwable throwable, BuyerAcceptsOfferProtocol.State state) {
|
||||
log.error("Error while executing trade process at state: " + state + " / " + throwable);
|
||||
trade.setFault(throwable);
|
||||
trade.setState(Trade.State.FAILED);
|
||||
persistPendingTrades();
|
||||
}
|
||||
|
||||
// probably not needed
|
||||
@Override
|
||||
public void onWaitingForPeerResponse(BuyerAcceptsOfferProtocol.State state) {
|
||||
log.debug("Waiting for peers response at state " + state);
|
||||
}
|
||||
|
||||
// probably not needed
|
||||
@Override
|
||||
public void onWaitingForUserInteraction(BuyerAcceptsOfferProtocol.State state) {
|
||||
log.debug("Waiting for UI activity at state " + state);
|
||||
switch (state) {
|
||||
case RespondToTakeOfferRequest:
|
||||
removeFailedTrade(trade);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -336,18 +335,15 @@ public class TradeManager {
|
||||
Trade trade = createTrade(offer);
|
||||
trade.setTradeAmount(amount);
|
||||
|
||||
currentPendingTrade = trade;
|
||||
SellerTakesOfferProtocolListener listener = new SellerTakesOfferProtocolListener() {
|
||||
@Override
|
||||
public void onTakeOfferRequestAccepted(Trade trade) {
|
||||
trade.setState(Trade.State.OFFERER_ACCEPTED);
|
||||
public void onTakeOfferRequestAccepted() {
|
||||
persistPendingTrades();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTakeOfferRequestRejected(Trade trade) {
|
||||
trade.setState(Trade.State.OFFERER_REJECTED);
|
||||
persistPendingTrades();
|
||||
public void onTakeOfferRequestRejected() {
|
||||
removeFailedTrade(trade);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -369,25 +365,28 @@ public class TradeManager {
|
||||
trade.setState(Trade.State.COMPLETED);
|
||||
// We close the trade when the user has withdrawn his trade funds (see #283)
|
||||
//closeTrade(trade);
|
||||
persistPendingTrades();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFault(Throwable throwable, SellerTakesOfferProtocol.State state) {
|
||||
log.error("onFault: " + throwable.getMessage() + " / " + state);
|
||||
log.error("Error while executing trade process at state: " + state + " / " + throwable);
|
||||
switch (state) {
|
||||
case GetPeerAddress:
|
||||
// TODO add unreachable node to a local ignore list in case of repeated failures
|
||||
removeFailedTrade(trade);
|
||||
break;
|
||||
case RequestTakeOffer:
|
||||
// TODO add unreachable node to a local ignore list in case of repeated failures
|
||||
removeFailedTrade(trade);
|
||||
break;
|
||||
case PayTakeOfferFee:
|
||||
removeFailedTrade(trade);
|
||||
break;
|
||||
case SendTakeOfferFeePayedMessage:
|
||||
removeFailedTrade(trade);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// probably not needed
|
||||
@Override
|
||||
public void onWaitingForPeerResponse(SellerTakesOfferProtocol.State state) {
|
||||
log.debug("onWaitingForPeerResponse");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
@ -411,7 +410,7 @@ public class TradeManager {
|
||||
// Also we don't support yet offline messaging (mail box)
|
||||
public void fiatPaymentStarted(String tradeId) {
|
||||
if (offererAsBuyerProtocolMap.get(tradeId) != null) {
|
||||
offererAsBuyerProtocolMap.get(tradeId).onUIEventBankTransferInited();
|
||||
offererAsBuyerProtocolMap.get(tradeId).handleUIEventBankTransferInited();
|
||||
pendingTrades.get(tradeId).setState(Trade.State.PAYMENT_STARTED);
|
||||
persistPendingTrades();
|
||||
}
|
||||
@ -423,7 +422,7 @@ public class TradeManager {
|
||||
}
|
||||
|
||||
public void fiatPaymentReceived(String tradeId) {
|
||||
takerAsSellerProtocolMap.get(tradeId).onUIEventFiatReceived();
|
||||
takerAsSellerProtocolMap.get(tradeId).handleUIEventFiatReceived();
|
||||
}
|
||||
|
||||
public void requestIsOfferAvailable(Offer offer) {
|
||||
@ -436,12 +435,12 @@ public class TradeManager {
|
||||
log.warn("requestIsOfferAvailable 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 stopRequestIsOfferAvailableRequest(Offer offer) {
|
||||
requestIsOfferAvailableProtocolMap.remove(offer.getId());
|
||||
}
|
||||
|
||||
|
||||
public void onOfferRemovedFromRemoteOfferBook(Offer offer) {
|
||||
requestIsOfferAvailableProtocolMap.remove(offer.getId());
|
||||
}
|
||||
@ -488,23 +487,24 @@ public class TradeManager {
|
||||
checkNotNull(tradeId);
|
||||
|
||||
if (tradeMessage instanceof RequestTakeOfferMessage) {
|
||||
// Step 3. in trade protocol
|
||||
createOffererAsBuyerProtocol(tradeId, sender);
|
||||
}
|
||||
else if (tradeMessage instanceof RespondToTakeOfferRequestMessage) {
|
||||
takerAsSellerProtocolMap.get(tradeId).onRespondToTakeOfferRequestMessage((RespondToTakeOfferRequestMessage) tradeMessage);
|
||||
takerAsSellerProtocolMap.get(tradeId).handleRespondToTakeOfferRequestMessage((RespondToTakeOfferRequestMessage) tradeMessage);
|
||||
}
|
||||
else if (tradeMessage instanceof TakeOfferFeePayedMessage) {
|
||||
offererAsBuyerProtocolMap.get(tradeId).onTakeOfferFeePayedMessage((TakeOfferFeePayedMessage) tradeMessage);
|
||||
offererAsBuyerProtocolMap.get(tradeId).handleTakeOfferFeePayedMessage((TakeOfferFeePayedMessage) tradeMessage);
|
||||
}
|
||||
else if (tradeMessage instanceof RequestTakerDepositPaymentMessage) {
|
||||
takerAsSellerProtocolMap.get(tradeId).onRequestTakerDepositPaymentMessage((RequestTakerDepositPaymentMessage) tradeMessage);
|
||||
else if (tradeMessage instanceof TakerDepositPaymentRequestMessage) {
|
||||
takerAsSellerProtocolMap.get(tradeId).handleTakerDepositPaymentRequestMessage((TakerDepositPaymentRequestMessage) tradeMessage);
|
||||
}
|
||||
else if (tradeMessage instanceof RequestOffererPublishDepositTxMessage) {
|
||||
offererAsBuyerProtocolMap.get(tradeId).onRequestOffererPublishDepositTxMessage((RequestOffererPublishDepositTxMessage) tradeMessage);
|
||||
offererAsBuyerProtocolMap.get(tradeId).handleRequestOffererPublishDepositTxMessage((RequestOffererPublishDepositTxMessage) tradeMessage);
|
||||
}
|
||||
else if (tradeMessage instanceof DepositTxPublishedMessage) {
|
||||
persistPendingTrades();
|
||||
takerAsSellerProtocolMap.get(tradeId).onDepositTxPublishedMessage((DepositTxPublishedMessage) tradeMessage);
|
||||
takerAsSellerProtocolMap.get(tradeId).handleDepositTxPublishedMessage((DepositTxPublishedMessage) tradeMessage);
|
||||
}
|
||||
else if (tradeMessage instanceof BankTransferInitedMessage) {
|
||||
// Here happened a null pointer. I assume the only possible reason was that we got a null for the
|
||||
@ -513,10 +513,10 @@ public class TradeManager {
|
||||
// For getting better info we add a check. tradeId is checked above.
|
||||
if (takerAsSellerProtocolMap.get(tradeId) == null)
|
||||
log.error("takerAsSellerProtocolMap.get(tradeId) = null. That must not happen.");
|
||||
takerAsSellerProtocolMap.get(tradeId).onBankTransferInitedMessage((BankTransferInitedMessage) tradeMessage);
|
||||
takerAsSellerProtocolMap.get(tradeId).handleBankTransferInitedMessage((BankTransferInitedMessage) tradeMessage);
|
||||
}
|
||||
else if (tradeMessage instanceof PayoutTxPublishedMessage) {
|
||||
offererAsBuyerProtocolMap.get(tradeId).onPayoutTxPublishedMessage((PayoutTxPublishedMessage) tradeMessage);
|
||||
offererAsBuyerProtocolMap.get(tradeId).handlePayoutTxPublishedMessage((PayoutTxPublishedMessage) tradeMessage);
|
||||
}
|
||||
else {
|
||||
log.error("Incoming tradeMessage not supported. " + tradeMessage);
|
||||
|
@ -15,9 +15,10 @@
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.trade.protocol.trade.offerer;
|
||||
package io.bitsquare.trade.listeners;
|
||||
|
||||
import io.bitsquare.offer.Offer;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.BuyerAcceptsOfferProtocol;
|
||||
|
||||
import org.bitcoinj.core.Transaction;
|
||||
|
||||
@ -31,8 +32,4 @@ public interface BuyerAcceptsOfferProtocolListener {
|
||||
void onPayoutTxPublished(Transaction payoutTx);
|
||||
|
||||
void onFault(Throwable throwable, BuyerAcceptsOfferProtocol.State state);
|
||||
|
||||
void onWaitingForPeerResponse(BuyerAcceptsOfferProtocol.State state);
|
||||
|
||||
void onWaitingForUserInteraction(BuyerAcceptsOfferProtocol.State state);
|
||||
}
|
@ -15,9 +15,10 @@
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.trade.protocol.trade.taker;
|
||||
package io.bitsquare.trade.listeners;
|
||||
|
||||
import io.bitsquare.trade.Trade;
|
||||
import io.bitsquare.trade.protocol.trade.taker.SellerTakesOfferProtocol;
|
||||
|
||||
import org.bitcoinj.core.Transaction;
|
||||
|
||||
@ -30,10 +31,8 @@ public interface SellerTakesOfferProtocolListener {
|
||||
|
||||
void onFault(Throwable throwable, SellerTakesOfferProtocol.State state);
|
||||
|
||||
void onWaitingForPeerResponse(SellerTakesOfferProtocol.State state);
|
||||
void onTakeOfferRequestAccepted();
|
||||
|
||||
void onTakeOfferRequestAccepted(Trade trade);
|
||||
|
||||
void onTakeOfferRequestRejected(Trade trade);
|
||||
void onTakeOfferRequestRejected();
|
||||
|
||||
}
|
@ -27,15 +27,15 @@ import io.bitsquare.offer.Offer;
|
||||
import io.bitsquare.trade.Contract;
|
||||
import io.bitsquare.trade.Trade;
|
||||
import io.bitsquare.trade.TradeMessageService;
|
||||
import io.bitsquare.trade.listeners.BuyerAcceptsOfferProtocolListener;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.CreateDepositTx;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.HandleTakeOfferRequest;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.RequestTakerDepositPayment;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.RespondToTakeOfferRequest;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.SendDepositTxIdToTaker;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.SendSignedPayoutTx;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.SendTakerDepositPaymentRequest;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.SetupListenerForBlockChainConfirmation;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.SignAndPublishDepositTx;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.VerifyAndSignContract;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.VerifyTakeOfferFeePayment;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.tasks.VerifyTakerAccount;
|
||||
import io.bitsquare.trade.protocol.trade.taker.messages.PayoutTxPublishedMessage;
|
||||
import io.bitsquare.trade.protocol.trade.taker.messages.RequestOffererPublishDepositTxMessage;
|
||||
@ -72,25 +72,24 @@ public class BuyerAcceptsOfferProtocol {
|
||||
|
||||
public enum State {
|
||||
Init,
|
||||
HandleTakeOfferRequest,
|
||||
RespondToTakeOfferRequest,
|
||||
|
||||
onTakeOfferFeePayedMessage,
|
||||
VerifyTakeOfferFeePayment,
|
||||
handleTakeOfferFeePayedMessage,
|
||||
/* VerifyTakeOfferFeePayment,*/
|
||||
CreateDepositTx,
|
||||
RequestTakerDepositPayment,
|
||||
|
||||
onRequestOffererPublishDepositTxMessage,
|
||||
handleRequestOffererPublishDepositTxMessage,
|
||||
VerifyTakerAccount,
|
||||
VerifyAndSignContract,
|
||||
SignAndPublishDepositTx,
|
||||
SendDepositTxIdToTaker,
|
||||
SetupListenerForBlockChainConfirmation,
|
||||
onResultSetupListenerForBlockChainConfirmation,
|
||||
|
||||
onUIEventBankTransferInited,
|
||||
handleUIEventBankTransferInited,
|
||||
SendSignedPayoutTx,
|
||||
|
||||
onPayoutTxPublishedMessage
|
||||
handlePayoutTxPublishedMessage
|
||||
}
|
||||
|
||||
// provided
|
||||
@ -118,7 +117,7 @@ public class BuyerAcceptsOfferProtocol {
|
||||
|
||||
// data written by messages, read by tasks
|
||||
private String takeOfferFeeTxId;
|
||||
private String takerPubKey;
|
||||
private String tradePubKeyAsHex;
|
||||
private String peersPayoutAddress;
|
||||
private String peersAccountId;
|
||||
private BankAccount peersBankAccount;
|
||||
@ -131,7 +130,7 @@ public class BuyerAcceptsOfferProtocol {
|
||||
|
||||
// state
|
||||
private State state;
|
||||
private int step = 0;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
@ -173,33 +172,28 @@ public class BuyerAcceptsOfferProtocol {
|
||||
}
|
||||
|
||||
public void start() {
|
||||
handleTakeOfferRequest();
|
||||
respondToTakeOfferRequest();
|
||||
}
|
||||
|
||||
// 1. HandleTakeOfferRequest
|
||||
// Async
|
||||
// In case of an error: Repeat once, then give up. No rollback activity needed
|
||||
private void handleTakeOfferRequest() {
|
||||
log.debug("handleTakeOfferRequest called " + step++);
|
||||
state = State.HandleTakeOfferRequest;
|
||||
HandleTakeOfferRequest.run(this::onResultHandleTakeOfferRequest, this::onHandleTakeOfferRequestFault, peer, tradeMessageService, trade.getState(),
|
||||
tradeId);
|
||||
// 4. RespondToTakeOfferRequest
|
||||
private void respondToTakeOfferRequest() {
|
||||
log.debug("respondToTakeOfferRequest called: state = " + state);
|
||||
state = State.RespondToTakeOfferRequest;
|
||||
RespondToTakeOfferRequest.run(this::handleRespondToTakeOfferRequestResult, this::handleErrorMessage, tradeMessageService, peer,
|
||||
trade.getState(), tradeId);
|
||||
}
|
||||
|
||||
private void onHandleTakeOfferRequestFault(Throwable throwable) {
|
||||
HandleTakeOfferRequest.run(this::onResultHandleTakeOfferRequest, this::onFault, peer, tradeMessageService, trade.getState(), tradeId);
|
||||
}
|
||||
private void handleRespondToTakeOfferRequestResult() {
|
||||
log.debug("handleRespondToTakeOfferRequestResult called: state = " + state);
|
||||
|
||||
public void onResultHandleTakeOfferRequest(boolean takeOfferRequestAccepted) {
|
||||
log.debug("onResultHandleTakeOfferRequest called " + step++);
|
||||
if (takeOfferRequestAccepted) {
|
||||
// Here we are not setting a state as that is not relevant for the trade process.
|
||||
// In accept case we remove the offer from the offerbook, but that happens outside of the flow of the trade process
|
||||
if (trade.getState() == Trade.State.OPEN) {
|
||||
trade.setState(Trade.State.OFFERER_ACCEPTED);
|
||||
listener.onOfferAccepted(offer);
|
||||
listener.onWaitingForPeerResponse(state);
|
||||
}
|
||||
else {
|
||||
// Don't use OFFERER_REJECTED as that trade might has been accepted to another taker.
|
||||
log.info("Finish here as we have already the offer accepted.");
|
||||
log.info("Ignore that request as we have already the offer accepted.");
|
||||
}
|
||||
}
|
||||
|
||||
@ -208,48 +202,48 @@ public class BuyerAcceptsOfferProtocol {
|
||||
// Incoming message from peer
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void onTakeOfferFeePayedMessage(@NotNull TakeOfferFeePayedMessage message) {
|
||||
log.debug("onTakeOfferFeePayedMessage called " + step++);
|
||||
log.debug("state " + state);
|
||||
// 8. handleTakeOfferFeePayedMessage
|
||||
public void handleTakeOfferFeePayedMessage(@NotNull TakeOfferFeePayedMessage message) {
|
||||
log.debug("handleTakeOfferFeePayedMessage called: state = " + state);
|
||||
|
||||
// validation
|
||||
checkState(state == State.HandleTakeOfferRequest);
|
||||
checkArgument(tradeId.equals(message.getTradeId()));
|
||||
checkState(state == State.RespondToTakeOfferRequest);
|
||||
checkTradeId(tradeId, message);
|
||||
String takeOfferFeeTxId = nonEmptyStringOf(message.getTakeOfferFeeTxId());
|
||||
Coin tradeAmount = positiveCoinOf(nonZeroCoinOf(message.getTradeAmount()));
|
||||
String takerPubKey = nonEmptyStringOf(message.getTakerPubKey());
|
||||
String tradePubKeyAsHex = nonEmptyStringOf(message.getTakerPubKeyAsHex());
|
||||
|
||||
// apply new state
|
||||
state = State.onTakeOfferFeePayedMessage;
|
||||
state = State.handleTakeOfferFeePayedMessage;
|
||||
this.takeOfferFeeTxId = takeOfferFeeTxId;
|
||||
this.takerPubKey = takerPubKey;
|
||||
this.tradePubKeyAsHex = tradePubKeyAsHex;
|
||||
trade.setTakeOfferFeeTxID(takeOfferFeeTxId);
|
||||
trade.setTradeAmount(tradeAmount);
|
||||
|
||||
// next task
|
||||
state = State.VerifyTakeOfferFeePayment;
|
||||
VerifyTakeOfferFeePayment.run(this::onResultVerifyTakeOfferFeePayment, this::onFault, walletService,
|
||||
this.takeOfferFeeTxId);
|
||||
createDepositTx();
|
||||
}
|
||||
|
||||
public void onResultVerifyTakeOfferFeePayment() {
|
||||
log.debug("onResultVerifyTakeOfferFeePayment called " + step++);
|
||||
|
||||
// 9. CreateDepositTx
|
||||
private void createDepositTx() {
|
||||
log.debug("handleVerifyTakeOfferFeePaymentResult called: state = " + state);
|
||||
checkState(state == State.handleTakeOfferFeePayedMessage);
|
||||
Coin offererInputAmount = trade.getSecurityDeposit().add(FeePolicy.TX_FEE);
|
||||
state = State.CreateDepositTx;
|
||||
CreateDepositTx.run(this::onResultCreateDepositTx, this::onFault, walletService, tradeId, offererInputAmount,
|
||||
takerPubKey, arbitratorPubKey);
|
||||
CreateDepositTx.run(this::handleCreateDepositTxResult, this::handleFault, walletService, tradeId, offererInputAmount,
|
||||
tradePubKeyAsHex, arbitratorPubKey);
|
||||
}
|
||||
|
||||
public void onResultCreateDepositTx(String offererPubKey, String preparedOffererDepositTxAsHex,
|
||||
long offererTxOutIndex) {
|
||||
log.debug("onResultCreateDepositTx called " + step++);
|
||||
// 4. RequestTakerDepositPayment
|
||||
private void handleCreateDepositTxResult(String offererPubKey, String preparedOffererDepositTxAsHex, long offererTxOutIndex) {
|
||||
log.debug("handleCreateDepositTxResult called: state = " + state);
|
||||
checkState(state == State.CreateDepositTx);
|
||||
|
||||
this.preparedOffererDepositTxAsHex = preparedOffererDepositTxAsHex;
|
||||
this.offererTxOutIndex = offererTxOutIndex;
|
||||
|
||||
state = State.RequestTakerDepositPayment;
|
||||
RequestTakerDepositPayment.run(this::onResultRequestTakerDepositPayment,
|
||||
this::onFault,
|
||||
SendTakerDepositPaymentRequest.run(this::handleErrorMessage,
|
||||
peer,
|
||||
tradeMessageService,
|
||||
tradeId,
|
||||
@ -260,23 +254,19 @@ public class BuyerAcceptsOfferProtocol {
|
||||
offererTxOutIndex);
|
||||
}
|
||||
|
||||
public void onResultRequestTakerDepositPayment() {
|
||||
log.debug("onResultRequestTakerDepositPayment called " + step++);
|
||||
listener.onWaitingForPeerResponse(state);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Incoming message from peer
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void onRequestOffererPublishDepositTxMessage(RequestOffererPublishDepositTxMessage message) {
|
||||
log.debug("onRequestOffererPublishDepositTxMessage called " + step++);
|
||||
// 5. VerifyTakerAccount
|
||||
public void handleRequestOffererPublishDepositTxMessage(RequestOffererPublishDepositTxMessage message) {
|
||||
log.debug("handleRequestOffererPublishDepositTxMessage called: state = " + state);
|
||||
log.debug("state " + state);
|
||||
|
||||
// validation
|
||||
checkState(state == State.RequestTakerDepositPayment);
|
||||
checkArgument(tradeId.equals(message.getTradeId()));
|
||||
checkTradeId(tradeId, message);
|
||||
String peersPayoutAddress = nonEmptyStringOf(message.getTakerPayoutAddress());
|
||||
String peersAccountId = nonEmptyStringOf(message.getTakerAccountId());
|
||||
BankAccount peersBankAccount = checkNotNull(message.getTakerBankAccount());
|
||||
@ -288,7 +278,7 @@ public class BuyerAcceptsOfferProtocol {
|
||||
long takerTxOutIndex = nonNegativeLongOf(message.getTakerTxOutIndex());
|
||||
|
||||
// apply new state
|
||||
state = State.onRequestOffererPublishDepositTxMessage;
|
||||
state = State.handleRequestOffererPublishDepositTxMessage;
|
||||
this.peersPayoutAddress = peersPayoutAddress;
|
||||
this.peersAccountId = peersAccountId;
|
||||
this.peersBankAccount = peersBankAccount;
|
||||
@ -301,17 +291,18 @@ public class BuyerAcceptsOfferProtocol {
|
||||
|
||||
// next task
|
||||
state = State.VerifyTakerAccount;
|
||||
VerifyTakerAccount.run(this::onResultVerifyTakerAccount, this::onFault, blockChainService,
|
||||
VerifyTakerAccount.run(this::handleVerifyTakerAccountResult, this::handleFault, blockChainService,
|
||||
this.peersAccountId, this.peersBankAccount);
|
||||
}
|
||||
|
||||
public void onResultVerifyTakerAccount() {
|
||||
log.debug("onResultVerifyTakerAccount called " + step++);
|
||||
// 6. VerifyAndSignContract
|
||||
private void handleVerifyTakerAccountResult() {
|
||||
log.debug("handleVerifyTakerAccountResult called: state = " + state);
|
||||
|
||||
Coin tradeAmount = trade.getTradeAmount();
|
||||
state = State.VerifyAndSignContract;
|
||||
VerifyAndSignContract.run(this::onResultVerifyAndSignContract,
|
||||
this::onFault,
|
||||
VerifyAndSignContract.run(this::handleVerifyAndSignContractResult,
|
||||
this::handleFault,
|
||||
signatureService,
|
||||
accountId,
|
||||
tradeAmount,
|
||||
@ -326,15 +317,16 @@ public class BuyerAcceptsOfferProtocol {
|
||||
accountKey);
|
||||
}
|
||||
|
||||
public void onResultVerifyAndSignContract(Contract contract, String contractAsJson, String signature) {
|
||||
log.debug("onResultVerifyAndSignContract called " + step++);
|
||||
// 7. SignAndPublishDepositTx
|
||||
private void handleVerifyAndSignContractResult(Contract contract, String contractAsJson, String signature) {
|
||||
log.debug("handleVerifyAndSignContractResult called: state = " + state);
|
||||
|
||||
trade.setContract(contract);
|
||||
trade.setContractAsJson(contractAsJson);
|
||||
trade.setContractTakerSignature(signature);
|
||||
trade.setTakerContractSignature(signature);
|
||||
state = State.SignAndPublishDepositTx;
|
||||
SignAndPublishDepositTx.run(this::onResultSignAndPublishDepositTx,
|
||||
this::onFault,
|
||||
SignAndPublishDepositTx.run(this::handleSignAndPublishDepositTxResult,
|
||||
this::handleFault,
|
||||
walletService,
|
||||
preparedOffererDepositTxAsHex,
|
||||
signedTakerDepositTxAsHex,
|
||||
@ -344,54 +336,64 @@ public class BuyerAcceptsOfferProtocol {
|
||||
takerTxOutIndex);
|
||||
}
|
||||
|
||||
public void onResultSignAndPublishDepositTx(Transaction depositTransaction) {
|
||||
log.debug("onResultSignAndPublishDepositTx called " + step++);
|
||||
// 8. SendDepositTxIdToTaker
|
||||
private void handleSignAndPublishDepositTxResult(Transaction depositTransaction) {
|
||||
log.debug("handleSignAndPublishDepositTxResult called: state = " + state);
|
||||
|
||||
listener.onDepositTxPublished(depositTransaction);
|
||||
|
||||
state = State.SendDepositTxIdToTaker;
|
||||
SendDepositTxIdToTaker.run(this::onResultSendDepositTxIdToTaker, this::onFault, peer, tradeMessageService,
|
||||
SendDepositTxIdToTaker.run(this::handleSendDepositTxIdToTakerResult, this::handleErrorMessage, peer, tradeMessageService,
|
||||
tradeId, depositTransaction);
|
||||
}
|
||||
|
||||
public void onResultSendDepositTxIdToTaker() {
|
||||
log.debug("onResultSendDepositTxIdToTaker called " + step++);
|
||||
private void handleSendDepositTxIdToTakerResult() {
|
||||
log.debug("handleSendDepositTxIdToTakerResult called: state = " + state);
|
||||
|
||||
state = State.SetupListenerForBlockChainConfirmation;
|
||||
SetupListenerForBlockChainConfirmation.run(this::onResultSetupListenerForBlockChainConfirmation,
|
||||
trade.getDepositTx(), listener);
|
||||
SetupListenerForBlockChainConfirmation.run(trade.getDepositTx(), listener);
|
||||
}
|
||||
|
||||
public void onResultSetupListenerForBlockChainConfirmation() {
|
||||
log.debug("onResultSetupListenerForBlockChainConfirmation called " + step++);
|
||||
|
||||
state = State.onResultSetupListenerForBlockChainConfirmation;
|
||||
listener.onWaitingForUserInteraction(state);
|
||||
/*
|
||||
// 9. VerifyTakeOfferFeePayment
|
||||
private void verifyTakeOfferFeePayment() {
|
||||
state = State.VerifyTakeOfferFeePayment;
|
||||
VerifyTakeOfferFeePayment.run(this::handleVerifyTakeOfferFeePaymentResult, this::handleFault, walletService, this.takeOfferFeeTxId);
|
||||
}
|
||||
|
||||
// 10. CreateDepositTx
|
||||
private void handleVerifyTakeOfferFeePaymentResult() {
|
||||
log.debug("handleVerifyTakeOfferFeePaymentResult called: state = " + state);
|
||||
checkState(state == State.VerifyTakeOfferFeePayment);
|
||||
Coin offererInputAmount = trade.getSecurityDeposit().add(FeePolicy.TX_FEE);
|
||||
state = State.CreateDepositTx;
|
||||
CreateDepositTx.run(this::handleCreateDepositTxResult, this::handleFault, walletService, tradeId, offererInputAmount,
|
||||
tradePubKeyAsHex, arbitratorPubKey);
|
||||
}
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Triggered UI event
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Triggered from UI event: Button click "Bank transfer inited"
|
||||
public void onUIEventBankTransferInited() {
|
||||
log.debug("onUIEventBankTransferInited called " + step++);
|
||||
// 9. SendSignedPayoutTx
|
||||
public void handleUIEventBankTransferInited() {
|
||||
log.debug("onUIEventBankTransferInited called: state = " + state);
|
||||
log.debug("state " + state);
|
||||
|
||||
// validation
|
||||
checkState(state.ordinal() >= State.SignAndPublishDepositTx.ordinal() &&
|
||||
state.ordinal() <= State.onResultSetupListenerForBlockChainConfirmation.ordinal());
|
||||
state.ordinal() <= State.SetupListenerForBlockChainConfirmation.ordinal());
|
||||
|
||||
state = State.onUIEventBankTransferInited;
|
||||
state = State.handleUIEventBankTransferInited;
|
||||
|
||||
// next task
|
||||
String depositTransactionId = trade.getDepositTx().getHashAsString();
|
||||
Coin tradeAmount = trade.getTradeAmount();
|
||||
Coin securityDeposit = trade.getSecurityDeposit();
|
||||
state = State.SendSignedPayoutTx;
|
||||
SendSignedPayoutTx.run(this::onResultSendSignedPayoutTx,
|
||||
this::onFault,
|
||||
SendSignedPayoutTx.run(this::handleFault,
|
||||
peer,
|
||||
tradeMessageService,
|
||||
walletService,
|
||||
@ -403,50 +405,40 @@ public class BuyerAcceptsOfferProtocol {
|
||||
tradeAmount);
|
||||
}
|
||||
|
||||
public void onResultSendSignedPayoutTx() {
|
||||
log.debug("onResultSendSignedPayoutTx called " + step++);
|
||||
|
||||
listener.onWaitingForPeerResponse(state);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Incoming message from peer
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void onPayoutTxPublishedMessage(PayoutTxPublishedMessage message) {
|
||||
log.debug("onPayoutTxPublishedMessage called " + step++);
|
||||
log.debug("state " + state);
|
||||
// 10. handlePayoutTxPublishedMessage
|
||||
public void handlePayoutTxPublishedMessage(PayoutTxPublishedMessage message) {
|
||||
log.debug("onPayoutTxPublishedMessage called: state = " + state);
|
||||
|
||||
// validation
|
||||
checkState(state == State.SendSignedPayoutTx);
|
||||
checkArgument(tradeId.equals(message.getTradeId()));
|
||||
checkTradeId(tradeId, message);
|
||||
String payoutTxAsHex = nonEmptyStringOf(message.getPayoutTxAsHex());
|
||||
|
||||
state = State.onPayoutTxPublishedMessage;
|
||||
|
||||
Transaction payoutTx = new Transaction(walletService.getWallet().getParams(),
|
||||
Utils.parseAsHexOrBase58(payoutTxAsHex));
|
||||
// apply new state
|
||||
state = State.handlePayoutTxPublishedMessage;
|
||||
Transaction payoutTx = new Transaction(walletService.getWallet().getParams(), Utils.parseAsHexOrBase58(payoutTxAsHex));
|
||||
listener.onPayoutTxPublished(payoutTx);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Getters, Setters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public String getId() {
|
||||
return tradeId;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Private
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// generic fault handler
|
||||
private void onFault(Throwable throwable) {
|
||||
private void handleFault(Throwable throwable) {
|
||||
trade.setFault(throwable);
|
||||
trade.setState(Trade.State.FAILED);
|
||||
listener.onFault(throwable, state);
|
||||
}
|
||||
|
||||
private void handleErrorMessage(String errorMessage) {
|
||||
handleFault(new Exception(errorMessage));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -21,12 +21,14 @@ import io.bitsquare.trade.protocol.trade.TradeMessage;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class RespondToTakeOfferRequestMessage implements Serializable, TradeMessage {
|
||||
private static final long serialVersionUID = 6177387534087739018L;
|
||||
private final String tradeId;
|
||||
private final boolean takeOfferRequestAccepted;
|
||||
|
||||
public RespondToTakeOfferRequestMessage(String tradeId, boolean takeOfferRequestAccepted) {
|
||||
public RespondToTakeOfferRequestMessage(@NotNull String tradeId, boolean takeOfferRequestAccepted) {
|
||||
this.tradeId = tradeId;
|
||||
this.takeOfferRequestAccepted = takeOfferRequestAccepted;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ import io.bitsquare.trade.protocol.trade.TradeMessage;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class RequestTakerDepositPaymentMessage implements Serializable, TradeMessage {
|
||||
public class TakerDepositPaymentRequestMessage implements Serializable, TradeMessage {
|
||||
private static final long serialVersionUID = -3988720410493712913L;
|
||||
|
||||
private final String tradeId;
|
||||
@ -32,7 +32,7 @@ public class RequestTakerDepositPaymentMessage implements Serializable, TradeMes
|
||||
private final String preparedOffererDepositTxAsHex;
|
||||
private final long offererTxOutIndex;
|
||||
|
||||
public RequestTakerDepositPaymentMessage(String tradeId, BankAccount bankAccount, String accountID,
|
||||
public TakerDepositPaymentRequestMessage(String tradeId, BankAccount bankAccount, String accountID,
|
||||
String offererPubKey, String preparedOffererDepositTxAsHex,
|
||||
long offererTxOutIndex) {
|
||||
this.tradeId = tradeId;
|
@ -38,20 +38,19 @@ public class CreateDepositTx {
|
||||
Coin offererInputAmount,
|
||||
String takerMultiSigPubKey,
|
||||
String arbitratorPubKeyAsHex) {
|
||||
log.trace("Run task");
|
||||
log.trace("Run CreateDepositTx task");
|
||||
try {
|
||||
String offererPubKey = walletService.getAddressInfoByTradeID(tradeId).getPubKeyAsHexString();
|
||||
Transaction transaction = walletService.offererCreatesMSTxAndAddPayment(
|
||||
offererInputAmount, offererPubKey, takerMultiSigPubKey, arbitratorPubKeyAsHex, tradeId);
|
||||
Transaction transaction = walletService.offererCreatesMSTxAndAddPayment(offererInputAmount, offererPubKey, takerMultiSigPubKey,
|
||||
arbitratorPubKeyAsHex, tradeId);
|
||||
|
||||
String preparedOffererDepositTxAsHex = Utils.HEX.encode(transaction.bitcoinSerialize());
|
||||
long offererTxOutIndex = transaction.getInput(0).getOutpoint().getIndex();
|
||||
|
||||
resultHandler.onResult(offererPubKey, preparedOffererDepositTxAsHex, offererTxOutIndex);
|
||||
} catch (InsufficientMoneyException e) {
|
||||
log.error("Create deposit tx faultHandler.onFault due InsufficientMoneyException " + e);
|
||||
exceptionHandler.handleException(
|
||||
new Exception("Create deposit tx faultHandler.onFault due InsufficientMoneyException " + e));
|
||||
log.error("Create deposit tx failed due InsufficientMoneyException " + e);
|
||||
exceptionHandler.handleException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,38 +22,38 @@ import io.bitsquare.trade.Trade;
|
||||
import io.bitsquare.trade.TradeMessageService;
|
||||
import io.bitsquare.trade.listeners.SendMessageListener;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.messages.RespondToTakeOfferRequestMessage;
|
||||
import io.bitsquare.util.handlers.ExceptionHandler;
|
||||
import io.bitsquare.util.handlers.ErrorMessageHandler;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class HandleTakeOfferRequest {
|
||||
private static final Logger log = LoggerFactory.getLogger(HandleTakeOfferRequest.class);
|
||||
public class RespondToTakeOfferRequest {
|
||||
private static final Logger log = LoggerFactory.getLogger(RespondToTakeOfferRequest.class);
|
||||
|
||||
public static void run(ResultHandler resultHandler, ExceptionHandler exceptionHandler, Peer peer,
|
||||
TradeMessageService tradeMessageService, Trade.State tradeState, String tradeId) {
|
||||
public static void run(ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler,
|
||||
TradeMessageService tradeMessageService, Peer peer, Trade.State tradeState, String tradeId) {
|
||||
log.trace("Run HandleTakeOfferRequest task");
|
||||
boolean isTradeIsOpen = tradeState == Trade.State.OPEN;
|
||||
if (!isTradeIsOpen) {
|
||||
boolean takeOfferRequestAccepted = tradeState == Trade.State.OPEN;
|
||||
if (!takeOfferRequestAccepted) {
|
||||
log.warn("Received take offer request but the offer not marked as open anymore.");
|
||||
}
|
||||
RespondToTakeOfferRequestMessage tradeMessage = new RespondToTakeOfferRequestMessage(tradeId, isTradeIsOpen);
|
||||
RespondToTakeOfferRequestMessage tradeMessage = new RespondToTakeOfferRequestMessage(tradeId, takeOfferRequestAccepted);
|
||||
tradeMessageService.sendMessage(peer, tradeMessage, new SendMessageListener() {
|
||||
@Override
|
||||
public void handleResult() {
|
||||
log.trace("RespondToTakeOfferRequestMessage successfully arrived at peer");
|
||||
resultHandler.handleResult(isTradeIsOpen);
|
||||
resultHandler.handleResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleFault() {
|
||||
log.error("AcceptTakeOfferRequestMessage did not arrive at peer");
|
||||
exceptionHandler.handleException(new Exception("AcceptTakeOfferRequestMessage did not arrive at peer"));
|
||||
errorMessageHandler.handleErrorMessage("AcceptTakeOfferRequestMessage did not arrive at peer");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public interface ResultHandler {
|
||||
void handleResult(boolean takeOfferRequestAccepted);
|
||||
void handleResult();
|
||||
}
|
||||
}
|
@ -17,11 +17,11 @@
|
||||
|
||||
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.network.Peer;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.messages.DepositTxPublishedMessage;
|
||||
import io.bitsquare.util.handlers.ExceptionHandler;
|
||||
import io.bitsquare.util.handlers.ErrorMessageHandler;
|
||||
import io.bitsquare.util.handlers.ResultHandler;
|
||||
|
||||
import org.bitcoinj.core.Transaction;
|
||||
@ -33,7 +33,7 @@ import org.slf4j.LoggerFactory;
|
||||
public class SendDepositTxIdToTaker {
|
||||
private static final Logger log = LoggerFactory.getLogger(SendDepositTxIdToTaker.class);
|
||||
|
||||
public static void run(ResultHandler resultHandler, ExceptionHandler exceptionHandler, Peer peer,
|
||||
public static void run(ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler, Peer peer,
|
||||
TradeMessageService tradeMessageService, String tradeId, Transaction depositTransaction) {
|
||||
log.trace("Run task");
|
||||
DepositTxPublishedMessage tradeMessage =
|
||||
@ -49,7 +49,7 @@ public class SendDepositTxIdToTaker {
|
||||
@Override
|
||||
public void handleFault() {
|
||||
log.error("DepositTxPublishedMessage did not arrive at peer");
|
||||
exceptionHandler.handleException(new Exception("DepositTxPublishedMessage did not arrive at peer"));
|
||||
errorMessageHandler.handleErrorMessage("DepositTxPublishedMessage did not arrive at peer");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -18,12 +18,11 @@
|
||||
package io.bitsquare.trade.protocol.trade.offerer.tasks;
|
||||
|
||||
import io.bitsquare.btc.WalletService;
|
||||
import io.bitsquare.network.Peer;
|
||||
import io.bitsquare.trade.TradeMessageService;
|
||||
import io.bitsquare.trade.listeners.SendMessageListener;
|
||||
import io.bitsquare.network.Peer;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.messages.BankTransferInitedMessage;
|
||||
import io.bitsquare.util.handlers.ExceptionHandler;
|
||||
import io.bitsquare.util.handlers.ResultHandler;
|
||||
|
||||
import org.bitcoinj.core.Coin;
|
||||
import org.bitcoinj.core.ECKey;
|
||||
@ -36,8 +35,7 @@ import org.slf4j.LoggerFactory;
|
||||
public class SendSignedPayoutTx {
|
||||
private static final Logger log = LoggerFactory.getLogger(SendSignedPayoutTx.class);
|
||||
|
||||
public static void run(ResultHandler resultHandler,
|
||||
ExceptionHandler exceptionHandler,
|
||||
public static void run(ExceptionHandler exceptionHandler,
|
||||
Peer peer,
|
||||
TradeMessageService tradeMessageService,
|
||||
WalletService walletService,
|
||||
@ -72,7 +70,6 @@ public class SendSignedPayoutTx {
|
||||
@Override
|
||||
public void handleResult() {
|
||||
log.trace("BankTransferInitedMessage successfully arrived at peer");
|
||||
resultHandler.handleResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -18,21 +18,19 @@
|
||||
package io.bitsquare.trade.protocol.trade.offerer.tasks;
|
||||
|
||||
import io.bitsquare.bank.BankAccount;
|
||||
import io.bitsquare.network.Peer;
|
||||
import io.bitsquare.trade.TradeMessageService;
|
||||
import io.bitsquare.trade.listeners.SendMessageListener;
|
||||
import io.bitsquare.network.Peer;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.messages.RequestTakerDepositPaymentMessage;
|
||||
import io.bitsquare.util.handlers.ExceptionHandler;
|
||||
import io.bitsquare.util.handlers.ResultHandler;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.messages.TakerDepositPaymentRequestMessage;
|
||||
import io.bitsquare.util.handlers.ErrorMessageHandler;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class RequestTakerDepositPayment {
|
||||
private static final Logger log = LoggerFactory.getLogger(RequestTakerDepositPayment.class);
|
||||
public class SendTakerDepositPaymentRequest {
|
||||
private static final Logger log = LoggerFactory.getLogger(SendTakerDepositPaymentRequest.class);
|
||||
|
||||
public static void run(ResultHandler resultHandler,
|
||||
ExceptionHandler exceptionHandler,
|
||||
public static void run(ErrorMessageHandler errorMessageHandler,
|
||||
Peer peer,
|
||||
TradeMessageService tradeMessageService,
|
||||
String tradeId,
|
||||
@ -41,21 +39,19 @@ public class RequestTakerDepositPayment {
|
||||
String offererPubKey,
|
||||
String preparedOffererDepositTxAsHex,
|
||||
long offererTxOutIndex) {
|
||||
log.trace("Run task");
|
||||
RequestTakerDepositPaymentMessage tradeMessage = new RequestTakerDepositPaymentMessage(
|
||||
log.trace("Run SendTakerDepositPaymentRequest task");
|
||||
TakerDepositPaymentRequestMessage tradeMessage = new TakerDepositPaymentRequestMessage(
|
||||
tradeId, bankAccount, accountId, offererPubKey, preparedOffererDepositTxAsHex, offererTxOutIndex);
|
||||
tradeMessageService.sendMessage(peer, tradeMessage, new SendMessageListener() {
|
||||
@Override
|
||||
public void handleResult() {
|
||||
log.trace("RequestTakerDepositPaymentMessage successfully arrived at peer");
|
||||
resultHandler.handleResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleFault() {
|
||||
log.error("RequestTakerDepositPaymentMessage did not arrive at peer");
|
||||
exceptionHandler.handleException(new Exception("RequestTakerDepositPaymentMessage did not arrive at " +
|
||||
"peer"));
|
||||
errorMessageHandler.handleErrorMessage("RequestTakerDepositPaymentMessage did not arrive at peer");
|
||||
}
|
||||
});
|
||||
}
|
@ -17,8 +17,7 @@
|
||||
|
||||
package io.bitsquare.trade.protocol.trade.offerer.tasks;
|
||||
|
||||
import io.bitsquare.trade.protocol.trade.offerer.BuyerAcceptsOfferProtocolListener;
|
||||
import io.bitsquare.util.handlers.ResultHandler;
|
||||
import io.bitsquare.trade.listeners.BuyerAcceptsOfferProtocolListener;
|
||||
|
||||
import org.bitcoinj.core.Transaction;
|
||||
import org.bitcoinj.core.TransactionConfidence;
|
||||
@ -29,9 +28,8 @@ import org.slf4j.LoggerFactory;
|
||||
public class SetupListenerForBlockChainConfirmation {
|
||||
private static final Logger log = LoggerFactory.getLogger(SetupListenerForBlockChainConfirmation.class);
|
||||
|
||||
public static void run(ResultHandler resultHandler,
|
||||
Transaction depositTransaction, BuyerAcceptsOfferProtocolListener listener) {
|
||||
log.trace("Run task");
|
||||
public static void run(Transaction depositTransaction, BuyerAcceptsOfferProtocolListener listener) {
|
||||
log.trace("Run SetupListenerForBlockChainConfirmation task");
|
||||
//TODO
|
||||
// sharedModel.offererPaymentProtocolListener.onDepositTxConfirmedInBlockchain();
|
||||
|
||||
@ -44,7 +42,6 @@ public class SetupListenerForBlockChainConfirmation {
|
||||
listener.onDepositTxConfirmedInBlockchain();
|
||||
depositTransaction.getConfidence().removeEventListener(this);
|
||||
log.trace("Tx is in blockchain");
|
||||
resultHandler.handleResult();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -29,7 +29,7 @@ public class VerifyTakeOfferFeePayment {
|
||||
|
||||
public static void run(ResultHandler resultHandler, ExceptionHandler exceptionHandler, WalletService walletService,
|
||||
String takeOfferFeeTxId) {
|
||||
log.trace("Run task");
|
||||
log.trace("Run VerifyTakeOfferFeePayment task");
|
||||
//TODO mocked yet, need a confidence listeners
|
||||
int numOfPeersSeenTx = walletService.getNumOfPeersSeenTx(takeOfferFeeTxId);
|
||||
if (numOfPeersSeenTx > 2) {
|
||||
|
@ -26,10 +26,11 @@ import io.bitsquare.offer.Offer;
|
||||
import io.bitsquare.trade.Contract;
|
||||
import io.bitsquare.trade.Trade;
|
||||
import io.bitsquare.trade.TradeMessageService;
|
||||
import io.bitsquare.trade.listeners.SellerTakesOfferProtocolListener;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.messages.BankTransferInitedMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.messages.DepositTxPublishedMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.messages.RequestTakerDepositPaymentMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.messages.RespondToTakeOfferRequestMessage;
|
||||
import io.bitsquare.trade.protocol.trade.offerer.messages.TakerDepositPaymentRequestMessage;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.CreateAndSignContract;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.GetPeerAddress;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.PayDeposit;
|
||||
@ -37,8 +38,9 @@ import io.bitsquare.trade.protocol.trade.taker.tasks.PayTakeOfferFee;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.RequestTakeOffer;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.SendPayoutTxToOfferer;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.SendSignedTakerDepositTxAsHex;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.SendTakeOfferFeePayedTxId;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.SendTakeOfferFeePayedMessage;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.SignAndPublishPayoutTx;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.TakerCommitDepositTx;
|
||||
import io.bitsquare.trade.protocol.trade.taker.tasks.VerifyOffererAccount;
|
||||
import io.bitsquare.user.User;
|
||||
|
||||
@ -54,6 +56,7 @@ import org.slf4j.LoggerFactory;
|
||||
import static com.google.common.base.Preconditions.*;
|
||||
import static io.bitsquare.util.Validator.*;
|
||||
|
||||
|
||||
/**
|
||||
* Responsible for the correct execution of the sequence of tasks, message passing to the peer and message processing
|
||||
* from the peer.
|
||||
@ -69,16 +72,20 @@ public class SellerTakesOfferProtocol {
|
||||
Init,
|
||||
GetPeerAddress,
|
||||
RequestTakeOffer,
|
||||
|
||||
handleRespondToTakeOfferRequestMessage,
|
||||
PayTakeOfferFee,
|
||||
SendTakeOfferFeePayedMessage,
|
||||
|
||||
onRequestTakerDepositPaymentMessage,
|
||||
|
||||
SendTakeOfferFeePayedTxId,
|
||||
handleTakerDepositPaymentRequestMessage,
|
||||
VerifyOffererAccount,
|
||||
CreateAndSignContract,
|
||||
PayDeposit,
|
||||
SendSignedTakerDepositTxAsHex,
|
||||
onBankTransferInitedMessage,
|
||||
|
||||
handleDepositTxPublishedMessage,
|
||||
TakerCommitDepositTx,
|
||||
handleBankTransferInitedMessage,
|
||||
SignAndPublishPayoutTx,
|
||||
SendPayoutTxToOfferer
|
||||
}
|
||||
@ -98,7 +105,7 @@ public class SellerTakesOfferProtocol {
|
||||
private final String accountId;
|
||||
private final PublicKey messagePublicKey;
|
||||
private final Coin tradeAmount;
|
||||
private final String pubKeyForThatTrade;
|
||||
private final String tradePubKeyAsHex;
|
||||
private final ECKey accountKey;
|
||||
private final PublicKey offererMessagePublicKey;
|
||||
private final Coin securityDeposit;
|
||||
@ -120,12 +127,9 @@ public class SellerTakesOfferProtocol {
|
||||
private Coin offererPaybackAmount;
|
||||
private Coin takerPaybackAmount;
|
||||
private String offererPayoutAddress;
|
||||
private int repeatCounter = 0;
|
||||
|
||||
|
||||
// state
|
||||
private State state;
|
||||
private int step = 0;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -159,7 +163,7 @@ public class SellerTakesOfferProtocol {
|
||||
accountId = user.getAccountId();
|
||||
messagePublicKey = user.getMessagePublicKey();
|
||||
|
||||
pubKeyForThatTrade = walletService.getAddressInfoByTradeID(tradeId).getPubKeyAsHexString();
|
||||
tradePubKeyAsHex = walletService.getAddressInfoByTradeID(tradeId).getPubKeyAsHexString();
|
||||
accountKey = walletService.getRegistrationAddressEntry().getKey();
|
||||
|
||||
state = State.Init;
|
||||
@ -170,38 +174,18 @@ public class SellerTakesOfferProtocol {
|
||||
}
|
||||
|
||||
// 1. GetPeerAddress
|
||||
// Async
|
||||
// In case of an error: Repeat once, then give up. No rollback activity needed
|
||||
private void getPeerAddress() {
|
||||
log.debug("getPeerAddress called " + step++);
|
||||
log.debug("getPeerAddress called: state = " + state);
|
||||
state = State.GetPeerAddress;
|
||||
GetPeerAddress.run(this::onResultGetPeerAddress, this::onGetPeerAddressFault, tradeMessageService, offererMessagePublicKey);
|
||||
}
|
||||
|
||||
private void onGetPeerAddressFault(String errorMessage) {
|
||||
log.debug("Run getPeerAddress again after onGetPeerAddressFault" + step);
|
||||
GetPeerAddress.run(this::onResultGetPeerAddress, this::onErrorMessage, tradeMessageService, offererMessagePublicKey);
|
||||
GetPeerAddress.run(this::handleGetPeerAddressResult, this::handleErrorMessage, tradeMessageService, offererMessagePublicKey);
|
||||
}
|
||||
|
||||
// 2. RequestTakeOffer
|
||||
// Async
|
||||
// In case of an error: Repeat once, then give up. No rollback activity needed
|
||||
public void onResultGetPeerAddress(Peer peer) {
|
||||
log.debug("onResultGetPeerAddress called " + step++);
|
||||
private void handleGetPeerAddressResult(Peer peer) {
|
||||
log.debug("handleGetPeerAddressResult called: state = " + state);
|
||||
this.peer = peer;
|
||||
|
||||
state = State.RequestTakeOffer;
|
||||
RequestTakeOffer.run(this::onResultRequestTakeOffer, this::onRequestTakeOfferFault, peer, tradeMessageService, tradeId);
|
||||
}
|
||||
|
||||
private void onRequestTakeOfferFault(Throwable throwable) {
|
||||
log.debug("Run getPeerAddress again after onGetPeerAddressFault" + step);
|
||||
RequestTakeOffer.run(this::onResultRequestTakeOffer, this::onFault, peer, tradeMessageService, tradeId);
|
||||
}
|
||||
|
||||
public void onResultRequestTakeOffer() {
|
||||
log.debug("onResultRequestTakeOffer called " + step++);
|
||||
listener.onWaitingForPeerResponse(state);
|
||||
RequestTakeOffer.run(this::handleErrorMessage, tradeMessageService, peer, tradeId);
|
||||
}
|
||||
|
||||
|
||||
@ -209,52 +193,57 @@ public class SellerTakesOfferProtocol {
|
||||
// Incoming message from peer
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// 3. PayTakeOfferFee
|
||||
// Async
|
||||
// In case of an error: Repeat once, then give up. No rollback activity needed
|
||||
public void onRespondToTakeOfferRequestMessage(RespondToTakeOfferRequestMessage message) {
|
||||
log.debug("onRespondToTakeOfferRequestMessage called " + step++);
|
||||
log.debug("state " + state);
|
||||
checkState(state == State.RequestTakeOffer);
|
||||
checkArgument(tradeId.equals(message.getTradeId()));
|
||||
|
||||
if (message.isTakeOfferRequestAccepted()) {
|
||||
state = State.PayTakeOfferFee;
|
||||
listener.onTakeOfferRequestAccepted(trade);
|
||||
PayTakeOfferFee.run(this::onResultPayTakeOfferFee, this::onFault, walletService, tradeId);
|
||||
}
|
||||
else {
|
||||
listener.onTakeOfferRequestRejected(trade);
|
||||
// exit case
|
||||
}
|
||||
}
|
||||
|
||||
public void onResultPayTakeOfferFee(String takeOfferFeeTxId) {
|
||||
log.debug("onResultPayTakeOfferFee called " + step++);
|
||||
trade.setTakeOfferFeeTxID(takeOfferFeeTxId);
|
||||
|
||||
state = State.SendTakeOfferFeePayedTxId;
|
||||
SendTakeOfferFeePayedTxId.run(this::onResultSendTakeOfferFeePayedTxId, this::onFault, peer,
|
||||
tradeMessageService, tradeId, takeOfferFeeTxId, tradeAmount, pubKeyForThatTrade);
|
||||
}
|
||||
|
||||
public void onResultSendTakeOfferFeePayedTxId() {
|
||||
log.debug("onResultSendTakeOfferFeePayedTxId called " + step++);
|
||||
listener.onWaitingForPeerResponse(state);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Incoming message from peer
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void onRequestTakerDepositPaymentMessage(RequestTakerDepositPaymentMessage message) {
|
||||
log.debug("onRequestTakerDepositPaymentMessage called " + step++);
|
||||
log.debug("state " + state);
|
||||
// 5. handleRespondToTakeOfferRequestMessage
|
||||
public void handleRespondToTakeOfferRequestMessage(RespondToTakeOfferRequestMessage message) {
|
||||
log.debug("handleRespondToTakeOfferRequestMessage called: state = " + state);
|
||||
|
||||
// validation
|
||||
checkState(state == State.SendTakeOfferFeePayedTxId);
|
||||
checkArgument(tradeId.equals(message.getTradeId()));
|
||||
checkState(state == State.RequestTakeOffer);
|
||||
checkTradeId(tradeId, message);
|
||||
|
||||
// apply new state
|
||||
state = State.handleRespondToTakeOfferRequestMessage;
|
||||
if (message.isTakeOfferRequestAccepted()) {
|
||||
trade.setState(Trade.State.OFFERER_ACCEPTED);
|
||||
listener.onTakeOfferRequestAccepted();
|
||||
|
||||
// next task
|
||||
payTakeOfferFee();
|
||||
}
|
||||
else {
|
||||
// exit case
|
||||
trade.setState(Trade.State.OFFERER_REJECTED);
|
||||
listener.onTakeOfferRequestRejected();
|
||||
}
|
||||
}
|
||||
|
||||
// 6. PayTakeOfferFee
|
||||
private void payTakeOfferFee() {
|
||||
state = State.PayTakeOfferFee;
|
||||
PayTakeOfferFee.run(this::handlePayTakeOfferFeeResult, this::handleFault, walletService, tradeId);
|
||||
}
|
||||
|
||||
// 7. SendTakeOfferFeePayedMessage
|
||||
private void handlePayTakeOfferFeeResult(String takeOfferFeeTxId) {
|
||||
log.debug("handlePayTakeOfferFeeResult called: state = " + state);
|
||||
trade.setTakeOfferFeeTxID(takeOfferFeeTxId);
|
||||
state = State.SendTakeOfferFeePayedMessage;
|
||||
SendTakeOfferFeePayedMessage.run(this::handleErrorMessage, peer,
|
||||
tradeMessageService, tradeId, takeOfferFeeTxId, tradeAmount, tradePubKeyAsHex);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Incoming message from peer
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// 5. VerifyOffererAccount
|
||||
public void handleTakerDepositPaymentRequestMessage(TakerDepositPaymentRequestMessage message) {
|
||||
log.debug("handleTakerDepositPaymentRequestMessage called: state = " + state);
|
||||
|
||||
// validation
|
||||
checkState(state == State.SendTakeOfferFeePayedMessage);
|
||||
checkTradeId(tradeId, message);
|
||||
String peersAccountId = nonEmptyStringOf(message.getAccountId());
|
||||
BankAccount peersBankAccount = checkNotNull(message.getBankAccount());
|
||||
String offererPubKey = nonEmptyStringOf(message.getOffererPubKey());
|
||||
@ -262,7 +251,7 @@ public class SellerTakesOfferProtocol {
|
||||
long offererTxOutIndex = nonNegativeLongOf(message.getOffererTxOutIndex());
|
||||
|
||||
// apply new state
|
||||
state = State.onRequestTakerDepositPaymentMessage;
|
||||
state = State.handleTakerDepositPaymentRequestMessage;
|
||||
this.peersAccountId = peersAccountId;
|
||||
this.peersBankAccount = peersBankAccount;
|
||||
this.peersPubKey = offererPubKey;
|
||||
@ -271,16 +260,17 @@ public class SellerTakesOfferProtocol {
|
||||
|
||||
// next task
|
||||
state = State.VerifyOffererAccount;
|
||||
VerifyOffererAccount.run(this::onResultVerifyOffererAccount, this::onFault, blockChainService, peersAccountId,
|
||||
peersBankAccount);
|
||||
VerifyOffererAccount.run(this::handleVerifyOffererAccountResult, this::handleFault, blockChainService, peersAccountId, peersBankAccount);
|
||||
}
|
||||
|
||||
public void onResultVerifyOffererAccount() {
|
||||
log.debug("onResultVerifyOffererAccount called " + step++);
|
||||
// 6. CreateAndSignContract
|
||||
private void handleVerifyOffererAccountResult() {
|
||||
log.debug("handleVerifyOffererAccountResult called: state = " + state);
|
||||
checkState(state == State.VerifyOffererAccount);
|
||||
String takeOfferFeeTxId = trade.getTakeOfferFeeTxId();
|
||||
state = State.CreateAndSignContract;
|
||||
CreateAndSignContract.run(this::onResultCreateAndSignContract,
|
||||
this::onFault,
|
||||
CreateAndSignContract.run(this::handleCreateAndSignContractResult,
|
||||
this::handleFault,
|
||||
signatureService,
|
||||
offer,
|
||||
tradeAmount,
|
||||
@ -294,26 +284,26 @@ public class SellerTakesOfferProtocol {
|
||||
accountKey);
|
||||
}
|
||||
|
||||
public void onResultCreateAndSignContract(Contract contract, String contractAsJson, String signature) {
|
||||
log.debug("onResultCreateAndSignContract called " + step++);
|
||||
|
||||
// 7. PayDeposit
|
||||
private void handleCreateAndSignContractResult(Contract contract, String contractAsJson, String signature) {
|
||||
log.debug("handleCreateAndSignContractResult called: state = " + state);
|
||||
checkState(state == State.CreateAndSignContract);
|
||||
trade.setContract(contract);
|
||||
trade.setContractAsJson(contractAsJson);
|
||||
trade.setContractTakerSignature(signature);
|
||||
|
||||
trade.setTakerContractSignature(signature);
|
||||
state = State.PayDeposit;
|
||||
PayDeposit.run(this::onResultPayDeposit, this::onFault, walletService, securityDeposit, tradeAmount, tradeId,
|
||||
pubKeyForThatTrade, arbitratorPubKey, peersPubKey, preparedPeersDepositTxAsHex);
|
||||
PayDeposit.run(this::handlePayDepositResult, this::handleFault, walletService, securityDeposit, tradeAmount, tradeId,
|
||||
tradePubKeyAsHex, arbitratorPubKey, peersPubKey, preparedPeersDepositTxAsHex);
|
||||
}
|
||||
|
||||
public void onResultPayDeposit(Transaction signedTakerDepositTx) {
|
||||
log.debug("onResultPayDeposit called " + step++);
|
||||
// 8. SendSignedTakerDepositTxAsHex
|
||||
private void handlePayDepositResult(Transaction signedTakerDepositTx) {
|
||||
log.debug("handlePayDepositResult called: state = " + state);
|
||||
checkState(state == State.PayDeposit);
|
||||
String contractAsJson = trade.getContractAsJson();
|
||||
String takerSignature = trade.getTakerSignature();
|
||||
|
||||
String takerContractSignature = trade.getTakerContractSignature();
|
||||
state = State.SendSignedTakerDepositTxAsHex;
|
||||
SendSignedTakerDepositTxAsHex.run(this::onResultSendSignedTakerDepositTxAsHex,
|
||||
this::onFault,
|
||||
SendSignedTakerDepositTxAsHex.run(this::handleErrorMessage,
|
||||
peer,
|
||||
tradeMessageService,
|
||||
walletService,
|
||||
@ -322,30 +312,39 @@ public class SellerTakesOfferProtocol {
|
||||
messagePublicKey,
|
||||
tradeId,
|
||||
contractAsJson,
|
||||
takerSignature,
|
||||
takerContractSignature,
|
||||
signedTakerDepositTx,
|
||||
peersTxOutIndex);
|
||||
}
|
||||
|
||||
public void onResultSendSignedTakerDepositTxAsHex() {
|
||||
log.debug("onResultSendSignedTakerDepositTxAsHex called " + step++);
|
||||
listener.onWaitingForPeerResponse(state);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Incoming message from peer
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// informational, does only trigger UI feedback/update
|
||||
public void onDepositTxPublishedMessage(DepositTxPublishedMessage message) {
|
||||
log.debug("onDepositTxPublishedMessage called " + step++);
|
||||
// 9.a TakerCommitDepositTx
|
||||
public void handleDepositTxPublishedMessage(DepositTxPublishedMessage message) {
|
||||
log.debug("onDepositTxPublishedMessage called: state = " + state);
|
||||
log.debug("state " + state);
|
||||
|
||||
|
||||
// validation
|
||||
checkState(state.ordinal() >= State.SendSignedTakerDepositTxAsHex.ordinal());
|
||||
checkArgument(tradeId.equals(message.getTradeId()));
|
||||
//TODO takerCommitDepositTx should be in task as well
|
||||
Transaction tx = walletService.takerCommitDepositTx(message.getDepositTxAsHex());
|
||||
listener.onDepositTxPublished(tx);
|
||||
checkTradeId(tradeId, message);
|
||||
nonEmptyStringOf(message.getDepositTxAsHex());
|
||||
|
||||
// apply new state
|
||||
state = State.handleDepositTxPublishedMessage;
|
||||
String depositTxAsHex = message.getDepositTxAsHex();
|
||||
|
||||
// next task
|
||||
state = State.TakerCommitDepositTx;
|
||||
TakerCommitDepositTx.run(this::handleTakerCommitDepositTxResult, this::handleFault, walletService, depositTxAsHex);
|
||||
}
|
||||
|
||||
private void handleTakerCommitDepositTxResult(Transaction transaction) {
|
||||
log.debug("handleTakerCommitDepositTxResult called: state = " + state);
|
||||
listener.onDepositTxPublished(transaction);
|
||||
}
|
||||
|
||||
|
||||
@ -353,14 +352,15 @@ public class SellerTakesOfferProtocol {
|
||||
// Incoming message from peer
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// informational, store data for later, does only trigger UI feedback/update
|
||||
public void onBankTransferInitedMessage(BankTransferInitedMessage message) {
|
||||
log.debug("onBankTransferInitedMessage called " + step++);
|
||||
// 9.b. handleBankTransferInitedMessage
|
||||
public void handleBankTransferInitedMessage(BankTransferInitedMessage message) {
|
||||
log.debug("onBankTransferInitedMessage called: state = " + state);
|
||||
log.debug("state " + state);
|
||||
|
||||
// validate
|
||||
checkState(state.ordinal() >= State.SendSignedTakerDepositTxAsHex.ordinal() &&
|
||||
state.ordinal() < State.SignAndPublishPayoutTx.ordinal());
|
||||
checkArgument(tradeId.equals(message.getTradeId()));
|
||||
checkTradeId(tradeId, message);
|
||||
String depositTxAsHex = nonEmptyStringOf(message.getDepositTxAsHex());
|
||||
String offererSignatureR = nonEmptyStringOf(message.getOffererSignatureR());
|
||||
String offererSignatureS = nonEmptyStringOf(message.getOffererSignatureS());
|
||||
@ -369,7 +369,7 @@ public class SellerTakesOfferProtocol {
|
||||
String offererPayoutAddress = nonEmptyStringOf(message.getOffererPayoutAddress());
|
||||
|
||||
// apply state
|
||||
state = State.onBankTransferInitedMessage;
|
||||
state = State.handleBankTransferInitedMessage;
|
||||
this.depositTxAsHex = depositTxAsHex;
|
||||
this.offererSignatureR = offererSignatureR;
|
||||
this.offererSignatureS = offererSignatureS;
|
||||
@ -386,14 +386,15 @@ public class SellerTakesOfferProtocol {
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// User clicked the "bank transfer received" button, so we release the funds for pay out
|
||||
public void onUIEventFiatReceived() {
|
||||
log.debug("onUIEventFiatReceived called " + step++);
|
||||
// 10. SignAndPublishPayoutTx
|
||||
public void handleUIEventFiatReceived() {
|
||||
log.debug("onUIEventFiatReceived called: state = " + state);
|
||||
log.debug("state " + state);
|
||||
checkState(state == State.onBankTransferInitedMessage);
|
||||
checkState(state == State.handleBankTransferInitedMessage || state == State.TakerCommitDepositTx);
|
||||
|
||||
state = State.SignAndPublishPayoutTx;
|
||||
SignAndPublishPayoutTx.run(this::onResultSignAndPublishPayoutTx,
|
||||
this::onFault,
|
||||
SignAndPublishPayoutTx.run(this::handleSignAndPublishPayoutTxResult,
|
||||
this::handleFault,
|
||||
walletService,
|
||||
tradeId,
|
||||
depositTxAsHex,
|
||||
@ -404,26 +405,17 @@ public class SellerTakesOfferProtocol {
|
||||
offererPayoutAddress);
|
||||
}
|
||||
|
||||
public void onResultSignAndPublishPayoutTx(Transaction transaction, String payoutTxAsHex) {
|
||||
log.debug("onResultSignAndPublishPayoutTx called " + step++);
|
||||
// 11. SendPayoutTxToOfferer
|
||||
private void handleSignAndPublishPayoutTxResult(Transaction transaction, String payoutTxAsHex) {
|
||||
log.debug("handleSignAndPublishPayoutTxResult called: state = " + state);
|
||||
listener.onPayoutTxPublished(trade, transaction);
|
||||
|
||||
state = State.SendPayoutTxToOfferer;
|
||||
SendPayoutTxToOfferer.run(this::onResultSendPayoutTxToOfferer, this::onFault, peer, tradeMessageService,
|
||||
SendPayoutTxToOfferer.run(this::handleSendPayoutTxToOffererResult, this::handleErrorMessage, peer, tradeMessageService,
|
||||
tradeId, payoutTxAsHex);
|
||||
}
|
||||
|
||||
public void onResultSendPayoutTxToOfferer() {
|
||||
log.debug("onResultSendPayoutTxToOfferer called " + step++);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Getters, Setters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public String getId() {
|
||||
return tradeId;
|
||||
private void handleSendPayoutTxToOffererResult() {
|
||||
log.debug("onResultSendPayoutTxToOfferer called: state = " + state);
|
||||
}
|
||||
|
||||
|
||||
@ -432,12 +424,14 @@ public class SellerTakesOfferProtocol {
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// generic fault handler
|
||||
private void onFault(Throwable throwable) {
|
||||
private void handleFault(Throwable throwable) {
|
||||
trade.setFault(throwable);
|
||||
trade.setState(Trade.State.FAILED);
|
||||
listener.onFault(throwable, state);
|
||||
}
|
||||
|
||||
private void onErrorMessage(String errorMessage) {
|
||||
listener.onFault(new Exception(errorMessage), state);
|
||||
private void handleErrorMessage(String errorMessage) {
|
||||
handleFault(new Exception(errorMessage));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -29,13 +29,13 @@ public class TakeOfferFeePayedMessage implements Serializable, TradeMessage {
|
||||
|
||||
private final Coin tradeAmount;
|
||||
private final String takeOfferFeeTxID;
|
||||
private final String takerPubKey;
|
||||
private final String tradePubKeyAsHex;
|
||||
|
||||
public TakeOfferFeePayedMessage(String tradeId, String takeOfferFeeTxID, Coin tradeAmount, String takerPubKey) {
|
||||
public TakeOfferFeePayedMessage(String tradeId, String takeOfferFeeTxID, Coin tradeAmount, String tradePubKeyAsHex) {
|
||||
this.tradeId = tradeId;
|
||||
this.takeOfferFeeTxID = takeOfferFeeTxID;
|
||||
this.tradeAmount = tradeAmount;
|
||||
this.takerPubKey = takerPubKey;
|
||||
this.tradePubKeyAsHex = tradePubKeyAsHex;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -51,8 +51,8 @@ public class TakeOfferFeePayedMessage implements Serializable, TradeMessage {
|
||||
return takeOfferFeeTxID;
|
||||
}
|
||||
|
||||
public String getTakerPubKey() {
|
||||
return takerPubKey;
|
||||
public String getTakerPubKeyAsHex() {
|
||||
return tradePubKeyAsHex;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ public class CreateAndSignContract {
|
||||
String peersAccountId,
|
||||
BankAccount peersBankAccount,
|
||||
ECKey registrationKey) {
|
||||
log.trace("Run task");
|
||||
log.trace("Run CreateAndSignContract task");
|
||||
try {
|
||||
Contract contract = new Contract(offer, tradeAmount, takeOfferFeeTxId, peersAccountId, accountId,
|
||||
peersBankAccount, bankAccount, peersMessagePublicKey, messagePublicKey);
|
||||
|
@ -29,7 +29,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
public class GetPeerAddress {
|
||||
private static final Logger log = LoggerFactory.getLogger(GetPeerAddress.class);
|
||||
|
||||
|
||||
public static void run(ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler,
|
||||
TradeMessageService tradeMessageService, PublicKey messagePublicKey) {
|
||||
log.trace("Run GetPeerAddress task");
|
||||
@ -42,8 +42,8 @@ public class GetPeerAddress {
|
||||
|
||||
@Override
|
||||
public void onFailed() {
|
||||
log.error("Lookup for peer address failed.");
|
||||
errorMessageHandler.handleErrorMessage("Lookup for peer address failed.");
|
||||
log.error("DHT lookup for peer address failed.");
|
||||
errorMessageHandler.handleErrorMessage("DHT lookup for peer address failed.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ public class PayDeposit {
|
||||
String arbitratorPubKey,
|
||||
String offererPubKey,
|
||||
String preparedOffererDepositTxAsHex) {
|
||||
log.trace("Run task");
|
||||
log.trace("Run PayDeposit task");
|
||||
try {
|
||||
Coin amountToPay = tradeAmount.add(securityDeposit);
|
||||
Coin msOutputAmount = amountToPay.add(securityDeposit);
|
||||
@ -53,18 +53,15 @@ public class PayDeposit {
|
||||
preparedOffererDepositTxAsHex,
|
||||
tradeId);
|
||||
|
||||
log.trace("sharedModel.signedTakerDepositTx: " + signedTakerDepositTx);
|
||||
log.trace("signedTakerDepositTx: " + signedTakerDepositTx);
|
||||
resultHandler.onResult(signedTakerDepositTx);
|
||||
} catch (InsufficientMoneyException e) {
|
||||
log.error("Pay deposit faultHandler.onFault due InsufficientMoneyException " + e);
|
||||
exceptionHandler.handleException(
|
||||
new Exception("Pay deposit faultHandler.onFault due InsufficientMoneyException " + e));
|
||||
log.error("Pay deposit failed due InsufficientMoneyException " + e);
|
||||
exceptionHandler.handleException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public interface ResultHandler {
|
||||
void onResult(Transaction signedTakerDepositTx);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ public class PayTakeOfferFee {
|
||||
|
||||
public static void run(ResultHandler resultHandler, ExceptionHandler exceptionHandler, WalletService walletService,
|
||||
String tradeId) {
|
||||
log.trace("Run task");
|
||||
log.trace("Run PayTakeOfferFee task");
|
||||
try {
|
||||
walletService.payTakeOfferFee(tradeId, new FutureCallback<Transaction>() {
|
||||
@Override
|
||||
@ -46,15 +46,13 @@ public class PayTakeOfferFee {
|
||||
|
||||
@Override
|
||||
public void onFailure(@NotNull Throwable t) {
|
||||
log.error("Take offer fee paid faultHandler.onFault with exception: " + t);
|
||||
exceptionHandler.handleException(
|
||||
new Exception("Take offer fee paid faultHandler.onFault with exception: " + t));
|
||||
log.error("Pay take offer fee caused an exception: " + t);
|
||||
exceptionHandler.handleException(t);
|
||||
}
|
||||
});
|
||||
} catch (InsufficientMoneyException e) {
|
||||
log.error("Take offer fee paid faultHandler.onFault due InsufficientMoneyException " + e);
|
||||
exceptionHandler.handleException(
|
||||
new Exception("Take offer fee paid faultHandler.onFault due to InsufficientMoneyException " + e));
|
||||
log.error("Pay take offer fee caused an exception: " + e);
|
||||
exceptionHandler.handleException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,12 +17,11 @@
|
||||
|
||||
package io.bitsquare.trade.protocol.trade.taker.tasks;
|
||||
|
||||
import io.bitsquare.network.Peer;
|
||||
import io.bitsquare.trade.TradeMessageService;
|
||||
import io.bitsquare.trade.listeners.SendMessageListener;
|
||||
import io.bitsquare.network.Peer;
|
||||
import io.bitsquare.trade.protocol.trade.taker.messages.RequestTakeOfferMessage;
|
||||
import io.bitsquare.util.handlers.ExceptionHandler;
|
||||
import io.bitsquare.util.handlers.ResultHandler;
|
||||
import io.bitsquare.util.handlers.ErrorMessageHandler;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -30,21 +29,20 @@ import org.slf4j.LoggerFactory;
|
||||
public class RequestTakeOffer {
|
||||
private static final Logger log = LoggerFactory.getLogger(RequestTakeOffer.class);
|
||||
|
||||
public static void run(ResultHandler resultHandler, ExceptionHandler exceptionHandler, Peer peer,
|
||||
TradeMessageService tradeMessageService, String tradeId) {
|
||||
public static void run(ErrorMessageHandler errorMessageHandler,
|
||||
TradeMessageService tradeMessageService, Peer peer, String tradeId) {
|
||||
log.trace("Run RequestTakeOffer task");
|
||||
tradeMessageService.sendMessage(peer, new RequestTakeOfferMessage(tradeId),
|
||||
new SendMessageListener() {
|
||||
@Override
|
||||
public void handleResult() {
|
||||
log.trace("RequestTakeOfferMessage successfully arrived at peer");
|
||||
resultHandler.handleResult();
|
||||
log.trace("Sending RequestTakeOfferMessage succeeded.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleFault() {
|
||||
log.error("RequestTakeOfferMessage did not arrive at peer");
|
||||
exceptionHandler.handleException(new Exception("RequestTakeOfferMessage did not arrive at peer"));
|
||||
log.error("Sending RequestTakeOfferMessage failed.");
|
||||
errorMessageHandler.handleErrorMessage("Sending RequestTakeOfferMessage failed.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -17,11 +17,11 @@
|
||||
|
||||
package io.bitsquare.trade.protocol.trade.taker.tasks;
|
||||
|
||||
import io.bitsquare.network.Peer;
|
||||
import io.bitsquare.trade.TradeMessageService;
|
||||
import io.bitsquare.trade.listeners.SendMessageListener;
|
||||
import io.bitsquare.network.Peer;
|
||||
import io.bitsquare.trade.protocol.trade.taker.messages.PayoutTxPublishedMessage;
|
||||
import io.bitsquare.util.handlers.ExceptionHandler;
|
||||
import io.bitsquare.util.handlers.ErrorMessageHandler;
|
||||
import io.bitsquare.util.handlers.ResultHandler;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
@ -30,7 +30,7 @@ import org.slf4j.LoggerFactory;
|
||||
public class SendPayoutTxToOfferer {
|
||||
private static final Logger log = LoggerFactory.getLogger(SendPayoutTxToOfferer.class);
|
||||
|
||||
public static void run(ResultHandler resultHandler, ExceptionHandler exceptionHandler, Peer peer,
|
||||
public static void run(ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler, Peer peer,
|
||||
TradeMessageService tradeMessageService, String tradeId, String payoutTxAsHex) {
|
||||
log.trace("Run task");
|
||||
PayoutTxPublishedMessage tradeMessage = new PayoutTxPublishedMessage(tradeId, payoutTxAsHex);
|
||||
@ -44,7 +44,7 @@ public class SendPayoutTxToOfferer {
|
||||
@Override
|
||||
public void handleFault() {
|
||||
log.error("PayoutTxPublishedMessage did not arrive at peer");
|
||||
exceptionHandler.handleException(new Exception("PayoutTxPublishedMessage did not arrive at peer"));
|
||||
errorMessageHandler.handleErrorMessage("PayoutTxPublishedMessage did not arrive at peer");
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -19,12 +19,11 @@ package io.bitsquare.trade.protocol.trade.taker.tasks;
|
||||
|
||||
import io.bitsquare.bank.BankAccount;
|
||||
import io.bitsquare.btc.WalletService;
|
||||
import io.bitsquare.network.Peer;
|
||||
import io.bitsquare.trade.TradeMessageService;
|
||||
import io.bitsquare.trade.listeners.SendMessageListener;
|
||||
import io.bitsquare.network.Peer;
|
||||
import io.bitsquare.trade.protocol.trade.taker.messages.RequestOffererPublishDepositTxMessage;
|
||||
import io.bitsquare.util.handlers.ExceptionHandler;
|
||||
import io.bitsquare.util.handlers.ResultHandler;
|
||||
import io.bitsquare.util.handlers.ErrorMessageHandler;
|
||||
|
||||
import org.bitcoinj.core.Transaction;
|
||||
import org.bitcoinj.core.Utils;
|
||||
@ -37,8 +36,7 @@ import org.slf4j.LoggerFactory;
|
||||
public class SendSignedTakerDepositTxAsHex {
|
||||
private static final Logger log = LoggerFactory.getLogger(SendSignedTakerDepositTxAsHex.class);
|
||||
|
||||
public static void run(ResultHandler resultHandler,
|
||||
ExceptionHandler exceptionHandler,
|
||||
public static void run(ErrorMessageHandler errorMessageHandler,
|
||||
Peer peer,
|
||||
TradeMessageService tradeMessageService,
|
||||
WalletService walletService,
|
||||
@ -47,10 +45,10 @@ public class SendSignedTakerDepositTxAsHex {
|
||||
PublicKey messagePublicKey,
|
||||
String tradeId,
|
||||
String contractAsJson,
|
||||
String takerSignature,
|
||||
String takerContractSignature,
|
||||
Transaction signedTakerDepositTx,
|
||||
long offererTxOutIndex) {
|
||||
log.trace("Run task");
|
||||
log.trace("Run SendSignedTakerDepositTxAsHex task");
|
||||
long takerTxOutIndex = signedTakerDepositTx.getInput(1).getOutpoint().getIndex();
|
||||
|
||||
RequestOffererPublishDepositTxMessage tradeMessage = new RequestOffererPublishDepositTxMessage(tradeId,
|
||||
@ -64,7 +62,7 @@ public class SendSignedTakerDepositTxAsHex {
|
||||
.getParentTransaction()
|
||||
.bitcoinSerialize()),
|
||||
contractAsJson,
|
||||
takerSignature,
|
||||
takerContractSignature,
|
||||
walletService.getAddressInfoByTradeID(tradeId).getAddressString(),
|
||||
takerTxOutIndex,
|
||||
offererTxOutIndex);
|
||||
@ -72,14 +70,12 @@ public class SendSignedTakerDepositTxAsHex {
|
||||
@Override
|
||||
public void handleResult() {
|
||||
log.trace("RequestOffererDepositPublicationMessage successfully arrived at peer");
|
||||
resultHandler.handleResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleFault() {
|
||||
log.error("RequestOffererDepositPublicationMessage did not arrive at peer");
|
||||
exceptionHandler.handleException(
|
||||
new Exception("RequestOffererDepositPublicationMessage did not arrive at peer"));
|
||||
errorMessageHandler.handleErrorMessage("RequestOffererDepositPublicationMessage did not arrive at peer");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -17,44 +17,41 @@
|
||||
|
||||
package io.bitsquare.trade.protocol.trade.taker.tasks;
|
||||
|
||||
import io.bitsquare.network.Peer;
|
||||
import io.bitsquare.trade.TradeMessageService;
|
||||
import io.bitsquare.trade.listeners.SendMessageListener;
|
||||
import io.bitsquare.network.Peer;
|
||||
import io.bitsquare.trade.protocol.trade.taker.messages.TakeOfferFeePayedMessage;
|
||||
import io.bitsquare.util.handlers.ExceptionHandler;
|
||||
import io.bitsquare.util.handlers.ResultHandler;
|
||||
import io.bitsquare.util.handlers.ErrorMessageHandler;
|
||||
|
||||
import org.bitcoinj.core.Coin;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class SendTakeOfferFeePayedTxId {
|
||||
private static final Logger log = LoggerFactory.getLogger(SendTakeOfferFeePayedTxId.class);
|
||||
public class SendTakeOfferFeePayedMessage {
|
||||
private static final Logger log = LoggerFactory.getLogger(SendTakeOfferFeePayedMessage.class);
|
||||
|
||||
public static void run(ResultHandler resultHandler,
|
||||
ExceptionHandler exceptionHandler,
|
||||
public static void run(ErrorMessageHandler errorMessageHandler,
|
||||
Peer peer,
|
||||
TradeMessageService tradeMessageService,
|
||||
String tradeId,
|
||||
String takeOfferFeeTxId,
|
||||
Coin tradeAmount,
|
||||
String pubKeyForThatTradeAsHex) {
|
||||
log.trace("Run task");
|
||||
String tradePubKeyAsHex) {
|
||||
log.trace("Run SendTakeOfferFeePayedMessage task");
|
||||
TakeOfferFeePayedMessage msg = new TakeOfferFeePayedMessage(tradeId, takeOfferFeeTxId, tradeAmount,
|
||||
pubKeyForThatTradeAsHex);
|
||||
tradePubKeyAsHex);
|
||||
|
||||
tradeMessageService.sendMessage(peer, msg, new SendMessageListener() {
|
||||
@Override
|
||||
public void handleResult() {
|
||||
log.trace("TakeOfferFeePayedMessage successfully arrived at peer");
|
||||
resultHandler.handleResult();
|
||||
log.trace("TakeOfferFeePayedMessage succeeded.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleFault() {
|
||||
log.error("TakeOfferFeePayedMessage did not arrive at peer");
|
||||
exceptionHandler.handleException(new Exception("TakeOfferFeePayedMessage did not arrive at peer"));
|
||||
log.error("Sending TakeOfferFeePayedMessage failed.");
|
||||
errorMessageHandler.handleErrorMessage("Sending TakeOfferFeePayedMessage failed.");
|
||||
}
|
||||
});
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.tasks;
|
||||
|
||||
import io.bitsquare.btc.WalletService;
|
||||
import io.bitsquare.util.handlers.ExceptionHandler;
|
||||
|
||||
import org.bitcoinj.core.Transaction;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class TakerCommitDepositTx {
|
||||
private static final Logger log = LoggerFactory.getLogger(TakerCommitDepositTx.class);
|
||||
|
||||
public static void run(ResultHandler resultHandler, ExceptionHandler exceptionHandler, WalletService walletService, String depositTxAsHex) {
|
||||
log.trace("Run PayDeposit task");
|
||||
try {
|
||||
Transaction transaction = walletService.takerCommitDepositTx(depositTxAsHex);
|
||||
resultHandler.onResult(transaction);
|
||||
} catch (Exception e) {
|
||||
log.error("takerCommitDepositTx failed with exception " + e);
|
||||
exceptionHandler.handleException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public interface ResultHandler {
|
||||
void onResult(Transaction transaction);
|
||||
}
|
||||
}
|
@ -31,7 +31,7 @@ public class VerifyOffererAccount {
|
||||
|
||||
public static void run(ResultHandler resultHandler, ExceptionHandler exceptionHandler,
|
||||
BlockChainService blockChainService, String peersAccountId, BankAccount peersBankAccount) {
|
||||
log.trace("Run task");
|
||||
log.trace("Run VerifyOffererAccount task");
|
||||
VerifyPeerAccount.run(resultHandler, exceptionHandler, blockChainService, peersAccountId, peersBankAccount);
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,8 @@
|
||||
|
||||
package io.bitsquare.util;
|
||||
|
||||
import io.bitsquare.trade.protocol.trade.TradeMessage;
|
||||
|
||||
import org.bitcoinj.core.Coin;
|
||||
|
||||
import static com.google.common.base.Preconditions.*;
|
||||
@ -49,4 +51,9 @@ public class Validator {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static void checkTradeId(String tradeId, TradeMessage tradeMessage) {
|
||||
checkArgument(tradeId.equals(tradeMessage.getTradeId()));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -48,7 +48,7 @@
|
||||
<logger name="org.bitcoinj.core.BitcoinSerializer" level="WARN"/>
|
||||
<logger name="org.bitcoinj.core.AbstractBlockChain" level="WARN"/>
|
||||
<logger name="org.bitcoinj.wallet.DeterministicKeyChain" level="WARN"/>
|
||||
<logger name="io.bitsquare.btc.WalletService" level="WARN"/>
|
||||
<!-- <logger name="io.bitsquare.btc.WalletService" level="WARN"/>-->
|
||||
|
||||
<!--
|
||||
<logger name="org.bitcoinj.core.Wallet" level="OFF"/>
|
||||
|
Loading…
x
Reference in New Issue
Block a user