FixAdress entry persistence bug

This commit is contained in:
Manfred Karrer 2015-03-26 16:14:19 +01:00
parent ccd2e6b676
commit 2f911101ba
10 changed files with 69 additions and 38 deletions

View file

@ -23,6 +23,8 @@ import org.bitcoinj.crypto.DeterministicKey;
import java.io.Serializable; import java.io.Serializable;
import java.util.Arrays;
/** /**
* Is a minimalistic wallet abstraction used to separate transactions between different activities like: * Is a minimalistic wallet abstraction used to separate transactions between different activities like:
* Registration, trade and arbiter deposit. * Registration, trade and arbiter deposit.
@ -31,9 +33,11 @@ public class AddressEntry implements Serializable {
// That object is saved to disc. We need to take care of changes to not break deserialization. // That object is saved to disc. We need to take care of changes to not break deserialization.
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
// that will be restored from the wallet at deserialisation
private transient DeterministicKey keyPair;
private final String offerId; private final String offerId;
private final Context context; private final Context context;
private transient DeterministicKey keyPair;
private final byte[] pubKey; private final byte[] pubKey;
private final byte[] pubKeyHash; private final byte[] pubKeyHash;
private final NetworkParameters params; private final NetworkParameters params;
@ -93,8 +97,11 @@ public class AddressEntry implements Serializable {
@Override @Override
public String toString() { public String toString() {
return "AddressEntry{" + return "AddressEntry{" +
"offerId='" + offerId + "offerId='" + offerId + '\'' +
", addressContext=" + context + ", context=" + context +
", pubKey=" + Arrays.toString(pubKey) +
", pubKeyHash=" + Arrays.toString(pubKeyHash) +
", params=" + params +
'}'; '}';
} }
} }

View file

@ -46,13 +46,14 @@ public class AddressEntryList extends ArrayList<AddressEntry> implements Seriali
this.storage = storage; this.storage = storage;
} }
public void init(Wallet wallet) { public void onWalletReady(Wallet wallet) {
this.wallet = wallet; this.wallet = wallet;
AddressEntryList persisted = storage.initAndGetPersisted(this); AddressEntryList persisted = storage.initAndGetPersisted(this);
if (persisted != null) { if (persisted != null) {
for (AddressEntry addressEntry : persisted) { for (AddressEntry addressEntry : persisted) {
addressEntry.setDeterministicKey((DeterministicKey) wallet.findKeyFromPubHash(addressEntry.getPubKeyHash())); addressEntry.setDeterministicKey((DeterministicKey) wallet.findKeyFromPubHash(addressEntry.getPubKeyHash()));
this.add(addressEntry);
} }
} }
else { else {

View file

@ -37,8 +37,7 @@ public class BitcoinModule extends BitsquareModule {
@Override @Override
protected void configure() { protected void configure() {
bind(BitcoinNetwork.class).toInstance( bind(BitcoinNetwork.class).toInstance(env.getProperty(BitcoinNetwork.KEY, BitcoinNetwork.class, BitcoinNetwork.DEFAULT));
env.getProperty(BitcoinNetwork.KEY, BitcoinNetwork.class, BitcoinNetwork.DEFAULT));
bind(FeePolicy.class).in(Singleton.class); bind(FeePolicy.class).in(Singleton.class);
bindConstant().annotatedWith(named(UserAgent.NAME_KEY)).to(env.getRequiredProperty(UserAgent.NAME_KEY)); bindConstant().annotatedWith(named(UserAgent.NAME_KEY)).to(env.getRequiredProperty(UserAgent.NAME_KEY));
@ -47,10 +46,11 @@ public class BitcoinModule extends BitsquareModule {
File walletDir = new File(env.getRequiredProperty(WalletService.DIR_KEY)); File walletDir = new File(env.getRequiredProperty(WalletService.DIR_KEY));
bind(File.class).annotatedWith(named(WalletService.DIR_KEY)).toInstance(walletDir); bind(File.class).annotatedWith(named(WalletService.DIR_KEY)).toInstance(walletDir);
bindConstant().annotatedWith(named(WalletService.PREFIX_KEY)).to( bindConstant().annotatedWith(named(WalletService.PREFIX_KEY)).to(env.getRequiredProperty(WalletService.PREFIX_KEY));
env.getRequiredProperty(WalletService.PREFIX_KEY));
bind(WalletService.class).in(Singleton.class);
bind(AddressEntryList.class).in(Singleton.class);
bind(TradeWalletService.class).in(Singleton.class);
bind(WalletService.class).in(Singleton.class);
bind(BlockChainService.class).in(Singleton.class); bind(BlockChainService.class).in(Singleton.class);
} }

View file

@ -48,6 +48,8 @@ import com.google.common.util.concurrent.ListenableFuture;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.inject.Inject;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -81,17 +83,21 @@ public class TradeWalletService {
private static final Logger log = LoggerFactory.getLogger(TradeWalletService.class); private static final Logger log = LoggerFactory.getLogger(TradeWalletService.class);
private final NetworkParameters params; private final NetworkParameters params;
private final Wallet wallet; private Wallet wallet;
private final WalletAppKit walletAppKit; private WalletAppKit walletAppKit;
private final FeePolicy feePolicy; private final FeePolicy feePolicy;
public TradeWalletService(NetworkParameters params, Wallet wallet, WalletAppKit walletAppKit, FeePolicy feePolicy) { @Inject
this.params = params; public TradeWalletService(BitcoinNetwork bitcoinNetwork, FeePolicy feePolicy) {
this.wallet = wallet; this.params = bitcoinNetwork.getParameters();
this.walletAppKit = walletAppKit;
this.feePolicy = feePolicy; this.feePolicy = feePolicy;
} }
public void setWalletAppKit(WalletAppKit walletAppKit) {
this.walletAppKit = walletAppKit;
wallet = walletAppKit.wallet();
}
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Trade fee // Trade fee
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@ -142,12 +148,28 @@ public class TradeWalletService {
// Trade // Trade
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
private Coin getBalance(List<TransactionOutput> transactionOutputs, Address address) {
Coin balance = Coin.ZERO;
for (TransactionOutput transactionOutput : transactionOutputs) {
if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey().isPayToScriptHash()) {
Address addressOutput = transactionOutput.getScriptPubKey().getToAddress(params);
if (addressOutput.equals(address))
balance = balance.add(transactionOutput.getValue());
}
}
return balance;
}
public Result createOffererDepositTxInputs(Coin offererInputAmount, AddressEntry offererAddressEntry) throws public Result createOffererDepositTxInputs(Coin offererInputAmount, AddressEntry offererAddressEntry) throws
TransactionVerificationException, WalletException { TransactionVerificationException, WalletException {
log.trace("createOffererDepositTxInputs called"); log.trace("createOffererDepositTxInputs called");
log.trace("offererInputAmount " + offererInputAmount.toFriendlyString()); log.trace("offererInputAmount " + offererInputAmount.toFriendlyString());
log.trace("offererAddressEntry " + offererAddressEntry.toString()); log.trace("offererAddressEntry " + offererAddressEntry.toString());
Coin balance = getBalance(wallet.calculateAllSpendCandidates(true), offererAddressEntry.getAddress());
log.trace("balance " + balance.toFriendlyString());
// We pay the tx fee 2 times to the deposit tx: // We pay the tx fee 2 times to the deposit tx:
// 1. Will be spent when publishing the deposit tx (paid by offerer) // 1. Will be spent when publishing the deposit tx (paid by offerer)
// 2. Will be added to the MS amount, so when publishing the payout tx the fee is already there and the outputs are not changed by fee reduction // 2. Will be added to the MS amount, so when publishing the payout tx the fee is already there and the outputs are not changed by fee reduction

View file

@ -87,6 +87,8 @@ public class WalletService {
private final Observable<Double> downloadProgress = downloadListener.getObservable(); private final Observable<Double> downloadProgress = downloadListener.getObservable();
private final WalletEventListener walletEventListener = new BitsquareWalletEventListener(); private final WalletEventListener walletEventListener = new BitsquareWalletEventListener();
private final TradeWalletService tradeWalletService;
private final AddressEntryList addressEntryList;
private final NetworkParameters params; private final NetworkParameters params;
private final FeePolicy feePolicy; private final FeePolicy feePolicy;
private final SignatureService signatureService; private final SignatureService signatureService;
@ -98,9 +100,7 @@ public class WalletService {
private Wallet wallet; private Wallet wallet;
private AddressEntry registrationAddressEntry; private AddressEntry registrationAddressEntry;
private AddressEntry arbitratorDepositAddressEntry; private AddressEntry arbitratorDepositAddressEntry;
private AddressEntryList addressEntryList;
private TradeWalletService tradeWalletService;
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Constructor // Constructor
@ -108,8 +108,9 @@ public class WalletService {
@Inject @Inject
public WalletService(BitcoinNetwork bitcoinNetwork, FeePolicy feePolicy, SignatureService signatureService, public WalletService(BitcoinNetwork bitcoinNetwork, FeePolicy feePolicy, SignatureService signatureService,
AddressEntryList addressEntryList, UserAgent userAgent, TradeWalletService tradeWalletService, AddressEntryList addressEntryList, UserAgent userAgent,
@Named(DIR_KEY) File walletDir, @Named(PREFIX_KEY) String walletPrefix) { @Named(DIR_KEY) File walletDir, @Named(PREFIX_KEY) String walletPrefix) {
this.tradeWalletService = tradeWalletService;
this.addressEntryList = addressEntryList; this.addressEntryList = addressEntryList;
this.params = bitcoinNetwork.getParameters(); this.params = bitcoinNetwork.getParameters();
this.feePolicy = feePolicy; this.feePolicy = feePolicy;
@ -145,7 +146,8 @@ public class WalletService {
walletAppKit.peerGroup().setBloomFilterFalsePositiveRate(0.00001); walletAppKit.peerGroup().setBloomFilterFalsePositiveRate(0.00001);
initWallet(); initWallet();
tradeWalletService = new TradeWalletService(params, wallet, walletAppKit, feePolicy); // set after wallet is ready
tradeWalletService.setWalletAppKit(walletAppKit);
status.onCompleted(); status.onCompleted();
} }
@ -200,7 +202,7 @@ public class WalletService {
wallet = walletAppKit.wallet(); wallet = walletAppKit.wallet();
wallet.addEventListener(walletEventListener); wallet.addEventListener(walletEventListener);
addressEntryList.init(wallet); addressEntryList.onWalletReady(wallet);
registrationAddressEntry = addressEntryList.getRegistrationAddressEntry(); registrationAddressEntry = addressEntryList.getRegistrationAddressEntry();
} }

View file

@ -62,8 +62,9 @@ public class GuiModule extends BitsquareModule {
bind(ViewLoader.class).to(FxmlViewLoader.class).in(Singleton.class); bind(ViewLoader.class).to(FxmlViewLoader.class).in(Singleton.class);
bind(CachingViewLoader.class).in(Singleton.class); bind(CachingViewLoader.class).in(Singleton.class);
bind(OfferBook.class).in(Singleton.class);
bind(Navigation.class).in(Singleton.class); bind(Navigation.class).in(Singleton.class);
bind(OfferBook.class).in(Singleton.class);
bind(OverlayManager.class).in(Singleton.class); bind(OverlayManager.class).in(Singleton.class);
bind(BSFormatter.class).in(Singleton.class); bind(BSFormatter.class).in(Singleton.class);

View file

@ -112,8 +112,6 @@ class PendingTradesDataModel implements Activatable, DataModel {
removeListenerFromSelectedTrade(); removeListenerFromSelectedTrade();
selectedItem = item; selectedItem = item;
if (selectedItem != null) {
isOfferer = getTrade().getOffer().getP2PSigPubKey().equals(user.getP2PSigPubKey()); isOfferer = getTrade().getOffer().getP2PSigPubKey().equals(user.getP2PSigPubKey());
Trade trade = getTrade(); Trade trade = getTrade();
@ -127,10 +125,6 @@ class PendingTradesDataModel implements Activatable, DataModel {
if (trade.getDepositTx() != null) if (trade.getDepositTx() != null)
txId.set(trade.getDepositTx().getHashAsString()); txId.set(trade.getDepositTx().getHashAsString());
} }
else {
txId.set(null);
}
}
void fiatPaymentStarted() { void fiatPaymentStarted() {
tradeManager.onFiatPaymentStarted(getTrade()); tradeManager.onFiatPaymentStarted(getTrade());

View file

@ -139,8 +139,10 @@ public class PendingTradesView extends ActivatableViewAndModel<AnchorPane, Pendi
model.withdrawAddressFocusOut(withdrawAddressTextField.getText()); model.withdrawAddressFocusOut(withdrawAddressTextField.getText());
}; };
selectedItemChangeListener = (ov, oldValue, newValue) -> { selectedItemChangeListener = (ov, oldValue, newValue) -> {
if (newValue != null) {
model.selectTrade(newValue); model.selectTrade(newValue);
updateScreen(); updateScreen();
}
}; };
withdrawAddressTextField.setValidator(model.getBtcAddressValidator()); withdrawAddressTextField.setValidator(model.getBtcAddressValidator());

View file

@ -53,6 +53,7 @@ public class PlaceOfferProtocol {
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
public void placeOffer() { public void placeOffer() {
log.debug("model.offer.id" + model.offer.getId());
TaskRunner<PlaceOfferModel> taskRunner = new TaskRunner<>(model, TaskRunner<PlaceOfferModel> taskRunner = new TaskRunner<>(model,
() -> { () -> {
log.debug("sequence at handleRequestTakeOfferMessage completed"); log.debug("sequence at handleRequestTakeOfferMessage completed");

View file

@ -38,6 +38,7 @@ public class CreateOffererDepositTxInputs extends Task<OffererAsBuyerModel> {
@Override @Override
protected void doRun() { protected void doRun() {
try { try {
log.debug("model.trade.id" + model.trade.getId());
Coin offererInputAmount = model.trade.getSecurityDeposit().add(FeePolicy.TX_FEE); Coin offererInputAmount = model.trade.getSecurityDeposit().add(FeePolicy.TX_FEE);
TradeWalletService.Result result = model.tradeWalletService.createOffererDepositTxInputs(offererInputAmount, TradeWalletService.Result result = model.tradeWalletService.createOffererDepositTxInputs(offererInputAmount,
model.offerer.addressEntry); model.offerer.addressEntry);