Handle listener removal

This commit is contained in:
Manfred Karrer 2015-03-18 13:01:21 +01:00
parent 769037e137
commit cfee2f32ff
49 changed files with 171 additions and 222 deletions

View File

@ -140,7 +140,7 @@ public class TradeWalletService {
// Trade
///////////////////////////////////////////////////////////////////////////////////////////
public TransactionDataResult offererCreatesDepositTxInputs(Coin inputAmount, AddressEntry offererAddressEntry) throws
public TransactionDataResult createOffererDepositTxInputs(Coin inputAmount, AddressEntry offererAddressEntry) throws
TransactionVerificationException, WalletException {
// We pay the tx fee 2 times to the deposit tx:
@ -369,14 +369,14 @@ public class TradeWalletService {
return depositTx;
}
public TransactionDataResult offererCreatesAndSignsPayoutTx(Transaction depositTx,
Coin offererPayoutAmount,
Coin takerPayoutAmount,
String takerAddressString,
AddressEntry addressEntry,
byte[] offererPubKey,
byte[] takerPubKey,
byte[] arbitratorPubKey)
public byte[] offererCreatesAndSignsPayoutTx(Transaction depositTx,
Coin offererPayoutAmount,
Coin takerPayoutAmount,
String takerAddressString,
AddressEntry addressEntry,
byte[] offererPubKey,
byte[] takerPubKey,
byte[] arbitratorPubKey)
throws AddressFormatException, TransactionVerificationException {
Transaction payoutTx = createPayoutTx(depositTx, offererPayoutAmount, takerPayoutAmount, addressEntry.getAddressString(), takerAddressString);
@ -387,7 +387,7 @@ public class TradeWalletService {
verifyTransaction(payoutTx);
return new TransactionDataResult(payoutTx, offererSignature.encodeToDER());
return offererSignature.encodeToDER();
}
public void takerSignsAndPublishPayoutTx(Transaction depositTx,
@ -415,8 +415,8 @@ public class TradeWalletService {
verifyTransaction(payoutTx);
checkWalletConsistency();
checkScriptSig(payoutTx, input, 0);
input.verify(input.getConnectedOutput());
// checkScriptSig(payoutTx, input, 0);
// input.verify(input.getConnectedOutput());
printTxWithInputs("payoutTx", payoutTx);
@ -557,7 +557,6 @@ public class TradeWalletService {
private Transaction depositTx;
private Transaction payoutTx;
private byte[] offererSignature;
public TransactionDataResult(List<TransactionOutput> connectedOutputsForAllInputs, List<TransactionOutput> outputs) {
@ -571,12 +570,6 @@ public class TradeWalletService {
this.outputs = outputs;
}
public TransactionDataResult(Transaction payoutTx, byte[] offererSignature) {
this.payoutTx = payoutTx;
this.offererSignature = offererSignature;
}
public List<TransactionOutput> getOutputs() {
return outputs;
}
@ -589,10 +582,6 @@ public class TradeWalletService {
return depositTx;
}
public Transaction getPayoutTx() {
return payoutTx;
}
public byte[] getOffererSignature() {
return offererSignature;
}

View File

@ -29,7 +29,7 @@ import io.bitsquare.trade.protocol.placeoffer.tasks.BroadcastCreateOfferFeeTx;
import io.bitsquare.trade.protocol.placeoffer.tasks.CreateOfferFeeTx;
import io.bitsquare.trade.protocol.placeoffer.tasks.ValidateOffer;
import io.bitsquare.trade.protocol.trade.offerer.BuyerAsOffererProtocol;
import io.bitsquare.trade.protocol.trade.offerer.tasks.GetOffererDepositTxInputs;
import io.bitsquare.trade.protocol.trade.offerer.tasks.CreateOffererDepositTxInputs;
import io.bitsquare.trade.protocol.trade.offerer.tasks.ProcessPayoutTxPublishedMessage;
import io.bitsquare.trade.protocol.trade.offerer.tasks.ProcessRequestDepositTxInputsMessage;
import io.bitsquare.trade.protocol.trade.offerer.tasks.ProcessRequestOffererPublishDepositTxMessage;
@ -103,7 +103,7 @@ public class DebugView extends InitializableView {
/*---- Protocol ----*/
BuyerAsOffererProtocol.class,
ProcessRequestDepositTxInputsMessage.class,
GetOffererDepositTxInputs.class,
CreateOffererDepositTxInputs.class,
RequestDepositPayment.class,
ProcessRequestOffererPublishDepositTxMessage.class,

View File

@ -314,10 +314,10 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
Dialog.Actions.CLOSE.handle(actionEvent);
}
});
Popups.openInfoPopup(BSResources.get("createOffer.success.headline"),
// TODO temp just for testing
/* Popups.openInfoPopup(BSResources.get("createOffer.success.headline"),
BSResources.get("createOffer.success.info"),
actions);
actions);*/
}
});
}

View File

@ -269,10 +269,10 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
Dialog.Actions.CLOSE.handle(actionEvent);
}
});
Popups.openInfoPopup(BSResources.get("takeOffer.success.headline"),
// TODO temp just for testing
/* Popups.openInfoPopup(BSResources.get("takeOffer.success.headline"),
BSResources.get("takeOffer.success.info"),
actions);
actions);*/
}
});
}

View File

@ -67,6 +67,7 @@ public class Trade implements Serializable {
private Contract contract;
private String contractAsJson;
private String takerContractSignature;
private String offererContractSignature;
private Transaction depositTx;
private Transaction payoutTx;
@ -101,6 +102,10 @@ public class Trade implements Serializable {
this.takerContractSignature = takerSignature;
}
public void setOffererContractSignature(String offererContractSignature) {
this.offererContractSignature = offererContractSignature;
}
public Coin getTradeAmount() {
return tradeAmount;
}
@ -149,6 +154,10 @@ public class Trade implements Serializable {
return takerContractSignature;
}
public String getOffererContractSignature() {
return offererContractSignature;
}
public Transaction getDepositTx() {
return depositTx;
}

View File

@ -38,10 +38,10 @@ import io.bitsquare.trade.protocol.availability.messages.ReportOfferAvailability
import io.bitsquare.trade.protocol.availability.messages.RequestIsOfferAvailableMessage;
import io.bitsquare.trade.protocol.placeoffer.PlaceOfferModel;
import io.bitsquare.trade.protocol.placeoffer.PlaceOfferProtocol;
import io.bitsquare.trade.protocol.trade.offerer.models.BuyerAsOffererModel;
import io.bitsquare.trade.protocol.trade.offerer.BuyerAsOffererProtocol;
import io.bitsquare.trade.protocol.trade.taker.models.SellerAsTakerModel;
import io.bitsquare.trade.protocol.trade.offerer.models.BuyerAsOffererModel;
import io.bitsquare.trade.protocol.trade.taker.SellerAsTakerProtocol;
import io.bitsquare.trade.protocol.trade.taker.models.SellerAsTakerModel;
import io.bitsquare.user.AccountSettings;
import io.bitsquare.user.User;
@ -360,7 +360,7 @@ public class TradeManager {
}
private void createBuyerAcceptsOfferProtocol(Offer offer) {
Trade trade;
if (pendingTrades.containsKey(offer.getId())) {
@ -372,7 +372,7 @@ public class TradeManager {
pendingTrades.put(trade.getId(), trade);
persistPendingTrades();
}
BuyerAsOffererModel model = new BuyerAsOffererModel(
trade,
tradeMessageService,

View File

@ -22,7 +22,7 @@ import io.bitsquare.trade.protocol.trade.messages.OfferMessage;
import java.io.Serializable;
// That msg is used to ping the offerer if he is online and if the offer is still available
public class RequestIsOfferAvailableMessage extends OfferMessage implements Serializable {
public class RequestIsOfferAvailableMessage extends OfferMessage implements Serializable {
private static final long serialVersionUID = 4630151440192191798L;
public RequestIsOfferAvailableMessage(String offerId) {

View File

@ -50,7 +50,7 @@ public class GetPeerAddress extends Task<CheckOfferAvailabilityModel> {
@Override
public void onFailed() {
model.offer.setState(Offer.State.OFFERER_OFFLINE);
failed();
}
});

View File

@ -18,9 +18,9 @@
package io.bitsquare.trade.protocol.placeoffer;
import io.bitsquare.btc.WalletService;
import io.bitsquare.common.taskrunner.SharedTaskModel;
import io.bitsquare.offer.Offer;
import io.bitsquare.offer.OfferBookService;
import io.bitsquare.common.taskrunner.SharedTaskModel;
import org.bitcoinj.core.Transaction;
@ -33,7 +33,7 @@ public class PlaceOfferModel extends SharedTaskModel {
public final Offer offer;
public final WalletService walletService;
public final OfferBookService offerBookService;
private Transaction transaction;
public PlaceOfferModel(Offer offer,

View File

@ -17,13 +17,13 @@
package io.bitsquare.trade.protocol.placeoffer;
import io.bitsquare.common.handlers.ErrorMessageHandler;
import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.handlers.TransactionResultHandler;
import io.bitsquare.trade.protocol.placeoffer.tasks.AddOfferToRemoteOfferBook;
import io.bitsquare.trade.protocol.placeoffer.tasks.BroadcastCreateOfferFeeTx;
import io.bitsquare.trade.protocol.placeoffer.tasks.CreateOfferFeeTx;
import io.bitsquare.trade.protocol.placeoffer.tasks.ValidateOffer;
import io.bitsquare.common.handlers.ErrorMessageHandler;
import io.bitsquare.common.taskrunner.TaskRunner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@ -17,9 +17,9 @@
package io.bitsquare.trade.protocol.placeoffer.tasks;
import io.bitsquare.trade.protocol.placeoffer.PlaceOfferModel;
import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.protocol.placeoffer.PlaceOfferModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@ -38,31 +38,20 @@ public class SharedTradeModel extends SharedTaskModel implements Serializable {
// provided
transient public final Offer offer;
transient public final TradeMessageService tradeMessageService;
transient public final WalletService walletService;
transient public final BlockChainService blockChainService;
transient public final SignatureService signatureService;
transient protected final Persistence persistence;
// derived
transient public final String id;
transient public final TradeWalletService tradeWalletService;
transient public final byte[] arbitratorPubKey;
/* transient public final FiatAccount fiatAccount;
transient public final String accountId;
transient public final PublicKey messagePubKey;
transient public final byte[] registrationPubKey;
transient public final DeterministicKey registrationKeyPair;
transient public final AddressEntry addressEntry;*/
// data written/read by tasks
transient private TradeMessage tradeMessage;
protected SharedTradeModel(Offer offer,
TradeMessageService tradeMessageService,
WalletService walletService,
@ -80,13 +69,6 @@ public class SharedTradeModel extends SharedTaskModel implements Serializable {
tradeWalletService = walletService.getTradeWalletService();
//TODO use default arbitrator for now
arbitratorPubKey = offer.getArbitrators().get(0).getPubKey();
/* registrationPubKey = walletService.getRegistrationAddressEntry().getPubKey();
registrationKeyPair = walletService.getRegistrationAddressEntry().getKeyPair();
addressEntry = walletService.getAddressEntry(id);
fiatAccount = user.getBankAccount(offer.getBankAccountId());
accountId = user.getAccountId();
messagePubKey = user.getNetworkPubKey();*/
}
public void setTradeMessage(TradeMessage tradeMessage) {
@ -97,5 +79,4 @@ public class SharedTradeModel extends SharedTaskModel implements Serializable {
return tradeMessage;
}
}

View File

@ -23,6 +23,6 @@ import java.io.Serializable;
public class OfferMessage implements Message, Serializable {
private static final long serialVersionUID = -89035992124170905L;
public String offerId;
}

View File

@ -23,6 +23,6 @@ import java.io.Serializable;
public class TradeMessage implements Message, Serializable {
private static final long serialVersionUID = 7572470983485004081L;
public String tradeId;
}

View File

@ -21,9 +21,12 @@ import io.bitsquare.network.Message;
import io.bitsquare.network.Peer;
import io.bitsquare.trade.Trade;
import io.bitsquare.trade.handlers.MessageHandler;
import io.bitsquare.trade.protocol.trade.messages.PayoutTxPublishedMessage;
import io.bitsquare.trade.protocol.trade.messages.RequestDepositTxInputsMessage;
import io.bitsquare.trade.protocol.trade.messages.RequestOffererPublishDepositTxMessage;
import io.bitsquare.trade.protocol.trade.messages.TradeMessage;
import io.bitsquare.trade.protocol.trade.offerer.models.BuyerAsOffererModel;
import io.bitsquare.trade.protocol.trade.offerer.tasks.GetOffererDepositTxInputs;
import io.bitsquare.trade.protocol.trade.offerer.tasks.CreateOffererDepositTxInputs;
import io.bitsquare.trade.protocol.trade.offerer.tasks.ProcessPayoutTxPublishedMessage;
import io.bitsquare.trade.protocol.trade.offerer.tasks.ProcessRequestDepositTxInputsMessage;
import io.bitsquare.trade.protocol.trade.offerer.tasks.ProcessRequestOffererPublishDepositTxMessage;
@ -36,13 +39,11 @@ import io.bitsquare.trade.protocol.trade.offerer.tasks.SignPayoutTx;
import io.bitsquare.trade.protocol.trade.offerer.tasks.VerifyAndSignContract;
import io.bitsquare.trade.protocol.trade.offerer.tasks.VerifyTakeOfferFeePayment;
import io.bitsquare.trade.protocol.trade.offerer.tasks.VerifyTakerAccount;
import io.bitsquare.trade.protocol.trade.messages.PayoutTxPublishedMessage;
import io.bitsquare.trade.protocol.trade.messages.RequestDepositTxInputsMessage;
import io.bitsquare.trade.protocol.trade.messages.RequestOffererPublishDepositTxMessage;
import org.bitcoinj.core.Transaction;
import org.bitcoinj.core.TransactionConfidence;
import javafx.application.Platform;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -76,11 +77,16 @@ public class BuyerAsOffererProtocol {
public void cleanup() {
log.debug("cleanup " + this);
model.tradeMessageService.removeMessageHandler(messageHandler);
if (transactionConfidence != null) {
if (!transactionConfidence.removeEventListener(transactionConfidenceListener))
throw new RuntimeException("Remove transactionConfidenceListener failed.");
}
// tradeMessageService and transactionConfidence use CopyOnWriteArrayList as listeners, but be safe and delay remove a bit.
Platform.runLater(() -> {
model.tradeMessageService.removeMessageHandler(messageHandler);
if (transactionConfidence != null) {
if (!transactionConfidence.removeEventListener(transactionConfidenceListener))
throw new RuntimeException("Remove transactionConfidenceListener failed at BuyerAsOffererProtocol.");
}
});
}
///////////////////////////////////////////////////////////////////////////////////////////
@ -102,7 +108,7 @@ public class BuyerAsOffererProtocol {
);
taskRunner.addTasks(
ProcessRequestDepositTxInputsMessage.class,
GetOffererDepositTxInputs.class,
CreateOffererDepositTxInputs.class,
RequestDepositPayment.class
);
taskRunner.run();
@ -114,14 +120,12 @@ public class BuyerAsOffererProtocol {
BuyerAsOffererTaskRunner<BuyerAsOffererModel> taskRunner = new BuyerAsOffererTaskRunner<>(model,
() -> {
log.debug("taskRunner at handleRequestOffererPublishDepositTxMessage completed");
transactionConfidenceListener = new TransactionConfidence.Listener() {
@Override
public void onConfidenceChanged(Transaction tx, ChangeReason reason) {
log.trace("onConfidenceChanged " + tx.getConfidence());
if (reason == ChangeReason.TYPE && tx.getConfidence().getConfidenceType() == TransactionConfidence.ConfidenceType.BUILDING) {
transactionConfidenceListener = (tx, reason) -> {
log.trace("onConfidenceChanged " + tx.getConfidence());
if (reason == TransactionConfidence.Listener.ChangeReason.TYPE && tx.getConfidence().getConfidenceType() == TransactionConfidence
.ConfidenceType.BUILDING) {
model.trade.setState(Trade.State.DEPOSIT_CONFIRMED);
}
model.trade.setState(Trade.State.DEPOSIT_CONFIRMED);
}
};
transactionConfidence = model.trade.getDepositTx().getConfidence();
@ -190,15 +194,15 @@ public class BuyerAsOffererProtocol {
// Massage dispatcher
///////////////////////////////////////////////////////////////////////////////////////////
private void handleMessage(Message message, Peer peer) {
log.trace("handleNewMessage: message = " + message.getClass().getSimpleName());
private void handleMessage(Message message, Peer sender) {
log.trace("handleNewMessage: message = " + message.getClass().getSimpleName() + " from " + sender);
if (message instanceof TradeMessage) {
TradeMessage tradeMessage = (TradeMessage) message;
nonEmptyStringOf(tradeMessage.tradeId);
if (tradeMessage.tradeId.equals(model.id)) {
if (tradeMessage instanceof RequestDepositTxInputsMessage) {
handleRequestDepositTxInputsMessage((RequestDepositTxInputsMessage) tradeMessage, peer);
handleRequestDepositTxInputsMessage((RequestDepositTxInputsMessage) tradeMessage, sender);
}
else if (tradeMessage instanceof RequestOffererPublishDepositTxMessage) {

View File

@ -41,9 +41,10 @@ public class BuyerAsOffererModel extends SharedTradeModel implements Serializabl
public final TakerModel taker;
public final OffererModel offerer;
// written by tasks
private Transaction publishedDepositTx;
private String takeOfferFeeTxId;
public BuyerAsOffererModel(Trade trade,
TradeMessageService tradeMessageService,
WalletService walletService,
@ -60,9 +61,9 @@ public class BuyerAsOffererModel extends SharedTradeModel implements Serializabl
this.trade = trade;
Object modelObject = persistence.read(this, "BuyerAsOffererModel_" + id);
if (modelObject instanceof BuyerAsOffererModel) {
BuyerAsOffererModel persistedModel = (BuyerAsOffererModel) modelObject;
Serializable serializable = persistence.read(this, "BuyerAsOffererModel_" + id);
if (serializable instanceof BuyerAsOffererModel) {
BuyerAsOffererModel persistedModel = (BuyerAsOffererModel) serializable;
log.debug("Model reconstructed form persisted model.");
setPublishedDepositTx(persistedModel.getPublishedDepositTx());

View File

@ -19,10 +19,8 @@ package io.bitsquare.trade.protocol.trade.offerer.models;
import io.bitsquare.btc.AddressEntry;
import io.bitsquare.fiat.FiatAccount;
import io.bitsquare.network.Peer;
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.Transaction;
import org.bitcoinj.core.TransactionOutput;
import org.bitcoinj.crypto.DeterministicKey;
@ -46,10 +44,8 @@ public class OffererModel implements Serializable {
transient public byte[] pubKey;
// written by tasks
public byte[] payoutSignature;
public byte[] payoutTxSignature;
public Coin payoutAmount;
public List<TransactionOutput> connectedOutputsForAllInputs;
public List<TransactionOutput> outputs;
public Peer peer;
public Transaction preparedPayoutTx;
public List<TransactionOutput> outputs; // used to verify amounts with change outputs
}

View File

@ -30,18 +30,19 @@ import java.security.PublicKey;
import java.util.List;
public class TakerModel implements Serializable{
public class TakerModel implements Serializable {
private static final long serialVersionUID = 2660909397210346486L;
// written by tasks
public Peer peer;
public String accountId;
public FiatAccount fiatAccount;
public PublicKey messagePublicKey;
public String contractAsJson;
public String contractAsJson;//TODO only write access now, missing impl.
public String contractSignature;
public Coin payoutAmount;
public Transaction depositTx;
public List<TransactionOutput> connectedOutputsForAllInputs;
public List<TransactionOutput> outputs;
public String payoutAddress;
public byte[] pubKey;
}

View File

@ -28,10 +28,10 @@ import org.bitcoinj.core.Coin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class GetOffererDepositTxInputs extends Task<BuyerAsOffererModel> {
private static final Logger log = LoggerFactory.getLogger(GetOffererDepositTxInputs.class);
public class CreateOffererDepositTxInputs extends Task<BuyerAsOffererModel> {
private static final Logger log = LoggerFactory.getLogger(CreateOffererDepositTxInputs.class);
public GetOffererDepositTxInputs(TaskRunner taskHandler, BuyerAsOffererModel model) {
public CreateOffererDepositTxInputs(TaskRunner taskHandler, BuyerAsOffererModel model) {
super(taskHandler, model);
}
@ -39,7 +39,7 @@ public class GetOffererDepositTxInputs extends Task<BuyerAsOffererModel> {
protected void doRun() {
try {
Coin offererInputAmount = model.trade.getSecurityDeposit().add(FeePolicy.TX_FEE);
TradeWalletService.TransactionDataResult result = model.tradeWalletService.offererCreatesDepositTxInputs(offererInputAmount,
TradeWalletService.TransactionDataResult result = model.tradeWalletService.createOffererDepositTxInputs(offererInputAmount,
model.offerer.addressEntry);
model.offerer.connectedOutputsForAllInputs = result.getConnectedOutputsForAllInputs();

View File

@ -17,11 +17,11 @@
package io.bitsquare.trade.protocol.trade.offerer.tasks;
import io.bitsquare.trade.Trade;
import io.bitsquare.trade.protocol.trade.offerer.models.BuyerAsOffererModel;
import io.bitsquare.trade.protocol.trade.messages.PayoutTxPublishedMessage;
import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.Trade;
import io.bitsquare.trade.protocol.trade.messages.PayoutTxPublishedMessage;
import io.bitsquare.trade.protocol.trade.offerer.models.BuyerAsOffererModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@ -20,8 +20,8 @@ package io.bitsquare.trade.protocol.trade.offerer.tasks;
import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.Trade;
import io.bitsquare.trade.protocol.trade.offerer.models.BuyerAsOffererModel;
import io.bitsquare.trade.protocol.trade.messages.RequestDepositTxInputsMessage;
import io.bitsquare.trade.protocol.trade.offerer.models.BuyerAsOffererModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -42,7 +42,7 @@ public class ProcessRequestDepositTxInputsMessage extends Task<BuyerAsOffererMod
checkTradeId(model.id, model.getTradeMessage());
Trade trade = model.trade;
RequestDepositTxInputsMessage requestDepositTxInputsMessage = (RequestDepositTxInputsMessage) model.getTradeMessage();
trade.setTradeAmount(positiveCoinOf(nonZeroCoinOf(requestDepositTxInputsMessage.tradeAmount)));
model.setTakeOfferFeeTxId(nonEmptyStringOf(requestDepositTxInputsMessage.takeOfferFeeTxId));
model.taker.pubKey = checkNotNull(requestDepositTxInputsMessage.takerPubKey);

View File

@ -19,8 +19,8 @@ package io.bitsquare.trade.protocol.trade.offerer.tasks;
import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.protocol.trade.offerer.models.BuyerAsOffererModel;
import io.bitsquare.trade.protocol.trade.messages.RequestOffererPublishDepositTxMessage;
import io.bitsquare.trade.protocol.trade.offerer.models.BuyerAsOffererModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -45,11 +45,11 @@ public class ProcessRequestOffererPublishDepositTxMessage extends Task<BuyerAsOf
model.taker.accountId = nonEmptyStringOf(message.takerAccountId);
model.taker.messagePublicKey = checkNotNull(message.takerMessagePublicKey);
model.taker.contractAsJson = nonEmptyStringOf(message.takerContractAsJson);
model.taker.contractSignature = nonEmptyStringOf(message.takerContractSignature);
model.taker.payoutAddress = nonEmptyStringOf(message.takerPayoutAddress);
model.taker.depositTx = checkNotNull(message.takersDepositTx);
model.taker.connectedOutputsForAllInputs = checkNotNull(message.takerConnectedOutputsForAllInputs);
checkArgument(message.takerConnectedOutputsForAllInputs.size() > 0);
model.taker.outputs = checkNotNull(message.takerOutputs);
complete();
} catch (Throwable t) {

View File

@ -17,11 +17,11 @@
package io.bitsquare.trade.protocol.trade.offerer.tasks;
import io.bitsquare.trade.listeners.SendMessageListener;
import io.bitsquare.trade.protocol.trade.offerer.models.BuyerAsOffererModel;
import io.bitsquare.trade.protocol.trade.messages.RequestDepositPaymentMessage;
import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.listeners.SendMessageListener;
import io.bitsquare.trade.protocol.trade.messages.RequestDepositPaymentMessage;
import io.bitsquare.trade.protocol.trade.offerer.models.BuyerAsOffererModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@ -17,11 +17,11 @@
package io.bitsquare.trade.protocol.trade.offerer.tasks;
import io.bitsquare.trade.listeners.SendMessageListener;
import io.bitsquare.trade.protocol.trade.offerer.models.BuyerAsOffererModel;
import io.bitsquare.trade.protocol.trade.messages.BankTransferStartedMessage;
import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.listeners.SendMessageListener;
import io.bitsquare.trade.protocol.trade.messages.BankTransferStartedMessage;
import io.bitsquare.trade.protocol.trade.offerer.models.BuyerAsOffererModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -38,7 +38,7 @@ public class SendBankTransferStartedMessage extends Task<BuyerAsOffererModel> {
BankTransferStartedMessage tradeMessage = new BankTransferStartedMessage(
model.id,
model.getPublishedDepositTx(),
model.offerer.payoutSignature,
model.offerer.payoutTxSignature,
model.offerer.payoutAmount,
model.taker.payoutAmount,
model.offerer.addressEntry.getAddressString());

View File

@ -17,11 +17,11 @@
package io.bitsquare.trade.protocol.trade.offerer.tasks;
import io.bitsquare.trade.listeners.SendMessageListener;
import io.bitsquare.trade.protocol.trade.offerer.models.BuyerAsOffererModel;
import io.bitsquare.trade.protocol.trade.messages.DepositTxPublishedMessage;
import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.listeners.SendMessageListener;
import io.bitsquare.trade.protocol.trade.messages.DepositTxPublishedMessage;
import io.bitsquare.trade.protocol.trade.offerer.models.BuyerAsOffererModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@ -17,44 +17,54 @@
package io.bitsquare.trade.protocol.trade.offerer.tasks;
import io.bitsquare.trade.Trade;
import io.bitsquare.trade.protocol.trade.offerer.models.BuyerAsOffererModel;
import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.Trade;
import io.bitsquare.trade.protocol.trade.offerer.models.BuyerAsOffererModel;
import org.bitcoinj.core.Transaction;
import org.bitcoinj.core.TransactionConfidence;
import javafx.application.Platform;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SetupListenerForBlockChainConfirmation extends Task<BuyerAsOffererModel> {
private static final Logger log = LoggerFactory.getLogger(SetupListenerForBlockChainConfirmation.class);
private TransactionConfidence.Listener transactionConfidenceListener;
private TransactionConfidence transactionConfidence;
public SetupListenerForBlockChainConfirmation(TaskRunner taskHandler, BuyerAsOffererModel model) {
super(taskHandler, model);
}
@Override
protected void doRun() {
TransactionConfidence confidence = model.trade.getDepositTx().getConfidence();
confidence.addEventListener(new TransactionConfidence.Listener() {
transactionConfidence = model.trade.getDepositTx().getConfidence();
transactionConfidenceListener = new TransactionConfidence.Listener() {
@Override
public void onConfidenceChanged(Transaction tx, ChangeReason reason) {
log.trace("onConfidenceChanged " + tx.getConfidence());
if (reason == ChangeReason.TYPE && tx.getConfidence().getConfidenceType() == TransactionConfidence.ConfidenceType.BUILDING) {
model.trade.setState(Trade.State.DEPOSIT_CONFIRMED);
boolean removed = confidence.removeEventListener(this);
log.debug("listener removed? " + removed);
// transactionConfidence use CopyOnWriteArrayList as listeners, but be safe and delay remove a bit.
Platform.runLater(() -> removeEventListener());
}
}
});
};
transactionConfidence.addEventListener(transactionConfidenceListener);
complete();
}
private void removeEventListener() {
if (!transactionConfidence.removeEventListener(transactionConfidenceListener))
throw new RuntimeException("Remove transactionConfidenceListener failed at SetupListenerForBlockChainConfirmation.");
}
@Override
protected void updateStateOnFault() {
}

View File

@ -18,10 +18,10 @@
package io.bitsquare.trade.protocol.trade.offerer.tasks;
import io.bitsquare.btc.FeePolicy;
import io.bitsquare.trade.Trade;
import io.bitsquare.trade.protocol.trade.offerer.models.BuyerAsOffererModel;
import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.Trade;
import io.bitsquare.trade.protocol.trade.offerer.models.BuyerAsOffererModel;
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.Transaction;

View File

@ -17,7 +17,6 @@
package io.bitsquare.trade.protocol.trade.offerer.tasks;
import io.bitsquare.btc.TradeWalletService;
import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.Trade;
@ -43,7 +42,7 @@ public class SignPayoutTx extends Task<BuyerAsOffererModel> {
Coin offererPayoutAmount = trade.getTradeAmount().add(securityDeposit);
@SuppressWarnings("UnnecessaryLocalVariable") Coin takerPayoutAmount = securityDeposit;
TradeWalletService.TransactionDataResult result = model.tradeWalletService.offererCreatesAndSignsPayoutTx(
byte[] offererPayoutTxSignature = model.tradeWalletService.offererCreatesAndSignsPayoutTx(
trade.getDepositTx(),
offererPayoutAmount,
takerPayoutAmount,
@ -53,8 +52,7 @@ public class SignPayoutTx extends Task<BuyerAsOffererModel> {
model.taker.pubKey,
model.arbitratorPubKey);
model.offerer.preparedPayoutTx = result.getPayoutTx();
model.offerer.payoutSignature = result.getOffererSignature();
model.offerer.payoutTxSignature = offererPayoutTxSignature;
model.offerer.payoutAmount = offererPayoutAmount;
model.taker.payoutAmount = takerPayoutAmount;

View File

@ -17,12 +17,12 @@
package io.bitsquare.trade.protocol.trade.offerer.tasks;
import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.Contract;
import io.bitsquare.trade.Trade;
import io.bitsquare.trade.protocol.trade.offerer.models.BuyerAsOffererModel;
import io.bitsquare.util.Utilities;
import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -53,7 +53,8 @@ public class VerifyAndSignContract extends Task<BuyerAsOffererModel> {
trade.setContract(contract);
trade.setContractAsJson(contractAsJson);
trade.setTakerContractSignature(signature);
trade.setOffererContractSignature(signature);
trade.setTakerContractSignature(model.taker.contractSignature);
complete();
}

View File

@ -17,9 +17,9 @@
package io.bitsquare.trade.protocol.trade.offerer.tasks;
import io.bitsquare.trade.protocol.trade.offerer.models.BuyerAsOffererModel;
import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.protocol.trade.offerer.models.BuyerAsOffererModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@ -21,10 +21,10 @@ import io.bitsquare.network.Message;
import io.bitsquare.network.Peer;
import io.bitsquare.trade.Trade;
import io.bitsquare.trade.handlers.MessageHandler;
import io.bitsquare.trade.protocol.trade.messages.TradeMessage;
import io.bitsquare.trade.protocol.trade.messages.BankTransferStartedMessage;
import io.bitsquare.trade.protocol.trade.messages.DepositTxPublishedMessage;
import io.bitsquare.trade.protocol.trade.messages.RequestDepositPaymentMessage;
import io.bitsquare.trade.protocol.trade.messages.TradeMessage;
import io.bitsquare.trade.protocol.trade.taker.models.SellerAsTakerModel;
import io.bitsquare.trade.protocol.trade.taker.tasks.BroadcastTakeOfferFeeTx;
import io.bitsquare.trade.protocol.trade.taker.tasks.CreateAndSignContract;
@ -185,7 +185,7 @@ public class SellerAsTakerProtocol {
///////////////////////////////////////////////////////////////////////////////////////////
private void handleMessage(Message message, Peer sender) {
log.trace("handleNewMessage: message = " + message.getClass().getSimpleName());
log.trace("handleNewMessage: message = " + message.getClass().getSimpleName() + " from " + sender);
if (message instanceof TradeMessage) {
TradeMessage tradeMessage = (TradeMessage) message;
nonEmptyStringOf(tradeMessage.tradeId);

View File

@ -30,7 +30,11 @@ import java.util.List;
public class OffererModel implements Serializable {
private static final long serialVersionUID = 1582902150121576205L;
// Those fields are set at constructor but not declared as final because constructor is not called in case model gets created from a persisted model
// Declared transient as they will be provided in any case at construction time
public Peer peer;
// written by tasks
public byte[] pubKey;
public Coin payoutAmount;
public String payoutAddress;

View File

@ -42,10 +42,11 @@ public class SellerAsTakerModel extends SharedTradeModel implements Serializable
public final TakerModel taker;
public final OffererModel offerer;
// written by tasks
private Transaction publishedDepositTx;
private Transaction takeOfferFeeTx;
private Transaction payoutTx;
public SellerAsTakerModel(Trade trade,
Peer offererPeer,
TradeMessageService tradeMessageService,
@ -63,9 +64,9 @@ public class SellerAsTakerModel extends SharedTradeModel implements Serializable
this.trade = trade;
Object modelObject = persistence.read(this, "SellerAsTakerModel_" + id);
if (modelObject instanceof SellerAsTakerModel) {
SellerAsTakerModel persistedModel = (SellerAsTakerModel) modelObject;
Serializable serializable = persistence.read(this, "SellerAsTakerModel_" + id);
if (serializable instanceof SellerAsTakerModel) {
SellerAsTakerModel persistedModel = (SellerAsTakerModel) serializable;
log.debug("Model reconstructed form persisted model.");
setPublishedDepositTx(persistedModel.getPublishedDepositTx());
@ -79,7 +80,7 @@ public class SellerAsTakerModel extends SharedTradeModel implements Serializable
taker = new TakerModel();
offerer = new OffererModel();
}
offerer.peer = offererPeer;
taker.registrationPubKey = walletService.getRegistrationAddressEntry().getPubKey();

View File

@ -39,15 +39,15 @@ public class TakerModel implements Serializable {
transient public FiatAccount fiatAccount;
transient public String accountId;
transient public PublicKey messagePubKey;
transient public byte[] registrationPubKey;
transient public byte[] registrationPubKey; // TODO not read yet, missing impl.
transient public DeterministicKey registrationKeyPair;
transient public AddressEntry addressEntry;
transient public byte[] pubKey;
// written by tasks
public List<TransactionOutput> connectedOutputsForAllInputs;
public List<TransactionOutput> outputs;
public Coin payoutAmount;
public Transaction preparedDepositTx;
}

View File

@ -46,7 +46,7 @@ public class BroadcastTakeOfferFeeTx extends Task<SellerAsTakerModel> {
@Override
public void onSuccess(Transaction transaction) {
log.debug("Take offer fee published successfully. Transaction ID = " + transaction.getHashAsString());
model.trade.setState(Trade.State.TAKE_OFFER_FEE_PUBLISHED);
complete();
@ -55,6 +55,7 @@ public class BroadcastTakeOfferFeeTx extends Task<SellerAsTakerModel> {
@Override
public void onFailure(@NotNull Throwable t) {
model.trade.setState(Trade.State.TAKE_OFFER_FEE_PUBLISH_FAILED);
failed(t);
}
});
@ -67,8 +68,4 @@ public class BroadcastTakeOfferFeeTx extends Task<SellerAsTakerModel> {
failed(e);
}
}
@Override
protected void updateStateOnFault() {
}
}

View File

@ -56,8 +56,4 @@ public class CreateAndSignContract extends Task<SellerAsTakerModel> {
complete();
}
@Override
protected void updateStateOnFault() {
}
}

View File

@ -51,8 +51,4 @@ public class CreateTakeOfferFeeTx extends Task<SellerAsTakerModel> {
failed(e);
}
}
@Override
protected void updateStateOnFault() {
}
}

View File

@ -52,8 +52,4 @@ public class ProcessBankTransferStartedMessage extends Task<SellerAsTakerModel>
failed(t);
}
}
@Override
protected void updateStateOnFault() {
}
}

View File

@ -17,10 +17,10 @@
package io.bitsquare.trade.protocol.trade.taker.tasks;
import io.bitsquare.trade.protocol.trade.messages.DepositTxPublishedMessage;
import io.bitsquare.trade.protocol.trade.taker.models.SellerAsTakerModel;
import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.protocol.trade.messages.DepositTxPublishedMessage;
import io.bitsquare.trade.protocol.trade.taker.models.SellerAsTakerModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -48,8 +48,4 @@ public class ProcessDepositTxPublishedMessage extends Task<SellerAsTakerModel> {
failed(t);
}
}
@Override
protected void updateStateOnFault() {
}
}

View File

@ -53,8 +53,4 @@ public class ProcessRequestDepositPaymentMessage extends Task<SellerAsTakerModel
failed(t);
}
}
@Override
protected void updateStateOnFault() {
}
}

View File

@ -17,11 +17,11 @@
package io.bitsquare.trade.protocol.trade.taker.tasks;
import io.bitsquare.trade.listeners.SendMessageListener;
import io.bitsquare.trade.protocol.trade.taker.models.SellerAsTakerModel;
import io.bitsquare.trade.protocol.trade.messages.PayoutTxPublishedMessage;
import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.listeners.SendMessageListener;
import io.bitsquare.trade.protocol.trade.messages.PayoutTxPublishedMessage;
import io.bitsquare.trade.protocol.trade.taker.models.SellerAsTakerModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -49,8 +49,4 @@ public class SendPayoutTxToOfferer extends Task<SellerAsTakerModel> {
}
});
}
@Override
protected void updateStateOnFault() {
}
}

View File

@ -17,12 +17,14 @@
package io.bitsquare.trade.protocol.trade.taker.tasks;
import io.bitsquare.trade.Trade;
import io.bitsquare.trade.listeners.SendMessageListener;
import io.bitsquare.trade.protocol.trade.taker.models.SellerAsTakerModel;
import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.Trade;
import io.bitsquare.trade.listeners.SendMessageListener;
import io.bitsquare.trade.protocol.trade.messages.RequestDepositTxInputsMessage;
import io.bitsquare.trade.protocol.trade.taker.models.SellerAsTakerModel;
import javafx.application.Platform;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -58,19 +60,18 @@ public class SendRequestDepositTxInputsMessage extends Task<SellerAsTakerModel>
// We try to repeat once and if that fails as well we persist the state for a later retry.
if (retryCounter == 0) {
retryCounter++;
// doRun();
Platform.runLater(SendRequestDepositTxInputsMessage.this::doRun);
}
else {
appendToErrorMessage("Sending TakeOfferFeePayedMessage to offerer failed. Maybe the network connection was lost or the offerer lost his " +
"connection. " +
"We persisted the state of the trade, please try again later or cancel that trade.");
model.trade.setState(Trade.State.MESSAGE_SENDING_FAILED);
failed();
}
}
});
}
@Override
protected void updateStateOnFault() {
appendToErrorMessage("Sending TakeOfferFeePayedMessage to offerer failed. Maybe the network connection was lost or the offerer lost his connection. " +
"We persisted the state of the trade, please try again later or cancel that trade.");
model.trade.setState(Trade.State.MESSAGE_SENDING_FAILED);
}
}

View File

@ -60,8 +60,4 @@ public class SendSignedTakerDepositTx extends Task<SellerAsTakerModel> {
}
});
}
@Override
protected void updateStateOnFault() {
}
}

View File

@ -17,10 +17,10 @@
package io.bitsquare.trade.protocol.trade.taker.tasks;
import io.bitsquare.trade.Trade;
import io.bitsquare.trade.protocol.trade.taker.models.SellerAsTakerModel;
import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.Trade;
import io.bitsquare.trade.protocol.trade.taker.models.SellerAsTakerModel;
import org.bitcoinj.core.Transaction;
@ -69,8 +69,4 @@ public class SignAndPublishPayoutTx extends Task<SellerAsTakerModel> {
failed(e);
}
}
@Override
protected void updateStateOnFault() {
}
}

View File

@ -17,10 +17,10 @@
package io.bitsquare.trade.protocol.trade.taker.tasks;
import io.bitsquare.trade.Trade;
import io.bitsquare.trade.protocol.trade.taker.models.SellerAsTakerModel;
import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.Trade;
import io.bitsquare.trade.protocol.trade.taker.models.SellerAsTakerModel;
import org.bitcoinj.core.Transaction;
@ -46,8 +46,4 @@ public class TakerCommitDepositTx extends Task<SellerAsTakerModel> {
failed(t);
}
}
@Override
protected void updateStateOnFault() {
}
}

View File

@ -59,14 +59,11 @@ public class TakerCreatesAndSignsDepositTx extends Task<SellerAsTakerModel> {
complete();
} catch (Exception e) {
Trade.State state = Trade.State.FAULT;
state.setErrorMessage(errorMessage);
model.trade.setState(state);
failed(e);
}
}
@Override
protected void updateStateOnFault() {
Trade.State state = Trade.State.FAULT;
state.setErrorMessage(errorMessage);
model.trade.setState(state);
}
}

View File

@ -17,9 +17,9 @@
package io.bitsquare.trade.protocol.trade.taker.tasks;
import io.bitsquare.trade.protocol.trade.taker.models.SellerAsTakerModel;
import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.trade.protocol.trade.taker.models.SellerAsTakerModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@ -45,8 +45,4 @@ public class VerifyOffererAccount extends Task<SellerAsTakerModel> {
failed("Account registration validation for peer faultHandler.onFault.");
}
}
@Override
protected void updateStateOnFault() {
}
}

View File

@ -28,7 +28,6 @@ import io.bitsquare.trade.listeners.SendMessageListener;
import java.security.PublicKey;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executor;
@ -55,7 +54,7 @@ public class TomP2PTradeMessageService implements TradeMessageService {
private static final Logger log = LoggerFactory.getLogger(TomP2PTradeMessageService.class);
private final TomP2PNode tomP2PNode;
private final List<MessageHandler> messageHandlers = new CopyOnWriteArrayList<>();
private final CopyOnWriteArrayList<MessageHandler> messageHandlers = new CopyOnWriteArrayList<>();
private Executor executor;