mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-08-06 05:34:50 -04:00
refactoring trade protocol
This commit is contained in:
parent
5da272bdbf
commit
cb4ca6b2a7
7 changed files with 184 additions and 733 deletions
|
@ -7,6 +7,7 @@ import com.google.inject.Inject;
|
||||||
import io.bitsquare.btc.BlockChainFacade;
|
import io.bitsquare.btc.BlockChainFacade;
|
||||||
import io.bitsquare.btc.WalletFacade;
|
import io.bitsquare.btc.WalletFacade;
|
||||||
import io.bitsquare.crypto.CryptoFacade;
|
import io.bitsquare.crypto.CryptoFacade;
|
||||||
|
import io.bitsquare.gui.popups.Popups;
|
||||||
import io.bitsquare.msg.MessageFacade;
|
import io.bitsquare.msg.MessageFacade;
|
||||||
import io.bitsquare.msg.TradeMessage;
|
import io.bitsquare.msg.TradeMessage;
|
||||||
import io.bitsquare.msg.listeners.TakeOfferRequestListener;
|
import io.bitsquare.msg.listeners.TakeOfferRequestListener;
|
||||||
|
@ -233,6 +234,32 @@ public class Trading
|
||||||
log.debug("trading onPayoutTxPublishedMessage");
|
log.debug("trading onPayoutTxPublishedMessage");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFault(Throwable throwable, OffererAsBuyerProtocol.State state)
|
||||||
|
{
|
||||||
|
log.error("Error while executing trade process at state: " + state + " / " + throwable);
|
||||||
|
Popups.openErrorPopup("Error while executing trade process", "Error while executing trade process at state: " + state + " / " + throwable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onWaitingForPeerResponse(OffererAsBuyerProtocol.State state)
|
||||||
|
{
|
||||||
|
log.debug("Waiting for peers response at state " + state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCompleted(OffererAsBuyerProtocol.State state)
|
||||||
|
{
|
||||||
|
log.debug("Trade protocol completed at state " + state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onWaitingForUserInteraction(OffererAsBuyerProtocol.State state)
|
||||||
|
{
|
||||||
|
log.debug("Waiting for UI activity at state " + state);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDepositTxConfirmedInBlockchain()
|
public void onDepositTxConfirmedInBlockchain()
|
||||||
{
|
{
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -14,4 +14,12 @@ public interface OffererAsBuyerProtocolListener
|
||||||
void onDepositTxConfirmedUpdate(TransactionConfidence confidence);
|
void onDepositTxConfirmedUpdate(TransactionConfidence confidence);
|
||||||
|
|
||||||
void onPayoutTxPublished(String payoutTxID);
|
void onPayoutTxPublished(String payoutTxID);
|
||||||
|
|
||||||
|
void onFault(Throwable throwable, OffererAsBuyerProtocol.State state);
|
||||||
|
|
||||||
|
void onWaitingForPeerResponse(OffererAsBuyerProtocol.State state);
|
||||||
|
|
||||||
|
void onCompleted(OffererAsBuyerProtocol.State state);
|
||||||
|
|
||||||
|
void onWaitingForUserInteraction(OffererAsBuyerProtocol.State state);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,8 +20,15 @@ import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static com.google.common.base.Preconditions.checkState;
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
import static io.bitsquare.util.Validator.*;
|
import static io.bitsquare.util.Validator.nonEmptyStringOf;
|
||||||
|
import static io.bitsquare.util.Validator.nonNegativeLongOf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Responsible for the correct execution of the sequence of tasks, message passing to the peer and message processing from the peer.
|
||||||
|
* That class handles the role of the taker as the Bitcoin seller.
|
||||||
|
* It uses sub tasks to not pollute the main class too much with all the async result/fault handling.
|
||||||
|
* Any data from incoming messages as well data used to send to the peer need to be validated before further processing.
|
||||||
|
*/
|
||||||
public class TakerAsSellerProtocol
|
public class TakerAsSellerProtocol
|
||||||
{
|
{
|
||||||
private static final Logger log = LoggerFactory.getLogger(TakerAsSellerProtocol.class);
|
private static final Logger log = LoggerFactory.getLogger(TakerAsSellerProtocol.class);
|
||||||
|
@ -92,7 +99,7 @@ public class TakerAsSellerProtocol
|
||||||
|
|
||||||
public void start()
|
public void start()
|
||||||
{
|
{
|
||||||
String messagePubKeyAsHex = validString(offer.getMessagePubKeyAsHex());
|
String messagePubKeyAsHex = nonEmptyStringOf(offer.getMessagePubKeyAsHex());
|
||||||
|
|
||||||
GetPeerAddress.run(this::onResultGetPeerAddress, this::onFault, messageFacade, messagePubKeyAsHex);
|
GetPeerAddress.run(this::onResultGetPeerAddress, this::onFault, messageFacade, messagePubKeyAsHex);
|
||||||
state = State.GetPeerAddress;
|
state = State.GetPeerAddress;
|
||||||
|
@ -105,7 +112,7 @@ public class TakerAsSellerProtocol
|
||||||
|
|
||||||
public void onResultGetPeerAddress(PeerAddress peerAddress)
|
public void onResultGetPeerAddress(PeerAddress peerAddress)
|
||||||
{
|
{
|
||||||
this.peerAddress = validPeerAddress(peerAddress);
|
this.peerAddress = checkNotNull(peerAddress);
|
||||||
|
|
||||||
RequestTakeOffer.run(this::onResultRequestTakeOffer, this::onFault, this.peerAddress, messageFacade, tradeId);
|
RequestTakeOffer.run(this::onResultRequestTakeOffer, this::onFault, this.peerAddress, messageFacade, tradeId);
|
||||||
state = State.RequestTakeOffer;
|
state = State.RequestTakeOffer;
|
||||||
|
@ -143,7 +150,7 @@ public class TakerAsSellerProtocol
|
||||||
public void onResultPayTakeOfferFee(Transaction transaction)
|
public void onResultPayTakeOfferFee(Transaction transaction)
|
||||||
{
|
{
|
||||||
checkNotNull(transaction);
|
checkNotNull(transaction);
|
||||||
String transactionId = validString(transaction.getHashAsString());
|
String transactionId = nonEmptyStringOf(transaction.getHashAsString());
|
||||||
|
|
||||||
trade.setTakeOfferFeeTxID(transactionId);
|
trade.setTakeOfferFeeTxID(transactionId);
|
||||||
|
|
||||||
|
@ -178,11 +185,11 @@ public class TakerAsSellerProtocol
|
||||||
|
|
||||||
checkState(state == State.SendTakeOfferFeePayedTxId);
|
checkState(state == State.SendTakeOfferFeePayedTxId);
|
||||||
|
|
||||||
peersAccountId = validString(message.getAccountID());
|
peersAccountId = nonEmptyStringOf(message.getAccountID());
|
||||||
peersBankAccount = checkNotNull(message.getBankAccount());
|
peersBankAccount = checkNotNull(message.getBankAccount());
|
||||||
offererPubKey = validString(message.getOffererPubKey());
|
offererPubKey = nonEmptyStringOf(message.getOffererPubKey());
|
||||||
preparedOffererDepositTxAsHex = validString(message.getPreparedOffererDepositTxAsHex());
|
preparedOffererDepositTxAsHex = nonEmptyStringOf(message.getPreparedOffererDepositTxAsHex());
|
||||||
offererTxOutIndex = validNonNegativeLong(message.getOffererTxOutIndex());
|
offererTxOutIndex = nonNegativeLongOf(message.getOffererTxOutIndex());
|
||||||
|
|
||||||
VerifyOffererAccount.run(this::onResultVerifyOffererAccount,
|
VerifyOffererAccount.run(this::onResultVerifyOffererAccount,
|
||||||
this::onFault,
|
this::onFault,
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package io.bitsquare.trade.protocol.tasks.offerer;
|
package io.bitsquare.trade.protocol.tasks.offerer;
|
||||||
|
|
||||||
|
import com.google.bitcoin.core.Transaction;
|
||||||
import com.google.bitcoin.core.Utils;
|
import com.google.bitcoin.core.Utils;
|
||||||
import io.bitsquare.msg.MessageFacade;
|
import io.bitsquare.msg.MessageFacade;
|
||||||
import io.bitsquare.msg.listeners.OutgoingTradeMessageListener;
|
import io.bitsquare.msg.listeners.OutgoingTradeMessageListener;
|
||||||
import io.bitsquare.trade.Trade;
|
|
||||||
import io.bitsquare.trade.protocol.messages.offerer.DepositTxPublishedMessage;
|
import io.bitsquare.trade.protocol.messages.offerer.DepositTxPublishedMessage;
|
||||||
import io.bitsquare.trade.protocol.tasks.FaultHandler;
|
import io.bitsquare.trade.protocol.tasks.FaultHandler;
|
||||||
import io.bitsquare.trade.protocol.tasks.ResultHandler;
|
import io.bitsquare.trade.protocol.tasks.ResultHandler;
|
||||||
|
@ -15,9 +15,9 @@ public class SendDepositTxIdToTaker
|
||||||
{
|
{
|
||||||
private static final Logger log = LoggerFactory.getLogger(SendDepositTxIdToTaker.class);
|
private static final Logger log = LoggerFactory.getLogger(SendDepositTxIdToTaker.class);
|
||||||
|
|
||||||
public static void run(ResultHandler resultHandler, FaultHandler faultHandler, PeerAddress peerAddress, MessageFacade messageFacade, Trade trade)
|
public static void run(ResultHandler resultHandler, FaultHandler faultHandler, PeerAddress peerAddress, MessageFacade messageFacade, String tradeId, Transaction depositTransaction)
|
||||||
{
|
{
|
||||||
DepositTxPublishedMessage tradeMessage = new DepositTxPublishedMessage(trade.getId(), Utils.bytesToHexString(trade.getDepositTransaction().bitcoinSerialize()));
|
DepositTxPublishedMessage tradeMessage = new DepositTxPublishedMessage(tradeId, Utils.bytesToHexString(depositTransaction.bitcoinSerialize()));
|
||||||
messageFacade.sendTradeMessage(peerAddress, tradeMessage, new OutgoingTradeMessageListener()
|
messageFacade.sendTradeMessage(peerAddress, tradeMessage, new OutgoingTradeMessageListener()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
package io.bitsquare.trade.protocol.tasks.offerer;
|
package io.bitsquare.trade.protocol.tasks.offerer;
|
||||||
|
|
||||||
import com.google.bitcoin.core.ECKey;
|
import com.google.bitcoin.core.ECKey;
|
||||||
import com.google.bitcoin.core.Transaction;
|
|
||||||
import io.bitsquare.btc.WalletFacade;
|
import io.bitsquare.btc.WalletFacade;
|
||||||
import io.bitsquare.msg.MessageFacade;
|
import io.bitsquare.msg.MessageFacade;
|
||||||
import io.bitsquare.msg.listeners.OutgoingTradeMessageListener;
|
import io.bitsquare.msg.listeners.OutgoingTradeMessageListener;
|
||||||
import io.bitsquare.trade.Trade;
|
|
||||||
import io.bitsquare.trade.protocol.messages.offerer.BankTransferInitedMessage;
|
import io.bitsquare.trade.protocol.messages.offerer.BankTransferInitedMessage;
|
||||||
import io.bitsquare.trade.protocol.tasks.FaultHandler;
|
import io.bitsquare.trade.protocol.tasks.FaultHandler;
|
||||||
import io.bitsquare.trade.protocol.tasks.ResultHandler;
|
import io.bitsquare.trade.protocol.tasks.ResultHandler;
|
||||||
|
@ -24,34 +22,30 @@ public class SendSignedPayoutTx
|
||||||
PeerAddress peerAddress,
|
PeerAddress peerAddress,
|
||||||
MessageFacade messageFacade,
|
MessageFacade messageFacade,
|
||||||
WalletFacade walletFacade,
|
WalletFacade walletFacade,
|
||||||
Trade trade,
|
String tradeId,
|
||||||
String takerPayoutAddress)
|
String takerPayoutAddress,
|
||||||
|
String offererPayoutAddress,
|
||||||
|
String depositTransactionId,
|
||||||
|
BigInteger collateral,
|
||||||
|
BigInteger tradeAmount)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Transaction depositTransaction = trade.getDepositTransaction();
|
BigInteger offererPaybackAmount = tradeAmount.add(collateral);
|
||||||
BigInteger collateral = trade.getCollateralAmount();
|
|
||||||
BigInteger offererPaybackAmount = trade.getTradeAmount().add(collateral);
|
|
||||||
BigInteger takerPaybackAmount = collateral;
|
BigInteger takerPaybackAmount = collateral;
|
||||||
|
|
||||||
log.trace("offererPaybackAmount " + offererPaybackAmount);
|
Pair<ECKey.ECDSASignature, String> result = walletFacade.offererCreatesAndSignsPayoutTx(depositTransactionId,
|
||||||
log.trace("takerPaybackAmount " + takerPaybackAmount);
|
|
||||||
log.trace("depositTransaction.getHashAsString() " + depositTransaction.getHashAsString());
|
|
||||||
log.trace("takerPayoutAddress " + takerPayoutAddress);
|
|
||||||
|
|
||||||
Pair<ECKey.ECDSASignature, String> result = walletFacade.offererCreatesAndSignsPayoutTx(depositTransaction.getHashAsString(),
|
|
||||||
offererPaybackAmount,
|
offererPaybackAmount,
|
||||||
takerPaybackAmount,
|
takerPaybackAmount,
|
||||||
takerPayoutAddress,
|
takerPayoutAddress,
|
||||||
trade.getId());
|
tradeId);
|
||||||
|
|
||||||
ECKey.ECDSASignature offererSignature = result.getKey();
|
ECKey.ECDSASignature offererSignature = result.getKey();
|
||||||
String offererSignatureR = offererSignature.r.toString();
|
String offererSignatureR = offererSignature.r.toString();
|
||||||
String offererSignatureS = offererSignature.s.toString();
|
String offererSignatureS = offererSignature.s.toString();
|
||||||
String depositTxAsHex = result.getValue();
|
String depositTxAsHex = result.getValue();
|
||||||
String offererPayoutAddress = walletFacade.getAddressInfoByTradeID(trade.getId()).getAddressString();
|
|
||||||
|
|
||||||
BankTransferInitedMessage tradeMessage = new BankTransferInitedMessage(trade.getId(),
|
BankTransferInitedMessage tradeMessage = new BankTransferInitedMessage(tradeId,
|
||||||
depositTxAsHex,
|
depositTxAsHex,
|
||||||
offererSignatureR,
|
offererSignatureR,
|
||||||
offererSignatureS,
|
offererSignatureS,
|
||||||
|
@ -59,13 +53,6 @@ public class SendSignedPayoutTx
|
||||||
takerPaybackAmount,
|
takerPaybackAmount,
|
||||||
offererPayoutAddress);
|
offererPayoutAddress);
|
||||||
|
|
||||||
log.trace("depositTxAsHex " + depositTxAsHex);
|
|
||||||
log.trace("offererSignatureR " + offererSignatureR);
|
|
||||||
log.trace("offererSignatureS " + offererSignatureS);
|
|
||||||
log.trace("offererPaybackAmount " + offererPaybackAmount);
|
|
||||||
log.trace("takerPaybackAmount " + takerPaybackAmount);
|
|
||||||
log.trace("offererPayoutAddress " + offererPayoutAddress);
|
|
||||||
|
|
||||||
messageFacade.sendTradeMessage(peerAddress, tradeMessage, new OutgoingTradeMessageListener()
|
messageFacade.sendTradeMessage(peerAddress, tradeMessage, new OutgoingTradeMessageListener()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package io.bitsquare.util;
|
package io.bitsquare.util;
|
||||||
|
|
||||||
import net.tomp2p.peers.PeerAddress;
|
import java.math.BigInteger;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -11,24 +11,31 @@ public class Validator
|
||||||
{
|
{
|
||||||
private static final Logger log = LoggerFactory.getLogger(Validator.class);
|
private static final Logger log = LoggerFactory.getLogger(Validator.class);
|
||||||
|
|
||||||
public static String validString(String value)
|
public static String nonEmptyStringOf(String value)
|
||||||
{
|
{
|
||||||
checkNotNull(value);
|
checkNotNull(value);
|
||||||
checkArgument(value.length() > 0);
|
checkArgument(value.length() > 0);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long validNonNegativeLong(long value)
|
public static long nonNegativeLongOf(long value)
|
||||||
{
|
{
|
||||||
checkArgument(value >= 0);
|
checkArgument(value >= 0);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PeerAddress validPeerAddress(PeerAddress value)
|
public static BigInteger nonZeroBigIntegerOf(BigInteger value)
|
||||||
{
|
{
|
||||||
checkNotNull(value);
|
checkNotNull(value);
|
||||||
|
checkArgument(value.compareTo(BigInteger.ZERO) != 0);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static BigInteger nonNegativeBigIntegerOf(BigInteger value)
|
||||||
|
{
|
||||||
|
checkNotNull(value);
|
||||||
|
checkArgument(value.compareTo(BigInteger.ZERO) >= 0);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue