mirror of
https://github.com/haveno-dex/haveno.git
synced 2024-12-22 19:49:32 +00:00
cleanup trade states, consolidate protocol tasks, remove old tasks
This commit is contained in:
parent
3d43ae1f20
commit
333b7421f5
76 changed files with 114 additions and 3807 deletions
|
@ -18,7 +18,7 @@ import static bisq.core.trade.Trade.Phase.DEPOSIT_UNLOCKED;
|
||||||
import static bisq.core.trade.Trade.Phase.PAYMENT_SENT;
|
import static bisq.core.trade.Trade.Phase.PAYMENT_SENT;
|
||||||
import static bisq.core.trade.Trade.Phase.PAYOUT_PUBLISHED;
|
import static bisq.core.trade.Trade.Phase.PAYOUT_PUBLISHED;
|
||||||
import static bisq.core.trade.Trade.State.BUYER_SAW_ARRIVED_PAYMENT_SENT_MSG;
|
import static bisq.core.trade.Trade.State.BUYER_SAW_ARRIVED_PAYMENT_SENT_MSG;
|
||||||
import static bisq.core.trade.Trade.State.DEPOSIT_UNLOCKED_IN_BLOCK_CHAIN;
|
import static bisq.core.trade.Trade.State.DEPOSIT_TXS_UNLOCKED_IN_BLOCKCHAIN;
|
||||||
import static bisq.core.trade.Trade.State.SELLER_RECEIVED_PAYMENT_SENT_MSG;
|
import static bisq.core.trade.Trade.State.SELLER_RECEIVED_PAYMENT_SENT_MSG;
|
||||||
import static java.lang.String.format;
|
import static java.lang.String.format;
|
||||||
import static java.lang.System.out;
|
import static java.lang.System.out;
|
||||||
|
@ -79,7 +79,7 @@ public class AbstractTradeTest extends AbstractOfferTest {
|
||||||
GrpcClient grpcClient,
|
GrpcClient grpcClient,
|
||||||
String tradeId) {
|
String tradeId) {
|
||||||
Predicate<TradeInfo> isTradeInDepositUnlockedStateAndPhase = (t) ->
|
Predicate<TradeInfo> isTradeInDepositUnlockedStateAndPhase = (t) ->
|
||||||
t.getState().equals(DEPOSIT_UNLOCKED_IN_BLOCK_CHAIN.name())
|
t.getState().equals(DEPOSIT_TXS_UNLOCKED_IN_BLOCKCHAIN.name())
|
||||||
&& t.getPhase().equals(DEPOSIT_UNLOCKED.name());
|
&& t.getPhase().equals(DEPOSIT_UNLOCKED.name());
|
||||||
|
|
||||||
String userName = toUserName.apply(grpcClient);
|
String userName = toUserName.apply(grpcClient);
|
||||||
|
@ -94,7 +94,7 @@ public class AbstractTradeTest extends AbstractOfferTest {
|
||||||
i);
|
i);
|
||||||
genBtcBlocksThenWait(1, 4_000);
|
genBtcBlocksThenWait(1, 4_000);
|
||||||
} else {
|
} else {
|
||||||
EXPECTED_PROTOCOL_STATUS.setState(DEPOSIT_UNLOCKED_IN_BLOCK_CHAIN)
|
EXPECTED_PROTOCOL_STATUS.setState(DEPOSIT_TXS_UNLOCKED_IN_BLOCKCHAIN)
|
||||||
.setPhase(DEPOSIT_UNLOCKED)
|
.setPhase(DEPOSIT_UNLOCKED)
|
||||||
.setDepositPublished(true)
|
.setDepositPublished(true)
|
||||||
.setDepositConfirmed(true);
|
.setDepositConfirmed(true);
|
||||||
|
|
|
@ -40,21 +40,14 @@ import bisq.core.support.dispute.refund.refundagent.RefundAgent;
|
||||||
import bisq.core.support.messages.ChatMessage;
|
import bisq.core.support.messages.ChatMessage;
|
||||||
import bisq.core.trade.messages.PaymentSentMessage;
|
import bisq.core.trade.messages.PaymentSentMessage;
|
||||||
import bisq.core.trade.messages.PayoutTxPublishedMessage;
|
import bisq.core.trade.messages.PayoutTxPublishedMessage;
|
||||||
import bisq.core.trade.messages.DelayedPayoutTxSignatureRequest;
|
|
||||||
import bisq.core.trade.messages.DelayedPayoutTxSignatureResponse;
|
|
||||||
import bisq.core.trade.messages.DepositRequest;
|
import bisq.core.trade.messages.DepositRequest;
|
||||||
import bisq.core.trade.messages.DepositResponse;
|
import bisq.core.trade.messages.DepositResponse;
|
||||||
import bisq.core.trade.messages.DepositTxAndDelayedPayoutTxMessage;
|
|
||||||
import bisq.core.trade.messages.DepositTxMessage;
|
|
||||||
import bisq.core.trade.messages.InitMultisigRequest;
|
import bisq.core.trade.messages.InitMultisigRequest;
|
||||||
import bisq.core.trade.messages.InitTradeRequest;
|
import bisq.core.trade.messages.InitTradeRequest;
|
||||||
import bisq.core.trade.messages.InputsForDepositTxRequest;
|
|
||||||
import bisq.core.trade.messages.InputsForDepositTxResponse;
|
|
||||||
import bisq.core.trade.messages.MediatedPayoutTxPublishedMessage;
|
import bisq.core.trade.messages.MediatedPayoutTxPublishedMessage;
|
||||||
import bisq.core.trade.messages.MediatedPayoutTxSignatureMessage;
|
import bisq.core.trade.messages.MediatedPayoutTxSignatureMessage;
|
||||||
import bisq.core.trade.messages.PaymentAccountPayloadRequest;
|
import bisq.core.trade.messages.PaymentAccountPayloadRequest;
|
||||||
import bisq.core.trade.messages.PaymentReceivedMessage;
|
import bisq.core.trade.messages.PaymentReceivedMessage;
|
||||||
import bisq.core.trade.messages.PeerPublishedDelayedPayoutTxMessage;
|
|
||||||
import bisq.core.trade.messages.RefreshTradeStateRequest;
|
import bisq.core.trade.messages.RefreshTradeStateRequest;
|
||||||
import bisq.core.trade.messages.SignContractRequest;
|
import bisq.core.trade.messages.SignContractRequest;
|
||||||
import bisq.core.trade.messages.SignContractResponse;
|
import bisq.core.trade.messages.SignContractResponse;
|
||||||
|
@ -170,18 +163,6 @@ public class CoreNetworkProtoResolver extends CoreProtoResolver implements Netwo
|
||||||
return UpdateMultisigRequest.fromProto(proto.getUpdateMultisigRequest(), this, messageVersion);
|
return UpdateMultisigRequest.fromProto(proto.getUpdateMultisigRequest(), this, messageVersion);
|
||||||
case UPDATE_MULTISIG_RESPONSE:
|
case UPDATE_MULTISIG_RESPONSE:
|
||||||
return UpdateMultisigResponse.fromProto(proto.getUpdateMultisigResponse(), this, messageVersion);
|
return UpdateMultisigResponse.fromProto(proto.getUpdateMultisigResponse(), this, messageVersion);
|
||||||
case INPUTS_FOR_DEPOSIT_TX_REQUEST:
|
|
||||||
return InputsForDepositTxRequest.fromProto(proto.getInputsForDepositTxRequest(), this, messageVersion);
|
|
||||||
case INPUTS_FOR_DEPOSIT_TX_RESPONSE:
|
|
||||||
return InputsForDepositTxResponse.fromProto(proto.getInputsForDepositTxResponse(), this, messageVersion);
|
|
||||||
case DEPOSIT_TX_MESSAGE:
|
|
||||||
return DepositTxMessage.fromProto(proto.getDepositTxMessage(), messageVersion);
|
|
||||||
case DELAYED_PAYOUT_TX_SIGNATURE_REQUEST:
|
|
||||||
return DelayedPayoutTxSignatureRequest.fromProto(proto.getDelayedPayoutTxSignatureRequest(), messageVersion);
|
|
||||||
case DELAYED_PAYOUT_TX_SIGNATURE_RESPONSE:
|
|
||||||
return DelayedPayoutTxSignatureResponse.fromProto(proto.getDelayedPayoutTxSignatureResponse(), messageVersion);
|
|
||||||
case DEPOSIT_TX_AND_DELAYED_PAYOUT_TX_MESSAGE:
|
|
||||||
return DepositTxAndDelayedPayoutTxMessage.fromProto(proto.getDepositTxAndDelayedPayoutTxMessage(), messageVersion);
|
|
||||||
|
|
||||||
case PAYMENT_SENT_MESSAGE:
|
case PAYMENT_SENT_MESSAGE:
|
||||||
return PaymentSentMessage.fromProto(proto.getPaymentSentMessage(), messageVersion);
|
return PaymentSentMessage.fromProto(proto.getPaymentSentMessage(), messageVersion);
|
||||||
|
@ -190,8 +171,6 @@ public class CoreNetworkProtoResolver extends CoreProtoResolver implements Netwo
|
||||||
case PAYOUT_TX_PUBLISHED_MESSAGE:
|
case PAYOUT_TX_PUBLISHED_MESSAGE:
|
||||||
return PayoutTxPublishedMessage.fromProto(proto.getPayoutTxPublishedMessage(), messageVersion);
|
return PayoutTxPublishedMessage.fromProto(proto.getPayoutTxPublishedMessage(), messageVersion);
|
||||||
|
|
||||||
case PEER_PUBLISHED_DELAYED_PAYOUT_TX_MESSAGE:
|
|
||||||
return PeerPublishedDelayedPayoutTxMessage.fromProto(proto.getPeerPublishedDelayedPayoutTxMessage(), messageVersion);
|
|
||||||
case TRADER_SIGNED_WITNESS_MESSAGE:
|
case TRADER_SIGNED_WITNESS_MESSAGE:
|
||||||
return TraderSignedWitnessMessage.fromProto(proto.getTraderSignedWitnessMessage(), messageVersion);
|
return TraderSignedWitnessMessage.fromProto(proto.getTraderSignedWitnessMessage(), messageVersion);
|
||||||
|
|
||||||
|
|
|
@ -104,8 +104,8 @@ public abstract class Trade implements Tradable, Model {
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public enum State {
|
public enum State {
|
||||||
// #################### Phase INIT
|
|
||||||
// When trade protocol starts no funds are on stake
|
// trade initialization
|
||||||
PREPARATION(Phase.INIT),
|
PREPARATION(Phase.INIT),
|
||||||
MULTISIG_PREPARED(Phase.INIT),
|
MULTISIG_PREPARED(Phase.INIT),
|
||||||
MULTISIG_MADE(Phase.INIT),
|
MULTISIG_MADE(Phase.INIT),
|
||||||
|
@ -113,79 +113,47 @@ public abstract class Trade implements Tradable, Model {
|
||||||
CONTRACT_SIGNATURE_REQUESTED(Phase.INIT),
|
CONTRACT_SIGNATURE_REQUESTED(Phase.INIT),
|
||||||
CONTRACT_SIGNED(Phase.INIT),
|
CONTRACT_SIGNED(Phase.INIT),
|
||||||
|
|
||||||
// At first part maker/taker have different roles
|
// deposit requested
|
||||||
// taker perspective
|
SENT_PUBLISH_DEPOSIT_TX_REQUEST(Phase.TAKER_FEE_PUBLISHED),
|
||||||
// #################### Phase TAKER_FEE_PUBLISHED
|
SAW_ARRIVED_PUBLISH_DEPOSIT_TX_REQUEST(Phase.TAKER_FEE_PUBLISHED),
|
||||||
TAKER_PUBLISHED_TAKER_FEE_TX(Phase.TAKER_FEE_PUBLISHED),
|
STORED_IN_MAILBOX_PUBLISH_DEPOSIT_TX_REQUEST(Phase.TAKER_FEE_PUBLISHED), //not a mailbox msg, not used...
|
||||||
|
SEND_FAILED_PUBLISH_DEPOSIT_TX_REQUEST(Phase.TAKER_FEE_PUBLISHED),
|
||||||
|
|
||||||
// PUBLISH_DEPOSIT_TX_REQUEST
|
// deposit published
|
||||||
// maker perspective
|
SAW_DEPOSIT_TXS_IN_NETWORK(Phase.DEPOSIT_PUBLISHED), // TODO: seeing in network usually happens after arbitrator publishes
|
||||||
MAKER_SENT_PUBLISH_DEPOSIT_TX_REQUEST(Phase.TAKER_FEE_PUBLISHED),
|
ARBITRATOR_PUBLISHED_DEPOSIT_TXS(Phase.DEPOSIT_PUBLISHED),
|
||||||
MAKER_SAW_ARRIVED_PUBLISH_DEPOSIT_TX_REQUEST(Phase.TAKER_FEE_PUBLISHED),
|
|
||||||
MAKER_STORED_IN_MAILBOX_PUBLISH_DEPOSIT_TX_REQUEST(Phase.TAKER_FEE_PUBLISHED), //not a mailbox msg, not used...
|
|
||||||
MAKER_SEND_FAILED_PUBLISH_DEPOSIT_TX_REQUEST(Phase.TAKER_FEE_PUBLISHED),
|
|
||||||
|
|
||||||
// taker perspective
|
// deposit confirmed (TODO)
|
||||||
TAKER_RECEIVED_PUBLISH_DEPOSIT_TX_REQUEST(Phase.TAKER_FEE_PUBLISHED), // Not used anymore
|
|
||||||
|
|
||||||
// Alternatively the taker could have seen the deposit tx earlier before he received the DEPOSIT_TX_PUBLISHED_MSG
|
// deposit unlocked
|
||||||
TAKER_SAW_DEPOSIT_TX_IN_NETWORK(Phase.DEPOSIT_PUBLISHED),
|
DEPOSIT_TXS_UNLOCKED_IN_BLOCKCHAIN(Phase.DEPOSIT_UNLOCKED),
|
||||||
|
|
||||||
// #################### Phase DEPOSIT_PUBLISHED
|
// payment sent
|
||||||
// We changes order in trade protocol of publishing deposit tx and sending it to the peer.
|
|
||||||
// Now we send it first to the peer and only if that succeeds we publish it to avoid likelihood of
|
|
||||||
// failed trades. We do not want to change the order of the enum though so we keep it here as it was originally.
|
|
||||||
ARBITRATOR_PUBLISHED_DEPOSIT_TX(Phase.DEPOSIT_PUBLISHED),
|
|
||||||
|
|
||||||
// DEPOSIT_TX_PUBLISHED_MSG
|
|
||||||
// taker perspective
|
|
||||||
TAKER_SENT_DEPOSIT_TX_PUBLISHED_MSG(Phase.DEPOSIT_PUBLISHED),
|
|
||||||
TAKER_SAW_ARRIVED_DEPOSIT_TX_PUBLISHED_MSG(Phase.DEPOSIT_PUBLISHED),
|
|
||||||
TAKER_STORED_IN_MAILBOX_DEPOSIT_TX_PUBLISHED_MSG(Phase.DEPOSIT_PUBLISHED),
|
|
||||||
TAKER_SEND_FAILED_DEPOSIT_TX_PUBLISHED_MSG(Phase.DEPOSIT_PUBLISHED),
|
|
||||||
|
|
||||||
// maker perspective
|
|
||||||
MAKER_RECEIVED_DEPOSIT_TX_PUBLISHED_MSG(Phase.DEPOSIT_PUBLISHED),
|
|
||||||
|
|
||||||
// Alternatively the maker could have seen the deposit tx earlier before he received the DEPOSIT_TX_PUBLISHED_MSG
|
|
||||||
MAKER_SAW_DEPOSIT_TX_IN_NETWORK(Phase.DEPOSIT_PUBLISHED),
|
|
||||||
|
|
||||||
|
|
||||||
// #################### Phase DEPOSIT_CONFIRMED
|
|
||||||
DEPOSIT_UNLOCKED_IN_BLOCK_CHAIN(Phase.DEPOSIT_UNLOCKED),
|
|
||||||
|
|
||||||
|
|
||||||
// #################### Phase PAYMENT_SENT
|
|
||||||
BUYER_CONFIRMED_IN_UI_PAYMENT_SENT(Phase.PAYMENT_SENT),
|
BUYER_CONFIRMED_IN_UI_PAYMENT_SENT(Phase.PAYMENT_SENT),
|
||||||
BUYER_SENT_PAYMENT_SENT_MSG(Phase.PAYMENT_SENT),
|
BUYER_SENT_PAYMENT_SENT_MSG(Phase.PAYMENT_SENT),
|
||||||
BUYER_SAW_ARRIVED_PAYMENT_SENT_MSG(Phase.PAYMENT_SENT),
|
BUYER_SAW_ARRIVED_PAYMENT_SENT_MSG(Phase.PAYMENT_SENT),
|
||||||
BUYER_STORED_IN_MAILBOX_PAYMENT_SENT_MSG(Phase.PAYMENT_SENT),
|
BUYER_STORED_IN_MAILBOX_PAYMENT_SENT_MSG(Phase.PAYMENT_SENT),
|
||||||
BUYER_SEND_FAILED_PAYMENT_SENT_MSG(Phase.PAYMENT_SENT),
|
BUYER_SEND_FAILED_PAYMENT_SENT_MSG(Phase.PAYMENT_SENT),
|
||||||
|
|
||||||
SELLER_RECEIVED_PAYMENT_SENT_MSG(Phase.PAYMENT_SENT),
|
SELLER_RECEIVED_PAYMENT_SENT_MSG(Phase.PAYMENT_SENT),
|
||||||
|
|
||||||
// #################### Phase PAYMENT_RECEIVED
|
// payment received
|
||||||
// note that this state can also be triggered by auto confirmation feature
|
|
||||||
SELLER_CONFIRMED_IN_UI_PAYMENT_RECEIPT(Phase.PAYMENT_RECEIVED),
|
SELLER_CONFIRMED_IN_UI_PAYMENT_RECEIPT(Phase.PAYMENT_RECEIVED),
|
||||||
SELLER_SENT_PAYMENT_RECEIVED_MSG(Phase.PAYMENT_RECEIVED),
|
SELLER_SENT_PAYMENT_RECEIVED_MSG(Phase.PAYMENT_RECEIVED),
|
||||||
SELLER_SAW_ARRIVED_PAYMENT_RECEIVED_MSG(Phase.PAYMENT_RECEIVED),
|
SELLER_SAW_ARRIVED_PAYMENT_RECEIVED_MSG(Phase.PAYMENT_RECEIVED),
|
||||||
SELLER_STORED_IN_MAILBOX_PAYMENT_RECEIVED_MSG(Phase.PAYMENT_RECEIVED),
|
SELLER_STORED_IN_MAILBOX_PAYMENT_RECEIVED_MSG(Phase.PAYMENT_RECEIVED),
|
||||||
SELLER_SEND_FAILED_PAYMENT_RECEIVED_MSG(Phase.PAYMENT_RECEIVED),
|
SELLER_SEND_FAILED_PAYMENT_RECEIVED_MSG(Phase.PAYMENT_RECEIVED),
|
||||||
|
|
||||||
// #################### Phase PAYOUT_PUBLISHED
|
// payout published
|
||||||
SELLER_PUBLISHED_PAYOUT_TX(Phase.PAYOUT_PUBLISHED), // TODO (woodser): this enum is over used, like during arbitration
|
SELLER_PUBLISHED_PAYOUT_TX(Phase.PAYOUT_PUBLISHED), // TODO (woodser): this enum is over used, like during arbitration
|
||||||
SELLER_SENT_PAYOUT_TX_PUBLISHED_MSG(Phase.PAYOUT_PUBLISHED),
|
SELLER_SENT_PAYOUT_TX_PUBLISHED_MSG(Phase.PAYOUT_PUBLISHED),
|
||||||
SELLER_SAW_ARRIVED_PAYOUT_TX_PUBLISHED_MSG(Phase.PAYOUT_PUBLISHED),
|
SELLER_SAW_ARRIVED_PAYOUT_TX_PUBLISHED_MSG(Phase.PAYOUT_PUBLISHED),
|
||||||
SELLER_STORED_IN_MAILBOX_PAYOUT_TX_PUBLISHED_MSG(Phase.PAYOUT_PUBLISHED),
|
SELLER_STORED_IN_MAILBOX_PAYOUT_TX_PUBLISHED_MSG(Phase.PAYOUT_PUBLISHED),
|
||||||
SELLER_SEND_FAILED_PAYOUT_TX_PUBLISHED_MSG(Phase.PAYOUT_PUBLISHED),
|
SELLER_SEND_FAILED_PAYOUT_TX_PUBLISHED_MSG(Phase.PAYOUT_PUBLISHED),
|
||||||
|
|
||||||
BUYER_RECEIVED_PAYOUT_TX_PUBLISHED_MSG(Phase.PAYOUT_PUBLISHED),
|
BUYER_RECEIVED_PAYOUT_TX_PUBLISHED_MSG(Phase.PAYOUT_PUBLISHED),
|
||||||
// Alternatively the maker could have seen the payout tx earlier before he received the PAYOUT_TX_PUBLISHED_MSG
|
|
||||||
BUYER_SAW_PAYOUT_TX_IN_NETWORK(Phase.PAYOUT_PUBLISHED),
|
BUYER_SAW_PAYOUT_TX_IN_NETWORK(Phase.PAYOUT_PUBLISHED),
|
||||||
BUYER_PUBLISHED_PAYOUT_TX(Phase.PAYOUT_PUBLISHED),
|
BUYER_PUBLISHED_PAYOUT_TX(Phase.PAYOUT_PUBLISHED),
|
||||||
|
|
||||||
|
// trade completed
|
||||||
// #################### Phase WITHDRAWN
|
|
||||||
WITHDRAW_COMPLETED(Phase.WITHDRAWN);
|
WITHDRAW_COMPLETED(Phase.WITHDRAWN);
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
@ -891,7 +859,7 @@ public abstract class Trade implements Tradable, Model {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setStateIfValidTransitionTo(this instanceof MakerTrade ? Trade.State.MAKER_SAW_DEPOSIT_TX_IN_NETWORK : Trade.State.TAKER_SAW_DEPOSIT_TX_IN_NETWORK);
|
setStateIfValidTransitionTo(Trade.State.SAW_DEPOSIT_TXS_IN_NETWORK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -934,7 +902,7 @@ public abstract class Trade implements Tradable, Model {
|
||||||
xmrWalletService.removeWalletListener(depositTxListener); // remove listener when notified
|
xmrWalletService.removeWalletListener(depositTxListener); // remove listener when notified
|
||||||
depositTxListener = null; // prevent re-applying trade state in subsequent requests
|
depositTxListener = null; // prevent re-applying trade state in subsequent requests
|
||||||
} else if (txs.size() == 2) {
|
} else if (txs.size() == 2) {
|
||||||
setStateIfValidTransitionTo(this instanceof MakerTrade ? Trade.State.MAKER_SAW_DEPOSIT_TX_IN_NETWORK : Trade.State.TAKER_SAW_DEPOSIT_TX_IN_NETWORK);
|
setStateIfValidTransitionTo(Trade.State.SAW_DEPOSIT_TXS_IN_NETWORK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1488,7 +1456,7 @@ public abstract class Trade implements Tradable, Model {
|
||||||
// As setState is called here from the trade itself we cannot trigger a requestPersistence call.
|
// As setState is called here from the trade itself we cannot trigger a requestPersistence call.
|
||||||
// But as we get setupConfidenceListener called at startup anyway there is no issue if it would not be
|
// But as we get setupConfidenceListener called at startup anyway there is no issue if it would not be
|
||||||
// persisted in case the shutdown routine did not persist the trade.
|
// persisted in case the shutdown routine did not persist the trade.
|
||||||
setStateIfValidTransitionTo(State.DEPOSIT_UNLOCKED_IN_BLOCK_CHAIN); // TODO (woodser): for xmr this means deposit txs have unlocked after 10 confirmations
|
setStateIfValidTransitionTo(State.DEPOSIT_TXS_UNLOCKED_IN_BLOCKCHAIN); // TODO (woodser): for xmr this means deposit txs have unlocked after 10 confirmations
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,6 @@ import bisq.core.trade.messages.DepositRequest;
|
||||||
import bisq.core.trade.messages.DepositResponse;
|
import bisq.core.trade.messages.DepositResponse;
|
||||||
import bisq.core.trade.messages.InitMultisigRequest;
|
import bisq.core.trade.messages.InitMultisigRequest;
|
||||||
import bisq.core.trade.messages.InitTradeRequest;
|
import bisq.core.trade.messages.InitTradeRequest;
|
||||||
import bisq.core.trade.messages.InputsForDepositTxRequest;
|
|
||||||
import bisq.core.trade.messages.PaymentAccountPayloadRequest;
|
import bisq.core.trade.messages.PaymentAccountPayloadRequest;
|
||||||
import bisq.core.trade.messages.SignContractRequest;
|
import bisq.core.trade.messages.SignContractRequest;
|
||||||
import bisq.core.trade.messages.SignContractResponse;
|
import bisq.core.trade.messages.SignContractResponse;
|
||||||
|
@ -242,9 +241,7 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi
|
||||||
@Override
|
@Override
|
||||||
public void onDirectMessage(DecryptedMessageWithPubKey message, NodeAddress peer) {
|
public void onDirectMessage(DecryptedMessageWithPubKey message, NodeAddress peer) {
|
||||||
NetworkEnvelope networkEnvelope = message.getNetworkEnvelope();
|
NetworkEnvelope networkEnvelope = message.getNetworkEnvelope();
|
||||||
if (networkEnvelope instanceof InputsForDepositTxRequest) {
|
if (networkEnvelope instanceof InitTradeRequest) {
|
||||||
//handleTakeOfferRequest(peer, (InputsForDepositTxRequest) networkEnvelope); // ignore bisq requests
|
|
||||||
} else if (networkEnvelope instanceof InitTradeRequest) {
|
|
||||||
handleInitTradeRequest((InitTradeRequest) networkEnvelope, peer);
|
handleInitTradeRequest((InitTradeRequest) networkEnvelope, peer);
|
||||||
} else if (networkEnvelope instanceof InitMultisigRequest) {
|
} else if (networkEnvelope instanceof InitMultisigRequest) {
|
||||||
handleInitMultisigRequest((InitMultisigRequest) networkEnvelope, peer);
|
handleInitMultisigRequest((InitMultisigRequest) networkEnvelope, peer);
|
||||||
|
|
|
@ -1,98 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.messages;
|
|
||||||
|
|
||||||
import bisq.network.p2p.DirectMessage;
|
|
||||||
import bisq.network.p2p.NodeAddress;
|
|
||||||
|
|
||||||
import bisq.common.app.Version;
|
|
||||||
import bisq.common.util.Utilities;
|
|
||||||
|
|
||||||
import com.google.protobuf.ByteString;
|
|
||||||
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import lombok.Value;
|
|
||||||
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@Value
|
|
||||||
public final class DelayedPayoutTxSignatureRequest extends TradeMessage implements DirectMessage {
|
|
||||||
private final NodeAddress senderNodeAddress;
|
|
||||||
private final byte[] delayedPayoutTx;
|
|
||||||
private final byte[] delayedPayoutTxSellerSignature;
|
|
||||||
|
|
||||||
public DelayedPayoutTxSignatureRequest(String uid,
|
|
||||||
String tradeId,
|
|
||||||
NodeAddress senderNodeAddress,
|
|
||||||
byte[] delayedPayoutTx,
|
|
||||||
byte[] delayedPayoutTxSellerSignature) {
|
|
||||||
this(Version.getP2PMessageVersion(),
|
|
||||||
uid,
|
|
||||||
tradeId,
|
|
||||||
senderNodeAddress,
|
|
||||||
delayedPayoutTx,
|
|
||||||
delayedPayoutTxSellerSignature);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// PROTO BUFFER
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
private DelayedPayoutTxSignatureRequest(String messageVersion,
|
|
||||||
String uid,
|
|
||||||
String tradeId,
|
|
||||||
NodeAddress senderNodeAddress,
|
|
||||||
byte[] delayedPayoutTx,
|
|
||||||
byte[] delayedPayoutTxSellerSignature) {
|
|
||||||
super(messageVersion, tradeId, uid);
|
|
||||||
this.senderNodeAddress = senderNodeAddress;
|
|
||||||
this.delayedPayoutTx = delayedPayoutTx;
|
|
||||||
this.delayedPayoutTxSellerSignature = delayedPayoutTxSellerSignature;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public protobuf.NetworkEnvelope toProtoNetworkEnvelope() {
|
|
||||||
return getNetworkEnvelopeBuilder()
|
|
||||||
.setDelayedPayoutTxSignatureRequest(protobuf.DelayedPayoutTxSignatureRequest.newBuilder()
|
|
||||||
.setUid(uid)
|
|
||||||
.setTradeId(tradeId)
|
|
||||||
.setSenderNodeAddress(senderNodeAddress.toProtoMessage())
|
|
||||||
.setDelayedPayoutTx(ByteString.copyFrom(delayedPayoutTx))
|
|
||||||
.setDelayedPayoutTxSellerSignature(ByteString.copyFrom(delayedPayoutTxSellerSignature)))
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DelayedPayoutTxSignatureRequest fromProto(protobuf.DelayedPayoutTxSignatureRequest proto,
|
|
||||||
String messageVersion) {
|
|
||||||
return new DelayedPayoutTxSignatureRequest(messageVersion,
|
|
||||||
proto.getUid(),
|
|
||||||
proto.getTradeId(),
|
|
||||||
NodeAddress.fromProto(proto.getSenderNodeAddress()),
|
|
||||||
proto.getDelayedPayoutTx().toByteArray(),
|
|
||||||
proto.getDelayedPayoutTxSellerSignature().toByteArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "DelayedPayoutTxSignatureRequest{" +
|
|
||||||
"\n senderNodeAddress=" + senderNodeAddress +
|
|
||||||
",\n delayedPayoutTx=" + Utilities.bytesAsHexString(delayedPayoutTx) +
|
|
||||||
",\n delayedPayoutTxSellerSignature=" + Utilities.bytesAsHexString(delayedPayoutTxSellerSignature) +
|
|
||||||
"\n} " + super.toString();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,99 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.messages;
|
|
||||||
|
|
||||||
import bisq.network.p2p.DirectMessage;
|
|
||||||
import bisq.network.p2p.NodeAddress;
|
|
||||||
|
|
||||||
import bisq.common.app.Version;
|
|
||||||
import bisq.common.util.Utilities;
|
|
||||||
|
|
||||||
import com.google.protobuf.ByteString;
|
|
||||||
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import lombok.Value;
|
|
||||||
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@Value
|
|
||||||
public final class DelayedPayoutTxSignatureResponse extends TradeMessage implements DirectMessage {
|
|
||||||
private final NodeAddress senderNodeAddress;
|
|
||||||
private final byte[] delayedPayoutTxBuyerSignature;
|
|
||||||
private final byte[] depositTx;
|
|
||||||
|
|
||||||
public DelayedPayoutTxSignatureResponse(String uid,
|
|
||||||
String tradeId,
|
|
||||||
NodeAddress senderNodeAddress,
|
|
||||||
byte[] delayedPayoutTxBuyerSignature,
|
|
||||||
byte[] depositTx) {
|
|
||||||
this(Version.getP2PMessageVersion(),
|
|
||||||
uid,
|
|
||||||
tradeId,
|
|
||||||
senderNodeAddress,
|
|
||||||
delayedPayoutTxBuyerSignature,
|
|
||||||
depositTx);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// PROTO BUFFER
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
private DelayedPayoutTxSignatureResponse(String messageVersion,
|
|
||||||
String uid,
|
|
||||||
String tradeId,
|
|
||||||
NodeAddress senderNodeAddress,
|
|
||||||
byte[] delayedPayoutTxBuyerSignature,
|
|
||||||
byte[] depositTx) {
|
|
||||||
super(messageVersion, tradeId, uid);
|
|
||||||
this.senderNodeAddress = senderNodeAddress;
|
|
||||||
this.delayedPayoutTxBuyerSignature = delayedPayoutTxBuyerSignature;
|
|
||||||
this.depositTx = depositTx;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public protobuf.NetworkEnvelope toProtoNetworkEnvelope() {
|
|
||||||
return getNetworkEnvelopeBuilder()
|
|
||||||
.setDelayedPayoutTxSignatureResponse(protobuf.DelayedPayoutTxSignatureResponse.newBuilder()
|
|
||||||
.setUid(uid)
|
|
||||||
.setTradeId(tradeId)
|
|
||||||
.setSenderNodeAddress(senderNodeAddress.toProtoMessage())
|
|
||||||
.setDelayedPayoutTxBuyerSignature(ByteString.copyFrom(delayedPayoutTxBuyerSignature))
|
|
||||||
.setDepositTx(ByteString.copyFrom(depositTx))
|
|
||||||
)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DelayedPayoutTxSignatureResponse fromProto(protobuf.DelayedPayoutTxSignatureResponse proto,
|
|
||||||
String messageVersion) {
|
|
||||||
return new DelayedPayoutTxSignatureResponse(messageVersion,
|
|
||||||
proto.getUid(),
|
|
||||||
proto.getTradeId(),
|
|
||||||
NodeAddress.fromProto(proto.getSenderNodeAddress()),
|
|
||||||
proto.getDelayedPayoutTxBuyerSignature().toByteArray(),
|
|
||||||
proto.getDepositTx().toByteArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "DelayedPayoutTxSignatureResponse{" +
|
|
||||||
"\n senderNodeAddress=" + senderNodeAddress +
|
|
||||||
",\n delayedPayoutTxBuyerSignature=" + Utilities.bytesAsHexString(delayedPayoutTxBuyerSignature) +
|
|
||||||
",\n depositTx=" + Utilities.bytesAsHexString(depositTx) +
|
|
||||||
"\n} " + super.toString();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,98 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.messages;
|
|
||||||
|
|
||||||
import bisq.network.p2p.NodeAddress;
|
|
||||||
|
|
||||||
import bisq.common.app.Version;
|
|
||||||
import bisq.common.util.Utilities;
|
|
||||||
|
|
||||||
import com.google.protobuf.ByteString;
|
|
||||||
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import lombok.Value;
|
|
||||||
|
|
||||||
// It is the last message in the take offer phase. We use MailboxMessage instead of DirectMessage to add more tolerance
|
|
||||||
// in case of network issues and as the message does not trigger further protocol execution.
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@Value
|
|
||||||
public final class DepositTxAndDelayedPayoutTxMessage extends TradeMailboxMessage {
|
|
||||||
private final NodeAddress senderNodeAddress;
|
|
||||||
private final byte[] depositTx;
|
|
||||||
private final byte[] delayedPayoutTx;
|
|
||||||
|
|
||||||
public DepositTxAndDelayedPayoutTxMessage(String uid,
|
|
||||||
String tradeId,
|
|
||||||
NodeAddress senderNodeAddress,
|
|
||||||
byte[] depositTx,
|
|
||||||
byte[] delayedPayoutTx) {
|
|
||||||
this(Version.getP2PMessageVersion(),
|
|
||||||
uid,
|
|
||||||
tradeId,
|
|
||||||
senderNodeAddress,
|
|
||||||
depositTx,
|
|
||||||
delayedPayoutTx);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// PROTO BUFFER
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
private DepositTxAndDelayedPayoutTxMessage(String messageVersion,
|
|
||||||
String uid,
|
|
||||||
String tradeId,
|
|
||||||
NodeAddress senderNodeAddress,
|
|
||||||
byte[] depositTx,
|
|
||||||
byte[] delayedPayoutTx) {
|
|
||||||
super(messageVersion, tradeId, uid);
|
|
||||||
this.senderNodeAddress = senderNodeAddress;
|
|
||||||
this.depositTx = depositTx;
|
|
||||||
this.delayedPayoutTx = delayedPayoutTx;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public protobuf.NetworkEnvelope toProtoNetworkEnvelope() {
|
|
||||||
return getNetworkEnvelopeBuilder()
|
|
||||||
.setDepositTxAndDelayedPayoutTxMessage(protobuf.DepositTxAndDelayedPayoutTxMessage.newBuilder()
|
|
||||||
.setUid(uid)
|
|
||||||
.setTradeId(tradeId)
|
|
||||||
.setSenderNodeAddress(senderNodeAddress.toProtoMessage())
|
|
||||||
.setDepositTx(ByteString.copyFrom(depositTx))
|
|
||||||
.setDelayedPayoutTx(ByteString.copyFrom(delayedPayoutTx)))
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DepositTxAndDelayedPayoutTxMessage fromProto(protobuf.DepositTxAndDelayedPayoutTxMessage proto,
|
|
||||||
String messageVersion) {
|
|
||||||
return new DepositTxAndDelayedPayoutTxMessage(messageVersion,
|
|
||||||
proto.getUid(),
|
|
||||||
proto.getTradeId(),
|
|
||||||
NodeAddress.fromProto(proto.getSenderNodeAddress()),
|
|
||||||
proto.getDepositTx().toByteArray(),
|
|
||||||
proto.getDelayedPayoutTx().toByteArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "DepositTxAndDelayedPayoutTxMessage{" +
|
|
||||||
"\n senderNodeAddress=" + senderNodeAddress +
|
|
||||||
",\n depositTx=" + Utilities.bytesAsHexString(depositTx) +
|
|
||||||
",\n delayedPayoutTx=" + Utilities.bytesAsHexString(delayedPayoutTx) +
|
|
||||||
"\n} " + super.toString();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,86 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.messages;
|
|
||||||
|
|
||||||
import bisq.network.p2p.DirectMessage;
|
|
||||||
import bisq.network.p2p.NodeAddress;
|
|
||||||
|
|
||||||
import bisq.common.app.Version;
|
|
||||||
import bisq.common.proto.ProtoUtil;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import lombok.Value;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
// It is the last message in the take offer phase. We use MailboxMessage instead of DirectMessage to add more tolerance
|
|
||||||
// in case of network issues and as the message does not trigger further protocol execution.
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@Value
|
|
||||||
public final class DepositTxMessage extends TradeMessage implements DirectMessage {
|
|
||||||
private final NodeAddress senderNodeAddress;
|
|
||||||
@Nullable
|
|
||||||
private final String tradeFeeTxId;
|
|
||||||
@Nullable
|
|
||||||
private final String depositTxId;
|
|
||||||
|
|
||||||
public DepositTxMessage(String uid,
|
|
||||||
String tradeId,
|
|
||||||
NodeAddress senderNodeAddress,
|
|
||||||
String tradeFeeTxId,
|
|
||||||
String depositTxId) {
|
|
||||||
super(Version.getP2PMessageVersion(), tradeId, uid);
|
|
||||||
this.senderNodeAddress = senderNodeAddress;
|
|
||||||
this.tradeFeeTxId = tradeFeeTxId;
|
|
||||||
this.depositTxId = depositTxId;
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// PROTO BUFFER
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public protobuf.NetworkEnvelope toProtoNetworkEnvelope() {
|
|
||||||
protobuf.DepositTxMessage.Builder builder = protobuf.DepositTxMessage.newBuilder()
|
|
||||||
.setTradeId(tradeId)
|
|
||||||
.setSenderNodeAddress(senderNodeAddress.toProtoMessage())
|
|
||||||
.setUid(uid);
|
|
||||||
Optional.ofNullable(tradeFeeTxId).ifPresent(e -> builder.setTradeFeeTxId(tradeFeeTxId));
|
|
||||||
Optional.ofNullable(depositTxId).ifPresent(e -> builder.setDepositTxId(depositTxId));
|
|
||||||
return getNetworkEnvelopeBuilder().setDepositTxMessage(builder).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DepositTxMessage fromProto(protobuf.DepositTxMessage proto, String messageVersion) {
|
|
||||||
return new DepositTxMessage(proto.getUid(),
|
|
||||||
proto.getTradeId(),
|
|
||||||
NodeAddress.fromProto(proto.getSenderNodeAddress()),
|
|
||||||
ProtoUtil.stringOrNullFromProto(proto.getTradeFeeTxId()),
|
|
||||||
ProtoUtil.stringOrNullFromProto(proto.getDepositTxId()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "DepositTxMessage{" +
|
|
||||||
"\n senderNodeAddress=" + senderNodeAddress +
|
|
||||||
",\n tradeFeeTxId=" + tradeFeeTxId +
|
|
||||||
",\n depositTxId=" + depositTxId +
|
|
||||||
"\n} " + super.toString();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,229 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.messages;
|
|
||||||
|
|
||||||
import bisq.core.btc.model.RawTransactionInput;
|
|
||||||
import bisq.core.payment.payload.PaymentAccountPayload;
|
|
||||||
import bisq.core.proto.CoreProtoResolver;
|
|
||||||
|
|
||||||
import bisq.network.p2p.DirectMessage;
|
|
||||||
import bisq.network.p2p.NodeAddress;
|
|
||||||
|
|
||||||
import bisq.common.crypto.PubKeyRing;
|
|
||||||
import bisq.common.proto.ProtoUtil;
|
|
||||||
import bisq.common.util.Utilities;
|
|
||||||
|
|
||||||
import com.google.protobuf.ByteString;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import lombok.Value;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@Value
|
|
||||||
public final class InputsForDepositTxRequest extends TradeMessage implements DirectMessage {
|
|
||||||
private final NodeAddress senderNodeAddress;
|
|
||||||
private final long tradeAmount;
|
|
||||||
private final long tradePrice;
|
|
||||||
private final long txFee;
|
|
||||||
private final long takerFee;
|
|
||||||
private final List<RawTransactionInput> rawTransactionInputs;
|
|
||||||
private final long changeOutputValue;
|
|
||||||
@Nullable
|
|
||||||
private final String changeOutputAddress;
|
|
||||||
private final byte[] takerMultiSigPubKey;
|
|
||||||
private final String takerPayoutAddressString;
|
|
||||||
private final PubKeyRing takerPubKeyRing;
|
|
||||||
private final PaymentAccountPayload takerPaymentAccountPayload;
|
|
||||||
private final String takerAccountId;
|
|
||||||
private final String takerFeeTxId;
|
|
||||||
private final List<NodeAddress> acceptedArbitratorNodeAddresses;
|
|
||||||
private final List<NodeAddress> acceptedMediatorNodeAddresses;
|
|
||||||
private final List<NodeAddress> acceptedRefundAgentNodeAddresses;
|
|
||||||
@Nullable
|
|
||||||
private final NodeAddress arbitratorNodeAddress;
|
|
||||||
private final NodeAddress mediatorNodeAddress;
|
|
||||||
private final NodeAddress refundAgentNodeAddress;
|
|
||||||
|
|
||||||
private final byte[] accountAgeWitnessSignatureOfOfferId;
|
|
||||||
private final long currentDate;
|
|
||||||
|
|
||||||
public InputsForDepositTxRequest(String tradeId,
|
|
||||||
NodeAddress senderNodeAddress,
|
|
||||||
long tradeAmount,
|
|
||||||
long tradePrice,
|
|
||||||
long txFee,
|
|
||||||
long takerFee,
|
|
||||||
List<RawTransactionInput> rawTransactionInputs,
|
|
||||||
long changeOutputValue,
|
|
||||||
@Nullable String changeOutputAddress,
|
|
||||||
byte[] takerMultiSigPubKey,
|
|
||||||
String takerPayoutAddressString,
|
|
||||||
PubKeyRing takerPubKeyRing,
|
|
||||||
PaymentAccountPayload takerPaymentAccountPayload,
|
|
||||||
String takerAccountId,
|
|
||||||
String takerFeeTxId,
|
|
||||||
List<NodeAddress> acceptedArbitratorNodeAddresses,
|
|
||||||
List<NodeAddress> acceptedMediatorNodeAddresses,
|
|
||||||
List<NodeAddress> acceptedRefundAgentNodeAddresses,
|
|
||||||
@Nullable NodeAddress arbitratorNodeAddress,
|
|
||||||
NodeAddress mediatorNodeAddress,
|
|
||||||
NodeAddress refundAgentNodeAddress,
|
|
||||||
String uid,
|
|
||||||
String messageVersion,
|
|
||||||
byte[] accountAgeWitnessSignatureOfOfferId,
|
|
||||||
long currentDate) {
|
|
||||||
super(messageVersion, tradeId, uid);
|
|
||||||
this.senderNodeAddress = senderNodeAddress;
|
|
||||||
this.tradeAmount = tradeAmount;
|
|
||||||
this.tradePrice = tradePrice;
|
|
||||||
this.txFee = txFee;
|
|
||||||
this.takerFee = takerFee;
|
|
||||||
this.rawTransactionInputs = rawTransactionInputs;
|
|
||||||
this.changeOutputValue = changeOutputValue;
|
|
||||||
this.changeOutputAddress = changeOutputAddress;
|
|
||||||
this.takerMultiSigPubKey = takerMultiSigPubKey;
|
|
||||||
this.takerPayoutAddressString = takerPayoutAddressString;
|
|
||||||
this.takerPubKeyRing = takerPubKeyRing;
|
|
||||||
this.takerPaymentAccountPayload = takerPaymentAccountPayload;
|
|
||||||
this.takerAccountId = takerAccountId;
|
|
||||||
this.takerFeeTxId = takerFeeTxId;
|
|
||||||
this.acceptedArbitratorNodeAddresses = acceptedArbitratorNodeAddresses;
|
|
||||||
this.acceptedMediatorNodeAddresses = acceptedMediatorNodeAddresses;
|
|
||||||
this.acceptedRefundAgentNodeAddresses = acceptedRefundAgentNodeAddresses;
|
|
||||||
this.arbitratorNodeAddress = arbitratorNodeAddress;
|
|
||||||
this.mediatorNodeAddress = mediatorNodeAddress;
|
|
||||||
this.refundAgentNodeAddress = refundAgentNodeAddress;
|
|
||||||
this.accountAgeWitnessSignatureOfOfferId = accountAgeWitnessSignatureOfOfferId;
|
|
||||||
this.currentDate = currentDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// PROTO BUFFER
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public protobuf.NetworkEnvelope toProtoNetworkEnvelope() {
|
|
||||||
protobuf.InputsForDepositTxRequest.Builder builder = protobuf.InputsForDepositTxRequest.newBuilder()
|
|
||||||
.setTradeId(tradeId)
|
|
||||||
.setSenderNodeAddress(senderNodeAddress.toProtoMessage())
|
|
||||||
.setTradeAmount(tradeAmount)
|
|
||||||
.setTradePrice(tradePrice)
|
|
||||||
.setTxFee(txFee)
|
|
||||||
.setTakerFee(takerFee)
|
|
||||||
.addAllRawTransactionInputs(rawTransactionInputs.stream()
|
|
||||||
.map(RawTransactionInput::toProtoMessage).collect(Collectors.toList()))
|
|
||||||
.setChangeOutputValue(changeOutputValue)
|
|
||||||
.setTakerMultiSigPubKey(ByteString.copyFrom(takerMultiSigPubKey))
|
|
||||||
.setTakerPayoutAddressString(takerPayoutAddressString)
|
|
||||||
.setTakerPubKeyRing(takerPubKeyRing.toProtoMessage())
|
|
||||||
.setTakerPaymentAccountPayload((protobuf.PaymentAccountPayload) takerPaymentAccountPayload.toProtoMessage())
|
|
||||||
.setTakerAccountId(takerAccountId)
|
|
||||||
.setTakerFeeTxId(takerFeeTxId)
|
|
||||||
.addAllAcceptedArbitratorNodeAddresses(acceptedArbitratorNodeAddresses.stream()
|
|
||||||
.map(NodeAddress::toProtoMessage).collect(Collectors.toList()))
|
|
||||||
.addAllAcceptedMediatorNodeAddresses(acceptedMediatorNodeAddresses.stream()
|
|
||||||
.map(NodeAddress::toProtoMessage).collect(Collectors.toList()))
|
|
||||||
.addAllAcceptedRefundAgentNodeAddresses(acceptedRefundAgentNodeAddresses.stream()
|
|
||||||
.map(NodeAddress::toProtoMessage).collect(Collectors.toList()))
|
|
||||||
.setMediatorNodeAddress(mediatorNodeAddress.toProtoMessage())
|
|
||||||
.setRefundAgentNodeAddress(refundAgentNodeAddress.toProtoMessage())
|
|
||||||
.setUid(uid)
|
|
||||||
.setAccountAgeWitnessSignatureOfOfferId(ByteString.copyFrom(accountAgeWitnessSignatureOfOfferId))
|
|
||||||
.setCurrentDate(currentDate);
|
|
||||||
|
|
||||||
Optional.ofNullable(changeOutputAddress).ifPresent(builder::setChangeOutputAddress);
|
|
||||||
Optional.ofNullable(arbitratorNodeAddress).ifPresent(e -> builder.setArbitratorNodeAddress(arbitratorNodeAddress.toProtoMessage()));
|
|
||||||
return getNetworkEnvelopeBuilder().setInputsForDepositTxRequest(builder).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static InputsForDepositTxRequest fromProto(protobuf.InputsForDepositTxRequest proto,
|
|
||||||
CoreProtoResolver coreProtoResolver,
|
|
||||||
String messageVersion) {
|
|
||||||
List<RawTransactionInput> rawTransactionInputs = proto.getRawTransactionInputsList().stream()
|
|
||||||
.map(rawTransactionInput -> new RawTransactionInput(rawTransactionInput.getIndex(),
|
|
||||||
rawTransactionInput.getParentTransaction().toByteArray(), rawTransactionInput.getValue()))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
List<NodeAddress> acceptedArbitratorNodeAddresses = proto.getAcceptedArbitratorNodeAddressesList().stream()
|
|
||||||
.map(NodeAddress::fromProto).collect(Collectors.toList());
|
|
||||||
List<NodeAddress> acceptedMediatorNodeAddresses = proto.getAcceptedMediatorNodeAddressesList().stream()
|
|
||||||
.map(NodeAddress::fromProto).collect(Collectors.toList());
|
|
||||||
List<NodeAddress> acceptedRefundAgentNodeAddresses = proto.getAcceptedRefundAgentNodeAddressesList().stream()
|
|
||||||
.map(NodeAddress::fromProto).collect(Collectors.toList());
|
|
||||||
|
|
||||||
return new InputsForDepositTxRequest(proto.getTradeId(),
|
|
||||||
NodeAddress.fromProto(proto.getSenderNodeAddress()),
|
|
||||||
proto.getTradeAmount(),
|
|
||||||
proto.getTradePrice(),
|
|
||||||
proto.getTxFee(),
|
|
||||||
proto.getTakerFee(),
|
|
||||||
rawTransactionInputs,
|
|
||||||
proto.getChangeOutputValue(),
|
|
||||||
ProtoUtil.stringOrNullFromProto(proto.getChangeOutputAddress()),
|
|
||||||
proto.getTakerMultiSigPubKey().toByteArray(),
|
|
||||||
proto.getTakerPayoutAddressString(),
|
|
||||||
PubKeyRing.fromProto(proto.getTakerPubKeyRing()),
|
|
||||||
coreProtoResolver.fromProto(proto.getTakerPaymentAccountPayload()),
|
|
||||||
proto.getTakerAccountId(),
|
|
||||||
proto.getTakerFeeTxId(),
|
|
||||||
acceptedArbitratorNodeAddresses,
|
|
||||||
acceptedMediatorNodeAddresses,
|
|
||||||
acceptedRefundAgentNodeAddresses,
|
|
||||||
NodeAddress.fromProto(proto.getArbitratorNodeAddress()),
|
|
||||||
NodeAddress.fromProto(proto.getMediatorNodeAddress()),
|
|
||||||
NodeAddress.fromProto(proto.getRefundAgentNodeAddress()),
|
|
||||||
proto.getUid(),
|
|
||||||
messageVersion,
|
|
||||||
ProtoUtil.byteArrayOrNullFromProto(proto.getAccountAgeWitnessSignatureOfOfferId()),
|
|
||||||
proto.getCurrentDate());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "InputsForDepositTxRequest{" +
|
|
||||||
"\n senderNodeAddress=" + senderNodeAddress +
|
|
||||||
",\n tradeAmount=" + tradeAmount +
|
|
||||||
",\n tradePrice=" + tradePrice +
|
|
||||||
",\n txFee=" + txFee +
|
|
||||||
",\n takerFee=" + takerFee +
|
|
||||||
",\n rawTransactionInputs=" + rawTransactionInputs +
|
|
||||||
",\n changeOutputValue=" + changeOutputValue +
|
|
||||||
",\n changeOutputAddress='" + changeOutputAddress + '\'' +
|
|
||||||
",\n takerMultiSigPubKey=" + Utilities.bytesAsHexString(takerMultiSigPubKey) +
|
|
||||||
",\n takerPayoutAddressString='" + takerPayoutAddressString + '\'' +
|
|
||||||
",\n takerPubKeyRing=" + takerPubKeyRing +
|
|
||||||
",\n takerPaymentAccountPayload=" + takerPaymentAccountPayload +
|
|
||||||
",\n takerAccountId='" + takerAccountId + '\'' +
|
|
||||||
",\n takerFeeTxId='" + takerFeeTxId + '\'' +
|
|
||||||
",\n acceptedArbitratorNodeAddresses=" + acceptedArbitratorNodeAddresses +
|
|
||||||
",\n acceptedMediatorNodeAddresses=" + acceptedMediatorNodeAddresses +
|
|
||||||
",\n acceptedRefundAgentNodeAddresses=" + acceptedRefundAgentNodeAddresses +
|
|
||||||
",\n arbitratorNodeAddress=" + arbitratorNodeAddress +
|
|
||||||
",\n mediatorNodeAddress=" + mediatorNodeAddress +
|
|
||||||
",\n refundAgentNodeAddress=" + refundAgentNodeAddress +
|
|
||||||
",\n accountAgeWitnessSignatureOfOfferId=" + Utilities.bytesAsHexString(accountAgeWitnessSignatureOfOfferId) +
|
|
||||||
",\n currentDate=" + currentDate +
|
|
||||||
"\n} " + super.toString();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,193 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.messages;
|
|
||||||
|
|
||||||
import bisq.core.btc.model.RawTransactionInput;
|
|
||||||
import bisq.core.payment.payload.PaymentAccountPayload;
|
|
||||||
import bisq.core.proto.CoreProtoResolver;
|
|
||||||
|
|
||||||
import bisq.network.p2p.DirectMessage;
|
|
||||||
import bisq.network.p2p.NodeAddress;
|
|
||||||
|
|
||||||
import bisq.common.app.Version;
|
|
||||||
import bisq.common.proto.ProtoUtil;
|
|
||||||
import bisq.common.util.Utilities;
|
|
||||||
|
|
||||||
import com.google.protobuf.ByteString;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import lombok.Value;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@Value
|
|
||||||
public final class InputsForDepositTxResponse extends TradeMessage implements DirectMessage {
|
|
||||||
private final PaymentAccountPayload makerPaymentAccountPayload;
|
|
||||||
private final String makerAccountId;
|
|
||||||
private final byte[] makerMultiSigPubKey;
|
|
||||||
private final String makerContractAsJson;
|
|
||||||
private final String makerContractSignature;
|
|
||||||
private final String makerPayoutAddressString;
|
|
||||||
private final byte[] preparedDepositTx;
|
|
||||||
private final List<RawTransactionInput> makerInputs;
|
|
||||||
private final NodeAddress senderNodeAddress;
|
|
||||||
|
|
||||||
// added in v 0.6. can be null if we trade with an older peer
|
|
||||||
@Nullable
|
|
||||||
private final byte[] accountAgeWitnessSignatureOfPreparedDepositTx;
|
|
||||||
private final long currentDate;
|
|
||||||
private final long lockTime;
|
|
||||||
|
|
||||||
public InputsForDepositTxResponse(String tradeId,
|
|
||||||
PaymentAccountPayload makerPaymentAccountPayload,
|
|
||||||
String makerAccountId,
|
|
||||||
byte[] makerMultiSigPubKey,
|
|
||||||
String makerContractAsJson,
|
|
||||||
String makerContractSignature,
|
|
||||||
String makerPayoutAddressString,
|
|
||||||
byte[] preparedDepositTx,
|
|
||||||
List<RawTransactionInput> makerInputs,
|
|
||||||
NodeAddress senderNodeAddress,
|
|
||||||
String uid,
|
|
||||||
@Nullable byte[] accountAgeWitnessSignatureOfPreparedDepositTx,
|
|
||||||
long currentDate,
|
|
||||||
long lockTime) {
|
|
||||||
this(tradeId,
|
|
||||||
makerPaymentAccountPayload,
|
|
||||||
makerAccountId,
|
|
||||||
makerMultiSigPubKey,
|
|
||||||
makerContractAsJson,
|
|
||||||
makerContractSignature,
|
|
||||||
makerPayoutAddressString,
|
|
||||||
preparedDepositTx,
|
|
||||||
makerInputs,
|
|
||||||
senderNodeAddress,
|
|
||||||
uid,
|
|
||||||
Version.getP2PMessageVersion(),
|
|
||||||
accountAgeWitnessSignatureOfPreparedDepositTx,
|
|
||||||
currentDate,
|
|
||||||
lockTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// PROTO BUFFER
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
private InputsForDepositTxResponse(String tradeId,
|
|
||||||
PaymentAccountPayload makerPaymentAccountPayload,
|
|
||||||
String makerAccountId,
|
|
||||||
byte[] makerMultiSigPubKey,
|
|
||||||
String makerContractAsJson,
|
|
||||||
String makerContractSignature,
|
|
||||||
String makerPayoutAddressString,
|
|
||||||
byte[] preparedDepositTx,
|
|
||||||
List<RawTransactionInput> makerInputs,
|
|
||||||
NodeAddress senderNodeAddress,
|
|
||||||
String uid,
|
|
||||||
String messageVersion,
|
|
||||||
@Nullable byte[] accountAgeWitnessSignatureOfPreparedDepositTx,
|
|
||||||
long currentDate,
|
|
||||||
long lockTime) {
|
|
||||||
super(messageVersion, tradeId, uid);
|
|
||||||
this.makerPaymentAccountPayload = makerPaymentAccountPayload;
|
|
||||||
this.makerAccountId = makerAccountId;
|
|
||||||
this.makerMultiSigPubKey = makerMultiSigPubKey;
|
|
||||||
this.makerContractAsJson = makerContractAsJson;
|
|
||||||
this.makerContractSignature = makerContractSignature;
|
|
||||||
this.makerPayoutAddressString = makerPayoutAddressString;
|
|
||||||
this.preparedDepositTx = preparedDepositTx;
|
|
||||||
this.makerInputs = makerInputs;
|
|
||||||
this.senderNodeAddress = senderNodeAddress;
|
|
||||||
this.accountAgeWitnessSignatureOfPreparedDepositTx = accountAgeWitnessSignatureOfPreparedDepositTx;
|
|
||||||
this.currentDate = currentDate;
|
|
||||||
this.lockTime = lockTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public protobuf.NetworkEnvelope toProtoNetworkEnvelope() {
|
|
||||||
final protobuf.InputsForDepositTxResponse.Builder builder = protobuf.InputsForDepositTxResponse.newBuilder()
|
|
||||||
.setTradeId(tradeId)
|
|
||||||
.setMakerPaymentAccountPayload((protobuf.PaymentAccountPayload) makerPaymentAccountPayload.toProtoMessage())
|
|
||||||
.setMakerAccountId(makerAccountId)
|
|
||||||
.setMakerMultiSigPubKey(ByteString.copyFrom(makerMultiSigPubKey))
|
|
||||||
.setMakerContractAsJson(makerContractAsJson)
|
|
||||||
.setMakerContractSignature(makerContractSignature)
|
|
||||||
.setMakerPayoutAddressString(makerPayoutAddressString)
|
|
||||||
.setPreparedDepositTx(ByteString.copyFrom(preparedDepositTx))
|
|
||||||
.addAllMakerInputs(makerInputs.stream().map(RawTransactionInput::toProtoMessage).collect(Collectors.toList()))
|
|
||||||
.setSenderNodeAddress(senderNodeAddress.toProtoMessage())
|
|
||||||
.setUid(uid)
|
|
||||||
.setLockTime(lockTime);
|
|
||||||
|
|
||||||
Optional.ofNullable(accountAgeWitnessSignatureOfPreparedDepositTx).ifPresent(e -> builder.setAccountAgeWitnessSignatureOfPreparedDepositTx(ByteString.copyFrom(e)));
|
|
||||||
builder.setCurrentDate(currentDate);
|
|
||||||
|
|
||||||
return getNetworkEnvelopeBuilder()
|
|
||||||
.setInputsForDepositTxResponse(builder)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static InputsForDepositTxResponse fromProto(protobuf.InputsForDepositTxResponse proto, CoreProtoResolver coreProtoResolver, String messageVersion) {
|
|
||||||
List<RawTransactionInput> makerInputs = proto.getMakerInputsList().stream()
|
|
||||||
.map(RawTransactionInput::fromProto)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
return new InputsForDepositTxResponse(proto.getTradeId(),
|
|
||||||
coreProtoResolver.fromProto(proto.getMakerPaymentAccountPayload()),
|
|
||||||
proto.getMakerAccountId(),
|
|
||||||
proto.getMakerMultiSigPubKey().toByteArray(),
|
|
||||||
proto.getMakerContractAsJson(),
|
|
||||||
proto.getMakerContractSignature(),
|
|
||||||
proto.getMakerPayoutAddressString(),
|
|
||||||
proto.getPreparedDepositTx().toByteArray(),
|
|
||||||
makerInputs,
|
|
||||||
NodeAddress.fromProto(proto.getSenderNodeAddress()),
|
|
||||||
proto.getUid(),
|
|
||||||
messageVersion,
|
|
||||||
ProtoUtil.byteArrayOrNullFromProto(proto.getAccountAgeWitnessSignatureOfPreparedDepositTx()),
|
|
||||||
proto.getCurrentDate(),
|
|
||||||
proto.getLockTime());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "InputsForDepositTxResponse{" +
|
|
||||||
"\n makerPaymentAccountPayload=" + makerPaymentAccountPayload +
|
|
||||||
",\n makerAccountId='" + makerAccountId + '\'' +
|
|
||||||
",\n makerMultiSigPubKey=" + Utilities.bytesAsHexString(makerMultiSigPubKey) +
|
|
||||||
",\n makerContractAsJson='" + makerContractAsJson + '\'' +
|
|
||||||
",\n makerContractSignature='" + makerContractSignature + '\'' +
|
|
||||||
",\n makerPayoutAddressString='" + makerPayoutAddressString + '\'' +
|
|
||||||
",\n preparedDepositTx=" + Utilities.bytesAsHexString(preparedDepositTx) +
|
|
||||||
",\n makerInputs=" + makerInputs +
|
|
||||||
",\n senderNodeAddress=" + senderNodeAddress +
|
|
||||||
",\n uid='" + uid + '\'' +
|
|
||||||
",\n accountAgeWitnessSignatureOfPreparedDepositTx=" + Utilities.bytesAsHexString(accountAgeWitnessSignatureOfPreparedDepositTx) +
|
|
||||||
",\n currentDate=" + new Date(currentDate) +
|
|
||||||
",\n lockTime=" + lockTime +
|
|
||||||
"\n} " + super.toString();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,76 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.messages;
|
|
||||||
|
|
||||||
import bisq.network.p2p.NodeAddress;
|
|
||||||
|
|
||||||
import bisq.common.app.Version;
|
|
||||||
|
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import lombok.Value;
|
|
||||||
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@Value
|
|
||||||
public final class PeerPublishedDelayedPayoutTxMessage extends TradeMailboxMessage {
|
|
||||||
private final NodeAddress senderNodeAddress;
|
|
||||||
|
|
||||||
public PeerPublishedDelayedPayoutTxMessage(String uid,
|
|
||||||
String tradeId,
|
|
||||||
NodeAddress senderNodeAddress) {
|
|
||||||
this(Version.getP2PMessageVersion(),
|
|
||||||
uid,
|
|
||||||
tradeId,
|
|
||||||
senderNodeAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// PROTO BUFFER
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
private PeerPublishedDelayedPayoutTxMessage(String messageVersion,
|
|
||||||
String uid,
|
|
||||||
String tradeId,
|
|
||||||
NodeAddress senderNodeAddress) {
|
|
||||||
super(messageVersion, tradeId, uid);
|
|
||||||
this.senderNodeAddress = senderNodeAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public protobuf.NetworkEnvelope toProtoNetworkEnvelope() {
|
|
||||||
final protobuf.PeerPublishedDelayedPayoutTxMessage.Builder builder = protobuf.PeerPublishedDelayedPayoutTxMessage.newBuilder();
|
|
||||||
builder.setUid(uid)
|
|
||||||
.setTradeId(tradeId)
|
|
||||||
.setSenderNodeAddress(senderNodeAddress.toProtoMessage());
|
|
||||||
return getNetworkEnvelopeBuilder().setPeerPublishedDelayedPayoutTxMessage(builder).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PeerPublishedDelayedPayoutTxMessage fromProto(protobuf.PeerPublishedDelayedPayoutTxMessage proto, String messageVersion) {
|
|
||||||
return new PeerPublishedDelayedPayoutTxMessage(messageVersion,
|
|
||||||
proto.getUid(),
|
|
||||||
proto.getTradeId(),
|
|
||||||
NodeAddress.fromProto(proto.getSenderNodeAddress()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "PeerPublishedDelayedPayoutTxMessage{" +
|
|
||||||
"\n senderNodeAddress=" + senderNodeAddress +
|
|
||||||
"\n} " + super.toString();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -75,7 +75,7 @@ public class ArbitratorProtocol extends DisputeProtocol {
|
||||||
ArbitratorProcessesDepositRequest.class)
|
ArbitratorProcessesDepositRequest.class)
|
||||||
.using(new TradeTaskRunner(trade,
|
.using(new TradeTaskRunner(trade,
|
||||||
() -> {
|
() -> {
|
||||||
if (trade.getState() == Trade.State.ARBITRATOR_PUBLISHED_DEPOSIT_TX) {
|
if (trade.getState() == Trade.State.ARBITRATOR_PUBLISHED_DEPOSIT_TXS) {
|
||||||
stopTimeout();
|
stopTimeout();
|
||||||
this.errorMessageHandler = null;
|
this.errorMessageHandler = null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,26 +19,16 @@ package bisq.core.trade.protocol;
|
||||||
|
|
||||||
import bisq.core.trade.BuyerAsMakerTrade;
|
import bisq.core.trade.BuyerAsMakerTrade;
|
||||||
import bisq.core.trade.Trade;
|
import bisq.core.trade.Trade;
|
||||||
import bisq.core.trade.messages.DelayedPayoutTxSignatureRequest;
|
|
||||||
import bisq.core.trade.messages.DepositResponse;
|
import bisq.core.trade.messages.DepositResponse;
|
||||||
import bisq.core.trade.messages.DepositTxAndDelayedPayoutTxMessage;
|
|
||||||
import bisq.core.trade.messages.InitMultisigRequest;
|
import bisq.core.trade.messages.InitMultisigRequest;
|
||||||
import bisq.core.trade.messages.InitTradeRequest;
|
import bisq.core.trade.messages.InitTradeRequest;
|
||||||
import bisq.core.trade.messages.PaymentAccountPayloadRequest;
|
import bisq.core.trade.messages.PaymentAccountPayloadRequest;
|
||||||
import bisq.core.trade.messages.PaymentReceivedMessage;
|
import bisq.core.trade.messages.PaymentReceivedMessage;
|
||||||
import bisq.core.trade.messages.SignContractRequest;
|
import bisq.core.trade.messages.SignContractRequest;
|
||||||
import bisq.core.trade.messages.SignContractResponse;
|
import bisq.core.trade.messages.SignContractResponse;
|
||||||
|
import bisq.core.trade.protocol.tasks.MakerSendsInitTradeRequestIfUnreserved;
|
||||||
import bisq.core.trade.protocol.tasks.ProcessInitTradeRequest;
|
import bisq.core.trade.protocol.tasks.ProcessInitTradeRequest;
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
import bisq.core.trade.protocol.tasks.TradeTask;
|
||||||
import bisq.core.trade.protocol.tasks.buyer.BuyerFinalizesDelayedPayoutTx;
|
|
||||||
import bisq.core.trade.protocol.tasks.buyer.BuyerProcessDelayedPayoutTxSignatureRequest;
|
|
||||||
import bisq.core.trade.protocol.tasks.buyer.BuyerSendsDelayedPayoutTxSignatureResponse;
|
|
||||||
import bisq.core.trade.protocol.tasks.buyer.BuyerSignsDelayedPayoutTx;
|
|
||||||
import bisq.core.trade.protocol.tasks.buyer.BuyerVerifiesPreparedDelayedPayoutTx;
|
|
||||||
import bisq.core.trade.protocol.tasks.maker.MaybeRemoveOpenOffer;
|
|
||||||
import bisq.core.trade.protocol.tasks.maker.MakerSendsInitTradeRequestIfUnreserved;
|
|
||||||
import bisq.core.trade.protocol.tasks.maker.MakerVerifyTakerFeePayment;
|
|
||||||
|
|
||||||
import bisq.network.p2p.NodeAddress;
|
import bisq.network.p2p.NodeAddress;
|
||||||
import bisq.common.handlers.ErrorMessageHandler;
|
import bisq.common.handlers.ErrorMessageHandler;
|
||||||
import bisq.common.handlers.ResultHandler;
|
import bisq.common.handlers.ResultHandler;
|
||||||
|
@ -134,37 +124,4 @@ public class BuyerAsMakerProtocol extends BuyerProtocol implements MakerProtocol
|
||||||
protected void handle(PaymentReceivedMessage message, NodeAddress peer) {
|
protected void handle(PaymentReceivedMessage message, NodeAddress peer) {
|
||||||
super.handle(message, peer);
|
super.handle(message, peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Class<? extends TradeTask> getVerifyPeersFeePaymentClass() {
|
|
||||||
return MakerVerifyTakerFeePayment.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO (woodser): remove or ignore any unsupported requests
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Incoming messages Take offer process
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void handle(DelayedPayoutTxSignatureRequest message, NodeAddress peer) {
|
|
||||||
expect(phase(Trade.Phase.TAKER_FEE_PUBLISHED)
|
|
||||||
.with(message)
|
|
||||||
.from(peer))
|
|
||||||
.setup(tasks(
|
|
||||||
MaybeRemoveOpenOffer.class,
|
|
||||||
BuyerProcessDelayedPayoutTxSignatureRequest.class,
|
|
||||||
BuyerVerifiesPreparedDelayedPayoutTx.class,
|
|
||||||
BuyerSignsDelayedPayoutTx.class,
|
|
||||||
BuyerFinalizesDelayedPayoutTx.class,
|
|
||||||
BuyerSendsDelayedPayoutTxSignatureResponse.class)
|
|
||||||
.withTimeout(60))
|
|
||||||
.executeTasks(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// We keep the handler here in as well to make it more transparent which messages we expect
|
|
||||||
@Override
|
|
||||||
protected void handle(DepositTxAndDelayedPayoutTxMessage message, NodeAddress peer) {
|
|
||||||
super.handle(message, peer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,32 +22,14 @@ import bisq.core.offer.Offer;
|
||||||
import bisq.core.trade.BuyerAsTakerTrade;
|
import bisq.core.trade.BuyerAsTakerTrade;
|
||||||
import bisq.core.trade.Trade;
|
import bisq.core.trade.Trade;
|
||||||
import bisq.core.trade.handlers.TradeResultHandler;
|
import bisq.core.trade.handlers.TradeResultHandler;
|
||||||
import bisq.core.trade.messages.DelayedPayoutTxSignatureRequest;
|
|
||||||
import bisq.core.trade.messages.DepositResponse;
|
import bisq.core.trade.messages.DepositResponse;
|
||||||
import bisq.core.trade.messages.DepositTxAndDelayedPayoutTxMessage;
|
|
||||||
import bisq.core.trade.messages.InitMultisigRequest;
|
import bisq.core.trade.messages.InitMultisigRequest;
|
||||||
import bisq.core.trade.messages.InputsForDepositTxResponse;
|
|
||||||
import bisq.core.trade.messages.PaymentAccountPayloadRequest;
|
import bisq.core.trade.messages.PaymentAccountPayloadRequest;
|
||||||
import bisq.core.trade.messages.PaymentReceivedMessage;
|
import bisq.core.trade.messages.PaymentReceivedMessage;
|
||||||
import bisq.core.trade.messages.SignContractRequest;
|
import bisq.core.trade.messages.SignContractRequest;
|
||||||
import bisq.core.trade.messages.SignContractResponse;
|
import bisq.core.trade.messages.SignContractResponse;
|
||||||
import bisq.core.trade.messages.TradeMessage;
|
import bisq.core.trade.messages.TradeMessage;
|
||||||
import bisq.core.trade.protocol.tasks.ApplyFilter;
|
import bisq.core.trade.protocol.tasks.ApplyFilter;
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
import bisq.core.trade.protocol.tasks.VerifyPeersAccountAgeWitness;
|
|
||||||
import bisq.core.trade.protocol.tasks.buyer.BuyerFinalizesDelayedPayoutTx;
|
|
||||||
import bisq.core.trade.protocol.tasks.buyer.BuyerProcessDelayedPayoutTxSignatureRequest;
|
|
||||||
import bisq.core.trade.protocol.tasks.buyer.BuyerSendsDelayedPayoutTxSignatureResponse;
|
|
||||||
import bisq.core.trade.protocol.tasks.buyer.BuyerSetupDepositTxListener;
|
|
||||||
import bisq.core.trade.protocol.tasks.buyer.BuyerSignsDelayedPayoutTx;
|
|
||||||
import bisq.core.trade.protocol.tasks.buyer.BuyerVerifiesPreparedDelayedPayoutTx;
|
|
||||||
import bisq.core.trade.protocol.tasks.buyer_as_taker.BuyerAsTakerSendsDepositTxMessage;
|
|
||||||
import bisq.core.trade.protocol.tasks.buyer_as_taker.BuyerAsTakerSignsDepositTx;
|
|
||||||
import bisq.core.trade.protocol.tasks.taker.TakerProcessesInputsForDepositTxResponse;
|
|
||||||
import bisq.core.trade.protocol.tasks.taker.TakerPublishFeeTx;
|
|
||||||
import bisq.core.trade.protocol.tasks.taker.TakerReservesTradeFunds;
|
|
||||||
import bisq.core.trade.protocol.tasks.taker.TakerSendsInitTradeRequestToArbitrator;
|
|
||||||
import bisq.core.trade.protocol.tasks.taker.TakerVerifyMakerFeePayment;
|
|
||||||
import bisq.network.p2p.NodeAddress;
|
import bisq.network.p2p.NodeAddress;
|
||||||
import bisq.common.handlers.ErrorMessageHandler;
|
import bisq.common.handlers.ErrorMessageHandler;
|
||||||
import bisq.common.handlers.ResultHandler;
|
import bisq.common.handlers.ResultHandler;
|
||||||
|
@ -56,7 +38,6 @@ import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
// TODO (woodser): remove unused request handling
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class BuyerAsTakerProtocol extends BuyerProtocol implements TakerProtocol {
|
public class BuyerAsTakerProtocol extends BuyerProtocol implements TakerProtocol {
|
||||||
|
|
||||||
|
@ -159,57 +140,5 @@ public class BuyerAsTakerProtocol extends BuyerProtocol implements TakerProtocol
|
||||||
@Override
|
@Override
|
||||||
protected void onTradeMessage(TradeMessage message, NodeAddress peer) {
|
protected void onTradeMessage(TradeMessage message, NodeAddress peer) {
|
||||||
super.onTradeMessage(message, peer);
|
super.onTradeMessage(message, peer);
|
||||||
|
|
||||||
if (message instanceof InputsForDepositTxResponse) {
|
|
||||||
handle((InputsForDepositTxResponse) message, peer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Class<? extends TradeTask> getVerifyPeersFeePaymentClass() {
|
|
||||||
return TakerVerifyMakerFeePayment.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO (woodser): remove unused
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Incoming messages Take offer process
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
private void handle(InputsForDepositTxResponse message, NodeAddress peer) {
|
|
||||||
expect(phase(Trade.Phase.INIT)
|
|
||||||
.with(message)
|
|
||||||
.from(peer))
|
|
||||||
.setup(tasks(TakerProcessesInputsForDepositTxResponse.class,
|
|
||||||
ApplyFilter.class,
|
|
||||||
VerifyPeersAccountAgeWitness.class,
|
|
||||||
//TakerVerifyAndSignContract.class,
|
|
||||||
TakerPublishFeeTx.class,
|
|
||||||
BuyerAsTakerSignsDepositTx.class,
|
|
||||||
BuyerSetupDepositTxListener.class,
|
|
||||||
BuyerAsTakerSendsDepositTxMessage.class)
|
|
||||||
.withTimeout(60))
|
|
||||||
.executeTasks(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void handle(DelayedPayoutTxSignatureRequest message, NodeAddress peer) {
|
|
||||||
expect(phase(Trade.Phase.TAKER_FEE_PUBLISHED)
|
|
||||||
.with(message)
|
|
||||||
.from(peer))
|
|
||||||
.setup(tasks(
|
|
||||||
BuyerProcessDelayedPayoutTxSignatureRequest.class,
|
|
||||||
BuyerVerifiesPreparedDelayedPayoutTx.class,
|
|
||||||
BuyerSignsDelayedPayoutTx.class,
|
|
||||||
BuyerFinalizesDelayedPayoutTx.class,
|
|
||||||
BuyerSendsDelayedPayoutTxSignatureResponse.class)
|
|
||||||
.withTimeout(60))
|
|
||||||
.executeTasks(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// We keep the handler here in as well to make it more transparent which messages we expect
|
|
||||||
@Override
|
|
||||||
protected void handle(DepositTxAndDelayedPayoutTxMessage message, NodeAddress peer) {
|
|
||||||
super.handle(message, peer);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,17 +19,14 @@ package bisq.core.trade.protocol;
|
||||||
|
|
||||||
import bisq.core.trade.BuyerTrade;
|
import bisq.core.trade.BuyerTrade;
|
||||||
import bisq.core.trade.Trade;
|
import bisq.core.trade.Trade;
|
||||||
import bisq.core.trade.messages.DelayedPayoutTxSignatureRequest;
|
|
||||||
import bisq.core.trade.messages.DepositTxAndDelayedPayoutTxMessage;
|
|
||||||
import bisq.core.trade.messages.PaymentReceivedMessage;
|
import bisq.core.trade.messages.PaymentReceivedMessage;
|
||||||
import bisq.core.trade.messages.TradeMessage;
|
import bisq.core.trade.messages.TradeMessage;
|
||||||
import bisq.core.trade.protocol.tasks.ApplyFilter;
|
import bisq.core.trade.protocol.tasks.ApplyFilter;
|
||||||
|
import bisq.core.trade.protocol.tasks.BuyerPreparesPaymentSentMessage;
|
||||||
|
import bisq.core.trade.protocol.tasks.BuyerProcessesPaymentReceivedMessage;
|
||||||
|
import bisq.core.trade.protocol.tasks.BuyerSendsPaymentSentMessage;
|
||||||
|
import bisq.core.trade.protocol.tasks.BuyerSetupPayoutTxListener;
|
||||||
import bisq.core.trade.protocol.tasks.SetupDepositTxsListener;
|
import bisq.core.trade.protocol.tasks.SetupDepositTxsListener;
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
import bisq.core.trade.protocol.tasks.buyer.BuyerPreparesPaymentSentMessage;
|
|
||||||
import bisq.core.trade.protocol.tasks.buyer.BuyerProcessesPaymentReceivedMessage;
|
|
||||||
import bisq.core.trade.protocol.tasks.buyer.BuyerSendsPaymentSentMessage;
|
|
||||||
import bisq.core.trade.protocol.tasks.buyer.BuyerSetupPayoutTxListener;
|
|
||||||
import bisq.core.util.Validator;
|
import bisq.core.util.Validator;
|
||||||
import bisq.network.p2p.NodeAddress;
|
import bisq.network.p2p.NodeAddress;
|
||||||
import bisq.common.handlers.ErrorMessageHandler;
|
import bisq.common.handlers.ErrorMessageHandler;
|
||||||
|
@ -77,49 +74,11 @@ public abstract class BuyerProtocol extends DisputeProtocol {
|
||||||
@Override
|
@Override
|
||||||
public void onMailboxMessage(TradeMessage message, NodeAddress peer) {
|
public void onMailboxMessage(TradeMessage message, NodeAddress peer) {
|
||||||
super.onMailboxMessage(message, peer);
|
super.onMailboxMessage(message, peer);
|
||||||
|
if (message instanceof PaymentReceivedMessage) {
|
||||||
if (message instanceof DepositTxAndDelayedPayoutTxMessage) {
|
|
||||||
handle((DepositTxAndDelayedPayoutTxMessage) message, peer);
|
|
||||||
} else if (message instanceof PaymentReceivedMessage) {
|
|
||||||
handle((PaymentReceivedMessage) message, peer);
|
handle((PaymentReceivedMessage) message, peer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void handle(DelayedPayoutTxSignatureRequest message, NodeAddress peer);
|
|
||||||
|
|
||||||
// The DepositTxAndDelayedPayoutTxMessage is a mailbox message as earlier we use only the deposit tx which can
|
|
||||||
// be also with from the network once published.
|
|
||||||
// Now we send the delayed payout tx as well and with that this message is mandatory for continuing the protocol.
|
|
||||||
// We do not support mailbox message handling during the take offer process as it is expected that both peers
|
|
||||||
// are online.
|
|
||||||
// For backward compatibility and extra resilience we still keep DepositTxAndDelayedPayoutTxMessage as a
|
|
||||||
// mailbox message but the stored in mailbox case is not expected and the seller would try to send the message again
|
|
||||||
// in the hope to reach the buyer directly.
|
|
||||||
protected void handle(DepositTxAndDelayedPayoutTxMessage message, NodeAddress peer) {
|
|
||||||
// expect(anyPhase(Trade.Phase.TAKER_FEE_PUBLISHED, Trade.Phase.DEPOSIT_PUBLISHED)
|
|
||||||
// .with(message)
|
|
||||||
// .from(peer)
|
|
||||||
// .preCondition(trade.getDepositTx() == null || trade.getDelayedPayoutTx() == null,
|
|
||||||
// () -> {
|
|
||||||
// log.warn("We with a DepositTxAndDelayedPayoutTxMessage but we have already processed the deposit and " +
|
|
||||||
// "delayed payout tx so we ignore the message. This can happen if the ACK message to the peer did not " +
|
|
||||||
// "arrive and the peer repeats sending us the message. We send another ACK msg.");
|
|
||||||
// stopTimeout();
|
|
||||||
// sendAckMessage(message, true, null);
|
|
||||||
// removeMailboxMessageAfterProcessing(message);
|
|
||||||
// }))
|
|
||||||
// .setup(tasks(BuyerProcessDepositTxAndDelayedPayoutTxMessage.class,
|
|
||||||
// BuyerVerifiesFinalDelayedPayoutTx.class)
|
|
||||||
// .using(new TradeTaskRunner(trade,
|
|
||||||
// () -> {
|
|
||||||
// stopTimeout();
|
|
||||||
// handleTaskRunnerSuccess(message);
|
|
||||||
// },
|
|
||||||
// errorMessage -> handleTaskRunnerFault(message, errorMessage))))
|
|
||||||
// .run(() -> processModel.witnessDebugLog(trade))
|
|
||||||
// .executeTasks();
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// User interaction
|
// User interaction
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -135,7 +94,6 @@ public abstract class BuyerProtocol extends DisputeProtocol {
|
||||||
.with(event)
|
.with(event)
|
||||||
.preCondition(trade.confirmPermitted()))
|
.preCondition(trade.confirmPermitted()))
|
||||||
.setup(tasks(ApplyFilter.class,
|
.setup(tasks(ApplyFilter.class,
|
||||||
getVerifyPeersFeePaymentClass(),
|
|
||||||
//UpdateMultisigWithTradingPeer.class, // TODO (woodser): can use this to test protocol with updated multisig from peer. peer should attempt to send updated multisig hex earlier as part of protocol. cannot use with countdown latch because response comes back in a separate thread and blocks on trade
|
//UpdateMultisigWithTradingPeer.class, // TODO (woodser): can use this to test protocol with updated multisig from peer. peer should attempt to send updated multisig hex earlier as part of protocol. cannot use with countdown latch because response comes back in a separate thread and blocks on trade
|
||||||
BuyerPreparesPaymentSentMessage.class,
|
BuyerPreparesPaymentSentMessage.class,
|
||||||
//BuyerSetupPayoutTxListener.class,
|
//BuyerSetupPayoutTxListener.class,
|
||||||
|
@ -170,7 +128,6 @@ public abstract class BuyerProtocol extends DisputeProtocol {
|
||||||
.with(message)
|
.with(message)
|
||||||
.from(peer))
|
.from(peer))
|
||||||
.setup(tasks(
|
.setup(tasks(
|
||||||
getVerifyPeersFeePaymentClass(),
|
|
||||||
BuyerProcessesPaymentReceivedMessage.class)
|
BuyerProcessesPaymentReceivedMessage.class)
|
||||||
.using(new TradeTaskRunner(trade,
|
.using(new TradeTaskRunner(trade,
|
||||||
() -> {
|
() -> {
|
||||||
|
@ -192,15 +149,8 @@ public abstract class BuyerProtocol extends DisputeProtocol {
|
||||||
@Override
|
@Override
|
||||||
protected void onTradeMessage(TradeMessage message, NodeAddress peer) {
|
protected void onTradeMessage(TradeMessage message, NodeAddress peer) {
|
||||||
super.onTradeMessage(message, peer);
|
super.onTradeMessage(message, peer);
|
||||||
|
if (message instanceof PaymentReceivedMessage) {
|
||||||
if (message instanceof DelayedPayoutTxSignatureRequest) {
|
|
||||||
handle((DelayedPayoutTxSignatureRequest) message, peer);
|
|
||||||
} else if (message instanceof DepositTxAndDelayedPayoutTxMessage) {
|
|
||||||
handle((DepositTxAndDelayedPayoutTxMessage) message, peer);
|
|
||||||
} else if (message instanceof PaymentReceivedMessage) {
|
|
||||||
handle((PaymentReceivedMessage) message, peer);
|
handle((PaymentReceivedMessage) message, peer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract protected Class<? extends TradeTask> getVerifyPeersFeePaymentClass();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,11 +20,8 @@ package bisq.core.trade.protocol;
|
||||||
import bisq.core.trade.Trade;
|
import bisq.core.trade.Trade;
|
||||||
import bisq.core.trade.messages.MediatedPayoutTxPublishedMessage;
|
import bisq.core.trade.messages.MediatedPayoutTxPublishedMessage;
|
||||||
import bisq.core.trade.messages.MediatedPayoutTxSignatureMessage;
|
import bisq.core.trade.messages.MediatedPayoutTxSignatureMessage;
|
||||||
import bisq.core.trade.messages.PeerPublishedDelayedPayoutTxMessage;
|
|
||||||
import bisq.core.trade.messages.TradeMessage;
|
import bisq.core.trade.messages.TradeMessage;
|
||||||
import bisq.core.trade.protocol.tasks.ApplyFilter;
|
import bisq.core.trade.protocol.tasks.ApplyFilter;
|
||||||
import bisq.core.trade.protocol.tasks.ProcessPeerPublishedDelayedPayoutTxMessage;
|
|
||||||
import bisq.core.trade.protocol.tasks.mediation.BroadcastMediatedPayoutTx;
|
|
||||||
import bisq.core.trade.protocol.tasks.mediation.FinalizeMediatedPayoutTx;
|
import bisq.core.trade.protocol.tasks.mediation.FinalizeMediatedPayoutTx;
|
||||||
import bisq.core.trade.protocol.tasks.mediation.ProcessMediatedPayoutSignatureMessage;
|
import bisq.core.trade.protocol.tasks.mediation.ProcessMediatedPayoutSignatureMessage;
|
||||||
import bisq.core.trade.protocol.tasks.mediation.ProcessMediatedPayoutTxPublishedMessage;
|
import bisq.core.trade.protocol.tasks.mediation.ProcessMediatedPayoutTxPublishedMessage;
|
||||||
|
@ -97,7 +94,6 @@ public abstract class DisputeProtocol extends TradeProtocol {
|
||||||
.setup(tasks(ApplyFilter.class,
|
.setup(tasks(ApplyFilter.class,
|
||||||
SignMediatedPayoutTx.class,
|
SignMediatedPayoutTx.class,
|
||||||
FinalizeMediatedPayoutTx.class,
|
FinalizeMediatedPayoutTx.class,
|
||||||
BroadcastMediatedPayoutTx.class,
|
|
||||||
SendMediatedPayoutTxPublishedMessage.class)
|
SendMediatedPayoutTxPublishedMessage.class)
|
||||||
.using(new TradeTaskRunner(trade,
|
.using(new TradeTaskRunner(trade,
|
||||||
() -> {
|
() -> {
|
||||||
|
@ -162,21 +158,6 @@ public abstract class DisputeProtocol extends TradeProtocol {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Peer has published the delayed payout tx
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
private void handle(PeerPublishedDelayedPayoutTxMessage message, NodeAddress peer) {
|
|
||||||
expect(anyPhase(Trade.Phase.DEPOSIT_UNLOCKED,
|
|
||||||
Trade.Phase.PAYMENT_SENT,
|
|
||||||
Trade.Phase.PAYMENT_RECEIVED)
|
|
||||||
.with(message)
|
|
||||||
.from(peer))
|
|
||||||
.setup(tasks(ProcessPeerPublishedDelayedPayoutTxMessage.class))
|
|
||||||
.executeTasks();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Dispatcher
|
// Dispatcher
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -187,8 +168,6 @@ public abstract class DisputeProtocol extends TradeProtocol {
|
||||||
handle((MediatedPayoutTxSignatureMessage) message, peer);
|
handle((MediatedPayoutTxSignatureMessage) message, peer);
|
||||||
} else if (message instanceof MediatedPayoutTxPublishedMessage) {
|
} else if (message instanceof MediatedPayoutTxPublishedMessage) {
|
||||||
handle((MediatedPayoutTxPublishedMessage) message, peer);
|
handle((MediatedPayoutTxPublishedMessage) message, peer);
|
||||||
} else if (message instanceof PeerPublishedDelayedPayoutTxMessage) {
|
|
||||||
handle((PeerPublishedDelayedPayoutTxMessage) message, peer);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,8 +178,6 @@ public abstract class DisputeProtocol extends TradeProtocol {
|
||||||
handle((MediatedPayoutTxSignatureMessage) message, peer);
|
handle((MediatedPayoutTxSignatureMessage) message, peer);
|
||||||
} else if (message instanceof MediatedPayoutTxPublishedMessage) {
|
} else if (message instanceof MediatedPayoutTxPublishedMessage) {
|
||||||
handle((MediatedPayoutTxPublishedMessage) message, peer);
|
handle((MediatedPayoutTxPublishedMessage) message, peer);
|
||||||
} else if (message instanceof PeerPublishedDelayedPayoutTxMessage) {
|
|
||||||
handle((PeerPublishedDelayedPayoutTxMessage) message, peer);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,21 +24,12 @@ import bisq.core.trade.messages.PaymentSentMessage;
|
||||||
import bisq.core.trade.messages.SignContractRequest;
|
import bisq.core.trade.messages.SignContractRequest;
|
||||||
import bisq.core.trade.messages.SignContractResponse;
|
import bisq.core.trade.messages.SignContractResponse;
|
||||||
import bisq.core.trade.messages.DepositResponse;
|
import bisq.core.trade.messages.DepositResponse;
|
||||||
import bisq.core.trade.messages.DepositTxMessage;
|
|
||||||
import bisq.core.trade.messages.InitMultisigRequest;
|
import bisq.core.trade.messages.InitMultisigRequest;
|
||||||
import bisq.core.trade.messages.InitTradeRequest;
|
import bisq.core.trade.messages.InitTradeRequest;
|
||||||
import bisq.core.trade.messages.PaymentAccountPayloadRequest;
|
import bisq.core.trade.messages.PaymentAccountPayloadRequest;
|
||||||
import bisq.core.trade.messages.TradeMessage;
|
import bisq.core.trade.messages.TradeMessage;
|
||||||
|
import bisq.core.trade.protocol.tasks.MakerSendsInitTradeRequestIfUnreserved;
|
||||||
import bisq.core.trade.protocol.tasks.ProcessInitTradeRequest;
|
import bisq.core.trade.protocol.tasks.ProcessInitTradeRequest;
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
import bisq.core.trade.protocol.tasks.maker.MaybeRemoveOpenOffer;
|
|
||||||
import bisq.core.trade.protocol.tasks.maker.MakerSendsInitTradeRequestIfUnreserved;
|
|
||||||
import bisq.core.trade.protocol.tasks.maker.MakerVerifyTakerFeePayment;
|
|
||||||
import bisq.core.trade.protocol.tasks.seller.SellerCreatesDelayedPayoutTx;
|
|
||||||
import bisq.core.trade.protocol.tasks.seller.SellerSendDelayedPayoutTxSignatureRequest;
|
|
||||||
import bisq.core.trade.protocol.tasks.seller.SellerSignsDelayedPayoutTx;
|
|
||||||
import bisq.core.trade.protocol.tasks.seller_as_maker.SellerAsMakerFinalizesDepositTx;
|
|
||||||
import bisq.core.trade.protocol.tasks.seller_as_maker.SellerAsMakerProcessDepositTxMessage;
|
|
||||||
import bisq.network.p2p.NodeAddress;
|
import bisq.network.p2p.NodeAddress;
|
||||||
import bisq.common.handlers.ErrorMessageHandler;
|
import bisq.common.handlers.ErrorMessageHandler;
|
||||||
import bisq.common.handlers.ResultHandler;
|
import bisq.common.handlers.ResultHandler;
|
||||||
|
@ -132,42 +123,9 @@ public class SellerAsMakerProtocol extends SellerProtocol implements MakerProtoc
|
||||||
@Override
|
@Override
|
||||||
protected void onTradeMessage(TradeMessage message, NodeAddress peer) {
|
protected void onTradeMessage(TradeMessage message, NodeAddress peer) {
|
||||||
super.onTradeMessage(message, peer);
|
super.onTradeMessage(message, peer);
|
||||||
|
log.info("Received {} from {} with tradeId {} and uid {}", message.getClass().getSimpleName(), peer, message.getTradeId(), message.getUid());
|
||||||
log.info("Received {} from {} with tradeId {} and uid {}",
|
|
||||||
message.getClass().getSimpleName(), peer, message.getTradeId(), message.getUid());
|
|
||||||
|
|
||||||
if (message instanceof DepositTxMessage) {
|
|
||||||
handle((DepositTxMessage) message, peer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Class<? extends TradeTask> getVerifyPeersFeePaymentClass() {
|
|
||||||
return MakerVerifyTakerFeePayment.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO (woodser): remove unused
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Incoming messages Take offer process
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
protected void handle(DepositTxMessage message, NodeAddress peer) {
|
|
||||||
expect(phase(Trade.Phase.TAKER_FEE_PUBLISHED)
|
|
||||||
.with(message)
|
|
||||||
.from(peer))
|
|
||||||
.setup(tasks(
|
|
||||||
MaybeRemoveOpenOffer.class,
|
|
||||||
SellerAsMakerProcessDepositTxMessage.class,
|
|
||||||
SellerAsMakerFinalizesDepositTx.class,
|
|
||||||
SellerCreatesDelayedPayoutTx.class,
|
|
||||||
SellerSignsDelayedPayoutTx.class,
|
|
||||||
SellerSendDelayedPayoutTxSignatureRequest.class)
|
|
||||||
.withTimeout(60))
|
|
||||||
.executeTasks(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Incoming message when buyer has clicked payment started button
|
// Incoming message when buyer has clicked payment started button
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -27,22 +27,9 @@ import bisq.core.trade.messages.SignContractRequest;
|
||||||
import bisq.core.trade.messages.SignContractResponse;
|
import bisq.core.trade.messages.SignContractResponse;
|
||||||
import bisq.core.trade.messages.DepositResponse;
|
import bisq.core.trade.messages.DepositResponse;
|
||||||
import bisq.core.trade.messages.InitMultisigRequest;
|
import bisq.core.trade.messages.InitMultisigRequest;
|
||||||
import bisq.core.trade.messages.InputsForDepositTxResponse;
|
|
||||||
import bisq.core.trade.messages.PaymentAccountPayloadRequest;
|
import bisq.core.trade.messages.PaymentAccountPayloadRequest;
|
||||||
import bisq.core.trade.messages.TradeMessage;
|
import bisq.core.trade.messages.TradeMessage;
|
||||||
import bisq.core.trade.protocol.tasks.ApplyFilter;
|
import bisq.core.trade.protocol.tasks.ApplyFilter;
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
import bisq.core.trade.protocol.tasks.VerifyPeersAccountAgeWitness;
|
|
||||||
import bisq.core.trade.protocol.tasks.seller.SellerCreatesDelayedPayoutTx;
|
|
||||||
import bisq.core.trade.protocol.tasks.seller.SellerSendDelayedPayoutTxSignatureRequest;
|
|
||||||
import bisq.core.trade.protocol.tasks.seller.SellerSignsDelayedPayoutTx;
|
|
||||||
import bisq.core.trade.protocol.tasks.seller_as_taker.SellerAsTakerSignsDepositTx;
|
|
||||||
import bisq.core.trade.protocol.tasks.taker.TakerProcessesInputsForDepositTxResponse;
|
|
||||||
import bisq.core.trade.protocol.tasks.taker.TakerPublishFeeTx;
|
|
||||||
import bisq.core.trade.protocol.tasks.taker.TakerReservesTradeFunds;
|
|
||||||
import bisq.core.trade.protocol.tasks.taker.TakerSendsInitTradeRequestToArbitrator;
|
|
||||||
import bisq.core.trade.protocol.tasks.taker.TakerVerifyMakerFeePayment;
|
|
||||||
|
|
||||||
import bisq.network.p2p.NodeAddress;
|
import bisq.network.p2p.NodeAddress;
|
||||||
import bisq.common.handlers.ErrorMessageHandler;
|
import bisq.common.handlers.ErrorMessageHandler;
|
||||||
import bisq.common.handlers.ResultHandler;
|
import bisq.common.handlers.ResultHandler;
|
||||||
|
@ -152,41 +139,6 @@ public class SellerAsTakerProtocol extends SellerProtocol implements TakerProtoc
|
||||||
@Override
|
@Override
|
||||||
protected void onTradeMessage(TradeMessage message, NodeAddress peer) {
|
protected void onTradeMessage(TradeMessage message, NodeAddress peer) {
|
||||||
super.onTradeMessage(message, peer);
|
super.onTradeMessage(message, peer);
|
||||||
|
log.info("Received {} from {} with tradeId {} and uid {}", message.getClass().getSimpleName(), peer, message.getTradeId(), message.getUid());
|
||||||
log.info("Received {} from {} with tradeId {} and uid {}",
|
|
||||||
message.getClass().getSimpleName(), peer, message.getTradeId(), message.getUid());
|
|
||||||
|
|
||||||
if (message instanceof InputsForDepositTxResponse) {
|
|
||||||
handle((InputsForDepositTxResponse) message, peer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Class<? extends TradeTask> getVerifyPeersFeePaymentClass() {
|
|
||||||
return TakerVerifyMakerFeePayment.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO (woodser): remove unused calls and classes
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Incoming messages Take offer process
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
private void handle(InputsForDepositTxResponse message, NodeAddress peer) {
|
|
||||||
expect(phase(Trade.Phase.INIT)
|
|
||||||
.with(message)
|
|
||||||
.from(peer))
|
|
||||||
.setup(tasks(
|
|
||||||
TakerProcessesInputsForDepositTxResponse.class,
|
|
||||||
ApplyFilter.class,
|
|
||||||
VerifyPeersAccountAgeWitness.class,
|
|
||||||
//TakerVerifyAndSignContract.class,
|
|
||||||
TakerPublishFeeTx.class,
|
|
||||||
SellerAsTakerSignsDepositTx.class,
|
|
||||||
SellerCreatesDelayedPayoutTx.class,
|
|
||||||
SellerSignsDelayedPayoutTx.class,
|
|
||||||
SellerSendDelayedPayoutTxSignatureRequest.class)
|
|
||||||
.withTimeout(60))
|
|
||||||
.executeTasks(true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,12 +23,10 @@ import bisq.core.trade.messages.PaymentSentMessage;
|
||||||
import bisq.core.trade.messages.TradeMessage;
|
import bisq.core.trade.messages.TradeMessage;
|
||||||
import bisq.core.trade.protocol.BuyerProtocol.BuyerEvent;
|
import bisq.core.trade.protocol.BuyerProtocol.BuyerEvent;
|
||||||
import bisq.core.trade.protocol.tasks.ApplyFilter;
|
import bisq.core.trade.protocol.tasks.ApplyFilter;
|
||||||
|
import bisq.core.trade.protocol.tasks.SellerPreparesPaymentReceivedMessage;
|
||||||
|
import bisq.core.trade.protocol.tasks.SellerProcessesPaymentSentMessage;
|
||||||
|
import bisq.core.trade.protocol.tasks.SellerSendsPaymentReceivedMessage;
|
||||||
import bisq.core.trade.protocol.tasks.SetupDepositTxsListener;
|
import bisq.core.trade.protocol.tasks.SetupDepositTxsListener;
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
import bisq.core.trade.protocol.tasks.seller.SellerProcessesPaymentSentMessage;
|
|
||||||
import bisq.core.trade.protocol.tasks.seller.SellerSendsPaymentReceivedMessage;
|
|
||||||
import bisq.core.trade.protocol.tasks.seller.SellerPreparesPaymentReceivedMessage;
|
|
||||||
|
|
||||||
import bisq.network.p2p.NodeAddress;
|
import bisq.network.p2p.NodeAddress;
|
||||||
import bisq.common.handlers.ErrorMessageHandler;
|
import bisq.common.handlers.ErrorMessageHandler;
|
||||||
import bisq.common.handlers.ResultHandler;
|
import bisq.common.handlers.ResultHandler;
|
||||||
|
@ -100,9 +98,8 @@ public abstract class SellerProtocol extends DisputeProtocol {
|
||||||
removeMailboxMessageAfterProcessing(message);
|
removeMailboxMessageAfterProcessing(message);
|
||||||
}))
|
}))
|
||||||
.setup(tasks(
|
.setup(tasks(
|
||||||
SellerProcessesPaymentSentMessage.class,
|
|
||||||
ApplyFilter.class,
|
ApplyFilter.class,
|
||||||
getVerifyPeersFeePaymentClass())
|
SellerProcessesPaymentSentMessage.class)
|
||||||
.using(new TradeTaskRunner(trade,
|
.using(new TradeTaskRunner(trade,
|
||||||
() -> {
|
() -> {
|
||||||
stopTimeout();
|
stopTimeout();
|
||||||
|
@ -134,7 +131,6 @@ public abstract class SellerProtocol extends DisputeProtocol {
|
||||||
.preCondition(trade.confirmPermitted()))
|
.preCondition(trade.confirmPermitted()))
|
||||||
.setup(tasks(
|
.setup(tasks(
|
||||||
ApplyFilter.class,
|
ApplyFilter.class,
|
||||||
getVerifyPeersFeePaymentClass(),
|
|
||||||
SellerPreparesPaymentReceivedMessage.class,
|
SellerPreparesPaymentReceivedMessage.class,
|
||||||
SellerSendsPaymentReceivedMessage.class)
|
SellerSendsPaymentReceivedMessage.class)
|
||||||
.using(new TradeTaskRunner(trade, () -> {
|
.using(new TradeTaskRunner(trade, () -> {
|
||||||
|
@ -159,7 +155,4 @@ public abstract class SellerProtocol extends DisputeProtocol {
|
||||||
handle((PaymentSentMessage) message, peer);
|
handle((PaymentSentMessage) message, peer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract protected Class<? extends TradeTask> getVerifyPeersFeePaymentClass();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.taker;
|
package bisq.core.trade.protocol;
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
import bisq.common.taskrunner.TaskRunner;
|
||||||
import bisq.core.btc.model.XmrAddressEntry;
|
import bisq.core.btc.model.XmrAddressEntry;
|
|
@ -15,7 +15,7 @@
|
||||||
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.taker;
|
package bisq.core.trade.protocol;
|
||||||
|
|
||||||
import bisq.core.support.dispute.arbitration.arbitrator.Arbitrator;
|
import bisq.core.support.dispute.arbitration.arbitrator.Arbitrator;
|
||||||
import bisq.core.trade.Trade;
|
import bisq.core.trade.Trade;
|
|
@ -15,7 +15,7 @@
|
||||||
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.taker;
|
package bisq.core.trade.protocol;
|
||||||
|
|
||||||
import bisq.core.trade.Trade;
|
import bisq.core.trade.Trade;
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
@ -24,13 +24,13 @@ import bisq.core.trade.TradeUtils;
|
||||||
import bisq.core.trade.handlers.TradeResultHandler;
|
import bisq.core.trade.handlers.TradeResultHandler;
|
||||||
import bisq.core.trade.messages.PaymentSentMessage;
|
import bisq.core.trade.messages.PaymentSentMessage;
|
||||||
import bisq.core.trade.messages.DepositResponse;
|
import bisq.core.trade.messages.DepositResponse;
|
||||||
import bisq.core.trade.messages.DepositTxAndDelayedPayoutTxMessage;
|
|
||||||
import bisq.core.trade.messages.InitMultisigRequest;
|
import bisq.core.trade.messages.InitMultisigRequest;
|
||||||
import bisq.core.trade.messages.PaymentAccountPayloadRequest;
|
import bisq.core.trade.messages.PaymentAccountPayloadRequest;
|
||||||
import bisq.core.trade.messages.SignContractRequest;
|
import bisq.core.trade.messages.SignContractRequest;
|
||||||
import bisq.core.trade.messages.SignContractResponse;
|
import bisq.core.trade.messages.SignContractResponse;
|
||||||
import bisq.core.trade.messages.TradeMessage;
|
import bisq.core.trade.messages.TradeMessage;
|
||||||
import bisq.core.trade.messages.UpdateMultisigRequest;
|
import bisq.core.trade.messages.UpdateMultisigRequest;
|
||||||
|
import bisq.core.trade.protocol.tasks.MaybeRemoveOpenOffer;
|
||||||
import bisq.core.trade.protocol.tasks.MaybeSendSignContractRequest;
|
import bisq.core.trade.protocol.tasks.MaybeSendSignContractRequest;
|
||||||
import bisq.core.trade.protocol.tasks.ProcessDepositResponse;
|
import bisq.core.trade.protocol.tasks.ProcessDepositResponse;
|
||||||
import bisq.core.trade.protocol.tasks.ProcessInitMultisigRequest;
|
import bisq.core.trade.protocol.tasks.ProcessInitMultisigRequest;
|
||||||
|
@ -38,7 +38,6 @@ import bisq.core.trade.protocol.tasks.ProcessPaymentAccountPayloadRequest;
|
||||||
import bisq.core.trade.protocol.tasks.ProcessSignContractRequest;
|
import bisq.core.trade.protocol.tasks.ProcessSignContractRequest;
|
||||||
import bisq.core.trade.protocol.tasks.ProcessSignContractResponse;
|
import bisq.core.trade.protocol.tasks.ProcessSignContractResponse;
|
||||||
import bisq.core.trade.protocol.tasks.ProcessUpdateMultisigRequest;
|
import bisq.core.trade.protocol.tasks.ProcessUpdateMultisigRequest;
|
||||||
import bisq.core.trade.protocol.tasks.maker.MaybeRemoveOpenOffer;
|
|
||||||
import bisq.core.util.Validator;
|
import bisq.core.util.Validator;
|
||||||
|
|
||||||
import bisq.network.p2p.AckMessage;
|
import bisq.network.p2p.AckMessage;
|
||||||
|
@ -324,7 +323,7 @@ public abstract class TradeProtocol implements DecryptedDirectMessageListener, D
|
||||||
latchTrade();
|
latchTrade();
|
||||||
Validator.checkTradeId(processModel.getOfferId(), response);
|
Validator.checkTradeId(processModel.getOfferId(), response);
|
||||||
processModel.setTradeMessage(response);
|
processModel.setTradeMessage(response);
|
||||||
expect(state(Trade.State.MAKER_SENT_PUBLISH_DEPOSIT_TX_REQUEST)
|
expect(state(Trade.State.SENT_PUBLISH_DEPOSIT_TX_REQUEST)
|
||||||
.with(response)
|
.with(response)
|
||||||
.from(sender)) // TODO (woodser): ensure this asserts sender == response.getSenderNodeAddress()
|
.from(sender)) // TODO (woodser): ensure this asserts sender == response.getSenderNodeAddress()
|
||||||
.setup(tasks(
|
.setup(tasks(
|
||||||
|
@ -348,11 +347,11 @@ public abstract class TradeProtocol implements DecryptedDirectMessageListener, D
|
||||||
System.out.println(getClass().getCanonicalName() + ".handlePaymentAccountPayloadRequest()");
|
System.out.println(getClass().getCanonicalName() + ".handlePaymentAccountPayloadRequest()");
|
||||||
synchronized (trade) {
|
synchronized (trade) {
|
||||||
Validator.checkTradeId(processModel.getOfferId(), request);
|
Validator.checkTradeId(processModel.getOfferId(), request);
|
||||||
if (trade.getState() == Trade.State.MAKER_RECEIVED_DEPOSIT_TX_PUBLISHED_MSG) {
|
if (trade.getState() == Trade.State.ARBITRATOR_PUBLISHED_DEPOSIT_TXS) {
|
||||||
latchTrade();
|
latchTrade();
|
||||||
Validator.checkTradeId(processModel.getOfferId(), request);
|
Validator.checkTradeId(processModel.getOfferId(), request);
|
||||||
processModel.setTradeMessage(request);
|
processModel.setTradeMessage(request);
|
||||||
expect(state(Trade.State.MAKER_RECEIVED_DEPOSIT_TX_PUBLISHED_MSG)
|
expect(state(Trade.State.ARBITRATOR_PUBLISHED_DEPOSIT_TXS)
|
||||||
.with(request)
|
.with(request)
|
||||||
.from(sender)) // TODO (woodser): ensure this asserts sender == response.getSenderNodeAddress()
|
.from(sender)) // TODO (woodser): ensure this asserts sender == response.getSenderNodeAddress()
|
||||||
.setup(tasks(
|
.setup(tasks(
|
||||||
|
@ -374,7 +373,7 @@ public abstract class TradeProtocol implements DecryptedDirectMessageListener, D
|
||||||
awaitTradeLatch();
|
awaitTradeLatch();
|
||||||
} else {
|
} else {
|
||||||
EasyBind.subscribe(trade.stateProperty(), state -> {
|
EasyBind.subscribe(trade.stateProperty(), state -> {
|
||||||
if (state == Trade.State.MAKER_RECEIVED_DEPOSIT_TX_PUBLISHED_MSG) new Thread(() -> handlePaymentAccountPayloadRequest(request, sender)).start(); // process notification without trade lock
|
if (state == Trade.State.ARBITRATOR_PUBLISHED_DEPOSIT_TXS) new Thread(() -> handlePaymentAccountPayloadRequest(request, sender)).start(); // process notification without trade lock
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -459,8 +458,6 @@ public abstract class TradeProtocol implements DecryptedDirectMessageListener, D
|
||||||
// TODO (woodser): add AckMessage for InitTradeRequest and support automatic re-send ?
|
// TODO (woodser): add AckMessage for InitTradeRequest and support automatic re-send ?
|
||||||
if (ackMessage.getSourceMsgClassName().equals(PaymentSentMessage.class.getSimpleName())) {
|
if (ackMessage.getSourceMsgClassName().equals(PaymentSentMessage.class.getSimpleName())) {
|
||||||
processModel.setPaymentStartedAckMessage(ackMessage);
|
processModel.setPaymentStartedAckMessage(ackMessage);
|
||||||
} else if (ackMessage.getSourceMsgClassName().equals(DepositTxAndDelayedPayoutTxMessage.class.getSimpleName())) {
|
|
||||||
processModel.setDepositTxSentAckMessage(ackMessage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ackMessage.isSuccess()) {
|
if (ackMessage.isSuccess()) {
|
||||||
|
|
|
@ -113,7 +113,7 @@ public class ArbitratorProcessesDepositRequest extends TradeTask {
|
||||||
|
|
||||||
// update trade state
|
// update trade state
|
||||||
log.info("Arbitrator submitted deposit txs for trade " + trade.getId());
|
log.info("Arbitrator submitted deposit txs for trade " + trade.getId());
|
||||||
trade.setState(Trade.State.ARBITRATOR_PUBLISHED_DEPOSIT_TX);
|
trade.setState(Trade.State.ARBITRATOR_PUBLISHED_DEPOSIT_TXS);
|
||||||
|
|
||||||
// create deposit response
|
// create deposit response
|
||||||
DepositResponse response = new DepositResponse(
|
DepositResponse response = new DepositResponse(
|
||||||
|
|
|
@ -1,76 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks;
|
|
||||||
|
|
||||||
import bisq.core.trade.Trade;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import monero.wallet.model.MoneroTxWallet;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public abstract class BroadcastPayoutTx extends TradeTask {
|
|
||||||
public BroadcastPayoutTx(TaskRunner<Trade> taskHandler, Trade trade) {
|
|
||||||
super(taskHandler, trade);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract void setState();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void run() {
|
|
||||||
try {
|
|
||||||
runInterceptHook();
|
|
||||||
if (true) throw new RuntimeException("BroadcastPayoutTx not implemented for xmr");
|
|
||||||
MoneroTxWallet payoutTx = trade.getPayoutTx();
|
|
||||||
checkNotNull(payoutTx, "payoutTx must not be null");
|
|
||||||
|
|
||||||
|
|
||||||
if (payoutTx.isRelayed()) {
|
|
||||||
log.debug("payoutTx was already published");
|
|
||||||
setState();
|
|
||||||
complete();
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
processModel.getProvider().getXmrWalletService().getWallet().relayTx(payoutTx);
|
|
||||||
if (!completed) {
|
|
||||||
log.debug("BroadcastTx succeeded. Transaction:" + payoutTx);
|
|
||||||
setState();
|
|
||||||
complete();
|
|
||||||
} else {
|
|
||||||
log.warn("We got the onSuccess callback called after the timeout has been triggered a complete().");
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
if (!completed) {
|
|
||||||
log.error("BroadcastTx failed. Error:" + e.getMessage());
|
|
||||||
failed(e);
|
|
||||||
} else {
|
|
||||||
log.warn("We got the onFailure callback called after the timeout has been triggered a complete().");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Throwable t) {
|
|
||||||
failed(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -15,12 +15,10 @@
|
||||||
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.buyer;
|
package bisq.core.trade.protocol.tasks;
|
||||||
|
|
||||||
import bisq.core.btc.wallet.XmrWalletService;
|
import bisq.core.btc.wallet.XmrWalletService;
|
||||||
import bisq.core.trade.Trade;
|
import bisq.core.trade.Trade;
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
import bisq.common.taskrunner.TaskRunner;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
|
@ -15,13 +15,12 @@
|
||||||
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.buyer;
|
package bisq.core.trade.protocol.tasks;
|
||||||
|
|
||||||
import bisq.core.account.sign.SignedWitness;
|
import bisq.core.account.sign.SignedWitness;
|
||||||
import bisq.core.btc.wallet.XmrWalletService;
|
import bisq.core.btc.wallet.XmrWalletService;
|
||||||
import bisq.core.trade.Trade;
|
import bisq.core.trade.Trade;
|
||||||
import bisq.core.trade.messages.PaymentReceivedMessage;
|
import bisq.core.trade.messages.PaymentReceivedMessage;
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
import bisq.core.util.Validator;
|
import bisq.core.util.Validator;
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
import bisq.common.taskrunner.TaskRunner;
|
|
@ -15,7 +15,7 @@
|
||||||
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.buyer;
|
package bisq.core.trade.protocol.tasks;
|
||||||
|
|
||||||
import bisq.core.btc.model.XmrAddressEntry;
|
import bisq.core.btc.model.XmrAddressEntry;
|
||||||
import bisq.core.btc.wallet.XmrWalletService;
|
import bisq.core.btc.wallet.XmrWalletService;
|
||||||
|
@ -24,8 +24,6 @@ import bisq.core.trade.Trade;
|
||||||
import bisq.core.trade.messages.PaymentSentMessage;
|
import bisq.core.trade.messages.PaymentSentMessage;
|
||||||
import bisq.core.trade.messages.TradeMailboxMessage;
|
import bisq.core.trade.messages.TradeMailboxMessage;
|
||||||
import bisq.core.trade.messages.TradeMessage;
|
import bisq.core.trade.messages.TradeMessage;
|
||||||
import bisq.core.trade.protocol.tasks.SendMailboxMessageTask;
|
|
||||||
|
|
||||||
import bisq.common.Timer;
|
import bisq.common.Timer;
|
||||||
import bisq.common.UserThread;
|
import bisq.common.UserThread;
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
import bisq.common.taskrunner.TaskRunner;
|
|
@ -15,12 +15,10 @@
|
||||||
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.buyer;
|
package bisq.core.trade.protocol.tasks;
|
||||||
|
|
||||||
import bisq.core.btc.listeners.AddressConfidenceListener;
|
import bisq.core.btc.listeners.AddressConfidenceListener;
|
||||||
import bisq.core.trade.Trade;
|
import bisq.core.trade.Trade;
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
import bisq.common.taskrunner.TaskRunner;
|
||||||
|
|
||||||
import org.fxmisc.easybind.Subscription;
|
import org.fxmisc.easybind.Subscription;
|
|
@ -15,11 +15,9 @@
|
||||||
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.buyer;
|
package bisq.core.trade.protocol.tasks;
|
||||||
|
|
||||||
import bisq.core.trade.Trade;
|
import bisq.core.trade.Trade;
|
||||||
import bisq.core.trade.protocol.tasks.SetupPayoutTxListener;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
import bisq.common.taskrunner.TaskRunner;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
|
@ -15,14 +15,12 @@
|
||||||
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.maker;
|
package bisq.core.trade.protocol.tasks;
|
||||||
|
|
||||||
import bisq.core.btc.model.XmrAddressEntry;
|
import bisq.core.btc.model.XmrAddressEntry;
|
||||||
import bisq.core.offer.Offer;
|
import bisq.core.offer.Offer;
|
||||||
import bisq.core.trade.Trade;
|
import bisq.core.trade.Trade;
|
||||||
import bisq.core.trade.messages.InitTradeRequest;
|
import bisq.core.trade.messages.InitTradeRequest;
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
|
|
||||||
import bisq.network.p2p.SendDirectMessageListener;
|
import bisq.network.p2p.SendDirectMessageListener;
|
||||||
|
|
||||||
import bisq.common.app.Version;
|
import bisq.common.app.Version;
|
|
@ -15,12 +15,10 @@
|
||||||
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.maker;
|
package bisq.core.trade.protocol.tasks;
|
||||||
|
|
||||||
import bisq.core.btc.wallet.Restrictions;
|
import bisq.core.btc.wallet.Restrictions;
|
||||||
import bisq.core.trade.Trade;
|
import bisq.core.trade.Trade;
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
|
|
||||||
import bisq.common.config.Config;
|
import bisq.common.config.Config;
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
import bisq.common.taskrunner.TaskRunner;
|
||||||
|
|
|
@ -15,12 +15,10 @@
|
||||||
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.maker;
|
package bisq.core.trade.protocol.tasks;
|
||||||
|
|
||||||
import bisq.core.trade.MakerTrade;
|
import bisq.core.trade.MakerTrade;
|
||||||
import bisq.core.trade.Trade;
|
import bisq.core.trade.Trade;
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
import bisq.common.taskrunner.TaskRunner;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
|
@ -41,7 +41,7 @@ public class ProcessDepositResponse extends TradeTask {
|
||||||
runInterceptHook();
|
runInterceptHook();
|
||||||
|
|
||||||
// arbitrator has broadcast deposit txs
|
// arbitrator has broadcast deposit txs
|
||||||
trade.setState(Trade.State.MAKER_RECEIVED_DEPOSIT_TX_PUBLISHED_MSG); // TODO (woodser): maker and taker?
|
trade.setState(Trade.State.ARBITRATOR_PUBLISHED_DEPOSIT_TXS);
|
||||||
|
|
||||||
// set payment account payload
|
// set payment account payload
|
||||||
trade.getSelf().setPaymentAccountPayload(processModel.getPaymentAccountPayload(trade));
|
trade.getSelf().setPaymentAccountPayload(processModel.getPaymentAccountPayload(trade));
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks;
|
|
||||||
|
|
||||||
import bisq.core.trade.Trade;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class ProcessPeerPublishedDelayedPayoutTxMessage extends TradeTask {
|
|
||||||
public ProcessPeerPublishedDelayedPayoutTxMessage(TaskRunner<Trade> taskHandler, Trade trade) {
|
|
||||||
super(taskHandler, trade);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void run() {
|
|
||||||
try {
|
|
||||||
runInterceptHook();
|
|
||||||
throw new RuntimeException("XMR adaptation does not support delayed payout tx");
|
|
||||||
|
|
||||||
// PeerPublishedDelayedPayoutTxMessage message = (PeerPublishedDelayedPayoutTxMessage) processModel.getTradeMessage();
|
|
||||||
// Validator.checkTradeId(processModel.getOfferId(), message);
|
|
||||||
// checkNotNull(message);
|
|
||||||
//
|
|
||||||
// // update to the latest peer address of our peer if the message is correct
|
|
||||||
// trade.setTradingPeerNodeAddress(processModel.getTempTradingPeerNodeAddress());
|
|
||||||
//
|
|
||||||
// // We add the tx to our wallet.
|
|
||||||
// Transaction delayedPayoutTx = checkNotNull(trade.getDelayedPayoutTx());
|
|
||||||
// WalletService.maybeAddSelfTxToWallet(delayedPayoutTx, processModel.getBtcWalletService().getWallet());
|
|
||||||
//
|
|
||||||
// processModel.getTradeManager().requestPersistence();
|
|
||||||
//
|
|
||||||
// complete();
|
|
||||||
} catch (Throwable t) {
|
|
||||||
failed(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -88,7 +88,7 @@ public class ProcessSignContractResponse extends TradeTask {
|
||||||
@Override
|
@Override
|
||||||
public void onArrived() {
|
public void onArrived() {
|
||||||
log.info("{} arrived: arbitrator={}; offerId={}; uid={}", request.getClass().getSimpleName(), trade.getArbitratorNodeAddress(), trade.getId(), request.getUid());
|
log.info("{} arrived: arbitrator={}; offerId={}; uid={}", request.getClass().getSimpleName(), trade.getArbitratorNodeAddress(), trade.getId(), request.getUid());
|
||||||
trade.setState(Trade.State.MAKER_SENT_PUBLISH_DEPOSIT_TX_REQUEST); // TODO: rename to DEPOSIT_REQUESTED
|
trade.setState(Trade.State.SENT_PUBLISH_DEPOSIT_TX_REQUEST); // TODO: rename to DEPOSIT_REQUESTED
|
||||||
processModel.getTradeManager().requestPersistence();
|
processModel.getTradeManager().requestPersistence();
|
||||||
complete();
|
complete();
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,11 +15,9 @@
|
||||||
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.seller;
|
package bisq.core.trade.protocol.tasks;
|
||||||
|
|
||||||
import bisq.core.trade.Trade;
|
import bisq.core.trade.Trade;
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
import bisq.common.taskrunner.TaskRunner;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
|
@ -15,7 +15,7 @@
|
||||||
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.seller;
|
package bisq.core.trade.protocol.tasks;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
@ -23,7 +23,6 @@ import bisq.common.taskrunner.TaskRunner;
|
||||||
import bisq.core.btc.wallet.XmrWalletService;
|
import bisq.core.btc.wallet.XmrWalletService;
|
||||||
import bisq.core.trade.Trade;
|
import bisq.core.trade.Trade;
|
||||||
import bisq.core.trade.messages.PaymentSentMessage;
|
import bisq.core.trade.messages.PaymentSentMessage;
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
import bisq.core.util.Validator;
|
import bisq.core.util.Validator;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import monero.wallet.MoneroWallet;
|
import monero.wallet.MoneroWallet;
|
|
@ -15,11 +15,9 @@
|
||||||
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.seller;
|
package bisq.core.trade.protocol.tasks;
|
||||||
|
|
||||||
import bisq.core.trade.Trade;
|
import bisq.core.trade.Trade;
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
import bisq.common.taskrunner.TaskRunner;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
|
@ -15,11 +15,9 @@
|
||||||
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.seller;
|
package bisq.core.trade.protocol.tasks;
|
||||||
|
|
||||||
import bisq.core.trade.Trade;
|
import bisq.core.trade.Trade;
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
import bisq.common.taskrunner.TaskRunner;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
|
@ -15,15 +15,13 @@
|
||||||
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
* along with Haveno. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.seller;
|
package bisq.core.trade.protocol.tasks;
|
||||||
|
|
||||||
import bisq.core.account.sign.SignedWitness;
|
import bisq.core.account.sign.SignedWitness;
|
||||||
import bisq.core.account.witness.AccountAgeWitnessService;
|
import bisq.core.account.witness.AccountAgeWitnessService;
|
||||||
import bisq.core.trade.Trade;
|
import bisq.core.trade.Trade;
|
||||||
import bisq.core.trade.messages.PaymentReceivedMessage;
|
import bisq.core.trade.messages.PaymentReceivedMessage;
|
||||||
import bisq.core.trade.messages.TradeMailboxMessage;
|
import bisq.core.trade.messages.TradeMailboxMessage;
|
||||||
import bisq.core.trade.protocol.tasks.SendMailboxMessageTask;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
import bisq.common.taskrunner.TaskRunner;
|
||||||
|
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
|
@ -1,65 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.arbitration;
|
|
||||||
|
|
||||||
import bisq.core.trade.Trade;
|
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class PublishedDelayedPayoutTx extends TradeTask {
|
|
||||||
public PublishedDelayedPayoutTx(TaskRunner<Trade> taskHandler, Trade trade) {
|
|
||||||
super(taskHandler, trade);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void run() {
|
|
||||||
throw new RuntimeException("PublishedDelayedPayoutTx not implemented for XMR");
|
|
||||||
// try {
|
|
||||||
// runInterceptHook();
|
|
||||||
//
|
|
||||||
// Transaction delayedPayoutTx = trade.getDelayedPayoutTx();
|
|
||||||
// BtcWalletService btcWalletService = processModel.getBtcWalletService();
|
|
||||||
//
|
|
||||||
// // We have spent the funds from the deposit tx with the delayedPayoutTx
|
|
||||||
// btcWalletService.resetCoinLockedInMultiSigAddressEntry(trade.getId());
|
|
||||||
// // We might receive funds on AddressEntry.Context.TRADE_PAYOUT so we don't swap that
|
|
||||||
//
|
|
||||||
// Transaction committedDelayedPayoutTx = WalletService.maybeAddSelfTxToWallet(delayedPayoutTx, btcWalletService.getWallet());
|
|
||||||
//
|
|
||||||
// processModel.getTradeWalletService().broadcastTx(committedDelayedPayoutTx, new TxBroadcaster.Callback() {
|
|
||||||
// @Override
|
|
||||||
// public void onSuccess(Transaction transaction) {
|
|
||||||
// log.info("publishDelayedPayoutTx onSuccess " + transaction);
|
|
||||||
// complete();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public void onFailure(TxBroadcastException exception) {
|
|
||||||
// log.error("publishDelayedPayoutTx onFailure", exception);
|
|
||||||
// failed(exception.toString());
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// } catch (Throwable t) {
|
|
||||||
// failed(t);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,71 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.arbitration;
|
|
||||||
|
|
||||||
import bisq.core.trade.Trade;
|
|
||||||
import bisq.core.trade.messages.PeerPublishedDelayedPayoutTxMessage;
|
|
||||||
import bisq.core.trade.messages.TradeMailboxMessage;
|
|
||||||
import bisq.core.trade.protocol.tasks.SendMailboxMessageTask;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class SendPeerPublishedDelayedPayoutTxMessage extends SendMailboxMessageTask {
|
|
||||||
|
|
||||||
public SendPeerPublishedDelayedPayoutTxMessage(TaskRunner<Trade> taskHandler, Trade trade) {
|
|
||||||
super(taskHandler, trade);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected TradeMailboxMessage getTradeMailboxMessage(String id) {
|
|
||||||
return new PeerPublishedDelayedPayoutTxMessage(UUID.randomUUID().toString(),
|
|
||||||
trade.getId(),
|
|
||||||
trade.getTradingPeerNodeAddress());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void setStateSent() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void setStateArrived() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void setStateStoredInMailbox() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void setStateFault() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void run() {
|
|
||||||
try {
|
|
||||||
runInterceptHook();
|
|
||||||
|
|
||||||
super.run();
|
|
||||||
} catch (Throwable t) {
|
|
||||||
failed(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,61 +0,0 @@
|
||||||
package bisq.core.trade.protocol.tasks.buyer;
|
|
||||||
|
|
||||||
import bisq.core.btc.model.AddressEntry;
|
|
||||||
import bisq.core.btc.wallet.BtcWalletService;
|
|
||||||
import bisq.core.trade.Trade;
|
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
|
||||||
import bisq.common.util.Utilities;
|
|
||||||
|
|
||||||
import org.bitcoinj.core.Transaction;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class BuyerFinalizesDelayedPayoutTx extends TradeTask {
|
|
||||||
public BuyerFinalizesDelayedPayoutTx(TaskRunner<Trade> taskHandler, Trade trade) {
|
|
||||||
super(taskHandler, trade);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void run() {
|
|
||||||
try {
|
|
||||||
runInterceptHook();
|
|
||||||
|
|
||||||
BtcWalletService btcWalletService = processModel.getBtcWalletService();
|
|
||||||
String id = processModel.getOffer().getId();
|
|
||||||
Transaction preparedDepositTx = btcWalletService.getTxFromSerializedTx(processModel.getPreparedDepositTx());
|
|
||||||
Transaction preparedDelayedPayoutTx = checkNotNull(processModel.getPreparedDelayedPayoutTx());
|
|
||||||
|
|
||||||
byte[] buyerMultiSigPubKey = processModel.getMyMultiSigPubKey();
|
|
||||||
checkArgument(Arrays.equals(buyerMultiSigPubKey,
|
|
||||||
btcWalletService.getOrCreateAddressEntry(id, AddressEntry.Context.MULTI_SIG).getPubKey()),
|
|
||||||
"buyerMultiSigPubKey from AddressEntry must match the one from the trade data. trade id =" + id);
|
|
||||||
byte[] sellerMultiSigPubKey = trade.getTradingPeer().getMultiSigPubKey();
|
|
||||||
|
|
||||||
byte[] buyerSignature = processModel.getDelayedPayoutTxSignature();
|
|
||||||
byte[] sellerSignature = trade.getTradingPeer().getDelayedPayoutTxSignature();
|
|
||||||
|
|
||||||
Transaction signedDelayedPayoutTx = processModel.getTradeWalletService().finalizeUnconnectedDelayedPayoutTx(
|
|
||||||
preparedDelayedPayoutTx,
|
|
||||||
buyerMultiSigPubKey,
|
|
||||||
sellerMultiSigPubKey,
|
|
||||||
buyerSignature,
|
|
||||||
sellerSignature,
|
|
||||||
preparedDepositTx.getOutput(0).getValue());
|
|
||||||
|
|
||||||
trade.applyDelayedPayoutTxBytes(signedDelayedPayoutTx.bitcoinSerialize());
|
|
||||||
log.info("DelayedPayoutTxBytes = {}", Utilities.bytesAsHexString(trade.getDelayedPayoutTxBytes()));
|
|
||||||
|
|
||||||
complete();
|
|
||||||
} catch (Throwable t) {
|
|
||||||
failed(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,65 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.buyer;
|
|
||||||
|
|
||||||
import bisq.core.trade.Trade;
|
|
||||||
import bisq.core.trade.messages.DelayedPayoutTxSignatureRequest;
|
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
import bisq.core.util.Validator;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
|
||||||
|
|
||||||
import org.bitcoinj.core.Transaction;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class BuyerProcessDelayedPayoutTxSignatureRequest extends TradeTask {
|
|
||||||
public BuyerProcessDelayedPayoutTxSignatureRequest(TaskRunner<Trade> taskHandler, Trade trade) {
|
|
||||||
super(taskHandler, trade);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void run() {
|
|
||||||
try {
|
|
||||||
runInterceptHook();
|
|
||||||
DelayedPayoutTxSignatureRequest request = (DelayedPayoutTxSignatureRequest) processModel.getTradeMessage();
|
|
||||||
checkNotNull(request);
|
|
||||||
Validator.checkTradeId(processModel.getOfferId(), request);
|
|
||||||
byte[] delayedPayoutTxAsBytes = checkNotNull(request.getDelayedPayoutTx());
|
|
||||||
Transaction preparedDelayedPayoutTx = processModel.getBtcWalletService().getTxFromSerializedTx(delayedPayoutTxAsBytes);
|
|
||||||
processModel.setPreparedDelayedPayoutTx(preparedDelayedPayoutTx);
|
|
||||||
trade.getTradingPeer().setDelayedPayoutTxSignature(checkNotNull(request.getDelayedPayoutTxSellerSignature()));
|
|
||||||
|
|
||||||
// When we receive that message the taker has published the taker fee, so we apply it to the trade.
|
|
||||||
// The takerFeeTx was sent in the first message. It should be part of DelayedPayoutTxSignatureRequest
|
|
||||||
// but that cannot be changed due backward compatibility issues. It is a left over from the old trade protocol.
|
|
||||||
trade.setTakerFeeTxId(processModel.getTakeOfferFeeTxId());
|
|
||||||
|
|
||||||
trade.setTradingPeerNodeAddress(processModel.getTempTradingPeerNodeAddress());
|
|
||||||
|
|
||||||
processModel.getTradeManager().requestPersistence();
|
|
||||||
|
|
||||||
complete();
|
|
||||||
} catch (Throwable t) {
|
|
||||||
failed(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,72 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.buyer;
|
|
||||||
|
|
||||||
import bisq.core.trade.Trade;
|
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class BuyerProcessDepositTxAndDelayedPayoutTxMessage extends TradeTask {
|
|
||||||
public BuyerProcessDepositTxAndDelayedPayoutTxMessage(TaskRunner<Trade> taskHandler, Trade trade) {
|
|
||||||
super(taskHandler, trade);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void run() {
|
|
||||||
try {
|
|
||||||
runInterceptHook();
|
|
||||||
throw new RuntimeException("BuyerProcessDepositTxAndDelayedPayoutTxMessage invalid in xmr base pair");
|
|
||||||
// var message = checkNotNull((DepositTxAndDelayedPayoutTxMessage) processModel.getTradeMessage());
|
|
||||||
// checkNotNull(message);
|
|
||||||
// Validator.checkTradeId(processModel.getOfferId(), message);
|
|
||||||
//
|
|
||||||
// // To access tx confidence we need to add that tx into our wallet.
|
|
||||||
// byte[] depositTxBytes = checkNotNull(message.getDepositTx());
|
|
||||||
// Transaction depositTx = processModel.getBtcWalletService().getTxFromSerializedTx(depositTxBytes);
|
|
||||||
// // update with full tx
|
|
||||||
// Wallet wallet = processModel.getBtcWalletService().getWallet();
|
|
||||||
// Transaction committedDepositTx = WalletService.maybeAddSelfTxToWallet(depositTx, wallet);
|
|
||||||
// trade.applyDepositTx(committedDepositTx);
|
|
||||||
// BtcWalletService.printTx("depositTx received from peer", committedDepositTx);
|
|
||||||
//
|
|
||||||
// // To access tx confidence we need to add that tx into our wallet.
|
|
||||||
// byte[] delayedPayoutTxBytes = checkNotNull(message.getDelayedPayoutTx());
|
|
||||||
// trade.applyDelayedPayoutTxBytes(delayedPayoutTxBytes);
|
|
||||||
// BtcWalletService.printTx("delayedPayoutTx received from peer",
|
|
||||||
// checkNotNull(trade.getDelayedPayoutTx()));
|
|
||||||
//
|
|
||||||
// trade.setTradingPeerNodeAddress(processModel.getTempTradingPeerNodeAddress());
|
|
||||||
//
|
|
||||||
// // If we got already the confirmation we don't want to apply an earlier state
|
|
||||||
// if (trade.getState().ordinal() < Trade.State.BUYER_SAW_DEPOSIT_TX_IN_NETWORK.ordinal()) {
|
|
||||||
// trade.setState(Trade.State.BUYER_RECEIVED_DEPOSIT_TX_PUBLISHED_MSG);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// processModel.getBtcWalletService().swapTradeEntryToAvailableEntry(trade.getId(),
|
|
||||||
// AddressEntry.Context.RESERVED_FOR_TRADE);
|
|
||||||
//
|
|
||||||
// complete();
|
|
||||||
} catch (Throwable t) {
|
|
||||||
failed(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,85 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.buyer;
|
|
||||||
|
|
||||||
import bisq.core.trade.Trade;
|
|
||||||
import bisq.core.trade.messages.DelayedPayoutTxSignatureResponse;
|
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
|
|
||||||
import bisq.network.p2p.NodeAddress;
|
|
||||||
import bisq.network.p2p.SendDirectMessageListener;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class BuyerSendsDelayedPayoutTxSignatureResponse extends TradeTask {
|
|
||||||
public BuyerSendsDelayedPayoutTxSignatureResponse(TaskRunner<Trade> taskHandler, Trade trade) {
|
|
||||||
super(taskHandler, trade);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void run() {
|
|
||||||
try {
|
|
||||||
runInterceptHook();
|
|
||||||
|
|
||||||
byte[] delayedPayoutTxSignature = checkNotNull(processModel.getDelayedPayoutTxSignature());
|
|
||||||
byte[] depositTxBytes = processModel.getDepositTx() != null
|
|
||||||
? processModel.getDepositTx().bitcoinSerialize() // set in BuyerAsTakerSignsDepositTx task
|
|
||||||
: processModel.getPreparedDepositTx(); // set in BuyerAsMakerCreatesAndSignsDepositTx task
|
|
||||||
|
|
||||||
DelayedPayoutTxSignatureResponse message = new DelayedPayoutTxSignatureResponse(UUID.randomUUID().toString(),
|
|
||||||
processModel.getOfferId(),
|
|
||||||
processModel.getMyNodeAddress(),
|
|
||||||
delayedPayoutTxSignature,
|
|
||||||
depositTxBytes);
|
|
||||||
|
|
||||||
NodeAddress peersNodeAddress = trade.getTradingPeerNodeAddress();
|
|
||||||
log.info("Send {} to peer {}. tradeId={}, uid={}",
|
|
||||||
message.getClass().getSimpleName(), peersNodeAddress, message.getTradeId(), message.getUid());
|
|
||||||
processModel.getP2PService().sendEncryptedDirectMessage(
|
|
||||||
peersNodeAddress,
|
|
||||||
trade.getTradingPeer().getPubKeyRing(),
|
|
||||||
message,
|
|
||||||
new SendDirectMessageListener() {
|
|
||||||
@Override
|
|
||||||
public void onArrived() {
|
|
||||||
log.info("{} arrived at peer {}. tradeId={}, uid={}",
|
|
||||||
message.getClass().getSimpleName(), peersNodeAddress, message.getTradeId(), message.getUid());
|
|
||||||
complete();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFault(String errorMessage) {
|
|
||||||
log.error("{} failed: Peer {}. tradeId={}, uid={}, errorMessage={}",
|
|
||||||
message.getClass().getSimpleName(), peersNodeAddress, message.getTradeId(), message.getUid(), errorMessage);
|
|
||||||
appendToErrorMessage("Sending message failed: message=" + message + "\nerrorMessage=" + errorMessage);
|
|
||||||
failed(errorMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} catch (Throwable t) {
|
|
||||||
failed(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,79 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.buyer;
|
|
||||||
|
|
||||||
import bisq.core.btc.model.AddressEntry;
|
|
||||||
import bisq.core.btc.wallet.BtcWalletService;
|
|
||||||
import bisq.core.trade.Trade;
|
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
|
||||||
|
|
||||||
import org.bitcoinj.core.NetworkParameters;
|
|
||||||
import org.bitcoinj.core.Transaction;
|
|
||||||
import org.bitcoinj.crypto.DeterministicKey;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class BuyerSignsDelayedPayoutTx extends TradeTask {
|
|
||||||
public BuyerSignsDelayedPayoutTx(TaskRunner<Trade> taskHandler, Trade trade) {
|
|
||||||
super(taskHandler, trade);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void run() {
|
|
||||||
try {
|
|
||||||
runInterceptHook();
|
|
||||||
|
|
||||||
Transaction preparedDelayedPayoutTx = checkNotNull(processModel.getPreparedDelayedPayoutTx());
|
|
||||||
|
|
||||||
BtcWalletService btcWalletService = processModel.getBtcWalletService();
|
|
||||||
NetworkParameters params = btcWalletService.getParams();
|
|
||||||
Transaction preparedDepositTx = new Transaction(params, processModel.getPreparedDepositTx());
|
|
||||||
|
|
||||||
String id = processModel.getOffer().getId();
|
|
||||||
|
|
||||||
byte[] buyerMultiSigPubKey = processModel.getMyMultiSigPubKey();
|
|
||||||
DeterministicKey myMultiSigKeyPair = btcWalletService.getMultiSigKeyPair(id, buyerMultiSigPubKey);
|
|
||||||
|
|
||||||
checkArgument(Arrays.equals(buyerMultiSigPubKey,
|
|
||||||
btcWalletService.getOrCreateAddressEntry(id, AddressEntry.Context.MULTI_SIG).getPubKey()),
|
|
||||||
"buyerMultiSigPubKey from AddressEntry must match the one from the trade data. trade id =" + id);
|
|
||||||
byte[] sellerMultiSigPubKey = trade.getTradingPeer().getMultiSigPubKey();
|
|
||||||
byte[] delayedPayoutTxSignature = processModel.getTradeWalletService().signDelayedPayoutTx(
|
|
||||||
preparedDelayedPayoutTx,
|
|
||||||
preparedDepositTx,
|
|
||||||
myMultiSigKeyPair,
|
|
||||||
buyerMultiSigPubKey,
|
|
||||||
sellerMultiSigPubKey);
|
|
||||||
processModel.setDelayedPayoutTxSignature(delayedPayoutTxSignature);
|
|
||||||
|
|
||||||
processModel.getTradeManager().requestPersistence();
|
|
||||||
|
|
||||||
complete();
|
|
||||||
} catch (Throwable t) {
|
|
||||||
failed(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.buyer;
|
|
||||||
|
|
||||||
import bisq.core.trade.Trade;
|
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class BuyerVerifiesFinalDelayedPayoutTx extends TradeTask {
|
|
||||||
public BuyerVerifiesFinalDelayedPayoutTx(TaskRunner<Trade> taskHandler, Trade trade) {
|
|
||||||
super(taskHandler, trade);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void run() {
|
|
||||||
try {
|
|
||||||
runInterceptHook();
|
|
||||||
|
|
||||||
throw new RuntimeException("BuyerVerifiesFinalDelayedPayoutTx not applicable for xmr");
|
|
||||||
} catch (Throwable t) {
|
|
||||||
failed(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,71 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.buyer;
|
|
||||||
|
|
||||||
import bisq.core.trade.Trade;
|
|
||||||
import bisq.core.trade.TradeDataValidation;
|
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class BuyerVerifiesPreparedDelayedPayoutTx extends TradeTask {
|
|
||||||
public BuyerVerifiesPreparedDelayedPayoutTx(TaskRunner<Trade> taskHandler, Trade trade) {
|
|
||||||
super(taskHandler, trade);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void run() {
|
|
||||||
try {
|
|
||||||
runInterceptHook();
|
|
||||||
|
|
||||||
var preparedDelayedPayoutTx = processModel.getPreparedDelayedPayoutTx();
|
|
||||||
TradeDataValidation.validateDelayedPayoutTx(trade,
|
|
||||||
preparedDelayedPayoutTx,
|
|
||||||
processModel.getBtcWalletService());
|
|
||||||
|
|
||||||
// If the deposit tx is non-malleable, we already know its final ID, so should check that now
|
|
||||||
// before sending any further data to the seller, to provide extra protection for the buyer.
|
|
||||||
if (isDepositTxNonMalleable()) {
|
|
||||||
var preparedDepositTx = processModel.getBtcWalletService().getTxFromSerializedTx(
|
|
||||||
processModel.getPreparedDepositTx());
|
|
||||||
TradeDataValidation.validatePayoutTxInput(preparedDepositTx, checkNotNull(preparedDelayedPayoutTx));
|
|
||||||
} else {
|
|
||||||
log.info("Deposit tx is malleable, so we skip preparedDelayedPayoutTx input validation.");
|
|
||||||
}
|
|
||||||
|
|
||||||
complete();
|
|
||||||
} catch (TradeDataValidation.ValidationException e) {
|
|
||||||
failed(e.getMessage());
|
|
||||||
} catch (Throwable t) {
|
|
||||||
failed(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isDepositTxNonMalleable() {
|
|
||||||
var buyerInputs = checkNotNull(processModel.getRawTransactionInputs());
|
|
||||||
var sellerInputs = checkNotNull(trade.getTradingPeer().getRawTransactionInputs());
|
|
||||||
|
|
||||||
return buyerInputs.stream().allMatch(processModel.getTradeWalletService()::isP2WH) &&
|
|
||||||
sellerInputs.stream().allMatch(processModel.getTradeWalletService()::isP2WH);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,109 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.buyer_as_maker;
|
|
||||||
|
|
||||||
import bisq.core.btc.model.AddressEntry;
|
|
||||||
import bisq.core.btc.model.PreparedDepositTxAndMakerInputs;
|
|
||||||
import bisq.core.btc.model.RawTransactionInput;
|
|
||||||
import bisq.core.btc.wallet.BtcWalletService;
|
|
||||||
import bisq.core.offer.Offer;
|
|
||||||
import bisq.core.trade.Trade;
|
|
||||||
import bisq.core.trade.protocol.TradingPeer;
|
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
|
||||||
|
|
||||||
import org.bitcoinj.core.Address;
|
|
||||||
import org.bitcoinj.core.Coin;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class BuyerAsMakerCreatesAndSignsDepositTx extends TradeTask {
|
|
||||||
public BuyerAsMakerCreatesAndSignsDepositTx(TaskRunner<Trade> taskHandler, Trade trade) {
|
|
||||||
super(taskHandler, trade);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void run() {
|
|
||||||
try {
|
|
||||||
runInterceptHook();
|
|
||||||
Coin tradeAmount = checkNotNull(trade.getAmount(), "trade.getTradeAmount() must not be null");
|
|
||||||
|
|
||||||
BtcWalletService walletService = processModel.getBtcWalletService();
|
|
||||||
String id = processModel.getOffer().getId();
|
|
||||||
TradingPeer tradingPeer = trade.getTradingPeer();
|
|
||||||
Offer offer = checkNotNull(trade.getOffer());
|
|
||||||
|
|
||||||
Coin makerInputAmount = offer.getBuyerSecurityDeposit();
|
|
||||||
Optional<AddressEntry> addressEntryOptional = walletService.getAddressEntry(id, AddressEntry.Context.MULTI_SIG);
|
|
||||||
checkArgument(addressEntryOptional.isPresent(), "addressEntryOptional must be present");
|
|
||||||
AddressEntry makerMultiSigAddressEntry = addressEntryOptional.get();
|
|
||||||
processModel.getBtcWalletService().setCoinLockedInMultiSigAddressEntry(makerMultiSigAddressEntry, makerInputAmount.value);
|
|
||||||
walletService.saveAddressEntryList();
|
|
||||||
|
|
||||||
Coin msOutputAmount = makerInputAmount
|
|
||||||
.add(trade.getTxFee())
|
|
||||||
.add(offer.getSellerSecurityDeposit())
|
|
||||||
.add(tradeAmount);
|
|
||||||
|
|
||||||
List<RawTransactionInput> takerRawTransactionInputs = checkNotNull(tradingPeer.getRawTransactionInputs());
|
|
||||||
checkArgument(takerRawTransactionInputs.stream().allMatch(processModel.getTradeWalletService()::isP2WH),
|
|
||||||
"all takerRawTransactionInputs must be P2WH");
|
|
||||||
long takerChangeOutputValue = tradingPeer.getChangeOutputValue();
|
|
||||||
@Nullable String takerChangeAddressString = tradingPeer.getChangeOutputAddress();
|
|
||||||
Address makerAddress = walletService.getOrCreateAddressEntry(id, AddressEntry.Context.RESERVED_FOR_TRADE).getAddress();
|
|
||||||
Address makerChangeAddress = walletService.getFreshAddressEntry().getAddress();
|
|
||||||
byte[] buyerPubKey = processModel.getMyMultiSigPubKey();
|
|
||||||
byte[] sellerPubKey = checkNotNull(tradingPeer.getMultiSigPubKey());
|
|
||||||
checkArgument(Arrays.equals(buyerPubKey,
|
|
||||||
makerMultiSigAddressEntry.getPubKey()),
|
|
||||||
"buyerPubKey from AddressEntry must match the one from the trade data. trade id =" + id);
|
|
||||||
|
|
||||||
PreparedDepositTxAndMakerInputs result = processModel.getTradeWalletService().buyerAsMakerCreatesAndSignsDepositTx(
|
|
||||||
trade.getContractHash(),
|
|
||||||
makerInputAmount,
|
|
||||||
msOutputAmount,
|
|
||||||
takerRawTransactionInputs,
|
|
||||||
takerChangeOutputValue,
|
|
||||||
takerChangeAddressString,
|
|
||||||
makerAddress,
|
|
||||||
makerChangeAddress,
|
|
||||||
buyerPubKey,
|
|
||||||
sellerPubKey);
|
|
||||||
|
|
||||||
processModel.setPreparedDepositTx(result.depositTransaction);
|
|
||||||
processModel.setRawTransactionInputs(result.rawMakerInputs);
|
|
||||||
|
|
||||||
processModel.getTradeManager().requestPersistence();
|
|
||||||
|
|
||||||
complete();
|
|
||||||
} catch (Throwable t) {
|
|
||||||
failed(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.buyer_as_maker;
|
|
||||||
|
|
||||||
import bisq.core.trade.Trade;
|
|
||||||
import bisq.core.trade.protocol.tasks.maker.MakerSendsInputsForDepositTxResponse;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
|
||||||
|
|
||||||
import org.bitcoinj.core.Transaction;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class BuyerAsMakerSendsInputsForDepositTxResponse extends MakerSendsInputsForDepositTxResponse {
|
|
||||||
public BuyerAsMakerSendsInputsForDepositTxResponse(TaskRunner<Trade> taskHandler, Trade trade) {
|
|
||||||
super(taskHandler, trade);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected byte[] getPreparedDepositTx() {
|
|
||||||
Transaction preparedDepositTx = processModel.getBtcWalletService().getTxFromSerializedTx(processModel.getPreparedDepositTx());
|
|
||||||
// Remove witnesses from preparedDepositTx, so that the seller can still compute the final
|
|
||||||
// tx id, but cannot publish it before providing the buyer with a signed delayed payout tx.
|
|
||||||
return preparedDepositTx.bitcoinSerialize(false);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,60 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.buyer_as_taker;
|
|
||||||
|
|
||||||
import bisq.core.trade.Trade;
|
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class BuyerAsTakerCreatesDepositTxInputs extends TradeTask {
|
|
||||||
|
|
||||||
public BuyerAsTakerCreatesDepositTxInputs(TaskRunner<Trade> taskHandler, Trade trade) {
|
|
||||||
super(taskHandler, trade);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void run() {
|
|
||||||
try {
|
|
||||||
runInterceptHook();
|
|
||||||
|
|
||||||
throw new RuntimeException("Outputs not communicated in xmr integration");
|
|
||||||
|
|
||||||
// processModel.getTradeManager().requestPersistence();
|
|
||||||
|
|
||||||
// Coin txFee = trade.getTxFee();
|
|
||||||
// Coin takerInputAmount = checkNotNull(trade.getOffer()).getBuyerSecurityDeposit()
|
|
||||||
// .add(txFee)
|
|
||||||
// .add(txFee); // 2 times the fee as we need it for payout tx as well
|
|
||||||
// InputsAndChangeOutput result = processModel.getTradeWalletService().takerCreatesDepositTxInputs(
|
|
||||||
// processModel.getTakeOfferFeeTx(),
|
|
||||||
// takerInputAmount,
|
|
||||||
// txFee);
|
|
||||||
// processModel.setRawTransactionInputs(result.rawTransactionInputs);
|
|
||||||
// processModel.setChangeOutputValue(result.changeOutputValue);
|
|
||||||
// processModel.setChangeOutputAddress(result.changeOutputAddress);
|
|
||||||
//
|
|
||||||
// complete();
|
|
||||||
} catch (Throwable t) {
|
|
||||||
failed(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,77 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.buyer_as_taker;
|
|
||||||
|
|
||||||
import bisq.core.trade.Trade;
|
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class BuyerAsTakerSendsDepositTxMessage extends TradeTask {
|
|
||||||
public BuyerAsTakerSendsDepositTxMessage(TaskRunner<Trade> taskHandler, Trade trade) {
|
|
||||||
super(taskHandler, trade);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void run() {
|
|
||||||
try {
|
|
||||||
runInterceptHook();
|
|
||||||
throw new RuntimeException("BuyerAsTakerSendsDepositTxMessage not implemented for xmr");
|
|
||||||
// if (processModel.getDepositTx() != null) {
|
|
||||||
// DepositTxMessage message = new DepositTxMessage(UUID.randomUUID().toString(),
|
|
||||||
// processModel.getOfferId(),
|
|
||||||
// processModel.getMyNodeAddress(),
|
|
||||||
// processModel.getDepositTx().bitcoinSerialize());
|
|
||||||
//
|
|
||||||
// NodeAddress peersNodeAddress = trade.getTradingPeerNodeAddress();
|
|
||||||
// log.info("Send {} to peer {}. tradeId={}, uid={}",
|
|
||||||
// message.getClass().getSimpleName(), peersNodeAddress, message.getTradeId(), message.getUid());
|
|
||||||
// processModel.getP2PService().sendEncryptedDirectMessage(
|
|
||||||
// peersNodeAddress,
|
|
||||||
// trade.getTradingPeer().getPubKeyRing(),
|
|
||||||
// message,
|
|
||||||
// new SendDirectMessageListener() {
|
|
||||||
// @Override
|
|
||||||
// public void onArrived() {
|
|
||||||
// log.info("{} arrived at peer {}. tradeId={}, uid={}",
|
|
||||||
// message.getClass().getSimpleName(), peersNodeAddress, message.getTradeId(), message.getUid());
|
|
||||||
// complete();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public void onFault(String errorMessage) {
|
|
||||||
// log.error("{} failed: Peer {}. tradeId={}, uid={}, errorMessage={}",
|
|
||||||
// message.getClass().getSimpleName(), peersNodeAddress, message.getTradeId(), message.getUid(), errorMessage);
|
|
||||||
//
|
|
||||||
// appendToErrorMessage("Sending message failed: message=" + message + "\nerrorMessage=" + errorMessage);
|
|
||||||
// failed();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
// } else {
|
|
||||||
// log.error("processModel.getDepositTx() = " + processModel.getDepositTx());
|
|
||||||
// failed("DepositTx is null");
|
|
||||||
// }
|
|
||||||
} catch (Throwable t) {
|
|
||||||
failed(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,82 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.buyer_as_taker;
|
|
||||||
|
|
||||||
import bisq.core.trade.Trade;
|
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class BuyerAsTakerSignsDepositTx extends TradeTask {
|
|
||||||
|
|
||||||
public BuyerAsTakerSignsDepositTx(TaskRunner<Trade> taskHandler, Trade trade) {
|
|
||||||
super(taskHandler, trade);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void run() {
|
|
||||||
try {
|
|
||||||
runInterceptHook();
|
|
||||||
throw new RuntimeException("BuyerAsTakerSignsDepositTx not implemented for xmr");
|
|
||||||
|
|
||||||
/* log.debug("\n\n------------------------------------------------------------\n"
|
|
||||||
+ "Contract as json\n"
|
|
||||||
+ trade.getContractAsJson()
|
|
||||||
+ "\n------------------------------------------------------------\n");*/
|
|
||||||
|
|
||||||
|
|
||||||
// byte[] contractHash = Hash.getSha256Hash(checkNotNull(trade.getContractAsJson()));
|
|
||||||
// trade.setContractHash(contractHash);
|
|
||||||
// List<RawTransactionInput> buyerInputs = checkNotNull(processModel.getRawTransactionInputs(), "buyerInputs must not be null");
|
|
||||||
// BtcWalletService walletService = processModel.getBtcWalletService();
|
|
||||||
// String id = processModel.getOffer().getId();
|
|
||||||
//
|
|
||||||
// Optional<AddressEntry> addressEntryOptional = walletService.getAddressEntry(id, AddressEntry.Context.MULTI_SIG);
|
|
||||||
// checkArgument(addressEntryOptional.isPresent(), "addressEntryOptional must be present");
|
|
||||||
// AddressEntry buyerMultiSigAddressEntry = addressEntryOptional.get();
|
|
||||||
// Coin buyerInput = Coin.valueOf(buyerInputs.stream().mapToLong(input -> input.value).sum());
|
|
||||||
//
|
|
||||||
// buyerMultiSigAddressEntry.setCoinLockedInMultiSig(buyerInput.subtract(trade.getTxFee().multiply(2)));
|
|
||||||
// walletService.saveAddressEntryList();
|
|
||||||
//
|
|
||||||
// TradingPeer tradingPeer = trade.getTradingPeer();
|
|
||||||
// byte[] buyerMultiSigPubKey = processModel.getMyMultiSigPubKey();
|
|
||||||
// checkArgument(Arrays.equals(buyerMultiSigPubKey, buyerMultiSigAddressEntry.getPubKey()),
|
|
||||||
// "buyerMultiSigPubKey from AddressEntry must match the one from the trade data. trade id =" + id);
|
|
||||||
//
|
|
||||||
// List<RawTransactionInput> sellerInputs = checkNotNull(tradingPeer.getRawTransactionInputs());
|
|
||||||
// byte[] sellerMultiSigPubKey = tradingPeer.getMultiSigPubKey();
|
|
||||||
// Transaction depositTx = processModel.getTradeWalletService().takerSignsDepositTx(
|
|
||||||
// false,
|
|
||||||
// contractHash,
|
|
||||||
// processModel.getPreparedDepositTx(),
|
|
||||||
// buyerInputs,
|
|
||||||
// sellerInputs,
|
|
||||||
// buyerMultiSigPubKey,
|
|
||||||
// sellerMultiSigPubKey);
|
|
||||||
// processModel.setDepositTx(depositTx);
|
|
||||||
//
|
|
||||||
// complete();
|
|
||||||
} catch (Throwable t) {
|
|
||||||
failed(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,125 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.maker;
|
|
||||||
|
|
||||||
import bisq.core.btc.model.AddressEntry;
|
|
||||||
import bisq.core.btc.wallet.BtcWalletService;
|
|
||||||
import bisq.core.trade.Trade;
|
|
||||||
import bisq.core.trade.messages.InputsForDepositTxResponse;
|
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
|
|
||||||
import bisq.network.p2p.NodeAddress;
|
|
||||||
import bisq.network.p2p.SendDirectMessageListener;
|
|
||||||
|
|
||||||
import bisq.common.crypto.Sig;
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
|
||||||
|
|
||||||
import java.security.PrivateKey;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public abstract class MakerSendsInputsForDepositTxResponse extends TradeTask {
|
|
||||||
public MakerSendsInputsForDepositTxResponse(TaskRunner<Trade> taskHandler, Trade trade) {
|
|
||||||
super(taskHandler, trade);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract byte[] getPreparedDepositTx();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void run() {
|
|
||||||
try {
|
|
||||||
runInterceptHook();
|
|
||||||
BtcWalletService walletService = processModel.getBtcWalletService();
|
|
||||||
String id = processModel.getOffer().getId();
|
|
||||||
|
|
||||||
Optional<AddressEntry> optionalMultiSigAddressEntry = walletService.getAddressEntry(id, AddressEntry.Context.MULTI_SIG);
|
|
||||||
checkArgument(optionalMultiSigAddressEntry.isPresent(), "addressEntry must be set here.");
|
|
||||||
AddressEntry makerPayoutAddressEntry = walletService.getOrCreateAddressEntry(id, AddressEntry.Context.TRADE_PAYOUT);
|
|
||||||
byte[] makerMultiSigPubKey = processModel.getMyMultiSigPubKey();
|
|
||||||
checkArgument(Arrays.equals(makerMultiSigPubKey,
|
|
||||||
optionalMultiSigAddressEntry.get().getPubKey()),
|
|
||||||
"makerMultiSigPubKey from AddressEntry must match the one from the trade data. trade id =" + id);
|
|
||||||
|
|
||||||
byte[] preparedDepositTx = getPreparedDepositTx();
|
|
||||||
|
|
||||||
// Maker has to use preparedDepositTx as nonce.
|
|
||||||
// He cannot manipulate the preparedDepositTx - so we avoid to have a challenge protocol for passing the
|
|
||||||
// nonce we want to get signed.
|
|
||||||
// This is used for verifying the peers account age witness
|
|
||||||
PrivateKey privateKey = processModel.getKeyRing().getSignatureKeyPair().getPrivate();
|
|
||||||
byte[] signatureOfNonce = Sig.sign(privateKey, preparedDepositTx);
|
|
||||||
InputsForDepositTxResponse message = new InputsForDepositTxResponse(
|
|
||||||
processModel.getOfferId(),
|
|
||||||
checkNotNull(processModel.getPaymentAccountPayload(trade)),
|
|
||||||
processModel.getAccountId(),
|
|
||||||
makerMultiSigPubKey,
|
|
||||||
trade.getContractAsJson(),
|
|
||||||
trade.getMaker().getContractSignature(),
|
|
||||||
makerPayoutAddressEntry.getAddressString(),
|
|
||||||
preparedDepositTx,
|
|
||||||
processModel.getRawTransactionInputs(),
|
|
||||||
processModel.getMyNodeAddress(),
|
|
||||||
UUID.randomUUID().toString(),
|
|
||||||
signatureOfNonce,
|
|
||||||
new Date().getTime(),
|
|
||||||
trade.getLockTime());
|
|
||||||
|
|
||||||
trade.setState(Trade.State.MAKER_SENT_PUBLISH_DEPOSIT_TX_REQUEST);
|
|
||||||
processModel.getTradeManager().requestPersistence();
|
|
||||||
NodeAddress peersNodeAddress = trade.getTradingPeerNodeAddress();
|
|
||||||
log.info("Send {} to peer {}. tradeId={}, uid={}",
|
|
||||||
message.getClass().getSimpleName(), peersNodeAddress, message.getTradeId(), message.getUid());
|
|
||||||
processModel.getP2PService().sendEncryptedDirectMessage(
|
|
||||||
peersNodeAddress,
|
|
||||||
trade.getTradingPeer().getPubKeyRing(),
|
|
||||||
message,
|
|
||||||
new SendDirectMessageListener() {
|
|
||||||
@Override
|
|
||||||
public void onArrived() {
|
|
||||||
log.info("{} arrived at peer {}. tradeId={}, uid={}",
|
|
||||||
message.getClass().getSimpleName(), peersNodeAddress, message.getTradeId(), message.getUid());
|
|
||||||
trade.setState(Trade.State.MAKER_SAW_ARRIVED_PUBLISH_DEPOSIT_TX_REQUEST);
|
|
||||||
processModel.getTradeManager().requestPersistence();
|
|
||||||
complete();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFault(String errorMessage) {
|
|
||||||
log.error("{} failed: Peer {}. tradeId={}, uid={}, errorMessage={}",
|
|
||||||
message.getClass().getSimpleName(), peersNodeAddress, message.getTradeId(), message.getUid(), errorMessage);
|
|
||||||
trade.setState(Trade.State.MAKER_SEND_FAILED_PUBLISH_DEPOSIT_TX_REQUEST);
|
|
||||||
appendToErrorMessage("Sending message failed: message=" + message + "\nerrorMessage=" + errorMessage);
|
|
||||||
processModel.getTradeManager().requestPersistence();
|
|
||||||
failed(errorMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} catch (Throwable t) {
|
|
||||||
failed(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.maker;
|
|
||||||
|
|
||||||
import bisq.core.trade.Trade;
|
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class MakerVerifyTakerFeePayment extends TradeTask {
|
|
||||||
|
|
||||||
public MakerVerifyTakerFeePayment(TaskRunner<Trade> taskHandler, Trade trade) {
|
|
||||||
super(taskHandler, trade);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void run() {
|
|
||||||
try {
|
|
||||||
runInterceptHook();
|
|
||||||
//TODO missing impl.
|
|
||||||
// int numOfPeersSeenTx = processModel.getWalletService().getNumOfPeersSeenTx(processModel.getTakeOfferFeeTxId());
|
|
||||||
/* if (numOfPeersSeenTx > 2) {
|
|
||||||
resultHandler.handleResult();
|
|
||||||
}*/
|
|
||||||
|
|
||||||
complete();
|
|
||||||
} catch (Throwable t) {
|
|
||||||
failed(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.mediation;
|
|
||||||
|
|
||||||
import bisq.core.support.dispute.mediation.MediationResultState;
|
|
||||||
import bisq.core.trade.Trade;
|
|
||||||
import bisq.core.trade.protocol.tasks.BroadcastPayoutTx;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class BroadcastMediatedPayoutTx extends BroadcastPayoutTx {
|
|
||||||
public BroadcastMediatedPayoutTx(TaskRunner<Trade> taskHandler, Trade trade) {
|
|
||||||
super(taskHandler, trade);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void run() {
|
|
||||||
try {
|
|
||||||
runInterceptHook();
|
|
||||||
|
|
||||||
super.run();
|
|
||||||
} catch (Throwable t) {
|
|
||||||
failed(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void setState() {
|
|
||||||
trade.setMediationResultState(MediationResultState.PAYOUT_TX_PUBLISHED);
|
|
||||||
processModel.getTradeManager().requestPersistence();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.seller;
|
|
||||||
|
|
||||||
import bisq.core.trade.Trade;
|
|
||||||
import bisq.core.trade.protocol.tasks.BroadcastPayoutTx;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class SellerBroadcastPayoutTx extends BroadcastPayoutTx {
|
|
||||||
public SellerBroadcastPayoutTx(TaskRunner<Trade> taskHandler, Trade trade) {
|
|
||||||
super(taskHandler, trade);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void run() {
|
|
||||||
try {
|
|
||||||
runInterceptHook();
|
|
||||||
|
|
||||||
super.run();
|
|
||||||
} catch (Throwable t) {
|
|
||||||
failed(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void setState() {
|
|
||||||
trade.setState(Trade.State.SELLER_PUBLISHED_PAYOUT_TX);
|
|
||||||
processModel.getTradeManager().requestPersistence();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.seller;
|
|
||||||
|
|
||||||
import bisq.core.btc.wallet.TradeWalletService;
|
|
||||||
import bisq.core.trade.Trade;
|
|
||||||
import bisq.core.trade.TradeDataValidation;
|
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
|
||||||
|
|
||||||
import org.bitcoinj.core.Coin;
|
|
||||||
import org.bitcoinj.core.Transaction;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class SellerCreatesDelayedPayoutTx extends TradeTask {
|
|
||||||
|
|
||||||
public SellerCreatesDelayedPayoutTx(TaskRunner<Trade> taskHandler, Trade trade) {
|
|
||||||
super(taskHandler, trade);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void run() {
|
|
||||||
try {
|
|
||||||
runInterceptHook();
|
|
||||||
throw new RuntimeException("SellerCreatesDelayedPayoutTx not implemented for xmr");
|
|
||||||
} catch (Throwable t) {
|
|
||||||
failed(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,78 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.seller;
|
|
||||||
|
|
||||||
import bisq.core.btc.model.AddressEntry;
|
|
||||||
import bisq.core.btc.wallet.BtcWalletService;
|
|
||||||
import bisq.core.trade.Trade;
|
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
|
||||||
import bisq.common.util.Utilities;
|
|
||||||
|
|
||||||
import org.bitcoinj.core.Transaction;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class SellerFinalizesDelayedPayoutTx extends TradeTask {
|
|
||||||
public SellerFinalizesDelayedPayoutTx(TaskRunner<Trade> taskHandler, Trade trade) {
|
|
||||||
super(taskHandler, trade);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void run() {
|
|
||||||
try {
|
|
||||||
runInterceptHook();
|
|
||||||
|
|
||||||
Transaction preparedDelayedPayoutTx = checkNotNull(processModel.getPreparedDelayedPayoutTx());
|
|
||||||
BtcWalletService btcWalletService = processModel.getBtcWalletService();
|
|
||||||
String id = processModel.getOffer().getId();
|
|
||||||
|
|
||||||
byte[] buyerMultiSigPubKey = trade.getTradingPeer().getMultiSigPubKey();
|
|
||||||
byte[] sellerMultiSigPubKey = processModel.getMyMultiSigPubKey();
|
|
||||||
checkArgument(Arrays.equals(sellerMultiSigPubKey,
|
|
||||||
btcWalletService.getOrCreateAddressEntry(id, AddressEntry.Context.MULTI_SIG).getPubKey()),
|
|
||||||
"sellerMultiSigPubKey from AddressEntry must match the one from the trade data. trade id =" + id);
|
|
||||||
|
|
||||||
byte[] buyerSignature = trade.getTradingPeer().getDelayedPayoutTxSignature();
|
|
||||||
byte[] sellerSignature = processModel.getDelayedPayoutTxSignature();
|
|
||||||
|
|
||||||
Transaction signedDelayedPayoutTx = processModel.getTradeWalletService().finalizeDelayedPayoutTx(
|
|
||||||
preparedDelayedPayoutTx,
|
|
||||||
buyerMultiSigPubKey,
|
|
||||||
sellerMultiSigPubKey,
|
|
||||||
buyerSignature,
|
|
||||||
sellerSignature);
|
|
||||||
|
|
||||||
trade.applyDelayedPayoutTx(signedDelayedPayoutTx);
|
|
||||||
log.info("DelayedPayoutTxBytes = {}", Utilities.bytesAsHexString(trade.getDelayedPayoutTxBytes()));
|
|
||||||
|
|
||||||
processModel.getTradeManager().requestPersistence();
|
|
||||||
|
|
||||||
complete();
|
|
||||||
} catch (Throwable t) {
|
|
||||||
failed(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.seller;
|
|
||||||
|
|
||||||
import bisq.core.trade.Trade;
|
|
||||||
import bisq.core.trade.messages.DelayedPayoutTxSignatureResponse;
|
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import static bisq.core.util.Validator.checkTradeId;
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class SellerProcessDelayedPayoutTxSignatureResponse extends TradeTask {
|
|
||||||
public SellerProcessDelayedPayoutTxSignatureResponse(TaskRunner<Trade> taskHandler, Trade trade) {
|
|
||||||
super(taskHandler, trade);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void run() {
|
|
||||||
try {
|
|
||||||
runInterceptHook();
|
|
||||||
DelayedPayoutTxSignatureResponse response = (DelayedPayoutTxSignatureResponse) processModel.getTradeMessage();
|
|
||||||
checkNotNull(response);
|
|
||||||
checkTradeId(processModel.getOfferId(), response);
|
|
||||||
|
|
||||||
trade.getTradingPeer().setDelayedPayoutTxSignature(checkNotNull(response.getDelayedPayoutTxBuyerSignature()));
|
|
||||||
|
|
||||||
processModel.getTradeWalletService().sellerAddsBuyerWitnessesToDepositTx(
|
|
||||||
processModel.getDepositTx(),
|
|
||||||
processModel.getBtcWalletService().getTxFromSerializedTx(response.getDepositTx())
|
|
||||||
);
|
|
||||||
|
|
||||||
// update to the latest peer address of our peer if the message is correct
|
|
||||||
trade.setTradingPeerNodeAddress(processModel.getTempTradingPeerNodeAddress());
|
|
||||||
|
|
||||||
processModel.getTradeManager().requestPersistence();
|
|
||||||
|
|
||||||
complete();
|
|
||||||
} catch (Throwable t) {
|
|
||||||
failed(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,86 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.seller;
|
|
||||||
|
|
||||||
import bisq.core.trade.Trade;
|
|
||||||
import bisq.core.trade.messages.DelayedPayoutTxSignatureRequest;
|
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
|
|
||||||
import bisq.network.p2p.NodeAddress;
|
|
||||||
import bisq.network.p2p.SendDirectMessageListener;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
|
||||||
|
|
||||||
import org.bitcoinj.core.Transaction;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class SellerSendDelayedPayoutTxSignatureRequest extends TradeTask {
|
|
||||||
public SellerSendDelayedPayoutTxSignatureRequest(TaskRunner<Trade> taskHandler, Trade trade) {
|
|
||||||
super(taskHandler, trade);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void run() {
|
|
||||||
try {
|
|
||||||
runInterceptHook();
|
|
||||||
|
|
||||||
Transaction preparedDelayedPayoutTx = checkNotNull(processModel.getPreparedDelayedPayoutTx(),
|
|
||||||
"processModel.getPreparedDelayedPayoutTx() must not be null");
|
|
||||||
byte[] delayedPayoutTxSignature = checkNotNull(processModel.getDelayedPayoutTxSignature(),
|
|
||||||
"processModel.getDelayedPayoutTxSignature() must not be null");
|
|
||||||
DelayedPayoutTxSignatureRequest message = new DelayedPayoutTxSignatureRequest(UUID.randomUUID().toString(),
|
|
||||||
processModel.getOfferId(),
|
|
||||||
processModel.getMyNodeAddress(),
|
|
||||||
preparedDelayedPayoutTx.bitcoinSerialize(),
|
|
||||||
delayedPayoutTxSignature);
|
|
||||||
|
|
||||||
NodeAddress peersNodeAddress = trade.getTradingPeerNodeAddress();
|
|
||||||
log.info("Send {} to peer {}. tradeId={}, uid={}",
|
|
||||||
message.getClass().getSimpleName(), peersNodeAddress, message.getTradeId(), message.getUid());
|
|
||||||
processModel.getP2PService().sendEncryptedDirectMessage(
|
|
||||||
peersNodeAddress,
|
|
||||||
trade.getTradingPeer().getPubKeyRing(),
|
|
||||||
message,
|
|
||||||
new SendDirectMessageListener() {
|
|
||||||
@Override
|
|
||||||
public void onArrived() {
|
|
||||||
log.info("{} arrived at peer {}. tradeId={}, uid={}",
|
|
||||||
message.getClass().getSimpleName(), peersNodeAddress, message.getTradeId(), message.getUid());
|
|
||||||
complete();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFault(String errorMessage) {
|
|
||||||
log.error("{} failed: Peer {}. tradeId={}, uid={}, errorMessage={}",
|
|
||||||
message.getClass().getSimpleName(), peersNodeAddress, message.getTradeId(), message.getUid(), errorMessage);
|
|
||||||
appendToErrorMessage("Sending message failed: message=" + message + "\nerrorMessage=" + errorMessage);
|
|
||||||
failed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} catch (Throwable t) {
|
|
||||||
failed(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,80 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.seller;
|
|
||||||
|
|
||||||
import bisq.core.btc.model.AddressEntry;
|
|
||||||
import bisq.core.btc.wallet.BtcWalletService;
|
|
||||||
import bisq.core.trade.Trade;
|
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
|
||||||
|
|
||||||
import org.bitcoinj.core.NetworkParameters;
|
|
||||||
import org.bitcoinj.core.Transaction;
|
|
||||||
import org.bitcoinj.crypto.DeterministicKey;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class SellerSignsDelayedPayoutTx extends TradeTask {
|
|
||||||
public SellerSignsDelayedPayoutTx(TaskRunner<Trade> taskHandler, Trade trade) {
|
|
||||||
super(taskHandler, trade);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void run() {
|
|
||||||
try {
|
|
||||||
runInterceptHook();
|
|
||||||
|
|
||||||
Transaction preparedDelayedPayoutTx = checkNotNull(processModel.getPreparedDelayedPayoutTx());
|
|
||||||
BtcWalletService btcWalletService = processModel.getBtcWalletService();
|
|
||||||
NetworkParameters params = btcWalletService.getParams();
|
|
||||||
Transaction preparedDepositTx = new Transaction(params, processModel.getPreparedDepositTx());
|
|
||||||
|
|
||||||
String id = processModel.getOffer().getId();
|
|
||||||
|
|
||||||
byte[] sellerMultiSigPubKey = processModel.getMyMultiSigPubKey();
|
|
||||||
DeterministicKey myMultiSigKeyPair = btcWalletService.getMultiSigKeyPair(id, sellerMultiSigPubKey);
|
|
||||||
|
|
||||||
checkArgument(Arrays.equals(sellerMultiSigPubKey,
|
|
||||||
btcWalletService.getOrCreateAddressEntry(id, AddressEntry.Context.MULTI_SIG).getPubKey()),
|
|
||||||
"sellerMultiSigPubKey from AddressEntry must match the one from the trade data. trade id =" + id);
|
|
||||||
byte[] buyerMultiSigPubKey = trade.getTradingPeer().getMultiSigPubKey();
|
|
||||||
|
|
||||||
byte[] delayedPayoutTxSignature = processModel.getTradeWalletService().signDelayedPayoutTx(
|
|
||||||
preparedDelayedPayoutTx,
|
|
||||||
preparedDepositTx,
|
|
||||||
myMultiSigKeyPair,
|
|
||||||
buyerMultiSigPubKey,
|
|
||||||
sellerMultiSigPubKey);
|
|
||||||
|
|
||||||
processModel.setDelayedPayoutTxSignature(delayedPayoutTxSignature);
|
|
||||||
|
|
||||||
processModel.getTradeManager().requestPersistence();
|
|
||||||
|
|
||||||
complete();
|
|
||||||
} catch (Throwable t) {
|
|
||||||
failed(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,116 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.seller_as_maker;
|
|
||||||
|
|
||||||
import bisq.core.btc.model.AddressEntry;
|
|
||||||
import bisq.core.btc.model.PreparedDepositTxAndMakerInputs;
|
|
||||||
import bisq.core.btc.model.RawTransactionInput;
|
|
||||||
import bisq.core.btc.wallet.BtcWalletService;
|
|
||||||
import bisq.core.offer.Offer;
|
|
||||||
import bisq.core.trade.Trade;
|
|
||||||
import bisq.core.trade.protocol.TradingPeer;
|
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
|
|
||||||
import bisq.common.crypto.Hash;
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
|
||||||
|
|
||||||
import org.bitcoinj.core.Address;
|
|
||||||
import org.bitcoinj.core.Coin;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class SellerAsMakerCreatesUnsignedDepositTx extends TradeTask {
|
|
||||||
public SellerAsMakerCreatesUnsignedDepositTx(TaskRunner<Trade> taskHandler, Trade trade) {
|
|
||||||
super(taskHandler, trade);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void run() {
|
|
||||||
try {
|
|
||||||
runInterceptHook();
|
|
||||||
checkNotNull(trade.getAmount(), "trade.getTradeAmount() must not be null");
|
|
||||||
|
|
||||||
BtcWalletService walletService = processModel.getBtcWalletService();
|
|
||||||
String id = processModel.getOffer().getId();
|
|
||||||
TradingPeer tradingPeer = trade.getTradingPeer();
|
|
||||||
Offer offer = checkNotNull(trade.getOffer());
|
|
||||||
|
|
||||||
// params
|
|
||||||
byte[] contractHash = Hash.getSha256Hash(checkNotNull(trade.getContractAsJson()));
|
|
||||||
trade.setContractHash(contractHash);
|
|
||||||
log.debug("\n\n------------------------------------------------------------\n"
|
|
||||||
+ "Contract as json\n"
|
|
||||||
+ trade.getContractAsJson()
|
|
||||||
+ "\n------------------------------------------------------------\n");
|
|
||||||
|
|
||||||
Coin makerInputAmount = offer.getSellerSecurityDeposit().add(trade.getAmount());
|
|
||||||
Optional<AddressEntry> addressEntryOptional = walletService.getAddressEntry(id, AddressEntry.Context.MULTI_SIG);
|
|
||||||
checkArgument(addressEntryOptional.isPresent(), "addressEntryOptional must be present");
|
|
||||||
AddressEntry makerMultiSigAddressEntry = addressEntryOptional.get();
|
|
||||||
processModel.getBtcWalletService().setCoinLockedInMultiSigAddressEntry(makerMultiSigAddressEntry, makerInputAmount.value);
|
|
||||||
|
|
||||||
walletService.saveAddressEntryList();
|
|
||||||
|
|
||||||
Coin msOutputAmount = makerInputAmount
|
|
||||||
.add(trade.getTxFee())
|
|
||||||
.add(offer.getBuyerSecurityDeposit());
|
|
||||||
|
|
||||||
List<RawTransactionInput> takerRawTransactionInputs = checkNotNull(tradingPeer.getRawTransactionInputs());
|
|
||||||
checkArgument(takerRawTransactionInputs.stream().allMatch(processModel.getTradeWalletService()::isP2WH),
|
|
||||||
"all takerRawTransactionInputs must be P2WH");
|
|
||||||
long takerChangeOutputValue = tradingPeer.getChangeOutputValue();
|
|
||||||
String takerChangeAddressString = tradingPeer.getChangeOutputAddress();
|
|
||||||
Address makerAddress = walletService.getOrCreateAddressEntry(id, AddressEntry.Context.RESERVED_FOR_TRADE).getAddress();
|
|
||||||
Address makerChangeAddress = walletService.getFreshAddressEntry().getAddress();
|
|
||||||
byte[] buyerPubKey = tradingPeer.getMultiSigPubKey();
|
|
||||||
byte[] sellerPubKey = processModel.getMyMultiSigPubKey();
|
|
||||||
checkArgument(Arrays.equals(sellerPubKey,
|
|
||||||
makerMultiSigAddressEntry.getPubKey()),
|
|
||||||
"sellerPubKey from AddressEntry must match the one from the trade data. trade id =" + id);
|
|
||||||
|
|
||||||
PreparedDepositTxAndMakerInputs result = processModel.getTradeWalletService().sellerAsMakerCreatesDepositTx(
|
|
||||||
contractHash,
|
|
||||||
makerInputAmount,
|
|
||||||
msOutputAmount,
|
|
||||||
takerRawTransactionInputs,
|
|
||||||
takerChangeOutputValue,
|
|
||||||
takerChangeAddressString,
|
|
||||||
makerAddress,
|
|
||||||
makerChangeAddress,
|
|
||||||
buyerPubKey,
|
|
||||||
sellerPubKey);
|
|
||||||
|
|
||||||
processModel.setPreparedDepositTx(result.depositTransaction);
|
|
||||||
processModel.setRawTransactionInputs(result.rawMakerInputs);
|
|
||||||
|
|
||||||
processModel.getTradeManager().requestPersistence();
|
|
||||||
|
|
||||||
complete();
|
|
||||||
} catch (Throwable t) {
|
|
||||||
failed(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.seller_as_maker;
|
|
||||||
|
|
||||||
import bisq.core.trade.Trade;
|
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
|
||||||
|
|
||||||
import org.bitcoinj.core.Transaction;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class SellerAsMakerFinalizesDepositTx extends TradeTask {
|
|
||||||
public SellerAsMakerFinalizesDepositTx(TaskRunner<Trade> taskHandler, Trade trade) {
|
|
||||||
super(taskHandler, trade);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void run() {
|
|
||||||
try {
|
|
||||||
runInterceptHook();
|
|
||||||
if (true) throw new RuntimeException("SellerAsMakerFinalizesDepositTx not implemented for xmr");
|
|
||||||
|
|
||||||
byte[] takersRawPreparedDepositTx = checkNotNull(trade.getTradingPeer().getPreparedDepositTx());
|
|
||||||
byte[] myRawPreparedDepositTx = checkNotNull(processModel.getPreparedDepositTx());
|
|
||||||
Transaction takersDepositTx = processModel.getBtcWalletService().getTxFromSerializedTx(takersRawPreparedDepositTx);
|
|
||||||
Transaction myDepositTx = processModel.getBtcWalletService().getTxFromSerializedTx(myRawPreparedDepositTx);
|
|
||||||
int numTakersInputs = checkNotNull(trade.getTradingPeer().getRawTransactionInputs()).size();
|
|
||||||
processModel.getTradeWalletService().sellerAsMakerFinalizesDepositTx(myDepositTx, takersDepositTx, numTakersInputs);
|
|
||||||
|
|
||||||
processModel.setDepositTx(myDepositTx);
|
|
||||||
|
|
||||||
processModel.getTradeManager().requestPersistence();
|
|
||||||
|
|
||||||
complete();
|
|
||||||
} catch (Throwable t) {
|
|
||||||
failed(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,58 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.seller_as_maker;
|
|
||||||
|
|
||||||
import bisq.core.trade.Trade;
|
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class SellerAsMakerProcessDepositTxMessage extends TradeTask {
|
|
||||||
public SellerAsMakerProcessDepositTxMessage(TaskRunner<Trade> taskHandler, Trade trade) {
|
|
||||||
super(taskHandler, trade);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void run() {
|
|
||||||
throw new RuntimeException("SellerAsMakerProcessDepositTxMessage needs updated for XMR");
|
|
||||||
// try {
|
|
||||||
// runInterceptHook();
|
|
||||||
// log.debug("current trade state " + trade.getState());
|
|
||||||
// DepositTxMessage message = (DepositTxMessage) processModel.getTradeMessage();
|
|
||||||
// Validator.checkTradeId(processModel.getOfferId(), message);
|
|
||||||
// checkNotNull(message);
|
|
||||||
//
|
|
||||||
// trade.getTradingPeer().setPreparedDepositTx(checkNotNull(message.getDepositTxWithoutWitnesses()));
|
|
||||||
// trade.setTradingPeerNodeAddress(processModel.getTempTradingPeerNodeAddress());
|
|
||||||
//
|
|
||||||
// // When we receive that message the taker has published the taker fee, so we apply it to the trade.
|
|
||||||
// // The takerFeeTx was sent in the first message. It should be part of DelayedPayoutTxSignatureRequest
|
|
||||||
// // but that cannot be changed due backward compatibility issues. It is a left over from the old trade protocol.
|
|
||||||
// trade.setTakerFeeTxId(processModel.getTakeOfferFeeTxId());
|
|
||||||
//
|
|
||||||
// processModel.getTradeManager().requestPersistence();
|
|
||||||
//
|
|
||||||
// complete();
|
|
||||||
// } catch (Throwable t) {
|
|
||||||
// failed(t);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.seller_as_maker;
|
|
||||||
|
|
||||||
import bisq.core.trade.Trade;
|
|
||||||
import bisq.core.trade.protocol.tasks.maker.MakerSendsInputsForDepositTxResponse;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
|
||||||
|
|
||||||
import org.bitcoinj.core.Transaction;
|
|
||||||
import org.bitcoinj.script.Script;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class SellerAsMakerSendsInputsForDepositTxResponse extends MakerSendsInputsForDepositTxResponse {
|
|
||||||
public SellerAsMakerSendsInputsForDepositTxResponse(TaskRunner<Trade> taskHandler, Trade trade) {
|
|
||||||
super(taskHandler, trade);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected byte[] getPreparedDepositTx() {
|
|
||||||
Transaction preparedDepositTx = processModel.getBtcWalletService().getTxFromSerializedTx(processModel.getPreparedDepositTx());
|
|
||||||
preparedDepositTx.getInputs().forEach(input -> {
|
|
||||||
// Remove signature before sending to peer as we don't want to risk that buyer could publish deposit tx
|
|
||||||
// before we have received his signature for the delayed payout tx.
|
|
||||||
input.setScriptSig(new Script(new byte[]{}));
|
|
||||||
});
|
|
||||||
|
|
||||||
processModel.getTradeManager().requestPersistence();
|
|
||||||
|
|
||||||
// Make sure witnesses are removed as well before sending, to cover the segwit case.
|
|
||||||
return preparedDepositTx.bitcoinSerialize(false);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.seller_as_taker;
|
|
||||||
|
|
||||||
import bisq.core.trade.Trade;
|
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class SellerAsTakerCreatesDepositTxInputs extends TradeTask {
|
|
||||||
public SellerAsTakerCreatesDepositTxInputs(TaskRunner<Trade> taskHandler, Trade trade) {
|
|
||||||
super(taskHandler, trade);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void run() {
|
|
||||||
try {
|
|
||||||
runInterceptHook();
|
|
||||||
throw new RuntimeException("XMR integration does not communicate outputs");
|
|
||||||
|
|
||||||
// Coin tradeAmount = checkNotNull(trade.getTradeAmount());
|
|
||||||
// Offer offer = checkNotNull(trade.getOffer());
|
|
||||||
// Coin txFee = trade.getTxFee();
|
|
||||||
// Coin takerInputAmount = offer.getSellerSecurityDeposit()
|
|
||||||
// .add(txFee)
|
|
||||||
// .add(txFee) // We add 2 times the fee as one is for the payout tx
|
|
||||||
// .add(tradeAmount);
|
|
||||||
// InputsAndChangeOutput result = processModel.getTradeWalletService().takerCreatesDepositTxInputs(
|
|
||||||
// processModel.getTakeOfferFeeTx(),
|
|
||||||
// takerInputAmount,
|
|
||||||
// txFee);
|
|
||||||
//
|
|
||||||
// processModel.setRawTransactionInputs(result.rawTransactionInputs);
|
|
||||||
// processModel.setChangeOutputValue(result.changeOutputValue);
|
|
||||||
// processModel.setChangeOutputAddress(result.changeOutputAddress);
|
|
||||||
//
|
|
||||||
// processModel.getTradeManager().requestPersistence();
|
|
||||||
//
|
|
||||||
// complete();
|
|
||||||
} catch (Throwable t) {
|
|
||||||
failed(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,104 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.seller_as_taker;
|
|
||||||
|
|
||||||
import bisq.core.btc.model.AddressEntry;
|
|
||||||
import bisq.core.btc.model.RawTransactionInput;
|
|
||||||
import bisq.core.btc.wallet.BtcWalletService;
|
|
||||||
import bisq.core.offer.Offer;
|
|
||||||
import bisq.core.trade.Contract;
|
|
||||||
import bisq.core.trade.Trade;
|
|
||||||
import bisq.core.trade.protocol.TradingPeer;
|
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
|
||||||
|
|
||||||
import org.bitcoinj.core.Coin;
|
|
||||||
import org.bitcoinj.core.Transaction;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class SellerAsTakerSignsDepositTx extends TradeTask {
|
|
||||||
public SellerAsTakerSignsDepositTx(TaskRunner<Trade> taskHandler, Trade trade) {
|
|
||||||
super(taskHandler, trade);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void run() {
|
|
||||||
try {
|
|
||||||
runInterceptHook();
|
|
||||||
if (true) throw new RuntimeException("SellerAsTakerSignsDepositTx not implemented for xmr");
|
|
||||||
|
|
||||||
List<RawTransactionInput> sellerInputs = checkNotNull(processModel.getRawTransactionInputs(),
|
|
||||||
"sellerInputs must not be null");
|
|
||||||
BtcWalletService walletService = processModel.getBtcWalletService();
|
|
||||||
String id = processModel.getOffer().getId();
|
|
||||||
|
|
||||||
Optional<AddressEntry> optionalMultiSigAddressEntry = walletService.getAddressEntry(id, AddressEntry.Context.MULTI_SIG);
|
|
||||||
checkArgument(optionalMultiSigAddressEntry.isPresent(), "addressEntryOptional must be present");
|
|
||||||
AddressEntry sellerMultiSigAddressEntry = optionalMultiSigAddressEntry.get();
|
|
||||||
byte[] sellerMultiSigPubKey = processModel.getMyMultiSigPubKey();
|
|
||||||
checkArgument(Arrays.equals(sellerMultiSigPubKey,
|
|
||||||
sellerMultiSigAddressEntry.getPubKey()),
|
|
||||||
"sellerMultiSigPubKey from AddressEntry must match the one from the trade data. trade id =" + id);
|
|
||||||
|
|
||||||
Coin sellerInput = Coin.valueOf(sellerInputs.stream().mapToLong(input -> input.value).sum());
|
|
||||||
|
|
||||||
Coin totalFee = trade.getTxFee().multiply(2); // Fee for deposit and payout tx
|
|
||||||
Coin multiSigValue = sellerInput.subtract(totalFee);
|
|
||||||
processModel.getBtcWalletService().setCoinLockedInMultiSigAddressEntry(sellerMultiSigAddressEntry, multiSigValue.value);
|
|
||||||
walletService.saveAddressEntryList();
|
|
||||||
|
|
||||||
Offer offer = trade.getOffer();
|
|
||||||
Coin msOutputAmount = offer.getBuyerSecurityDeposit().add(offer.getSellerSecurityDeposit()).add(trade.getTxFee())
|
|
||||||
.add(checkNotNull(trade.getAmount()));
|
|
||||||
|
|
||||||
TradingPeer tradingPeer = trade.getTradingPeer();
|
|
||||||
|
|
||||||
Transaction depositTx = processModel.getTradeWalletService().takerSignsDepositTx(
|
|
||||||
true,
|
|
||||||
trade.getContractHash(),
|
|
||||||
processModel.getPreparedDepositTx(),
|
|
||||||
msOutputAmount,
|
|
||||||
checkNotNull(tradingPeer.getRawTransactionInputs()),
|
|
||||||
sellerInputs,
|
|
||||||
tradingPeer.getMultiSigPubKey(),
|
|
||||||
sellerMultiSigPubKey);
|
|
||||||
|
|
||||||
// We set the deposit tx to trade once we have it published
|
|
||||||
processModel.setDepositTx(depositTx);
|
|
||||||
|
|
||||||
processModel.getTradeManager().requestPersistence();
|
|
||||||
|
|
||||||
complete();
|
|
||||||
} catch (Throwable t) {
|
|
||||||
Contract contract = trade.getContract();
|
|
||||||
if (contract != null)
|
|
||||||
contract.printDiff(trade.getTradingPeer().getContractAsJson());
|
|
||||||
failed(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,93 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.taker;
|
|
||||||
|
|
||||||
import bisq.core.btc.wallet.Restrictions;
|
|
||||||
import bisq.core.trade.Trade;
|
|
||||||
import bisq.core.trade.messages.InputsForDepositTxResponse;
|
|
||||||
import bisq.core.trade.protocol.TradingPeer;
|
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
|
|
||||||
import bisq.common.config.Config;
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import static bisq.core.util.Validator.checkTradeId;
|
|
||||||
import static bisq.core.util.Validator.nonEmptyStringOf;
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class TakerProcessesInputsForDepositTxResponse extends TradeTask {
|
|
||||||
public TakerProcessesInputsForDepositTxResponse(TaskRunner<Trade> taskHandler, Trade trade) {
|
|
||||||
super(taskHandler, trade);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void run() {
|
|
||||||
try {
|
|
||||||
runInterceptHook();
|
|
||||||
InputsForDepositTxResponse response = (InputsForDepositTxResponse) processModel.getTradeMessage();
|
|
||||||
checkTradeId(processModel.getOfferId(), response);
|
|
||||||
checkNotNull(response);
|
|
||||||
|
|
||||||
TradingPeer tradingPeer = trade.getTradingPeer();
|
|
||||||
tradingPeer.setPaymentAccountPayload(checkNotNull(response.getMakerPaymentAccountPayload()));
|
|
||||||
tradingPeer.setAccountId(nonEmptyStringOf(response.getMakerAccountId()));
|
|
||||||
tradingPeer.setMultiSigPubKey(checkNotNull(response.getMakerMultiSigPubKey()));
|
|
||||||
tradingPeer.setContractAsJson(nonEmptyStringOf(response.getMakerContractAsJson()));
|
|
||||||
tradingPeer.setContractSignature(nonEmptyStringOf(response.getMakerContractSignature()));
|
|
||||||
tradingPeer.setPayoutAddressString(nonEmptyStringOf(response.getMakerPayoutAddressString()));
|
|
||||||
tradingPeer.setRawTransactionInputs(checkNotNull(response.getMakerInputs()));
|
|
||||||
byte[] preparedDepositTx = checkNotNull(response.getPreparedDepositTx());
|
|
||||||
processModel.setPreparedDepositTx(preparedDepositTx);
|
|
||||||
long lockTime = response.getLockTime();
|
|
||||||
if (Config.baseCurrencyNetwork().isMainnet()) {
|
|
||||||
int myLockTime = processModel.getBtcWalletService().getBestChainHeight() +
|
|
||||||
Restrictions.getLockTime(processModel.getOffer().getPaymentMethod().isBlockchain());
|
|
||||||
// We allow a tolerance of 3 blocks as BestChainHeight might be a bit different on maker and taker in case a new
|
|
||||||
// block was just found
|
|
||||||
checkArgument(Math.abs(lockTime - myLockTime) <= 3,
|
|
||||||
"Lock time of maker is more than 3 blocks different to the lockTime I " +
|
|
||||||
"calculated. Makers lockTime= " + lockTime + ", myLockTime=" + myLockTime);
|
|
||||||
}
|
|
||||||
trade.setLockTime(lockTime);
|
|
||||||
long delay = processModel.getBtcWalletService().getBestChainHeight() - lockTime;
|
|
||||||
log.info("lockTime={}, delay={}", lockTime, delay);
|
|
||||||
|
|
||||||
// Maker has to sign preparedDepositTx. He cannot manipulate the preparedDepositTx - so we avoid to have a
|
|
||||||
// challenge protocol for passing the nonce we want to get signed.
|
|
||||||
tradingPeer.setAccountAgeWitnessNonce(preparedDepositTx);
|
|
||||||
tradingPeer.setAccountAgeWitnessSignature(checkNotNull(response.getAccountAgeWitnessSignatureOfPreparedDepositTx()));
|
|
||||||
|
|
||||||
tradingPeer.setCurrentDate(response.getCurrentDate());
|
|
||||||
|
|
||||||
checkArgument(response.getMakerInputs().size() > 0);
|
|
||||||
|
|
||||||
// update to the latest peer address of our peer if the message is correct
|
|
||||||
trade.setTradingPeerNodeAddress(processModel.getTempTradingPeerNodeAddress());
|
|
||||||
|
|
||||||
processModel.getTradeManager().requestPersistence();
|
|
||||||
|
|
||||||
complete();
|
|
||||||
} catch (Throwable t) {
|
|
||||||
failed(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,58 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Haveno.
|
|
||||||
*
|
|
||||||
* Haveno 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.
|
|
||||||
*
|
|
||||||
* Haveno 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 Haveno. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bisq.core.trade.protocol.tasks.taker;
|
|
||||||
|
|
||||||
import bisq.core.trade.Trade;
|
|
||||||
import bisq.core.trade.protocol.tasks.TradeTask;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.TaskRunner;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import monero.wallet.model.MoneroTxWallet;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class TakerPublishFeeTx extends TradeTask {
|
|
||||||
public TakerPublishFeeTx(TaskRunner<Trade> taskHandler, Trade trade) {
|
|
||||||
super(taskHandler, trade);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void run() {
|
|
||||||
try {
|
|
||||||
runInterceptHook();
|
|
||||||
|
|
||||||
// We committed to be sure the tx gets into the wallet even in the broadcast process it would be
|
|
||||||
// committed as well, but if user would close app before success handler returns the commit would not
|
|
||||||
// be done.
|
|
||||||
MoneroTxWallet takeOfferFeeTx = processModel.getTakeOfferFeeTx();
|
|
||||||
processModel.getProvider().getXmrWalletService().getWallet().relayTx(takeOfferFeeTx);
|
|
||||||
System.out.println("TAKER PUBLISHED FEE TX");
|
|
||||||
System.out.println(takeOfferFeeTx);
|
|
||||||
trade.setState(Trade.State.TAKER_PUBLISHED_TAKER_FEE_TX);
|
|
||||||
complete();
|
|
||||||
} catch (Throwable t) {
|
|
||||||
log.error(t.toString());
|
|
||||||
t.printStackTrace();
|
|
||||||
trade.setErrorMessage("An error occurred.\n Error message:\n" + t.getMessage());
|
|
||||||
failed(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -26,45 +26,20 @@ import bisq.core.offer.availability.tasks.SendOfferAvailabilityRequest;
|
||||||
import bisq.core.offer.placeoffer.tasks.AddToOfferBook;
|
import bisq.core.offer.placeoffer.tasks.AddToOfferBook;
|
||||||
import bisq.core.offer.placeoffer.tasks.MakerReservesOfferFunds;
|
import bisq.core.offer.placeoffer.tasks.MakerReservesOfferFunds;
|
||||||
import bisq.core.offer.placeoffer.tasks.ValidateOffer;
|
import bisq.core.offer.placeoffer.tasks.ValidateOffer;
|
||||||
|
import bisq.core.trade.protocol.TakerVerifyMakerFeePayment;
|
||||||
import bisq.core.trade.protocol.tasks.ApplyFilter;
|
import bisq.core.trade.protocol.tasks.ApplyFilter;
|
||||||
|
import bisq.core.trade.protocol.tasks.BuyerPreparesPaymentSentMessage;
|
||||||
|
import bisq.core.trade.protocol.tasks.BuyerProcessesPaymentReceivedMessage;
|
||||||
|
import bisq.core.trade.protocol.tasks.BuyerSendsPaymentSentMessage;
|
||||||
|
import bisq.core.trade.protocol.tasks.BuyerSetupPayoutTxListener;
|
||||||
|
import bisq.core.trade.protocol.tasks.MakerSetsLockTime;
|
||||||
|
import bisq.core.trade.protocol.tasks.MaybeRemoveOpenOffer;
|
||||||
|
import bisq.core.trade.protocol.tasks.SellerPreparesPaymentReceivedMessage;
|
||||||
|
import bisq.core.trade.protocol.tasks.SellerProcessesPaymentSentMessage;
|
||||||
|
import bisq.core.trade.protocol.tasks.SellerPublishesDepositTx;
|
||||||
|
import bisq.core.trade.protocol.tasks.SellerPublishesTradeStatistics;
|
||||||
|
import bisq.core.trade.protocol.tasks.SellerSendsPaymentReceivedMessage;
|
||||||
import bisq.core.trade.protocol.tasks.VerifyPeersAccountAgeWitness;
|
import bisq.core.trade.protocol.tasks.VerifyPeersAccountAgeWitness;
|
||||||
import bisq.core.trade.protocol.tasks.buyer.BuyerPreparesPaymentSentMessage;
|
|
||||||
import bisq.core.trade.protocol.tasks.buyer.BuyerProcessDelayedPayoutTxSignatureRequest;
|
|
||||||
import bisq.core.trade.protocol.tasks.buyer.BuyerProcessDepositTxAndDelayedPayoutTxMessage;
|
|
||||||
import bisq.core.trade.protocol.tasks.buyer.BuyerProcessesPaymentReceivedMessage;
|
|
||||||
import bisq.core.trade.protocol.tasks.buyer.BuyerSendsPaymentSentMessage;
|
|
||||||
import bisq.core.trade.protocol.tasks.buyer.BuyerSendsDelayedPayoutTxSignatureResponse;
|
|
||||||
import bisq.core.trade.protocol.tasks.buyer.BuyerSetupPayoutTxListener;
|
|
||||||
import bisq.core.trade.protocol.tasks.buyer.BuyerSignsDelayedPayoutTx;
|
|
||||||
import bisq.core.trade.protocol.tasks.buyer.BuyerVerifiesFinalDelayedPayoutTx;
|
|
||||||
import bisq.core.trade.protocol.tasks.buyer.BuyerVerifiesPreparedDelayedPayoutTx;
|
|
||||||
import bisq.core.trade.protocol.tasks.buyer_as_maker.BuyerAsMakerCreatesAndSignsDepositTx;
|
|
||||||
import bisq.core.trade.protocol.tasks.buyer_as_maker.BuyerAsMakerSendsInputsForDepositTxResponse;
|
|
||||||
import bisq.core.trade.protocol.tasks.buyer_as_taker.BuyerAsTakerCreatesDepositTxInputs;
|
|
||||||
import bisq.core.trade.protocol.tasks.buyer_as_taker.BuyerAsTakerSendsDepositTxMessage;
|
|
||||||
import bisq.core.trade.protocol.tasks.buyer_as_taker.BuyerAsTakerSignsDepositTx;
|
|
||||||
import bisq.core.trade.protocol.tasks.maker.MaybeRemoveOpenOffer;
|
|
||||||
import bisq.core.trade.protocol.tasks.maker.MakerSetsLockTime;
|
|
||||||
import bisq.core.trade.protocol.tasks.maker.MakerVerifyTakerFeePayment;
|
|
||||||
import bisq.core.trade.protocol.tasks.seller.SellerCreatesDelayedPayoutTx;
|
|
||||||
import bisq.core.trade.protocol.tasks.seller.SellerFinalizesDelayedPayoutTx;
|
|
||||||
import bisq.core.trade.protocol.tasks.seller.SellerProcessesPaymentSentMessage;
|
|
||||||
import bisq.core.trade.protocol.tasks.seller.SellerProcessDelayedPayoutTxSignatureResponse;
|
|
||||||
import bisq.core.trade.protocol.tasks.seller.SellerPublishesDepositTx;
|
|
||||||
import bisq.core.trade.protocol.tasks.seller.SellerPublishesTradeStatistics;
|
|
||||||
import bisq.core.trade.protocol.tasks.seller.SellerSendDelayedPayoutTxSignatureRequest;
|
|
||||||
import bisq.core.trade.protocol.tasks.seller.SellerSendsPaymentReceivedMessage;
|
|
||||||
import bisq.core.trade.protocol.tasks.seller.SellerPreparesPaymentReceivedMessage;
|
|
||||||
import bisq.core.trade.protocol.tasks.seller.SellerSignsDelayedPayoutTx;
|
|
||||||
import bisq.core.trade.protocol.tasks.seller_as_maker.SellerAsMakerCreatesUnsignedDepositTx;
|
|
||||||
import bisq.core.trade.protocol.tasks.seller_as_maker.SellerAsMakerFinalizesDepositTx;
|
|
||||||
import bisq.core.trade.protocol.tasks.seller_as_maker.SellerAsMakerSendsInputsForDepositTxResponse;
|
|
||||||
import bisq.core.trade.protocol.tasks.seller_as_taker.SellerAsTakerCreatesDepositTxInputs;
|
|
||||||
import bisq.core.trade.protocol.tasks.seller_as_taker.SellerAsTakerSignsDepositTx;
|
|
||||||
import bisq.core.trade.protocol.tasks.taker.TakerProcessesInputsForDepositTxResponse;
|
|
||||||
import bisq.core.trade.protocol.tasks.taker.TakerPublishFeeTx;
|
|
||||||
import bisq.core.trade.protocol.tasks.taker.TakerVerifyMakerFeePayment;
|
|
||||||
|
|
||||||
import bisq.common.taskrunner.Task;
|
import bisq.common.taskrunner.Task;
|
||||||
import bisq.common.util.Tuple2;
|
import bisq.common.util.Tuple2;
|
||||||
|
|
||||||
|
@ -118,19 +93,10 @@ public class DebugView extends InitializableView<GridPane, Void> {
|
||||||
FXCollections.observableArrayList(Arrays.asList(
|
FXCollections.observableArrayList(Arrays.asList(
|
||||||
ApplyFilter.class,
|
ApplyFilter.class,
|
||||||
TakerVerifyMakerFeePayment.class,
|
TakerVerifyMakerFeePayment.class,
|
||||||
SellerAsTakerCreatesDepositTxInputs.class,
|
|
||||||
|
|
||||||
TakerProcessesInputsForDepositTxResponse.class,
|
|
||||||
ApplyFilter.class,
|
ApplyFilter.class,
|
||||||
VerifyPeersAccountAgeWitness.class,
|
VerifyPeersAccountAgeWitness.class,
|
||||||
TakerPublishFeeTx.class,
|
|
||||||
SellerAsTakerSignsDepositTx.class,
|
|
||||||
SellerCreatesDelayedPayoutTx.class,
|
|
||||||
SellerSendDelayedPayoutTxSignatureRequest.class,
|
|
||||||
|
|
||||||
SellerProcessDelayedPayoutTxSignatureResponse.class,
|
|
||||||
SellerSignsDelayedPayoutTx.class,
|
|
||||||
SellerFinalizesDelayedPayoutTx.class,
|
|
||||||
//SellerSendsDepositTxAndDelayedPayoutTxMessage.class,
|
//SellerSendsDepositTxAndDelayedPayoutTxMessage.class,
|
||||||
SellerPublishesDepositTx.class,
|
SellerPublishesDepositTx.class,
|
||||||
SellerPublishesTradeStatistics.class,
|
SellerPublishesTradeStatistics.class,
|
||||||
|
@ -151,22 +117,11 @@ public class DebugView extends InitializableView<GridPane, Void> {
|
||||||
FXCollections.observableArrayList(Arrays.asList(
|
FXCollections.observableArrayList(Arrays.asList(
|
||||||
ApplyFilter.class,
|
ApplyFilter.class,
|
||||||
VerifyPeersAccountAgeWitness.class,
|
VerifyPeersAccountAgeWitness.class,
|
||||||
MakerVerifyTakerFeePayment.class,
|
|
||||||
MakerSetsLockTime.class,
|
MakerSetsLockTime.class,
|
||||||
BuyerAsMakerCreatesAndSignsDepositTx.class,
|
|
||||||
BuyerAsMakerSendsInputsForDepositTxResponse.class,
|
|
||||||
|
|
||||||
BuyerProcessDelayedPayoutTxSignatureRequest.class,
|
|
||||||
MaybeRemoveOpenOffer.class,
|
MaybeRemoveOpenOffer.class,
|
||||||
BuyerVerifiesPreparedDelayedPayoutTx.class,
|
|
||||||
BuyerSignsDelayedPayoutTx.class,
|
|
||||||
BuyerSendsDelayedPayoutTxSignatureResponse.class,
|
|
||||||
|
|
||||||
BuyerProcessDepositTxAndDelayedPayoutTxMessage.class,
|
|
||||||
BuyerVerifiesFinalDelayedPayoutTx.class,
|
|
||||||
|
|
||||||
ApplyFilter.class,
|
ApplyFilter.class,
|
||||||
MakerVerifyTakerFeePayment.class,
|
|
||||||
BuyerPreparesPaymentSentMessage.class,
|
BuyerPreparesPaymentSentMessage.class,
|
||||||
BuyerSetupPayoutTxListener.class,
|
BuyerSetupPayoutTxListener.class,
|
||||||
BuyerSendsPaymentSentMessage.class,
|
BuyerSendsPaymentSentMessage.class,
|
||||||
|
@ -180,22 +135,9 @@ public class DebugView extends InitializableView<GridPane, Void> {
|
||||||
FXCollections.observableArrayList(Arrays.asList(
|
FXCollections.observableArrayList(Arrays.asList(
|
||||||
ApplyFilter.class,
|
ApplyFilter.class,
|
||||||
TakerVerifyMakerFeePayment.class,
|
TakerVerifyMakerFeePayment.class,
|
||||||
BuyerAsTakerCreatesDepositTxInputs.class,
|
|
||||||
|
|
||||||
TakerProcessesInputsForDepositTxResponse.class,
|
|
||||||
ApplyFilter.class,
|
ApplyFilter.class,
|
||||||
VerifyPeersAccountAgeWitness.class,
|
VerifyPeersAccountAgeWitness.class,
|
||||||
TakerPublishFeeTx.class,
|
|
||||||
BuyerAsTakerSignsDepositTx.class,
|
|
||||||
BuyerAsTakerSendsDepositTxMessage.class,
|
|
||||||
|
|
||||||
BuyerProcessDelayedPayoutTxSignatureRequest.class,
|
|
||||||
BuyerVerifiesPreparedDelayedPayoutTx.class,
|
|
||||||
BuyerSignsDelayedPayoutTx.class,
|
|
||||||
BuyerSendsDelayedPayoutTxSignatureResponse.class,
|
|
||||||
|
|
||||||
BuyerProcessDepositTxAndDelayedPayoutTxMessage.class,
|
|
||||||
BuyerVerifiesFinalDelayedPayoutTx.class,
|
|
||||||
|
|
||||||
ApplyFilter.class,
|
ApplyFilter.class,
|
||||||
TakerVerifyMakerFeePayment.class,
|
TakerVerifyMakerFeePayment.class,
|
||||||
|
@ -209,30 +151,19 @@ public class DebugView extends InitializableView<GridPane, Void> {
|
||||||
FXCollections.observableArrayList(Arrays.asList(
|
FXCollections.observableArrayList(Arrays.asList(
|
||||||
ApplyFilter.class,
|
ApplyFilter.class,
|
||||||
VerifyPeersAccountAgeWitness.class,
|
VerifyPeersAccountAgeWitness.class,
|
||||||
MakerVerifyTakerFeePayment.class,
|
|
||||||
MakerSetsLockTime.class,
|
MakerSetsLockTime.class,
|
||||||
SellerAsMakerCreatesUnsignedDepositTx.class,
|
|
||||||
SellerAsMakerSendsInputsForDepositTxResponse.class,
|
|
||||||
|
|
||||||
//SellerAsMakerProcessDepositTxMessage.class,
|
//SellerAsMakerProcessDepositTxMessage.class,
|
||||||
MaybeRemoveOpenOffer.class,
|
MaybeRemoveOpenOffer.class,
|
||||||
SellerAsMakerFinalizesDepositTx.class,
|
|
||||||
SellerCreatesDelayedPayoutTx.class,
|
|
||||||
SellerSendDelayedPayoutTxSignatureRequest.class,
|
|
||||||
|
|
||||||
SellerProcessDelayedPayoutTxSignatureResponse.class,
|
|
||||||
SellerSignsDelayedPayoutTx.class,
|
|
||||||
SellerFinalizesDelayedPayoutTx.class,
|
|
||||||
//SellerSendsDepositTxAndDelayedPayoutTxMessage.class,
|
//SellerSendsDepositTxAndDelayedPayoutTxMessage.class,
|
||||||
SellerPublishesDepositTx.class,
|
SellerPublishesDepositTx.class,
|
||||||
SellerPublishesTradeStatistics.class,
|
SellerPublishesTradeStatistics.class,
|
||||||
|
|
||||||
SellerProcessesPaymentSentMessage.class,
|
SellerProcessesPaymentSentMessage.class,
|
||||||
ApplyFilter.class,
|
ApplyFilter.class,
|
||||||
MakerVerifyTakerFeePayment.class,
|
|
||||||
|
|
||||||
ApplyFilter.class,
|
ApplyFilter.class,
|
||||||
MakerVerifyTakerFeePayment.class,
|
|
||||||
SellerPreparesPaymentReceivedMessage.class,
|
SellerPreparesPaymentReceivedMessage.class,
|
||||||
//SellerBroadcastPayoutTx.class, // TODO (woodser): removed from main pipeline; debug view?
|
//SellerBroadcastPayoutTx.class, // TODO (woodser): removed from main pipeline; debug view?
|
||||||
SellerSendsPaymentReceivedMessage.class
|
SellerSendsPaymentReceivedMessage.class
|
||||||
|
|
|
@ -400,7 +400,7 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
|
||||||
trade != null ? trade.getShortId() : "trade is null");
|
trade != null ? trade.getShortId() : "trade is null");
|
||||||
|
|
||||||
switch (tradeState) {
|
switch (tradeState) {
|
||||||
// #################### Phase PREPARATION
|
// preparation
|
||||||
case PREPARATION:
|
case PREPARATION:
|
||||||
case CONTRACT_SIGNATURE_REQUESTED:
|
case CONTRACT_SIGNATURE_REQUESTED:
|
||||||
case CONTRACT_SIGNED:
|
case CONTRACT_SIGNED:
|
||||||
|
@ -408,50 +408,23 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
|
||||||
buyerState.set(BuyerState.UNDEFINED);
|
buyerState.set(BuyerState.UNDEFINED);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// At first part maker/taker have different roles
|
// deposit requested
|
||||||
// taker perspective
|
case SENT_PUBLISH_DEPOSIT_TX_REQUEST:
|
||||||
// #################### Phase TAKER_FEE_PAID
|
case SAW_ARRIVED_PUBLISH_DEPOSIT_TX_REQUEST:
|
||||||
case TAKER_PUBLISHED_TAKER_FEE_TX:
|
case STORED_IN_MAILBOX_PUBLISH_DEPOSIT_TX_REQUEST:
|
||||||
|
case SEND_FAILED_PUBLISH_DEPOSIT_TX_REQUEST:
|
||||||
|
|
||||||
// PUBLISH_DEPOSIT_TX_REQUEST
|
// deposit published
|
||||||
// maker perspective
|
case ARBITRATOR_PUBLISHED_DEPOSIT_TXS:
|
||||||
case MAKER_SENT_PUBLISH_DEPOSIT_TX_REQUEST:
|
case SAW_DEPOSIT_TXS_IN_NETWORK:
|
||||||
case MAKER_SAW_ARRIVED_PUBLISH_DEPOSIT_TX_REQUEST:
|
|
||||||
case MAKER_STORED_IN_MAILBOX_PUBLISH_DEPOSIT_TX_REQUEST:
|
|
||||||
case MAKER_SEND_FAILED_PUBLISH_DEPOSIT_TX_REQUEST:
|
|
||||||
|
|
||||||
// taker perspective
|
|
||||||
case TAKER_RECEIVED_PUBLISH_DEPOSIT_TX_REQUEST:
|
|
||||||
// We don't have a UI state for that, we still have not a ready initiated trade
|
|
||||||
sellerState.set(UNDEFINED);
|
|
||||||
buyerState.set(BuyerState.UNDEFINED);
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
// #################### Phase DEPOSIT_PAID
|
|
||||||
case ARBITRATOR_PUBLISHED_DEPOSIT_TX:
|
|
||||||
case TAKER_SAW_DEPOSIT_TX_IN_NETWORK:
|
|
||||||
|
|
||||||
// DEPOSIT_TX_PUBLISHED_MSG
|
|
||||||
// taker perspective
|
|
||||||
case TAKER_SENT_DEPOSIT_TX_PUBLISHED_MSG:
|
|
||||||
case TAKER_SAW_ARRIVED_DEPOSIT_TX_PUBLISHED_MSG:
|
|
||||||
case TAKER_STORED_IN_MAILBOX_DEPOSIT_TX_PUBLISHED_MSG:
|
|
||||||
case TAKER_SEND_FAILED_DEPOSIT_TX_PUBLISHED_MSG:
|
|
||||||
|
|
||||||
// maker perspective
|
|
||||||
case MAKER_RECEIVED_DEPOSIT_TX_PUBLISHED_MSG:
|
|
||||||
|
|
||||||
// Alternatively the maker could have seen the deposit tx earlier before he received the DEPOSIT_TX_PUBLISHED_MSG
|
|
||||||
case MAKER_SAW_DEPOSIT_TX_IN_NETWORK:
|
|
||||||
buyerState.set(BuyerState.STEP1);
|
buyerState.set(BuyerState.STEP1);
|
||||||
sellerState.set(SellerState.STEP1);
|
sellerState.set(SellerState.STEP1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
// buyer and seller step 2
|
// buyer and seller step 2
|
||||||
// #################### Phase DEPOSIT_UNLOCKED
|
// deposit unlocked
|
||||||
case DEPOSIT_UNLOCKED_IN_BLOCK_CHAIN:
|
case DEPOSIT_TXS_UNLOCKED_IN_BLOCKCHAIN:
|
||||||
sellerState.set(SellerState.STEP2);
|
sellerState.set(SellerState.STEP2);
|
||||||
buyerState.set(BuyerState.STEP2);
|
buyerState.set(BuyerState.STEP2);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -610,7 +610,7 @@ public class BuyerStep2View extends TradeStepView {
|
||||||
|
|
||||||
//TODO seems this was a hack to enable repeated confirm???
|
//TODO seems this was a hack to enable repeated confirm???
|
||||||
if (trade.isPaymentSent()) {
|
if (trade.isPaymentSent()) {
|
||||||
trade.setState(Trade.State.DEPOSIT_UNLOCKED_IN_BLOCK_CHAIN);
|
trade.setState(Trade.State.DEPOSIT_TXS_UNLOCKED_IN_BLOCKCHAIN);
|
||||||
model.dataModel.getTradeManager().requestPersistence();
|
model.dataModel.getTradeManager().requestPersistence();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1629,41 +1629,33 @@ message Trade {
|
||||||
MULTISIG_COMPLETED = 4;
|
MULTISIG_COMPLETED = 4;
|
||||||
CONTRACT_SIGNATURE_REQUESTED = 5;
|
CONTRACT_SIGNATURE_REQUESTED = 5;
|
||||||
CONTRACT_SIGNED = 6;
|
CONTRACT_SIGNED = 6;
|
||||||
TAKER_PUBLISHED_TAKER_FEE_TX = 7;
|
SENT_PUBLISH_DEPOSIT_TX_REQUEST = 7;
|
||||||
MAKER_SENT_PUBLISH_DEPOSIT_TX_REQUEST = 8;
|
SAW_ARRIVED_PUBLISH_DEPOSIT_TX_REQUEST = 8;
|
||||||
MAKER_SAW_ARRIVED_PUBLISH_DEPOSIT_TX_REQUEST = 9;
|
STORED_IN_MAILBOX_PUBLISH_DEPOSIT_TX_REQUEST = 9;
|
||||||
MAKER_STORED_IN_MAILBOX_PUBLISH_DEPOSIT_TX_REQUEST = 10;
|
SEND_FAILED_PUBLISH_DEPOSIT_TX_REQUEST = 10;
|
||||||
MAKER_SEND_FAILED_PUBLISH_DEPOSIT_TX_REQUEST = 11;
|
ARBITRATOR_PUBLISHED_DEPOSIT_TXS = 11;
|
||||||
TAKER_RECEIVED_PUBLISH_DEPOSIT_TX_REQUEST = 12;
|
SAW_DEPOSIT_TXS_IN_NETWORK = 12;
|
||||||
ARBITRATOR_PUBLISHED_DEPOSIT_TX = 13;
|
DEPOSIT_TXS_UNLOCKED_IN_BLOCKCHAIN = 13;
|
||||||
TAKER_SAW_DEPOSIT_TX_IN_NETWORK = 14;
|
BUYER_CONFIRMED_IN_UI_PAYMENT_SENT = 14;
|
||||||
TAKER_SENT_DEPOSIT_TX_PUBLISHED_MSG = 15;
|
BUYER_SENT_PAYMENT_SENT_MSG = 15;
|
||||||
TAKER_SAW_ARRIVED_DEPOSIT_TX_PUBLISHED_MSG = 16;
|
BUYER_SAW_ARRIVED_PAYMENT_SENT_MSG = 16;
|
||||||
TAKER_STORED_IN_MAILBOX_DEPOSIT_TX_PUBLISHED_MSG = 17;
|
BUYER_STORED_IN_MAILBOX_PAYMENT_SENT_MSG = 17;
|
||||||
TAKER_SEND_FAILED_DEPOSIT_TX_PUBLISHED_MSG = 18;
|
BUYER_SEND_FAILED_PAYMENT_SENT_MSG = 18;
|
||||||
MAKER_RECEIVED_DEPOSIT_TX_PUBLISHED_MSG = 19;
|
SELLER_RECEIVED_PAYMENT_SENT_MSG = 19;
|
||||||
MAKER_SAW_DEPOSIT_TX_IN_NETWORK = 20;
|
SELLER_CONFIRMED_IN_UI_PAYMENT_RECEIPT = 20;
|
||||||
DEPOSIT_UNLOCKED_IN_BLOCK_CHAIN = 21;
|
SELLER_SENT_PAYMENT_RECEIVED_MSG = 21;
|
||||||
BUYER_CONFIRMED_IN_UI_PAYMENT_SENT = 22;
|
SELLER_SAW_ARRIVED_PAYMENT_RECEIVED_MSG = 22;
|
||||||
BUYER_SENT_PAYMENT_SENT_MSG = 23;
|
SELLER_STORED_IN_MAILBOX_PAYMENT_RECEIVED_MSG = 23;
|
||||||
BUYER_SAW_ARRIVED_PAYMENT_SENT_MSG = 24;
|
SELLER_SEND_FAILED_PAYMENT_RECEIVED_MSG = 24;
|
||||||
BUYER_STORED_IN_MAILBOX_PAYMENT_SENT_MSG = 25;
|
SELLER_PUBLISHED_PAYOUT_TX = 25;
|
||||||
BUYER_SEND_FAILED_PAYMENT_SENT_MSG = 26;
|
SELLER_SENT_PAYOUT_TX_PUBLISHED_MSG = 26;
|
||||||
SELLER_RECEIVED_PAYMENT_SENT_MSG = 27;
|
SELLER_SAW_ARRIVED_PAYOUT_TX_PUBLISHED_MSG = 27;
|
||||||
SELLER_CONFIRMED_IN_UI_PAYMENT_RECEIPT = 28;
|
SELLER_STORED_IN_MAILBOX_PAYOUT_TX_PUBLISHED_MSG = 28;
|
||||||
SELLER_SENT_PAYMENT_RECEIVED_MSG = 29;
|
SELLER_SEND_FAILED_PAYOUT_TX_PUBLISHED_MSG = 29;
|
||||||
SELLER_SAW_ARRIVED_PAYMENT_RECEIVED_MSG = 30;
|
BUYER_RECEIVED_PAYOUT_TX_PUBLISHED_MSG = 30;
|
||||||
SELLER_STORED_IN_MAILBOX_PAYMENT_RECEIVED_MSG = 31;
|
BUYER_SAW_PAYOUT_TX_IN_NETWORK = 31;
|
||||||
SELLER_SEND_FAILED_PAYMENT_RECEIVED_MSG = 32;
|
BUYER_PUBLISHED_PAYOUT_TX = 32;
|
||||||
SELLER_PUBLISHED_PAYOUT_TX = 33;
|
WITHDRAW_COMPLETED = 33;
|
||||||
SELLER_SENT_PAYOUT_TX_PUBLISHED_MSG = 34;
|
|
||||||
SELLER_SAW_ARRIVED_PAYOUT_TX_PUBLISHED_MSG = 35;
|
|
||||||
SELLER_STORED_IN_MAILBOX_PAYOUT_TX_PUBLISHED_MSG = 36;
|
|
||||||
SELLER_SEND_FAILED_PAYOUT_TX_PUBLISHED_MSG = 37;
|
|
||||||
BUYER_RECEIVED_PAYOUT_TX_PUBLISHED_MSG = 38;
|
|
||||||
BUYER_SAW_PAYOUT_TX_IN_NETWORK = 39;
|
|
||||||
BUYER_PUBLISHED_PAYOUT_TX = 40;
|
|
||||||
WITHDRAW_COMPLETED = 41;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Phase {
|
enum Phase {
|
||||||
|
|
Loading…
Reference in a new issue