mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-12-16 08:14:15 -05:00
FixAdress entry persistence bug
This commit is contained in:
parent
ccd2e6b676
commit
2f911101ba
10 changed files with 69 additions and 38 deletions
|
|
@ -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 +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -112,24 +112,18 @@ class PendingTradesDataModel implements Activatable, DataModel {
|
||||||
removeListenerFromSelectedTrade();
|
removeListenerFromSelectedTrade();
|
||||||
|
|
||||||
selectedItem = item;
|
selectedItem = item;
|
||||||
|
isOfferer = getTrade().getOffer().getP2PSigPubKey().equals(user.getP2PSigPubKey());
|
||||||
|
|
||||||
if (selectedItem != null) {
|
Trade trade = getTrade();
|
||||||
isOfferer = getTrade().getOffer().getP2PSigPubKey().equals(user.getP2PSigPubKey());
|
if (trade instanceof TakerTrade)
|
||||||
|
takerProcessState.bind(((TakerTrade) trade).processStateProperty());
|
||||||
|
else
|
||||||
|
offererProcessState.bind(((OffererTrade) trade).processStateProperty());
|
||||||
|
|
||||||
Trade trade = getTrade();
|
log.trace("selectTrade trade.stateProperty().get() " + trade.processStateProperty().get());
|
||||||
if (trade instanceof TakerTrade)
|
|
||||||
takerProcessState.bind(((TakerTrade) trade).processStateProperty());
|
|
||||||
else
|
|
||||||
offererProcessState.bind(((OffererTrade) trade).processStateProperty());
|
|
||||||
|
|
||||||
log.trace("selectTrade trade.stateProperty().get() " + trade.processStateProperty().get());
|
if (trade.getDepositTx() != null)
|
||||||
|
txId.set(trade.getDepositTx().getHashAsString());
|
||||||
if (trade.getDepositTx() != null)
|
|
||||||
txId.set(trade.getDepositTx().getHashAsString());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
txId.set(null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void fiatPaymentStarted() {
|
void fiatPaymentStarted() {
|
||||||
|
|
|
||||||
|
|
@ -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) -> {
|
||||||
model.selectTrade(newValue);
|
if (newValue != null) {
|
||||||
updateScreen();
|
model.selectTrade(newValue);
|
||||||
|
updateScreen();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
withdrawAddressTextField.setValidator(model.getBtcAddressValidator());
|
withdrawAddressTextField.setValidator(model.getBtcAddressValidator());
|
||||||
|
|
|
||||||
|
|
@ -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");
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue