Fix bug with tx broadcast state

This commit is contained in:
Manfred Karrer 2016-02-12 18:23:15 +01:00
parent e5cfc2892b
commit 43d811d9fe
12 changed files with 59 additions and 69 deletions

View File

@ -233,8 +233,6 @@ abstract public class Trade implements Tradable, Model, Serializable {
createProtocol();
tradeProtocol.checkPayoutTxTimeLock(this);
if (decryptedMsgWithPubKey != null) {
tradeProtocol.applyMailboxMessage(decryptedMsgWithPubKey, this);
}

View File

@ -30,9 +30,9 @@ import io.bitsquare.trade.protocol.trade.messages.PayDepositRequest;
import io.bitsquare.trade.protocol.trade.messages.TradeMessage;
import io.bitsquare.trade.protocol.trade.tasks.buyer.*;
import io.bitsquare.trade.protocol.trade.tasks.offerer.*;
import io.bitsquare.trade.protocol.trade.tasks.shared.BroadcastAfterLockTime;
import io.bitsquare.trade.protocol.trade.tasks.shared.CommitPayoutTx;
import io.bitsquare.trade.protocol.trade.tasks.shared.InitWaitPeriodForOpenDispute;
import io.bitsquare.trade.protocol.trade.tasks.shared.SetupPayoutTxLockTimeReachedListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -56,7 +56,7 @@ public class BuyerAsOffererProtocol extends TradeProtocol implements BuyerProtoc
// If we are after the time lock state we need to setup the listener again
Trade.State tradeState = trade.getState();
if (tradeState.getPhase() == Trade.Phase.PAYOUT_PAID) {
if (tradeState.getPhase() == Trade.Phase.PAYOUT_PAID && tradeState != Trade.State.PAYOUT_BROAD_CASTED) {
TradeTaskRunner taskRunner = new TradeTaskRunner(trade,
() -> {
@ -65,7 +65,7 @@ public class BuyerAsOffererProtocol extends TradeProtocol implements BuyerProtoc
},
this::handleTaskRunnerFault);
taskRunner.addTasks(SetupPayoutTxLockTimeReachedListener.class);
taskRunner.addTasks(BroadcastAfterLockTime.class);
taskRunner.run();
}
}
@ -185,7 +185,7 @@ public class BuyerAsOffererProtocol extends TradeProtocol implements BuyerProtoc
SignAndFinalizePayoutTx.class,
CommitPayoutTx.class,
SendPayoutTxFinalizedMessage.class,
SetupPayoutTxLockTimeReachedListener.class
BroadcastAfterLockTime.class
);
taskRunner.run();
}

View File

@ -29,8 +29,8 @@ import io.bitsquare.trade.protocol.trade.messages.FinalizePayoutTxRequest;
import io.bitsquare.trade.protocol.trade.messages.PublishDepositTxRequest;
import io.bitsquare.trade.protocol.trade.messages.TradeMessage;
import io.bitsquare.trade.protocol.trade.tasks.buyer.*;
import io.bitsquare.trade.protocol.trade.tasks.shared.BroadcastAfterLockTime;
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.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -54,7 +54,7 @@ public class BuyerAsTakerProtocol extends TradeProtocol implements BuyerProtocol
// If we are after the timeLock state we need to setup the listener again
Trade.State tradeState = trade.getState();
if (tradeState.getPhase() == Trade.Phase.PAYOUT_PAID) {
if (tradeState.getPhase() == Trade.Phase.PAYOUT_PAID && tradeState != Trade.State.PAYOUT_BROAD_CASTED) {
TradeTaskRunner taskRunner = new TradeTaskRunner(trade,
() -> {
handleTaskRunnerSuccess("SetupPayoutTxLockTimeReachedListener");
@ -62,7 +62,7 @@ public class BuyerAsTakerProtocol extends TradeProtocol implements BuyerProtocol
},
this::handleTaskRunnerFault);
taskRunner.addTasks(SetupPayoutTxLockTimeReachedListener.class);
taskRunner.addTasks(BroadcastAfterLockTime.class);
taskRunner.run();
}
}
@ -173,7 +173,7 @@ public class BuyerAsTakerProtocol extends TradeProtocol implements BuyerProtocol
SignAndFinalizePayoutTx.class,
CommitPayoutTx.class,
SendPayoutTxFinalizedMessage.class,
SetupPayoutTxLockTimeReachedListener.class
BroadcastAfterLockTime.class
);
taskRunner.run();
}

View File

@ -26,9 +26,9 @@ import io.bitsquare.trade.Trade;
import io.bitsquare.trade.protocol.trade.messages.*;
import io.bitsquare.trade.protocol.trade.tasks.offerer.*;
import io.bitsquare.trade.protocol.trade.tasks.seller.*;
import io.bitsquare.trade.protocol.trade.tasks.shared.BroadcastAfterLockTime;
import io.bitsquare.trade.protocol.trade.tasks.shared.CommitPayoutTx;
import io.bitsquare.trade.protocol.trade.tasks.shared.InitWaitPeriodForOpenDispute;
import io.bitsquare.trade.protocol.trade.tasks.shared.SetupPayoutTxLockTimeReachedListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -53,7 +53,7 @@ public class SellerAsOffererProtocol extends TradeProtocol implements SellerProt
// If we are after the time lock state we need to setup the listener again
//TODO not sure if that is not called already from the checkPayoutTxTimeLock at tradeProtocol
Trade.State tradeState = trade.getState();
if (tradeState.getPhase() == Trade.Phase.PAYOUT_PAID) {
if (tradeState.getPhase() == Trade.Phase.PAYOUT_PAID && tradeState != Trade.State.PAYOUT_BROAD_CASTED) {
TradeTaskRunner taskRunner = new TradeTaskRunner(trade,
() -> {
handleTaskRunnerSuccess("SetupPayoutTxLockTimeReachedListener");
@ -61,7 +61,7 @@ public class SellerAsOffererProtocol extends TradeProtocol implements SellerProt
},
this::handleTaskRunnerFault);
taskRunner.addTasks(SetupPayoutTxLockTimeReachedListener.class);
taskRunner.addTasks(BroadcastAfterLockTime.class);
taskRunner.run();
}
}
@ -189,7 +189,7 @@ public class SellerAsOffererProtocol extends TradeProtocol implements SellerProt
taskRunner.addTasks(
ProcessPayoutTxFinalizedMessage.class,
CommitPayoutTx.class,
SetupPayoutTxLockTimeReachedListener.class
BroadcastAfterLockTime.class
);
taskRunner.run();
}

View File

@ -28,8 +28,8 @@ import io.bitsquare.trade.protocol.trade.messages.PayoutTxFinalizedMessage;
import io.bitsquare.trade.protocol.trade.messages.PublishDepositTxRequest;
import io.bitsquare.trade.protocol.trade.messages.TradeMessage;
import io.bitsquare.trade.protocol.trade.tasks.seller.*;
import io.bitsquare.trade.protocol.trade.tasks.shared.BroadcastAfterLockTime;
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.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -54,7 +54,7 @@ public class SellerAsTakerProtocol extends TradeProtocol implements SellerProtoc
// If we are after the timeLock state we need to setup the listener again
//TODO not sure if that is not called already from the checkPayoutTxTimeLock at tradeProtocol
Trade.State tradeState = trade.getState();
if (tradeState.getPhase() == Trade.Phase.PAYOUT_PAID) {
if (tradeState.getPhase() == Trade.Phase.PAYOUT_PAID && tradeState != Trade.State.PAYOUT_BROAD_CASTED) {
TradeTaskRunner taskRunner = new TradeTaskRunner(trade,
() -> {
handleTaskRunnerSuccess("SetupPayoutTxLockTimeReachedListener");
@ -62,7 +62,7 @@ public class SellerAsTakerProtocol extends TradeProtocol implements SellerProtoc
},
this::handleTaskRunnerFault);
taskRunner.addTasks(SetupPayoutTxLockTimeReachedListener.class);
taskRunner.addTasks(BroadcastAfterLockTime.class);
taskRunner.run();
}
}
@ -188,7 +188,7 @@ public class SellerAsTakerProtocol extends TradeProtocol implements SellerProtoc
taskRunner.addTasks(
ProcessPayoutTxFinalizedMessage.class,
CommitPayoutTx.class,
SetupPayoutTxLockTimeReachedListener.class
BroadcastAfterLockTime.class
);
taskRunner.run();
}

View File

@ -28,7 +28,6 @@ import io.bitsquare.trade.TakerTrade;
import io.bitsquare.trade.Trade;
import io.bitsquare.trade.TradeManager;
import io.bitsquare.trade.protocol.trade.messages.TradeMessage;
import io.bitsquare.trade.protocol.trade.tasks.shared.SetupPayoutTxLockTimeReachedListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -104,22 +103,6 @@ public abstract class TradeProtocol {
protected abstract void doHandleDecryptedMessage(TradeMessage tradeMessage, NodeAddress peerNodeAddress);
public void checkPayoutTxTimeLock(Trade trade) {
this.trade = trade;
if (trade.getState() == Trade.State.PAYOUT_TX_COMMITTED) {
TradeTaskRunner taskRunner = new TradeTaskRunner(trade,
() -> {
log.debug("taskRunner needPayoutTxBroadcast completed");
processModel.onComplete();
},
this::handleTaskRunnerFault);
taskRunner.addTasks(SetupPayoutTxLockTimeReachedListener.class);
taskRunner.run();
}
}
protected void startTimeout() {
stopTimeout();

View File

@ -25,16 +25,17 @@ import io.bitsquare.trade.Trade;
import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
import org.bitcoinj.core.StoredBlock;
import org.bitcoinj.core.Transaction;
import org.bitcoinj.core.TransactionConfidence;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.ExecutionException;
public class SetupPayoutTxLockTimeReachedListener extends TradeTask {
private static final Logger log = LoggerFactory.getLogger(SetupPayoutTxLockTimeReachedListener.class);
public class BroadcastAfterLockTime extends TradeTask {
private static final Logger log = LoggerFactory.getLogger(BroadcastAfterLockTime.class);
public SetupPayoutTxLockTimeReachedListener(TaskRunner taskHandler, Trade trade) {
public BroadcastAfterLockTime(TaskRunner taskHandler, Trade trade) {
super(taskHandler, trade);
}
@ -66,18 +67,31 @@ public class SetupPayoutTxLockTimeReachedListener extends TradeTask {
}
private void broadcastTx() {
processModel.getTradeWalletService().broadcastTx(trade.getPayoutTx(), new FutureCallback<Transaction>() {
@Override
public void onSuccess(Transaction transaction) {
log.debug("BroadcastTx succeeded. Transaction:" + transaction);
boolean needsBroadCast = true;
Transaction walletTx = processModel.getTradeWalletService().getWalletTx(trade.getPayoutTx().getHash());
if (walletTx != null) {
TransactionConfidence.ConfidenceType confidenceType = walletTx.getConfidence().getConfidenceType();
if (confidenceType.equals(TransactionConfidence.ConfidenceType.PENDING) ||
confidenceType.equals(TransactionConfidence.ConfidenceType.BUILDING)) {
needsBroadCast = false;
trade.setState(Trade.State.PAYOUT_BROAD_CASTED);
complete();
}
}
if (needsBroadCast) {
processModel.getTradeWalletService().broadcastTx(trade.getPayoutTx(), new FutureCallback<Transaction>() {
@Override
public void onSuccess(Transaction transaction) {
log.debug("BroadcastTx succeeded. Transaction:" + transaction);
trade.setState(Trade.State.PAYOUT_BROAD_CASTED);
complete();
}
@Override
public void onFailure(@NotNull Throwable t) {
failed(t);
}
});
@Override
public void onFailure(@NotNull Throwable t) {
failed(t);
}
});
}
}
}

View File

@ -110,13 +110,11 @@ public class BuyerSubView extends TradeSubView {
step2.setCompleted();
showItem(step3);
break;
case WAIT_FOR_UNLOCK_PAYOUT:
if (model.getLockTime() > 0) {
step1.setCompleted();
step2.setCompleted();
step3.setCompleted();
showItem(step4);
}
case WAIT_FOR_BROADCAST_AFTER_UNLOCK:
step1.setCompleted();
step2.setCompleted();
step3.setCompleted();
showItem(step4);
break;
case REQUEST_WITHDRAWAL:
step1.setCompleted();

View File

@ -53,7 +53,7 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
WAIT_FOR_BLOCKCHAIN_CONFIRMATION,
REQUEST_START_FIAT_PAYMENT,
WAIT_FOR_FIAT_PAYMENT_RECEIPT,
WAIT_FOR_UNLOCK_PAYOUT,
WAIT_FOR_BROADCAST_AFTER_UNLOCK,
REQUEST_WITHDRAWAL
}
@ -63,7 +63,7 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
WAIT_FOR_FIAT_PAYMENT_STARTED,
REQUEST_CONFIRM_FIAT_PAYMENT_RECEIVED,
WAIT_FOR_PAYOUT_TX,
WAIT_FOR_UNLOCK_PAYOUT,
WAIT_FOR_BROADCAST_AFTER_UNLOCK,
REQUEST_WITHDRAWAL
}
@ -412,12 +412,12 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
case PAYOUT_TX_SENT:
buyerState.set(PendingTradesViewModel.BuyerState.WAIT_FOR_UNLOCK_PAYOUT);
buyerState.set(PendingTradesViewModel.BuyerState.WAIT_FOR_BROADCAST_AFTER_UNLOCK);
break;
case PAYOUT_TX_RECEIVED:
break;
case PAYOUT_TX_COMMITTED:
sellerState.set(WAIT_FOR_UNLOCK_PAYOUT);
sellerState.set(SellerState.WAIT_FOR_BROADCAST_AFTER_UNLOCK);
break;
case PAYOUT_BROAD_CASTED:
sellerState.set(REQUEST_WITHDRAWAL);

View File

@ -20,7 +20,6 @@ package io.bitsquare.gui.main.portfolio.pendingtrades;
import io.bitsquare.gui.main.portfolio.pendingtrades.steps.TradeWizardItem;
import io.bitsquare.gui.main.portfolio.pendingtrades.steps.seller.*;
import javafx.beans.value.ChangeListener;
import javafx.scene.layout.GridPane;
public class SellerSubView extends TradeSubView {
private TradeWizardItem step1;
@ -59,7 +58,7 @@ public class SellerSubView extends TradeSubView {
step1 = new TradeWizardItem(SellerStep1View.class, "Wait for blockchain confirmation");
step2 = new TradeWizardItem(SellerStep2View.class, "Wait until payment has started");
step3 = new TradeWizardItem(SellerStep3View.class, "Confirm payment received");
step4 = new TradeWizardItem(SellerStep4aView.class, "Wait for payout unlock");
step4 = new TradeWizardItem(SellerStep4View.class, "Wait for payout unlock");
step5 = new TradeWizardItem(SellerStep5View.class, "Completed");
if (model.getLockTime() > 0) {
@ -74,7 +73,6 @@ public class SellerSubView extends TradeSubView {
addWizardsToGridPane(step2);
addWizardsToGridPane(step3);
addWizardsToGridPane(step5);
GridPane.setRowSpan(tradeProcessTitledGroupBg, 4);
}
}
@ -115,14 +113,13 @@ public class SellerSubView extends TradeSubView {
case WAIT_FOR_PAYOUT_TX:
step1.setCompleted();
step2.setCompleted();
step3.setCompleted();
showItem(step4);
showItem(step3);
// We don't use a wizard for that step as it only gets displayed in case the other peer is offline
tradeStepView = new SellerStep4bView(model);
tradeStepView = new SellerStep3bView(model);
contentPane.getChildren().setAll(tradeStepView);
break;
case WAIT_FOR_UNLOCK_PAYOUT:
case WAIT_FOR_BROADCAST_AFTER_UNLOCK:
step1.setCompleted();
step2.setCompleted();
step3.setCompleted();

View File

@ -20,13 +20,13 @@ package io.bitsquare.gui.main.portfolio.pendingtrades.steps.seller;
import io.bitsquare.gui.main.portfolio.pendingtrades.PendingTradesViewModel;
import io.bitsquare.gui.main.portfolio.pendingtrades.steps.TradeStepView;
public class SellerStep4bView extends TradeStepView {
public class SellerStep3bView extends TradeStepView {
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor, Initialisation
///////////////////////////////////////////////////////////////////////////////////////////
public SellerStep4bView(PendingTradesViewModel model) {
public SellerStep3bView(PendingTradesViewModel model) {
super(model);
}

View File

@ -20,13 +20,13 @@ package io.bitsquare.gui.main.portfolio.pendingtrades.steps.seller;
import io.bitsquare.gui.main.portfolio.pendingtrades.PendingTradesViewModel;
import io.bitsquare.gui.main.portfolio.pendingtrades.steps.buyer.BuyerStep4View;
public class SellerStep4aView extends BuyerStep4View {
public class SellerStep4View extends BuyerStep4View {
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor, Initialisation
///////////////////////////////////////////////////////////////////////////////////////////
public SellerStep4aView(PendingTradesViewModel model) {
public SellerStep4View(PendingTradesViewModel model) {
super(model);
}
}