diff --git a/core/src/main/java/io/bitsquare/btc/AddressEntry.java b/core/src/main/java/io/bitsquare/btc/AddressEntry.java index 4e6235d8b1..87399e3bda 100644 --- a/core/src/main/java/io/bitsquare/btc/AddressEntry.java +++ b/core/src/main/java/io/bitsquare/btc/AddressEntry.java @@ -23,8 +23,6 @@ import org.bitcoinj.crypto.DeterministicKey; import java.io.Serializable; -import java.util.Arrays; - import org.jetbrains.annotations.NotNull; /** @@ -102,9 +100,10 @@ public class AddressEntry implements Serializable { return "AddressEntry{" + "offerId='" + offerId + '\'' + ", context=" + context + - ", pubKey=" + Arrays.toString(pubKey) + + ", address=" + getAddressString() + + /* ", pubKey=" + Arrays.toString(pubKey) + ", pubKeyHash=" + Arrays.toString(pubKeyHash) + - ", params=" + params + + ", params=" + params +*/ '}'; } } diff --git a/core/src/main/java/io/bitsquare/btc/TradeWalletService.java b/core/src/main/java/io/bitsquare/btc/TradeWalletService.java index 3ddefb6c71..5ea59dda49 100644 --- a/core/src/main/java/io/bitsquare/btc/TradeWalletService.java +++ b/core/src/main/java/io/bitsquare/btc/TradeWalletService.java @@ -411,22 +411,27 @@ public class TradeWalletService { return wallet.getTransaction(tx.getHash()); } - public byte[] createAndSignPayoutTx(Transaction depositTx, - Coin buyerPayoutAmount, - Coin sellerPayoutAmount, - AddressEntry buyerAddressEntry, - String sellerPayoutAddressString, - long lockTimeDelta, - byte[] buyerPubKey, - byte[] sellerPubKey, - byte[] arbitratorPubKey) + public int getLastBlockSeenHeight() { + return wallet.getLastBlockSeenHeight(); + } + + public byte[] signPayoutTx(Transaction depositTx, + Coin buyerPayoutAmount, + Coin sellerPayoutAmount, + String buyerPayoutAddressString, + AddressEntry sellerAddressEntry, + long lockTime, + byte[] buyerPubKey, + byte[] sellerPubKey, + byte[] arbitratorPubKey) throws AddressFormatException, TransactionVerificationException, SigningException { log.trace("createAndSignPayoutTx called"); log.trace("depositTx " + depositTx.toString()); log.trace("buyerPayoutAmount " + buyerPayoutAmount.toFriendlyString()); log.trace("sellerPayoutAmount " + sellerPayoutAmount.toFriendlyString()); - log.trace("buyerAddressEntry " + buyerAddressEntry.toString()); - log.trace("sellerPayoutAddressString " + sellerPayoutAddressString); + log.trace("buyerPayoutAddressString " + buyerPayoutAddressString); + log.trace("sellerAddressEntry " + sellerAddressEntry.toString()); + log.trace("lockTime " + lockTime); log.trace("buyerPubKey " + ECKey.fromPublicOnly(buyerPubKey).toString()); log.trace("sellerPubKey " + ECKey.fromPublicOnly(sellerPubKey).toString()); log.trace("arbitratorPubKey " + ECKey.fromPublicOnly(arbitratorPubKey).toString()); @@ -434,45 +439,46 @@ public class TradeWalletService { Transaction preparedPayoutTx = createPayoutTx(depositTx, buyerPayoutAmount, sellerPayoutAmount, - buyerAddressEntry.getAddressString(), - sellerPayoutAddressString); - preparedPayoutTx.setLockTime(wallet.getLastBlockSeenHeight() + lockTimeDelta); - preparedPayoutTx.getInputs().stream().forEach(i -> i.setSequenceNumber(0)); + buyerPayoutAddressString, + sellerAddressEntry.getAddressString(), + lockTime + ); // MS redeemScript Script redeemScript = getMultiSigRedeemScript(buyerPubKey, sellerPubKey, arbitratorPubKey); Sha256Hash sigHash = preparedPayoutTx.hashForSignature(0, redeemScript, Transaction.SigHash.ALL, false); - ECKey.ECDSASignature buyerSignature = buyerAddressEntry.getKeyPair().sign(sigHash).toCanonicalised(); + ECKey.ECDSASignature sellerSignature = sellerAddressEntry.getKeyPair().sign(sigHash).toCanonicalised(); verifyTransaction(preparedPayoutTx); printTxWithInputs("preparedPayoutTx", preparedPayoutTx); - log.trace("buyerSignature r " + buyerSignature.toCanonicalised().r.toString()); - log.trace("buyerSignature s " + buyerSignature.toCanonicalised().s.toString()); + log.trace("sellerSignature r " + sellerSignature.toCanonicalised().r.toString()); + log.trace("sellerSignature s " + sellerSignature.toCanonicalised().s.toString()); Sha256Hash hashForSignature = preparedPayoutTx.hashForSignature(0, redeemScript.getProgram(), (byte) 1); log.trace("hashForSignature " + Utils.HEX.encode(hashForSignature.getBytes())); - return buyerSignature.encodeToDER(); + return sellerSignature.encodeToDER(); } public Transaction signAndFinalizePayoutTx(Transaction depositTx, - byte[] buyerSignature, + byte[] sellerSignature, Coin buyerPayoutAmount, Coin sellerPayoutAmount, - String buyerAddressString, - AddressEntry sellerAddressEntry, - long lockTimeDelta, + AddressEntry buyerAddressEntry, + String sellerAddressString, + long lockTime, byte[] buyerPubKey, byte[] sellerPubKey, byte[] arbitratorPubKey) throws AddressFormatException, TransactionVerificationException, WalletException, SigningException { log.trace("signAndPublishPayoutTx called"); log.trace("depositTx " + depositTx.toString()); - log.trace("buyerSignature r " + ECKey.ECDSASignature.decodeFromDER(buyerSignature).r.toString()); - log.trace("buyerSignature s " + ECKey.ECDSASignature.decodeFromDER(buyerSignature).s.toString()); + log.trace("sellerSignature r " + ECKey.ECDSASignature.decodeFromDER(sellerSignature).r.toString()); + log.trace("sellerSignature s " + ECKey.ECDSASignature.decodeFromDER(sellerSignature).s.toString()); log.trace("buyerPayoutAmount " + buyerPayoutAmount.toFriendlyString()); log.trace("sellerPayoutAmount " + sellerPayoutAmount.toFriendlyString()); - log.trace("buyerAddressString " + buyerAddressString); - log.trace("sellerAddressEntry " + sellerAddressEntry); + log.trace("buyerAddressEntry " + buyerAddressEntry); + log.trace("sellerAddressString " + sellerAddressString); + log.trace("lockTime " + lockTime); log.trace("buyerPubKey " + ECKey.fromPublicOnly(buyerPubKey).toString()); log.trace("sellerPubKey " + ECKey.fromPublicOnly(sellerPubKey).toString()); log.trace("arbitratorPubKey " + ECKey.fromPublicOnly(arbitratorPubKey).toString()); @@ -480,28 +486,26 @@ public class TradeWalletService { Transaction payoutTx = createPayoutTx(depositTx, buyerPayoutAmount, sellerPayoutAmount, - buyerAddressString, - sellerAddressEntry.getAddressString()); - payoutTx.setLockTime(wallet.getLastBlockSeenHeight() + lockTimeDelta); - payoutTx.getInputs().stream().forEach(i -> i.setSequenceNumber(0)); + buyerAddressEntry.getAddressString(), + sellerAddressString, + lockTime); Script redeemScript = getMultiSigRedeemScript(buyerPubKey, sellerPubKey, arbitratorPubKey); Sha256Hash sigHash = payoutTx.hashForSignature(0, redeemScript, Transaction.SigHash.ALL, false); - ECKey.ECDSASignature sellerSignature = sellerAddressEntry.getKeyPair().sign(sigHash).toCanonicalised(); + ECKey.ECDSASignature buyerSignature = buyerAddressEntry.getKeyPair().sign(sigHash).toCanonicalised(); - log.trace("sellerSignature r " + sellerSignature.r.toString()); - log.trace("sellerSignature s " + sellerSignature.s.toString()); + log.trace("buyerSignature r " + buyerSignature.r.toString()); + log.trace("buyerSignature s " + buyerSignature.s.toString()); Sha256Hash hashForSignature = payoutTx.hashForSignature(0, redeemScript.getProgram(), (byte) 1); log.trace("hashForSignature " + Utils.HEX.encode(hashForSignature.getBytes())); - TransactionSignature buyerTxSig = new TransactionSignature(ECKey.ECDSASignature.decodeFromDER(buyerSignature), - Transaction.SigHash.ALL, false); - TransactionSignature sellerTxSig = new TransactionSignature(sellerSignature, Transaction.SigHash.ALL, false); + TransactionSignature sellerTxSig = new TransactionSignature(ECKey.ECDSASignature.decodeFromDER(sellerSignature), Transaction.SigHash.ALL, false); + TransactionSignature buyerTxSig = new TransactionSignature(buyerSignature, Transaction.SigHash.ALL, false); // Take care of order of signatures. See comment below at getMultiSigRedeemScript Script inputScript = ScriptBuilder.createP2SHMultiSigInputScript(ImmutableList.of(sellerTxSig, buyerTxSig), redeemScript); TransactionInput input = payoutTx.getInput(0); input.setScriptSig(inputScript); - + printTxWithInputs("payoutTx", payoutTx); verifyTransaction(payoutTx); checkWalletConsistency(); checkScriptSig(payoutTx, input, 0); @@ -561,13 +565,15 @@ public class TradeWalletService { Coin buyerPayoutAmount, Coin sellerPayoutAmount, String buyerAddressString, - String sellerAddressString) throws AddressFormatException { - + String sellerAddressString, + long lockTime) throws AddressFormatException { TransactionOutput p2SHMultiSigOutput = depositTx.getOutput(0); Transaction transaction = new Transaction(params); transaction.addInput(p2SHMultiSigOutput); transaction.addOutput(buyerPayoutAmount, new Address(params, buyerAddressString)); transaction.addOutput(sellerPayoutAmount, new Address(params, sellerAddressString)); + transaction.setLockTime(lockTime); + transaction.getInputs().stream().forEach(i -> i.setSequenceNumber(0)); return transaction; } diff --git a/core/src/main/java/io/bitsquare/trade/Trade.java b/core/src/main/java/io/bitsquare/trade/Trade.java index 99e3a9a1ab..dbed693be7 100644 --- a/core/src/main/java/io/bitsquare/trade/Trade.java +++ b/core/src/main/java/io/bitsquare/trade/Trade.java @@ -104,6 +104,7 @@ abstract public class Trade implements Model, Serializable { private String sellerContractSignature; private String buyerContractSignature; private Transaction payoutTx; + private long lockTime; // Transient/Mutable transient private String errorMessage; @@ -168,12 +169,13 @@ abstract public class Trade implements Model, Serializable { createProtocol(); + tradeProtocol.checkPayoutTxTimeLock(this); + if (mailboxMessage != null) { tradeProtocol.applyMailboxMessage(mailboxMessage, this); // After applied to protocol we remove it mailboxMessage = null; } - tradeProtocol.checkPayoutTxTimeLock(this); } protected void initStateProperties() { @@ -334,16 +336,19 @@ abstract public class Trade implements Model, Serializable { tradeVolumeProperty.set(getTradeVolume()); } - // TODO support case of multiple fiat accounts - public long getLockTimeDelta() { - return getOffer().getFiatAccountType().lockTimeDelta; - } - @Nullable public Coin getTradeAmount() { return tradeAmount; } + public void setLockTime(long lockTime) { + this.lockTime = lockTime; + } + + public long getLockTime() { + return lockTime; + } + public void setSellerContractSignature(String takerSignature) { this.sellerContractSignature = takerSignature; } @@ -466,4 +471,5 @@ abstract public class Trade implements Model, Serializable { ", throwable=" + throwable + '}'; } + } \ No newline at end of file diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/BuyerAsOffererProtocol.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/BuyerAsOffererProtocol.java index 84c268cc1f..1ee400deea 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/BuyerAsOffererProtocol.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/BuyerAsOffererProtocol.java @@ -25,23 +25,24 @@ import io.bitsquare.trade.BuyerAsOffererTrade; import io.bitsquare.trade.Trade; import io.bitsquare.trade.protocol.availability.messages.ReportOfferAvailabilityMessage; import io.bitsquare.trade.protocol.availability.messages.RequestIsOfferAvailableMessage; -import io.bitsquare.trade.protocol.trade.messages.PayoutTxFinalizedMessage; import io.bitsquare.trade.protocol.trade.messages.RequestDepositTxInputsMessage; +import io.bitsquare.trade.protocol.trade.messages.RequestFinalizePayoutTxMessage; import io.bitsquare.trade.protocol.trade.messages.RequestPublishDepositTxMessage; import io.bitsquare.trade.protocol.trade.messages.TradeMessage; -import io.bitsquare.trade.protocol.trade.tasks.buyer.CommitPayoutTx; -import io.bitsquare.trade.protocol.trade.tasks.buyer.CreateAndSignPayoutTx; import io.bitsquare.trade.protocol.trade.tasks.buyer.CreateDepositTxInputs; -import io.bitsquare.trade.protocol.trade.tasks.buyer.ProcessPayoutTxFinalizedMessage; import io.bitsquare.trade.protocol.trade.tasks.buyer.ProcessRequestDepositTxInputsMessage; +import io.bitsquare.trade.protocol.trade.tasks.buyer.ProcessRequestFinalizePayoutTxMessage; import io.bitsquare.trade.protocol.trade.tasks.buyer.ProcessRequestPublishDepositTxMessage; import io.bitsquare.trade.protocol.trade.tasks.buyer.SendDepositTxPublishedMessage; import io.bitsquare.trade.protocol.trade.tasks.buyer.SendFiatTransferStartedMessage; +import io.bitsquare.trade.protocol.trade.tasks.buyer.SendPayoutTxFinalizedMessage; import io.bitsquare.trade.protocol.trade.tasks.buyer.SendRequestPayDepositMessage; +import io.bitsquare.trade.protocol.trade.tasks.buyer.SignAndFinalizePayoutTx; import io.bitsquare.trade.protocol.trade.tasks.buyer.SignAndPublishDepositTx; import io.bitsquare.trade.protocol.trade.tasks.buyer.VerifyAndSignContract; import io.bitsquare.trade.protocol.trade.tasks.offerer.VerifyTakeOfferFeePayment; import io.bitsquare.trade.protocol.trade.tasks.offerer.VerifyTakerAccount; +import io.bitsquare.trade.protocol.trade.tasks.shared.CommitPayoutTx; import io.bitsquare.trade.protocol.trade.tasks.shared.SetupPayoutTxLockTimeReachedListener; import io.bitsquare.trade.states.OffererTradeState; @@ -82,8 +83,8 @@ public class BuyerAsOffererProtocol extends TradeProtocol implements BuyerProtoc // Might be called twice, so check that its only processed once if (!processModel.isMailboxMessageProcessed()) { processModel.mailboxMessageProcessed(); - if (mailboxMessage instanceof PayoutTxFinalizedMessage) { - handle((PayoutTxFinalizedMessage) mailboxMessage); + if (mailboxMessage instanceof RequestFinalizePayoutTxMessage) { + handle((RequestFinalizePayoutTxMessage) mailboxMessage); } } } @@ -173,7 +174,6 @@ public class BuyerAsOffererProtocol extends TradeProtocol implements BuyerProtoc this::handleTaskRunnerFault); taskRunner.addTasks( VerifyTakeOfferFeePayment.class, - CreateAndSignPayoutTx.class, SendFiatTransferStartedMessage.class ); taskRunner.run(); @@ -184,7 +184,8 @@ public class BuyerAsOffererProtocol extends TradeProtocol implements BuyerProtoc // Incoming message handling /////////////////////////////////////////////////////////////////////////////////////////// - private void handle(PayoutTxFinalizedMessage tradeMessage) { + private void handle(RequestFinalizePayoutTxMessage tradeMessage) { + log.debug("handle RequestFinalizePayoutTxMessage called"); processModel.setTradeMessage(tradeMessage); TradeTaskRunner taskRunner = new TradeTaskRunner(buyerAsOffererTrade, @@ -196,8 +197,10 @@ public class BuyerAsOffererProtocol extends TradeProtocol implements BuyerProtoc this::handleTaskRunnerFault); taskRunner.addTasks( - ProcessPayoutTxFinalizedMessage.class, + ProcessRequestFinalizePayoutTxMessage.class, + SignAndFinalizePayoutTx.class, CommitPayoutTx.class, + SendPayoutTxFinalizedMessage.class, SetupPayoutTxLockTimeReachedListener.class ); taskRunner.run(); @@ -224,8 +227,8 @@ public class BuyerAsOffererProtocol extends TradeProtocol implements BuyerProtoc else if (tradeMessage instanceof RequestPublishDepositTxMessage) { handle((RequestPublishDepositTxMessage) tradeMessage); } - else if (tradeMessage instanceof PayoutTxFinalizedMessage) { - handle((PayoutTxFinalizedMessage) tradeMessage); + else if (tradeMessage instanceof RequestFinalizePayoutTxMessage) { + handle((RequestFinalizePayoutTxMessage) tradeMessage); } else { log.error("Incoming tradeMessage not supported. " + tradeMessage); diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/BuyerAsTakerProtocol.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/BuyerAsTakerProtocol.java index 76ce8efb57..d82c92f103 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/BuyerAsTakerProtocol.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/BuyerAsTakerProtocol.java @@ -22,19 +22,21 @@ import io.bitsquare.p2p.Message; import io.bitsquare.p2p.Peer; import io.bitsquare.trade.BuyerAsTakerTrade; import io.bitsquare.trade.Trade; -import io.bitsquare.trade.protocol.trade.messages.PayoutTxFinalizedMessage; +import io.bitsquare.trade.protocol.trade.messages.RequestFinalizePayoutTxMessage; import io.bitsquare.trade.protocol.trade.messages.RequestPublishDepositTxMessage; import io.bitsquare.trade.protocol.trade.messages.TradeMessage; -import io.bitsquare.trade.protocol.trade.tasks.buyer.CommitPayoutTx; -import io.bitsquare.trade.protocol.trade.tasks.buyer.CreateAndSignPayoutTx; import io.bitsquare.trade.protocol.trade.tasks.buyer.CreateDepositTxInputs; -import io.bitsquare.trade.protocol.trade.tasks.buyer.ProcessPayoutTxFinalizedMessage; +import io.bitsquare.trade.protocol.trade.tasks.buyer.ProcessRequestFinalizePayoutTxMessage; import io.bitsquare.trade.protocol.trade.tasks.buyer.ProcessRequestPublishDepositTxMessage; import io.bitsquare.trade.protocol.trade.tasks.buyer.SendDepositTxPublishedMessage; import io.bitsquare.trade.protocol.trade.tasks.buyer.SendFiatTransferStartedMessage; +import io.bitsquare.trade.protocol.trade.tasks.buyer.SendPayoutTxFinalizedMessage; import io.bitsquare.trade.protocol.trade.tasks.buyer.SendRequestPayDepositMessage; +import io.bitsquare.trade.protocol.trade.tasks.buyer.SignAndFinalizePayoutTx; import io.bitsquare.trade.protocol.trade.tasks.buyer.SignAndPublishDepositTx; import io.bitsquare.trade.protocol.trade.tasks.buyer.VerifyAndSignContract; +import io.bitsquare.trade.protocol.trade.tasks.seller.SignPayoutTx; +import io.bitsquare.trade.protocol.trade.tasks.shared.CommitPayoutTx; import io.bitsquare.trade.protocol.trade.tasks.shared.SetupPayoutTxLockTimeReachedListener; import io.bitsquare.trade.protocol.trade.tasks.taker.BroadcastTakeOfferFeeTx; import io.bitsquare.trade.protocol.trade.tasks.taker.CreateTakeOfferFeeTx; @@ -79,8 +81,8 @@ public class BuyerAsTakerProtocol extends TradeProtocol implements BuyerProtocol // Might be called twice, so check that its only processed once if (!processModel.isMailboxMessageProcessed()) { processModel.mailboxMessageProcessed(); - if (mailboxMessage instanceof PayoutTxFinalizedMessage) { - handle((PayoutTxFinalizedMessage) mailboxMessage); + if (mailboxMessage instanceof RequestFinalizePayoutTxMessage) { + handle((RequestFinalizePayoutTxMessage) mailboxMessage); } } } @@ -136,7 +138,7 @@ public class BuyerAsTakerProtocol extends TradeProtocol implements BuyerProtocol this::handleTaskRunnerFault); taskRunner.addTasks( VerifyOfferFeePayment.class, - CreateAndSignPayoutTx.class, + SignPayoutTx.class, SendFiatTransferStartedMessage.class ); taskRunner.run(); @@ -144,10 +146,10 @@ public class BuyerAsTakerProtocol extends TradeProtocol implements BuyerProtocol /////////////////////////////////////////////////////////////////////////////////////////// - // After peer has received Fiat tx + // Incoming message handling /////////////////////////////////////////////////////////////////////////////////////////// - private void handle(PayoutTxFinalizedMessage tradeMessage) { + private void handle(RequestFinalizePayoutTxMessage tradeMessage) { processModel.setTradeMessage(tradeMessage); TradeTaskRunner taskRunner = new TradeTaskRunner(buyerAsTakerTrade, @@ -159,13 +161,15 @@ public class BuyerAsTakerProtocol extends TradeProtocol implements BuyerProtocol this::handleTaskRunnerFault); taskRunner.addTasks( - ProcessPayoutTxFinalizedMessage.class, + ProcessRequestFinalizePayoutTxMessage.class, + SignAndFinalizePayoutTx.class, CommitPayoutTx.class, - SetupPayoutTxLockTimeReachedListener.class); + SendPayoutTxFinalizedMessage.class, + SetupPayoutTxLockTimeReachedListener.class + ); taskRunner.run(); } - /////////////////////////////////////////////////////////////////////////////////////////// // Massage dispatcher /////////////////////////////////////////////////////////////////////////////////////////// @@ -180,8 +184,8 @@ public class BuyerAsTakerProtocol extends TradeProtocol implements BuyerProtocol if (tradeMessage instanceof RequestPublishDepositTxMessage) { handle((RequestPublishDepositTxMessage) tradeMessage); } - else if (tradeMessage instanceof PayoutTxFinalizedMessage) { - handle((PayoutTxFinalizedMessage) tradeMessage); + else if (tradeMessage instanceof RequestFinalizePayoutTxMessage) { + handle((RequestFinalizePayoutTxMessage) tradeMessage); } else { log.error("Incoming message not supported. " + tradeMessage); diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/ProcessModel.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/ProcessModel.java index b73906ac40..98dd1ffcec 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/ProcessModel.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/ProcessModel.java @@ -30,7 +30,6 @@ import io.bitsquare.p2p.MessageService; import io.bitsquare.trade.protocol.trade.messages.TradeMessage; import io.bitsquare.user.User; -import org.bitcoinj.core.Coin; import org.bitcoinj.core.Transaction; import org.bitcoinj.core.TransactionOutput; import org.bitcoinj.crypto.DeterministicKey; @@ -70,7 +69,7 @@ public class ProcessModel implements Model, Serializable { transient private TradeMessage tradeMessage; private String takeOfferFeeTxId; private List connectedOutputsForAllInputs; - private Coin payoutAmount; + // private Coin payoutAmount; private Transaction preparedDepositTx; private List outputs; // used to verify amounts with change outputs private byte[] payoutTxSignature; @@ -215,14 +214,14 @@ public class ProcessModel implements Model, Serializable { this.connectedOutputsForAllInputs = connectedOutputsForAllInputs; } - @Nullable + /* @Nullable public Coin getPayoutAmount() { return payoutAmount; } public void setPayoutAmount(Coin payoutAmount) { this.payoutAmount = payoutAmount; - } + }*/ @Nullable public Transaction getPreparedDepositTx() { diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/SellerAsOffererProtocol.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/SellerAsOffererProtocol.java index e1e9a8f845..29a8121aa7 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/SellerAsOffererProtocol.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/SellerAsOffererProtocol.java @@ -27,6 +27,7 @@ import io.bitsquare.trade.protocol.availability.messages.ReportOfferAvailability import io.bitsquare.trade.protocol.availability.messages.RequestIsOfferAvailableMessage; import io.bitsquare.trade.protocol.trade.messages.DepositTxPublishedMessage; import io.bitsquare.trade.protocol.trade.messages.FiatTransferStartedMessage; +import io.bitsquare.trade.protocol.trade.messages.PayoutTxFinalizedMessage; import io.bitsquare.trade.protocol.trade.messages.RequestPayDepositMessage; import io.bitsquare.trade.protocol.trade.messages.TradeMessage; import io.bitsquare.trade.protocol.trade.tasks.offerer.VerifyTakeOfferFeePayment; @@ -36,10 +37,12 @@ import io.bitsquare.trade.protocol.trade.tasks.seller.CreateAndSignContract; import io.bitsquare.trade.protocol.trade.tasks.seller.CreateAndSignDepositTx; import io.bitsquare.trade.protocol.trade.tasks.seller.ProcessDepositTxPublishedMessage; import io.bitsquare.trade.protocol.trade.tasks.seller.ProcessFiatTransferStartedMessage; +import io.bitsquare.trade.protocol.trade.tasks.seller.ProcessPayoutTxFinalizedMessage; import io.bitsquare.trade.protocol.trade.tasks.seller.ProcessRequestPayDepositMessage; -import io.bitsquare.trade.protocol.trade.tasks.seller.SendPayoutTxFinalizedMessage; +import io.bitsquare.trade.protocol.trade.tasks.seller.SendRequestFinalizePayoutTxMessage; import io.bitsquare.trade.protocol.trade.tasks.seller.SendRequestPublishDepositTxMessage; -import io.bitsquare.trade.protocol.trade.tasks.seller.SignAndFinalizePayoutTx; +import io.bitsquare.trade.protocol.trade.tasks.seller.SignPayoutTx; +import io.bitsquare.trade.protocol.trade.tasks.shared.CommitPayoutTx; import io.bitsquare.trade.protocol.trade.tasks.shared.SetupPayoutTxLockTimeReachedListener; import io.bitsquare.trade.states.OffererTradeState; @@ -193,8 +196,6 @@ public class SellerAsOffererProtocol extends TradeProtocol implements SellerProt // User clicked the "bank transfer received" button, so we release the funds for pay out @Override public void onFiatPaymentReceived() { - sellerAsOffererTrade.setProcessState(OffererTradeState.ProcessState.FIAT_PAYMENT_RECEIVED); - TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsOffererTrade, () -> { log.debug("taskRunner at handleFiatReceivedUIEvent completed"); @@ -206,13 +207,26 @@ public class SellerAsOffererProtocol extends TradeProtocol implements SellerProt taskRunner.addTasks( VerifyTakeOfferFeePayment.class, - SignAndFinalizePayoutTx.class, - SendPayoutTxFinalizedMessage.class, - SetupPayoutTxLockTimeReachedListener.class + SignPayoutTx.class, + SendRequestFinalizePayoutTxMessage.class ); taskRunner.run(); } + private void handle(PayoutTxFinalizedMessage tradeMessage) { + processModel.setTradeMessage(tradeMessage); + + TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsOffererTrade, + () -> log.debug("taskRunner at handleFiatTransferStartedMessage completed"), + this::handleTaskRunnerFault); + + taskRunner.addTasks( + ProcessPayoutTxFinalizedMessage.class, + CommitPayoutTx.class, + SetupPayoutTxLockTimeReachedListener.class + ); + taskRunner.run(); + } /////////////////////////////////////////////////////////////////////////////////////////// // Massage dispatcher @@ -236,6 +250,9 @@ public class SellerAsOffererProtocol extends TradeProtocol implements SellerProt else if (tradeMessage instanceof FiatTransferStartedMessage) { handle((FiatTransferStartedMessage) tradeMessage); } + else if (tradeMessage instanceof PayoutTxFinalizedMessage) { + handle((PayoutTxFinalizedMessage) tradeMessage); + } else { log.error("Incoming tradeMessage not supported. " + tradeMessage); } diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/SellerAsTakerProtocol.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/SellerAsTakerProtocol.java index a09d9e63b6..35248be83d 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/SellerAsTakerProtocol.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/SellerAsTakerProtocol.java @@ -24,6 +24,7 @@ import io.bitsquare.trade.SellerAsTakerTrade; import io.bitsquare.trade.Trade; import io.bitsquare.trade.protocol.trade.messages.DepositTxPublishedMessage; import io.bitsquare.trade.protocol.trade.messages.FiatTransferStartedMessage; +import io.bitsquare.trade.protocol.trade.messages.PayoutTxFinalizedMessage; import io.bitsquare.trade.protocol.trade.messages.RequestPayDepositMessage; import io.bitsquare.trade.protocol.trade.messages.TradeMessage; import io.bitsquare.trade.protocol.trade.tasks.seller.CommitDepositTx; @@ -31,17 +32,18 @@ import io.bitsquare.trade.protocol.trade.tasks.seller.CreateAndSignContract; import io.bitsquare.trade.protocol.trade.tasks.seller.CreateAndSignDepositTx; import io.bitsquare.trade.protocol.trade.tasks.seller.ProcessDepositTxPublishedMessage; import io.bitsquare.trade.protocol.trade.tasks.seller.ProcessFiatTransferStartedMessage; +import io.bitsquare.trade.protocol.trade.tasks.seller.ProcessPayoutTxFinalizedMessage; import io.bitsquare.trade.protocol.trade.tasks.seller.ProcessRequestPayDepositMessage; -import io.bitsquare.trade.protocol.trade.tasks.seller.SendPayoutTxFinalizedMessage; import io.bitsquare.trade.protocol.trade.tasks.seller.SendRequestDepositTxInputsMessage; +import io.bitsquare.trade.protocol.trade.tasks.seller.SendRequestFinalizePayoutTxMessage; import io.bitsquare.trade.protocol.trade.tasks.seller.SendRequestPublishDepositTxMessage; -import io.bitsquare.trade.protocol.trade.tasks.seller.SignAndFinalizePayoutTx; +import io.bitsquare.trade.protocol.trade.tasks.seller.SignPayoutTx; +import io.bitsquare.trade.protocol.trade.tasks.shared.CommitPayoutTx; import io.bitsquare.trade.protocol.trade.tasks.shared.SetupPayoutTxLockTimeReachedListener; import io.bitsquare.trade.protocol.trade.tasks.taker.BroadcastTakeOfferFeeTx; import io.bitsquare.trade.protocol.trade.tasks.taker.CreateTakeOfferFeeTx; import io.bitsquare.trade.protocol.trade.tasks.taker.VerifyOfferFeePayment; import io.bitsquare.trade.protocol.trade.tasks.taker.VerifyOffererAccount; -import io.bitsquare.trade.states.TakerTradeState; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -87,6 +89,9 @@ public class SellerAsTakerProtocol extends TradeProtocol implements SellerProtoc else if (mailboxMessage instanceof DepositTxPublishedMessage) { handle((DepositTxPublishedMessage) mailboxMessage); } + else if (mailboxMessage instanceof PayoutTxFinalizedMessage) { + handle((PayoutTxFinalizedMessage) mailboxMessage); + } } } @@ -116,7 +121,7 @@ public class SellerAsTakerProtocol extends TradeProtocol implements SellerProtoc processModel.setTradeMessage(tradeMessage); TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsTakerTrade, - () -> log.debug("taskRunner at handleTakerDepositPaymentRequestMessage completed"), + () -> log.debug("taskRunner at RequestPayDepositMessage completed"), this::handleTaskRunnerFault); taskRunner.addTasks( @@ -135,7 +140,7 @@ public class SellerAsTakerProtocol extends TradeProtocol implements SellerProtoc processModel.setTradeMessage(tradeMessage); TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsTakerTrade, - () -> log.debug("taskRunner at handleDepositTxPublishedMessage completed"), + () -> log.debug("taskRunner at DepositTxPublishedMessage completed"), this::handleTaskRunnerFault); taskRunner.addTasks( @@ -154,7 +159,7 @@ public class SellerAsTakerProtocol extends TradeProtocol implements SellerProtoc processModel.setTradeMessage(tradeMessage); TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsTakerTrade, - () -> log.debug("taskRunner at handleFiatTransferStartedMessage completed"), + () -> log.debug("taskRunner at FiatTransferStartedMessage completed"), this::handleTaskRunnerFault); taskRunner.addTasks(ProcessFiatTransferStartedMessage.class); @@ -169,11 +174,9 @@ public class SellerAsTakerProtocol extends TradeProtocol implements SellerProtoc // User clicked the "bank transfer received" button, so we release the funds for pay out @Override public void onFiatPaymentReceived() { - sellerAsTakerTrade.setProcessState(TakerTradeState.ProcessState.FIAT_PAYMENT_RECEIVED); - TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsTakerTrade, () -> { - log.debug("taskRunner at handleFiatReceivedUIEvent completed"); + log.debug("taskRunner at onFiatPaymentReceived completed"); // we are done! processModel.onComplete(); @@ -182,13 +185,28 @@ public class SellerAsTakerProtocol extends TradeProtocol implements SellerProtoc taskRunner.addTasks( VerifyOfferFeePayment.class, - SignAndFinalizePayoutTx.class, - SendPayoutTxFinalizedMessage.class, + SignPayoutTx.class, + SendRequestFinalizePayoutTxMessage.class + ); + taskRunner.run(); + } + + private void handle(PayoutTxFinalizedMessage tradeMessage) { + processModel.setTradeMessage(tradeMessage); + + TradeTaskRunner taskRunner = new TradeTaskRunner(sellerAsTakerTrade, + () -> log.debug("taskRunner at PayoutTxFinalizedMessage completed"), + this::handleTaskRunnerFault); + + taskRunner.addTasks( + ProcessPayoutTxFinalizedMessage.class, + CommitPayoutTx.class, SetupPayoutTxLockTimeReachedListener.class ); taskRunner.run(); } + /////////////////////////////////////////////////////////////////////////////////////////// // Massage dispatcher /////////////////////////////////////////////////////////////////////////////////////////// @@ -209,7 +227,11 @@ public class SellerAsTakerProtocol extends TradeProtocol implements SellerProtoc else if (tradeMessage instanceof FiatTransferStartedMessage) { handle((FiatTransferStartedMessage) tradeMessage); } + else if (tradeMessage instanceof PayoutTxFinalizedMessage) { + handle((PayoutTxFinalizedMessage) tradeMessage); + } else { + log.error("Incoming message not supported. " + tradeMessage); } } diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/TradeProtocol.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/TradeProtocol.java index 9710a5a299..10fcb0c828 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/TradeProtocol.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/TradeProtocol.java @@ -61,11 +61,9 @@ public abstract class TradeProtocol { boolean needPayoutTxBroadcast = false; if (trade instanceof TakerTrade) - needPayoutTxBroadcast = trade.processStateProperty().get() == TakerTradeState.ProcessState.PAYOUT_FINALIZED - || trade.processStateProperty().get() == TakerTradeState.ProcessState.PAYOUT_FINALIZED_MSG_SENT; + needPayoutTxBroadcast = trade.processStateProperty().get() == TakerTradeState.ProcessState.PAYOUT_FINALIZED; else if (trade instanceof OffererTrade) - needPayoutTxBroadcast = trade.processStateProperty().get() == OffererTradeState.ProcessState.PAYOUT_FINALIZED - || trade.processStateProperty().get() == OffererTradeState.ProcessState.PAYOUT_FINALIZED_MSG_SENT; + needPayoutTxBroadcast = trade.processStateProperty().get() == OffererTradeState.ProcessState.PAYOUT_FINALIZED; if (needPayoutTxBroadcast) { TradeTaskRunner taskRunner = new TradeTaskRunner(trade, @@ -92,7 +90,7 @@ public abstract class TradeProtocol { log.debug("Timeout reached"); if (trade instanceof TakerTrade) trade.setProcessState(TakerTradeState.ProcessState.TIMEOUT); - else + else if (trade instanceof OffererTrade) trade.setProcessState(OffererTradeState.ProcessState.TIMEOUT); }); } diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/TradingPeer.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/TradingPeer.java index 1a1984a369..8a939f5c74 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/TradingPeer.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/TradingPeer.java @@ -19,7 +19,6 @@ package io.bitsquare.trade.protocol.trade; import io.bitsquare.fiat.FiatAccount; -import org.bitcoinj.core.Coin; import org.bitcoinj.core.Transaction; import org.bitcoinj.core.TransactionOutput; @@ -49,11 +48,12 @@ public class TradingPeer implements Serializable { private Transaction preparedDepositTx; private List connectedOutputsForAllInputs; private List outputs; - private Coin payoutAmount; + // private Coin payoutAmount; private String payoutAddressString; - private byte[] signature; + // private byte[] signature; private String contractAsJson; private String contractSignature; + private byte[] signature; /////////////////////////////////////////////////////////////////////////////////////////// @@ -138,13 +138,13 @@ public class TradingPeer implements Serializable { this.outputs = outputs; } - public Coin getPayoutAmount() { + /* public Coin getPayoutAmount() { return payoutAmount; } public void setPayoutAmount(Coin payoutAmount) { this.payoutAmount = payoutAmount; - } + }*/ public String getPayoutAddressString() { return payoutAddressString; @@ -154,13 +154,13 @@ public class TradingPeer implements Serializable { this.payoutAddressString = payoutAddressString; } - public byte[] getSignature() { + /* public byte[] getSignature() { return signature; } public void setSignature(byte[] signature) { this.signature = signature; - } + }*/ public String getContractAsJson() { return contractAsJson; @@ -177,4 +177,12 @@ public class TradingPeer implements Serializable { public void setContractSignature(String contractSignature) { this.contractSignature = contractSignature; } + + public void setSignature(byte[] signature) { + this.signature = signature; + } + + public byte[] getSignature() { + return signature; + } } diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/messages/FiatTransferStartedMessage.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/messages/FiatTransferStartedMessage.java index a6a1e2152d..5447bc249f 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/messages/FiatTransferStartedMessage.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/messages/FiatTransferStartedMessage.java @@ -19,8 +19,6 @@ package io.bitsquare.trade.protocol.trade.messages; import io.bitsquare.p2p.MailboxMessage; -import org.bitcoinj.core.Coin; - import java.io.Serializable; import javax.annotation.concurrent.Immutable; @@ -30,20 +28,11 @@ public class FiatTransferStartedMessage extends TradeMessage implements MailboxM // That object is sent over the wire, so we need to take care of version compatibility. private static final long serialVersionUID = 1L; - public final byte[] buyerSignature; - public final Coin buyerPayoutAmount; public final String buyerPayoutAddress; - public final Coin sellerPayoutAmount; public FiatTransferStartedMessage(String tradeId, - byte[] buyerSignature, - Coin buyerPayoutAmount, - String buyerPayoutAddress, - Coin sellerPayoutAmount) { + String buyerPayoutAddress) { super(tradeId); - this.buyerSignature = buyerSignature; - this.buyerPayoutAmount = buyerPayoutAmount; this.buyerPayoutAddress = buyerPayoutAddress; - this.sellerPayoutAmount = sellerPayoutAmount; } } diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/messages/RequestFinalizePayoutTxMessage.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/messages/RequestFinalizePayoutTxMessage.java new file mode 100644 index 0000000000..0943b5aa71 --- /dev/null +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/messages/RequestFinalizePayoutTxMessage.java @@ -0,0 +1,44 @@ +/* + * This file is part of Bitsquare. + * + * Bitsquare is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bitsquare is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bitsquare. If not, see . + */ + +package io.bitsquare.trade.protocol.trade.messages; + +import io.bitsquare.p2p.MailboxMessage; + +import java.io.Serializable; + +import javax.annotation.concurrent.Immutable; + +@Immutable +public class RequestFinalizePayoutTxMessage extends TradeMessage implements MailboxMessage, Serializable { + // That object is sent over the wire, so we need to take care of version compatibility. + private static final long serialVersionUID = 1L; + + public final byte[] sellerSignature; + public final String sellerPayoutAddress; + public final long lockTime; + + public RequestFinalizePayoutTxMessage(String tradeId, + byte[] sellerSignature, + String sellerPayoutAddress, + long lockTime) { + super(tradeId); + this.sellerSignature = sellerSignature; + this.sellerPayoutAddress = sellerPayoutAddress; + this.lockTime = lockTime; + } +} diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/ProcessRequestFinalizePayoutTxMessage.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/ProcessRequestFinalizePayoutTxMessage.java new file mode 100644 index 0000000000..e5946e6d66 --- /dev/null +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/ProcessRequestFinalizePayoutTxMessage.java @@ -0,0 +1,58 @@ +/* + * This file is part of Bitsquare. + * + * Bitsquare is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bitsquare is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bitsquare. If not, see . + */ + +package io.bitsquare.trade.protocol.trade.tasks.buyer; + +import io.bitsquare.common.taskrunner.TaskRunner; +import io.bitsquare.trade.Trade; +import io.bitsquare.trade.protocol.trade.TradeTask; +import io.bitsquare.trade.protocol.trade.messages.RequestFinalizePayoutTxMessage; +import io.bitsquare.trade.states.StateUtil; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static com.google.common.base.Preconditions.checkNotNull; +import static io.bitsquare.util.Validator.*; + +public class ProcessRequestFinalizePayoutTxMessage extends TradeTask { + private static final Logger log = LoggerFactory.getLogger(ProcessRequestFinalizePayoutTxMessage.class); + + public ProcessRequestFinalizePayoutTxMessage(TaskRunner taskHandler, Trade trade) { + super(taskHandler, trade); + } + + @Override + protected void doRun() { + try { + RequestFinalizePayoutTxMessage message = (RequestFinalizePayoutTxMessage) processModel.getTradeMessage(); + checkTradeId(processModel.getId(), message); + checkNotNull(message); + + processModel.tradingPeer.setSignature(checkNotNull(message.sellerSignature)); + processModel.tradingPeer.setPayoutAddressString(nonEmptyStringOf(message.sellerPayoutAddress)); + trade.setLockTime(nonNegativeLongOf(message.lockTime)); + + complete(); + } catch (Throwable t) { + t.printStackTrace(); + trade.setThrowable(t); + StateUtil.setOfferOpenState(trade); + failed(t); + } + } +} \ No newline at end of file diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/SendFiatTransferStartedMessage.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/SendFiatTransferStartedMessage.java index 006f87b4f0..a55dcf811d 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/SendFiatTransferStartedMessage.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/SendFiatTransferStartedMessage.java @@ -42,10 +42,7 @@ public class SendFiatTransferStartedMessage extends TradeTask { protected void doRun() { try { FiatTransferStartedMessage tradeMessage = new FiatTransferStartedMessage(processModel.getId(), - processModel.getPayoutTxSignature(), - processModel.getPayoutAmount(), - processModel.getAddressEntry().getAddressString(), - processModel.tradingPeer.getPayoutAmount() + processModel.getAddressEntry().getAddressString() ); processModel.getMessageService().sendMessage(trade.getTradingPeer(), tradeMessage, diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/SendPayoutTxFinalizedMessage.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/SendPayoutTxFinalizedMessage.java similarity index 78% rename from core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/SendPayoutTxFinalizedMessage.java rename to core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/SendPayoutTxFinalizedMessage.java index 40b7f24e4f..db438761e6 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/SendPayoutTxFinalizedMessage.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/SendPayoutTxFinalizedMessage.java @@ -15,18 +15,14 @@ * along with Bitsquare. If not, see . */ -package io.bitsquare.trade.protocol.trade.tasks.seller; +package io.bitsquare.trade.protocol.trade.tasks.buyer; import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.p2p.listener.SendMessageListener; -import io.bitsquare.trade.OffererTrade; -import io.bitsquare.trade.TakerTrade; import io.bitsquare.trade.Trade; import io.bitsquare.trade.protocol.trade.TradeTask; import io.bitsquare.trade.protocol.trade.messages.PayoutTxFinalizedMessage; -import io.bitsquare.trade.states.OffererTradeState; import io.bitsquare.trade.states.StateUtil; -import io.bitsquare.trade.states.TakerTradeState; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -49,19 +45,14 @@ public class SendPayoutTxFinalizedMessage extends TradeTask { new SendMessageListener() { @Override public void handleResult() { - log.trace("PayoutTxPublishedMessage successfully arrived at peer"); - - if (trade instanceof TakerTrade) - trade.setProcessState(TakerTradeState.ProcessState.PAYOUT_FINALIZED_MSG_SENT); - else if (trade instanceof OffererTrade) - trade.setProcessState(OffererTradeState.ProcessState.PAYOUT_FINALIZED_MSG_SENT); + log.trace("PayoutTxFinalizedMessage successfully arrived at peer"); complete(); } @Override public void handleFault() { - appendToErrorMessage("Sending PayoutTxPublishedMessage failed"); + appendToErrorMessage("Sending PayoutTxFinalizedMessage failed"); trade.setErrorMessage(errorMessage); StateUtil.setSendFailedState(trade); failed(); diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/SignAndFinalizePayoutTx.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/SignAndFinalizePayoutTx.java similarity index 83% rename from core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/SignAndFinalizePayoutTx.java rename to core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/SignAndFinalizePayoutTx.java index 787f5f7177..247274a6e3 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/SignAndFinalizePayoutTx.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/SignAndFinalizePayoutTx.java @@ -15,7 +15,7 @@ * along with Bitsquare. If not, see . */ -package io.bitsquare.trade.protocol.trade.tasks.seller; +package io.bitsquare.trade.protocol.trade.tasks.buyer; import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.trade.OffererTrade; @@ -25,6 +25,7 @@ import io.bitsquare.trade.protocol.trade.TradeTask; import io.bitsquare.trade.states.OffererTradeState; import io.bitsquare.trade.states.TakerTradeState; +import org.bitcoinj.core.Coin; import org.bitcoinj.core.Transaction; import org.slf4j.Logger; @@ -40,16 +41,21 @@ public class SignAndFinalizePayoutTx extends TradeTask { @Override protected void doRun() { try { + assert trade.getTradeAmount() != null; + assert trade.getSecurityDeposit() != null; + Coin sellerPayoutAmount = trade.getSecurityDeposit(); + Coin buyerPayoutAmount = sellerPayoutAmount.add(trade.getTradeAmount()); + Transaction transaction = processModel.getTradeWalletService().signAndFinalizePayoutTx( trade.getDepositTx(), processModel.tradingPeer.getSignature(), - processModel.tradingPeer.getPayoutAmount(), - processModel.getPayoutAmount(), - processModel.tradingPeer.getPayoutAddressString(), + buyerPayoutAmount, + sellerPayoutAmount, processModel.getAddressEntry(), - trade.getLockTimeDelta(), - processModel.tradingPeer.getTradeWalletPubKey(), + processModel.tradingPeer.getPayoutAddressString(), + trade.getLockTime(), processModel.getTradeWalletPubKey(), + processModel.tradingPeer.getTradeWalletPubKey(), processModel.getArbitratorPubKey() ); diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/ProcessFiatTransferStartedMessage.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/ProcessFiatTransferStartedMessage.java index 5bd70887ab..161d10c33a 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/ProcessFiatTransferStartedMessage.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/ProcessFiatTransferStartedMessage.java @@ -46,9 +46,6 @@ public class ProcessFiatTransferStartedMessage extends TradeTask { checkTradeId(processModel.getId(), message); checkNotNull(message); - processModel.tradingPeer.setSignature(checkNotNull(message.buyerSignature)); - processModel.setPayoutAmount(positiveCoinOf(nonZeroCoinOf(message.sellerPayoutAmount))); - processModel.tradingPeer.setPayoutAmount(positiveCoinOf(nonZeroCoinOf(message.buyerPayoutAmount))); processModel.tradingPeer.setPayoutAddressString(nonEmptyStringOf(message.buyerPayoutAddress)); if (trade instanceof OffererTrade) diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/ProcessPayoutTxFinalizedMessage.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/ProcessPayoutTxFinalizedMessage.java similarity index 97% rename from core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/ProcessPayoutTxFinalizedMessage.java rename to core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/ProcessPayoutTxFinalizedMessage.java index d4a61cc4b3..e2ec51e80c 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/ProcessPayoutTxFinalizedMessage.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/ProcessPayoutTxFinalizedMessage.java @@ -15,7 +15,7 @@ * along with Bitsquare. If not, see . */ -package io.bitsquare.trade.protocol.trade.tasks.buyer; +package io.bitsquare.trade.protocol.trade.tasks.seller; import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.trade.OffererTrade; diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/SendRequestFinalizePayoutTxMessage.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/SendRequestFinalizePayoutTxMessage.java new file mode 100644 index 0000000000..fab87b8c16 --- /dev/null +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/SendRequestFinalizePayoutTxMessage.java @@ -0,0 +1,82 @@ +/* + * This file is part of Bitsquare. + * + * Bitsquare is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bitsquare is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bitsquare. If not, see . + */ + +package io.bitsquare.trade.protocol.trade.tasks.seller; + +import io.bitsquare.common.taskrunner.TaskRunner; +import io.bitsquare.p2p.listener.SendMessageListener; +import io.bitsquare.trade.OffererTrade; +import io.bitsquare.trade.TakerTrade; +import io.bitsquare.trade.Trade; +import io.bitsquare.trade.protocol.trade.TradeTask; +import io.bitsquare.trade.protocol.trade.messages.RequestFinalizePayoutTxMessage; +import io.bitsquare.trade.states.OffererTradeState; +import io.bitsquare.trade.states.StateUtil; +import io.bitsquare.trade.states.TakerTradeState; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SendRequestFinalizePayoutTxMessage extends TradeTask { + private static final Logger log = LoggerFactory.getLogger(SendRequestFinalizePayoutTxMessage.class); + + public SendRequestFinalizePayoutTxMessage(TaskRunner taskHandler, Trade trade) { + super(taskHandler, trade); + } + + @Override + protected void doRun() { + try { + RequestFinalizePayoutTxMessage message = new RequestFinalizePayoutTxMessage( + processModel.getId(), + processModel.getPayoutTxSignature(), + processModel.getAddressEntry().getAddressString(), + trade.getLockTime() + ); + + processModel.getMessageService().sendMessage(trade.getTradingPeer(), + message, + processModel.tradingPeer.getP2pSigPubKey(), + processModel.tradingPeer.getP2pEncryptPubKey(), + new SendMessageListener() { + @Override + public void handleResult() { + log.trace("PayoutTxPublishedMessage successfully arrived at peer"); + + if (trade instanceof TakerTrade) + trade.setProcessState(TakerTradeState.ProcessState.REQUEST_PAYOUT_FINALIZE_MSG_SENT); + else if (trade instanceof OffererTrade) + trade.setProcessState(OffererTradeState.ProcessState.REQUEST_PAYOUT_FINALIZE_MSG_SENT); + + complete(); + } + + @Override + public void handleFault() { + appendToErrorMessage("Sending PayoutTxPublishedMessage failed"); + trade.setErrorMessage(errorMessage); + StateUtil.setSendFailedState(trade); + failed(); + } + }); + } catch (Throwable t) { + t.printStackTrace(); + trade.setThrowable(t); + failed(t); + } + } +} diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/CreateAndSignPayoutTx.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/SignPayoutTx.java similarity index 74% rename from core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/CreateAndSignPayoutTx.java rename to core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/SignPayoutTx.java index 68ab3280fe..57793a0c43 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/CreateAndSignPayoutTx.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/SignPayoutTx.java @@ -15,7 +15,7 @@ * along with Bitsquare. If not, see . */ -package io.bitsquare.trade.protocol.trade.tasks.buyer; +package io.bitsquare.trade.protocol.trade.tasks.seller; import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.trade.Trade; @@ -26,10 +26,10 @@ import org.bitcoinj.core.Coin; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class CreateAndSignPayoutTx extends TradeTask { - private static final Logger log = LoggerFactory.getLogger(CreateAndSignPayoutTx.class); +public class SignPayoutTx extends TradeTask { + private static final Logger log = LoggerFactory.getLogger(SignPayoutTx.class); - public CreateAndSignPayoutTx(TaskRunner taskHandler, Trade trade) { + public SignPayoutTx(TaskRunner taskHandler, Trade trade) { super(taskHandler, trade); } @@ -41,20 +41,21 @@ public class CreateAndSignPayoutTx extends TradeTask { Coin sellerPayoutAmount = trade.getSecurityDeposit(); Coin buyerPayoutAmount = sellerPayoutAmount.add(trade.getTradeAmount()); - byte[] buyerPayoutTxSignature = processModel.getTradeWalletService().createAndSignPayoutTx( + long lockTime = processModel.getTradeWalletService().getLastBlockSeenHeight() + trade.getOffer().getFiatAccountType().lockTimeDelta; + trade.setLockTime(lockTime); + + byte[] payoutTxSignature = processModel.getTradeWalletService().signPayoutTx( trade.getDepositTx(), buyerPayoutAmount, sellerPayoutAmount, - processModel.getAddressEntry(), processModel.tradingPeer.getPayoutAddressString(), - trade.getLockTimeDelta(), - processModel.getTradeWalletPubKey(), + processModel.getAddressEntry(), + lockTime, processModel.tradingPeer.getTradeWalletPubKey(), + processModel.getTradeWalletPubKey(), processModel.getArbitratorPubKey()); - processModel.setPayoutTxSignature(buyerPayoutTxSignature); - processModel.setPayoutAmount(buyerPayoutAmount); - processModel.tradingPeer.setPayoutAmount(sellerPayoutAmount); + processModel.setPayoutTxSignature(payoutTxSignature); complete(); } catch (Throwable t) { diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/CommitPayoutTx.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/shared/CommitPayoutTx.java similarity index 96% rename from core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/CommitPayoutTx.java rename to core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/shared/CommitPayoutTx.java index 8e68b55d5d..3bb5cb2b0c 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/CommitPayoutTx.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/shared/CommitPayoutTx.java @@ -15,7 +15,7 @@ * along with Bitsquare. If not, see . */ -package io.bitsquare.trade.protocol.trade.tasks.buyer; +package io.bitsquare.trade.protocol.trade.tasks.shared; import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.trade.Trade; diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/shared/SetupPayoutTxLockTimeReachedListener.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/shared/SetupPayoutTxLockTimeReachedListener.java index 0ae9df1536..9c8a99924f 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/shared/SetupPayoutTxLockTimeReachedListener.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/shared/SetupPayoutTxLockTimeReachedListener.java @@ -49,7 +49,8 @@ public class SetupPayoutTxLockTimeReachedListener extends TradeTask { @Override protected void doRun() { try { - if (processModel.getTradeWalletService().getBestChainHeight() >= trade.getPayoutTx().getLockTime()) { + log.debug("ChainHeight/LockTime: {} / {}", processModel.getTradeWalletService().getBestChainHeight(), trade.getLockTime()); + if (processModel.getTradeWalletService().getBestChainHeight() >= trade.getLockTime()) { broadcastTx(); } else { diff --git a/core/src/main/java/io/bitsquare/trade/states/OffererTradeState.java b/core/src/main/java/io/bitsquare/trade/states/OffererTradeState.java index 729dce4de7..cc4a4e0de0 100644 --- a/core/src/main/java/io/bitsquare/trade/states/OffererTradeState.java +++ b/core/src/main/java/io/bitsquare/trade/states/OffererTradeState.java @@ -35,15 +35,15 @@ public class OffererTradeState { public enum ProcessState implements TradeState.ProcessState { UNDEFINED, DEPOSIT_PUBLISHED, - DEPOSIT_CONFIRMED, + DEPOSIT_CONFIRMED, FIAT_PAYMENT_STARTED, - FIAT_PAYMENT_RECEIVED, + REQUEST_PAYOUT_FINALIZE_MSG_SENT, // seller only PAYOUT_FINALIZED, - PAYOUT_FINALIZED_MSG_SENT, + PAYOUT_BROAD_CASTED, - PAYOUT_BROAD_CASTED_FAILED, + PAYOUT_BROAD_CASTED_FAILED, MESSAGE_SENDING_FAILED, TIMEOUT, diff --git a/core/src/main/java/io/bitsquare/trade/states/TakerTradeState.java b/core/src/main/java/io/bitsquare/trade/states/TakerTradeState.java index c9d1baf4d9..b9dbe3c666 100644 --- a/core/src/main/java/io/bitsquare/trade/states/TakerTradeState.java +++ b/core/src/main/java/io/bitsquare/trade/states/TakerTradeState.java @@ -40,9 +40,9 @@ public class TakerTradeState { FIAT_PAYMENT_STARTED, - FIAT_PAYMENT_RECEIVED, + REQUEST_PAYOUT_FINALIZE_MSG_SENT, // seller only PAYOUT_FINALIZED, - PAYOUT_FINALIZED_MSG_SENT, + PAYOUT_BROAD_CASTED, PAYOUT_BROAD_CASTED_FAILED, diff --git a/gui/src/main/java/io/bitsquare/gui/main/debug/DebugView.java b/gui/src/main/java/io/bitsquare/gui/main/debug/DebugView.java index d4659df008..0870f63184 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/debug/DebugView.java +++ b/gui/src/main/java/io/bitsquare/gui/main/debug/DebugView.java @@ -30,14 +30,14 @@ import io.bitsquare.trade.protocol.placeoffer.tasks.CreateOfferFeeTx; import io.bitsquare.trade.protocol.placeoffer.tasks.ValidateOffer; import io.bitsquare.trade.protocol.trade.BuyerAsOffererProtocol; import io.bitsquare.trade.protocol.trade.SellerAsTakerProtocol; -import io.bitsquare.trade.protocol.trade.tasks.buyer.CreateAndSignPayoutTx; import io.bitsquare.trade.protocol.trade.tasks.buyer.CreateDepositTxInputs; -import io.bitsquare.trade.protocol.trade.tasks.buyer.ProcessPayoutTxFinalizedMessage; import io.bitsquare.trade.protocol.trade.tasks.buyer.ProcessRequestDepositTxInputsMessage; import io.bitsquare.trade.protocol.trade.tasks.buyer.ProcessRequestPublishDepositTxMessage; import io.bitsquare.trade.protocol.trade.tasks.buyer.SendDepositTxPublishedMessage; import io.bitsquare.trade.protocol.trade.tasks.buyer.SendFiatTransferStartedMessage; +import io.bitsquare.trade.protocol.trade.tasks.buyer.SendPayoutTxFinalizedMessage; import io.bitsquare.trade.protocol.trade.tasks.buyer.SendRequestPayDepositMessage; +import io.bitsquare.trade.protocol.trade.tasks.buyer.SignAndFinalizePayoutTx; import io.bitsquare.trade.protocol.trade.tasks.buyer.SignAndPublishDepositTx; import io.bitsquare.trade.protocol.trade.tasks.offerer.VerifyTakeOfferFeePayment; import io.bitsquare.trade.protocol.trade.tasks.offerer.VerifyTakerAccount; @@ -45,10 +45,10 @@ import io.bitsquare.trade.protocol.trade.tasks.seller.CommitDepositTx; import io.bitsquare.trade.protocol.trade.tasks.seller.CreateAndSignDepositTx; import io.bitsquare.trade.protocol.trade.tasks.seller.ProcessDepositTxPublishedMessage; import io.bitsquare.trade.protocol.trade.tasks.seller.ProcessFiatTransferStartedMessage; +import io.bitsquare.trade.protocol.trade.tasks.seller.ProcessPayoutTxFinalizedMessage; import io.bitsquare.trade.protocol.trade.tasks.seller.ProcessRequestPayDepositMessage; -import io.bitsquare.trade.protocol.trade.tasks.seller.SendPayoutTxFinalizedMessage; import io.bitsquare.trade.protocol.trade.tasks.seller.SendRequestDepositTxInputsMessage; -import io.bitsquare.trade.protocol.trade.tasks.seller.SignAndFinalizePayoutTx; +import io.bitsquare.trade.protocol.trade.tasks.seller.SignPayoutTx; import io.bitsquare.trade.protocol.trade.tasks.taker.CreateTakeOfferFeeTx; import io.bitsquare.trade.protocol.trade.tasks.taker.VerifyOfferFeePayment; import io.bitsquare.trade.protocol.trade.tasks.taker.VerifyOffererAccount; @@ -107,7 +107,7 @@ public class DebugView extends InitializableView { SignAndPublishDepositTx.class, SendDepositTxPublishedMessage.class, - CreateAndSignPayoutTx.class, + SignPayoutTx.class, VerifyTakeOfferFeePayment.class, SendFiatTransferStartedMessage.class, diff --git a/gui/src/main/java/io/bitsquare/gui/main/offer/takeoffer/TakeOfferViewModel.java b/gui/src/main/java/io/bitsquare/gui/main/offer/takeoffer/TakeOfferViewModel.java index c9867c6632..7c50e3e1e1 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/offer/takeoffer/TakeOfferViewModel.java +++ b/gui/src/main/java/io/bitsquare/gui/main/offer/takeoffer/TakeOfferViewModel.java @@ -255,8 +255,6 @@ class TakeOfferViewModel extends ActivatableWithDataModel im "Please try later again." + msg); takeOfferRequested = false; break; - case PAYOUT_FINALIZED: - break; case EXCEPTION: errorMessage.set(msg); takeOfferRequested = false; @@ -292,8 +290,6 @@ class TakeOfferViewModel extends ActivatableWithDataModel im "Please try later again." + msg); takeOfferRequested = false; break; - case PAYOUT_FINALIZED: - break; case EXCEPTION: errorMessage.set(msg); takeOfferRequested = false; diff --git a/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/BuyerSubView.java b/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/BuyerSubView.java index 1e5c27d012..babab201ae 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/BuyerSubView.java +++ b/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/BuyerSubView.java @@ -50,8 +50,8 @@ public class BuyerSubView extends TradeSubView { @Override protected void addWizards() { waitTxInBlockchain = new TradeWizardItem(WaitTxInBlockchainView.class, "Wait for blockchain confirmation"); - startFiat = new TradeWizardItem(StartFiatView.class, "Start payment"); - waitFiatReceived = new TradeWizardItem(WaitFiatReceivedView.class, "Wait until payment has arrived"); + startFiat = new TradeWizardItem(StartFiatView.class, "Start EUR payment"); + waitFiatReceived = new TradeWizardItem(WaitFiatReceivedView.class, "Wait until EUR payment arrived"); payoutUnlock = new TradeWizardItem(WaitPayoutLockTimeView.class, "Wait for payout unlock"); completed = new TradeWizardItem(CompletedView.class, "Completed"); diff --git a/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/PendingTradesDataModel.java b/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/PendingTradesDataModel.java index 668b27e2b1..8fc04804d1 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/PendingTradesDataModel.java +++ b/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/PendingTradesDataModel.java @@ -299,7 +299,7 @@ class PendingTradesDataModel implements Activatable, DataModel { } public long getLockTime() { - return trade.getPayoutTx().getLockTime(); + return trade.getLockTime(); } public int getBestChainHeight() { diff --git a/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/PendingTradesViewModel.java b/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/PendingTradesViewModel.java index cf5c0a848a..34833145ca 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/PendingTradesViewModel.java +++ b/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/PendingTradesViewModel.java @@ -58,7 +58,7 @@ public class PendingTradesViewModel extends ActivatableWithDataModel. + */ + +package io.bitsquare.gui.main.portfolio.pendingtrades.steps; + +import io.bitsquare.gui.main.portfolio.pendingtrades.PendingTradesViewModel; +import io.bitsquare.gui.util.Layout; + +import javafx.scene.control.*; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static io.bitsquare.gui.util.ComponentBuilder.*; + +public class WaitPayoutFinalizedView extends TradeStepDetailsView { + private static final Logger log = LoggerFactory.getLogger(WaitPayoutFinalizedView.class); + + private Label infoLabel; + + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor, Initialisation + /////////////////////////////////////////////////////////////////////////////////////////// + + public WaitPayoutFinalizedView(PendingTradesViewModel model) { + super(model); + } + + @Override + public void activate() { + super.activate(); + } + + @Override + public void deactivate() { + super.deactivate(); + } + + public void setInfoLabelText(String text) { + if (infoLabel != null) + infoLabel.setText(text); + } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Build view + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + protected void buildGridEntries() { + getAndAddTitledGroupBg(gridPane, gridRow, 1, "Information"); + infoLabel = getAndAddInfoLabel(gridPane, gridRow++, Layout.FIRST_ROW_DISTANCE); + } +} + + diff --git a/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/steps/WaitPayoutLockTimeView.java b/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/steps/WaitPayoutLockTimeView.java index 252d6e8bbc..b337e3dded 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/steps/WaitPayoutLockTimeView.java +++ b/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/steps/WaitPayoutLockTimeView.java @@ -46,7 +46,6 @@ public class WaitPayoutLockTimeView extends TradeStepDetailsView { private Label infoLabel; private TextField timeTextField; - /////////////////////////////////////////////////////////////////////////////////////////// // Constructor, Initialisation /////////////////////////////////////////////////////////////////////////////////////////// @@ -114,6 +113,7 @@ public class WaitPayoutLockTimeView extends TradeStepDetailsView { timeTextField.setText(model.getUnlockDate(missingBlocks)); } + /////////////////////////////////////////////////////////////////////////////////////////// // Build view /////////////////////////////////////////////////////////////////////////////////////////// diff --git a/gui/src/main/java/io/bitsquare/gui/util/ComponentBuilder.java b/gui/src/main/java/io/bitsquare/gui/util/ComponentBuilder.java index b9264bfea1..7d74896700 100644 --- a/gui/src/main/java/io/bitsquare/gui/util/ComponentBuilder.java +++ b/gui/src/main/java/io/bitsquare/gui/util/ComponentBuilder.java @@ -195,7 +195,7 @@ public class ComponentBuilder { return button; } - public static ButtonWithProgressIndicatorAndLabelBucket getAndAddButtonWithStatus(GridPane gridPane, + public static ButtonWithProgressIndicatorAndLabel getAndAddButtonWithStatus(GridPane gridPane, int rowIndex, String ButtonTitle, EventHandler onActionHandler) { @@ -220,7 +220,7 @@ public class ComponentBuilder { GridPane.setMargin(hBox, new Insets(15, 0, 40, 0)); gridPane.getChildren().add(hBox); - return new ButtonWithProgressIndicatorAndLabelBucket(button, progressIndicator, label); + return new ButtonWithProgressIndicatorAndLabel(button, progressIndicator, label); } public static class LabelTextFieldPair { @@ -263,12 +263,12 @@ public class ComponentBuilder { } } - public static class ButtonWithProgressIndicatorAndLabelBucket { + public static class ButtonWithProgressIndicatorAndLabel { public Button button; public ProgressIndicator progressIndicator; public Label label; - public ButtonWithProgressIndicatorAndLabelBucket(Button button, ProgressIndicator progressIndicator, Label label) { + public ButtonWithProgressIndicatorAndLabel(Button button, ProgressIndicator progressIndicator, Label label) { this.button = button; this.progressIndicator = progressIndicator; this.label = label;