Store arbitrator pubKey in trade object to avoid null pointer when the arbitrator is not available in the trade process

This commit is contained in:
Manfred Karrer 2016-08-25 02:36:16 +02:00
parent 682e2d2d8e
commit 18d3dfd38b
12 changed files with 32 additions and 26 deletions

View file

@ -1,11 +1,6 @@
package io.bitsquare.app;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DevFlags {
private static final Logger log = LoggerFactory.getLogger(DevFlags.class);
public static final boolean STRESS_TEST_MODE = false;
public static final boolean DEV_MODE = STRESS_TEST_MODE || false;
}

View file

@ -23,6 +23,7 @@ import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import io.bitsquare.app.Log;
import io.bitsquare.app.Version;
import io.bitsquare.arbitration.Arbitrator;
import io.bitsquare.arbitration.ArbitratorManager;
import io.bitsquare.btc.TradeWalletService;
import io.bitsquare.btc.WalletService;
@ -55,6 +56,8 @@ import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Holds all data which are relevant to the trade, but not those which are only needed in the trade process as shared data between tasks. Those data are
* stored in the task model.
@ -167,6 +170,7 @@ public abstract class Trade implements Tradable, Model {
private Transaction payoutTx;
private long lockTimeAsBlockHeight;
private NodeAddress arbitratorNodeAddress;
private byte[] arbitratorBtcPubKey;
private String takerPaymentAccountId;
private String errorMessage;
transient private StringProperty errorMessageProperty;
@ -553,8 +557,26 @@ public abstract class Trade implements Tradable, Model {
return arbitratorNodeAddress;
}
public void setArbitratorNodeAddress(NodeAddress arbitratorNodeAddress) {
public void applyArbitratorNodeAddress(NodeAddress arbitratorNodeAddress) {
this.arbitratorNodeAddress = arbitratorNodeAddress;
Arbitrator arbitrator = processModel.getUser().getAcceptedArbitratorByAddress(arbitratorNodeAddress);
checkNotNull(arbitrator, "arbitrator must not be null");
arbitratorBtcPubKey = arbitrator.getBtcPubKey();
}
public byte[] getArbitratorPubKey() {
// Prior to v0.4.8.4 we did not store the arbitratorBtcPubKey in the trade object so we need to support the
// previously used version as well and request the arbitrator from the user object (but that caused sometimes a bug when
// the client did not get delivered an arbitrator from the P2P network).
if (arbitratorBtcPubKey == null) {
Arbitrator arbitrator = processModel.getUser().getAcceptedArbitratorByAddress(arbitratorNodeAddress);
checkNotNull(arbitrator, "arbitrator must not be null");
arbitratorBtcPubKey = arbitrator.getBtcPubKey();
}
checkNotNull(arbitratorBtcPubKey, "ArbitratorPubKey must not be null");
return arbitratorBtcPubKey;
}
public String getTakerPaymentAccountId() {

View file

@ -18,7 +18,6 @@
package io.bitsquare.trade.protocol.trade;
import io.bitsquare.app.Version;
import io.bitsquare.arbitration.Arbitrator;
import io.bitsquare.arbitration.ArbitratorManager;
import io.bitsquare.btc.TradeWalletService;
import io.bitsquare.btc.WalletService;
@ -52,8 +51,6 @@ import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import static com.google.common.base.Preconditions.checkNotNull;
public class ProcessModel implements Model, Serializable {
// That object is saved to disc. We need to take care of changes to not break deserialization.
private static final long serialVersionUID = Version.LOCAL_DB_VERSION;
@ -150,14 +147,6 @@ public class ProcessModel implements Model, Serializable {
return tradeWalletService;
}
public byte[] getArbitratorPubKey(NodeAddress arbitratorNodeAddress) {
Arbitrator acceptedArbitratorByAddress = user.getAcceptedArbitratorByAddress(arbitratorNodeAddress);
checkNotNull(acceptedArbitratorByAddress, "acceptedArbitratorByAddress must not be null.\n" +
"Maybe there is no arbitrator in the network available or you did not receive the data from the P2P network.\n" +
"You can try to restart the app to see if that resolved the issue.");
return acceptedArbitratorByAddress.getBtcPubKey();
}
public Offer getOffer() {
return offer;
}

View file

@ -70,7 +70,7 @@ public class OffererCreatesAndSignsDepositTxAsBuyer extends TradeTask {
walletService.getOrCreateAddressEntry(AddressEntry.Context.AVAILABLE).getAddress(),
buyerMultiSigAddressEntry.getPubKey(),
processModel.tradingPeer.getMultiSigPubKey(),
processModel.getArbitratorPubKey(trade.getArbitratorNodeAddress()));
trade.getArbitratorPubKey());
processModel.setPreparedDepositTx(result.depositTransaction);
processModel.setRawTransactionInputs(result.rawOffererInputs);

View file

@ -55,7 +55,7 @@ public class SignAndFinalizePayoutTx extends TradeTask {
trade.getLockTimeAsBlockHeight(),
processModel.getWalletService().getOrCreateAddressEntry(processModel.getOffer().getId(), AddressEntry.Context.MULTI_SIG).getPubKey(),
processModel.tradingPeer.getMultiSigPubKey(),
processModel.getArbitratorPubKey(trade.getArbitratorNodeAddress())
trade.getArbitratorPubKey()
);
trade.setPayoutTx(transaction);

View file

@ -69,7 +69,7 @@ public class SignAndPublishDepositTxAsBuyer extends TradeTask {
tradingPeer.getRawTransactionInputs(),
buyerMultiSigAddressEntry.getPubKey(),
tradingPeer.getMultiSigPubKey(),
processModel.getArbitratorPubKey(trade.getArbitratorNodeAddress()),
trade.getArbitratorPubKey(),
new FutureCallback<Transaction>() {
@Override
public void onSuccess(Transaction transaction) {

View file

@ -75,7 +75,7 @@ public class ProcessPayDepositRequest extends TradeTask {
processModel.setTakerAcceptedArbitratorNodeAddresses(checkNotNull(payDepositRequest.acceptedArbitratorNodeAddresses));
if (payDepositRequest.acceptedArbitratorNodeAddresses.isEmpty())
failed("acceptedArbitratorNames must not be empty");
trade.setArbitratorNodeAddress(checkNotNull(payDepositRequest.arbitratorNodeAddress));
trade.applyArbitratorNodeAddress(checkNotNull(payDepositRequest.arbitratorNodeAddress));
try {
long takersTradePrice = payDepositRequest.tradePrice;

View file

@ -70,7 +70,7 @@ public class OffererCreatesAndSignsDepositTxAsSeller extends TradeTask {
walletService.getOrCreateAddressEntry(AddressEntry.Context.AVAILABLE).getAddress(),
processModel.tradingPeer.getMultiSigPubKey(),
sellerMultiSigAddressEntry.getPubKey(),
processModel.getArbitratorPubKey(trade.getArbitratorNodeAddress()));
trade.getArbitratorPubKey());
processModel.setPreparedDepositTx(result.depositTransaction);
processModel.setRawTransactionInputs(result.rawOffererInputs);

View file

@ -68,7 +68,7 @@ public class SignAndPublishDepositTxAsSeller extends TradeTask {
sellerInputs,
tradingPeer.getMultiSigPubKey(),
sellerMultiSigAddressEntry.getPubKey(),
processModel.getArbitratorPubKey(trade.getArbitratorNodeAddress()),
trade.getArbitratorPubKey(),
new FutureCallback<Transaction>() {
@Override
public void onSuccess(Transaction transaction) {

View file

@ -67,7 +67,7 @@ public class SignPayoutTx extends TradeTask {
lockTimeAsBlockHeight,
processModel.tradingPeer.getMultiSigPubKey(),
walletService.getOrCreateAddressEntry(id, AddressEntry.Context.MULTI_SIG).getPubKey(),
processModel.getArbitratorPubKey(trade.getArbitratorNodeAddress()));
trade.getArbitratorPubKey());
processModel.setPayoutTxSignature(payoutTxSignature);

View file

@ -36,7 +36,7 @@ public class SelectArbitrator extends TradeTask {
try {
runInterceptHook();
trade.setArbitratorNodeAddress(ArbitrationSelectionRule.select(processModel.getUser().getAcceptedArbitratorAddresses(), processModel.getOffer()));
trade.applyArbitratorNodeAddress(ArbitrationSelectionRule.select(processModel.getUser().getAcceptedArbitratorAddresses(), processModel.getOffer()));
complete();
} catch (Throwable t) {

View file

@ -147,7 +147,7 @@ public class PendingTradesDataModel extends ActivatableDataModel {
public void onFiatPaymentReceived(ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
checkNotNull(getTrade(), "trade must not be null");
checkArgument(getTrade() instanceof SellerTrade, "Check failed: trade instanceof SellerTrade");
checkArgument(getTrade() instanceof SellerTrade, "Check failed: trade not instanceof SellerTrade");
if (getTrade().getDisputeState() == Trade.DisputeState.NONE)
((SellerTrade) getTrade()).onFiatPaymentReceived(resultHandler, errorMessageHandler);
}