Skip to content

Commit

Permalink
Merge branch 'master' into 02-scripted-bot-test
Browse files Browse the repository at this point in the history
  • Loading branch information
ghubstan committed Feb 25, 2021
2 parents 4ac9fa5 + 0feb107 commit b341bb6
Show file tree
Hide file tree
Showing 23 changed files with 582 additions and 122 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,6 @@ public boolean isRegtest() {
}

public long getDefaultMinFeePerVbyte() {
return 2;
return 15; // 2021-02-22 due to mempool congestion, increased from 2
}
}
2 changes: 1 addition & 1 deletion core/src/main/java/bisq/core/app/DomainInitialisation.java
Original file line number Diff line number Diff line change
Expand Up @@ -196,12 +196,12 @@ public void initDomainServices(Consumer<String> rejectedTxErrorMessageHandler,

tradeLimits.onAllServicesInitialized();

tradeManager.onAllServicesInitialized();
arbitrationManager.onAllServicesInitialized();
mediationManager.onAllServicesInitialized();
refundManager.onAllServicesInitialized();
traderChatManager.onAllServicesInitialized();

tradeManager.onAllServicesInitialized();
closedTradableManager.onAllServicesInitialized();
failedTradesManager.onAllServicesInitialized();
xmrTxProofService.onAllServicesInitialized();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,11 @@
import java.util.List;
import java.util.Set;

import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.Nullable;

/**
* Used from org.bitcoinj.wallet.DefaultCoinSelector but added selectOutput method and changed static methods to
* instance methods.
Expand All @@ -49,6 +52,12 @@ public abstract class BisqDefaultCoinSelector implements CoinSelector {

protected final boolean permitForeignPendingTx;

// TransactionOutputs to be used as candidates in the select method.
// We reset the value to null just after we have applied it inside the select method.
@Nullable
@Setter
protected Set<TransactionOutput> utxoCandidates;

public CoinSelection select(Coin target, Set<TransactionOutput> candidates) {
return select(target, new ArrayList<>(candidates));
}
Expand All @@ -65,7 +74,16 @@ public BisqDefaultCoinSelector() {
public CoinSelection select(Coin target, List<TransactionOutput> candidates) {
ArrayList<TransactionOutput> selected = new ArrayList<>();
// Sort the inputs by age*value so we get the highest "coin days" spent.
ArrayList<TransactionOutput> sortedOutputs = new ArrayList<>(candidates);

ArrayList<TransactionOutput> sortedOutputs;
if (utxoCandidates != null) {
sortedOutputs = new ArrayList<>(utxoCandidates);
// We reuse the selectors. Reset the transactionOutputCandidates field
utxoCandidates = null;
} else {
sortedOutputs = new ArrayList<>(candidates);
}

// If we spend all we don't need to sort
if (!target.equals(NetworkParameters.MAX_MONEY))
sortOutputs(sortedOutputs);
Expand Down Expand Up @@ -120,6 +138,9 @@ protected boolean isTxSpendable(Transaction tx) {

abstract boolean isTxOutputSpendable(TransactionOutput output);

// TODO Why it uses coin age and not try to minimize number of inputs as the highest priority?
// Asked Oscar and he also don't knows why coin age is used. Should be changed so that min. number of inputs is
// target.
protected void sortOutputs(ArrayList<TransactionOutput> outputs) {
Collections.sort(outputs, (a, b) -> {
int depth1 = a.getParentTransactionDepthInBlocks();
Expand Down
42 changes: 40 additions & 2 deletions core/src/main/java/bisq/core/btc/wallet/BsqWalletService.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.Nullable;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.bitcoinj.core.TransactionConfidence.ConfidenceType.BUILDING;
Expand Down Expand Up @@ -135,6 +137,8 @@ public BsqWalletService(WalletsSetup walletsSetup,
this.unconfirmedBsqChangeOutputListService = unconfirmedBsqChangeOutputListService;
this.daoKillSwitch = daoKillSwitch;

nonBsqCoinSelector.setPreferences(preferences);

walletsSetup.addSetupCompletedHandler(() -> {
wallet = walletsSetup.getBsqWallet();
if (wallet != null) {
Expand Down Expand Up @@ -313,6 +317,16 @@ public void removeWalletTransactionsChangeListener(WalletTransactionsChangeListe
walletTransactionsChangeListeners.remove(listener);
}

public List<TransactionOutput> getSpendableBsqTransactionOutputs() {
return new ArrayList<>(bsqCoinSelector.select(NetworkParameters.MAX_MONEY,
wallet.calculateAllSpendCandidates()).gathered);
}

public List<TransactionOutput> getSpendableNonBsqTransactionOutputs() {
return new ArrayList<>(nonBsqCoinSelector.select(NetworkParameters.MAX_MONEY,
wallet.calculateAllSpendCandidates()).gathered);
}


///////////////////////////////////////////////////////////////////////////////////////////
// BSQ TransactionOutputs and Transactions
Expand Down Expand Up @@ -511,7 +525,19 @@ public void commitTx(Transaction tx, TxType txType) {
///////////////////////////////////////////////////////////////////////////////////////////

public Transaction getPreparedSendBsqTx(String receiverAddress, Coin receiverAmount)
throws AddressFormatException, InsufficientBsqException, WalletException, TransactionVerificationException, BsqChangeBelowDustException {
throws AddressFormatException, InsufficientBsqException, WalletException,
TransactionVerificationException, BsqChangeBelowDustException {
return getPreparedSendTx(receiverAddress, receiverAmount, bsqCoinSelector, false);
}

public Transaction getPreparedSendBsqTx(String receiverAddress,
Coin receiverAmount,
@Nullable Set<TransactionOutput> utxoCandidates)
throws AddressFormatException, InsufficientBsqException, WalletException,
TransactionVerificationException, BsqChangeBelowDustException {
if (utxoCandidates != null) {
bsqCoinSelector.setUtxoCandidates(utxoCandidates);
}
return getPreparedSendTx(receiverAddress, receiverAmount, bsqCoinSelector, false);
}

Expand All @@ -520,7 +546,19 @@ public Transaction getPreparedSendBsqTx(String receiverAddress, Coin receiverAmo
///////////////////////////////////////////////////////////////////////////////////////////

public Transaction getPreparedSendBtcTx(String receiverAddress, Coin receiverAmount)
throws AddressFormatException, InsufficientBsqException, WalletException, TransactionVerificationException, BsqChangeBelowDustException {
throws AddressFormatException, InsufficientBsqException, WalletException,
TransactionVerificationException, BsqChangeBelowDustException {
return getPreparedSendTx(receiverAddress, receiverAmount, nonBsqCoinSelector, true);
}

public Transaction getPreparedSendBtcTx(String receiverAddress,
Coin receiverAmount,
@Nullable Set<TransactionOutput> utxoCandidates)
throws AddressFormatException, InsufficientBsqException, WalletException,
TransactionVerificationException, BsqChangeBelowDustException {
if (utxoCandidates != null) {
nonBsqCoinSelector.setUtxoCandidates(utxoCandidates);
}
return getPreparedSendTx(receiverAddress, receiverAmount, nonBsqCoinSelector, true);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@

import bisq.core.dao.state.DaoStateService;
import bisq.core.dao.state.model.blockchain.TxOutputKey;
import bisq.core.user.Preferences;

import org.bitcoinj.core.Transaction;
import org.bitcoinj.core.TransactionConfidence;
import org.bitcoinj.core.TransactionOutput;

import javax.inject.Inject;

import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

/**
Expand All @@ -35,6 +37,8 @@
@Slf4j
public class NonBsqCoinSelector extends BisqDefaultCoinSelector {
private DaoStateService daoStateService;
@Setter
private Preferences preferences;

@Inject
public NonBsqCoinSelector(DaoStateService daoStateService) {
Expand All @@ -60,9 +64,9 @@ protected boolean isTxOutputSpendable(TransactionOutput output) {
return !daoStateService.existsTxOutput(key) || daoStateService.isRejectedIssuanceOutput(key);
}

// BTC utxo in the BSQ wallet are usually from rejected comp request so we don't expect dust attack utxos here.
// Prevent usage of dust attack utxos
@Override
protected boolean isDustAttackUtxo(TransactionOutput output) {
return false;
return output.getValue().value < preferences.getIgnoreDustThreshold();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,11 @@ protected AckMessageSourceType getAckMessageSourceType() {
// API
///////////////////////////////////////////////////////////////////////////////////////////

public void onAllServicesInitialized() {
super.onAllServicesInitialized();
tryApplyMessages();
}

public void onSupportMessage(SupportMessage message) {
if (canProcessMessage(message)) {
log.info("Received {} with tradeId {} and uid {}",
Expand Down
6 changes: 6 additions & 0 deletions core/src/main/resources/i18n/displayStrings.properties
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ shared.offerType=Offer type
shared.details=Details
shared.address=Address
shared.balanceWithCur=Balance in {0}
shared.utxo=Unspent transaction output
shared.txId=Transaction ID
shared.confirmations=Confirmations
shared.revert=Revert Tx
Expand Down Expand Up @@ -2270,6 +2271,7 @@ dao.wallet.send.receiverAddress=Receiver's BSQ address
dao.wallet.send.receiverBtcAddress=Receiver's BTC address
dao.wallet.send.setDestinationAddress=Fill in your destination address
dao.wallet.send.send=Send BSQ funds
dao.wallet.send.inputControl=Select inputs
dao.wallet.send.sendBtc=Send BTC funds
dao.wallet.send.sendFunds.headline=Confirm withdrawal request
dao.wallet.send.sendFunds.details=Sending: {0}\nTo receiving address: {1}.\nRequired mining fee is: {2} ({3} satoshis/vbyte)\nTransaction vsize: {4} vKb\n\nThe recipient will receive: {5}\n\nAre you sure you want to withdraw that amount?
Expand Down Expand Up @@ -2487,6 +2489,9 @@ dao.factsAndFigures.transactions.irregularTx=No. of all irregular transactions
# Windows
####################################################################

inputControlWindow.headline=Select inputs for transaction
inputControlWindow.balanceLabel=Available balance

contractWindow.title=Dispute details
contractWindow.dates=Offer date / Trade date
contractWindow.btcAddresses=Bitcoin address BTC buyer / BTC seller
Expand Down Expand Up @@ -3619,6 +3624,7 @@ validation.inputTooSmall=Input has to be larger than {0}
validation.inputToBeAtLeast=Input has to be at least {0}
validation.amountBelowDust=An amount below the dust limit of {0} satoshi is not allowed.
validation.length=Length must be between {0} and {1}
validation.fixedLength=Length must be {0}
validation.pattern=Input must be of format: {0}
validation.noHexString=The input is not in HEX format.
validation.advancedCash.invalidFormat=Must be a valid email or wallet id of format: X000000000000
Expand Down
20 changes: 16 additions & 4 deletions desktop/src/main/java/bisq/desktop/components/InputTextField.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public InputTextField() {

validationResult.addListener((ov, oldValue, newValue) -> {
if (newValue != null) {
resetValidation();
jfxValidationWrapper.resetValidation();
if (!newValue.isValid) {
if (!newValue.errorMessageEquals(oldValue)) { // avoid blinking
validate(); // ensure that the new error message replaces the old one
Expand All @@ -92,9 +92,7 @@ public InputTextField() {
});

textProperty().addListener((o, oldValue, newValue) -> {
if (validator != null) {
this.validationResult.set(validator.validate(getText()));
}
refreshValidation();
});

focusedProperty().addListener((o, oldValue, newValue) -> {
Expand All @@ -108,6 +106,7 @@ public InputTextField() {
});
}


public InputTextField(double inputLineExtension) {
this();
this.inputLineExtension = inputLineExtension;
Expand All @@ -119,6 +118,19 @@ public InputTextField(double inputLineExtension) {

public void resetValidation() {
jfxValidationWrapper.resetValidation();

String input = getText();
if (input.isEmpty()) {
validationResult.set(new InputValidator.ValidationResult(true));
} else {
validationResult.set(validator.validate(input));
}
}

public void refreshValidation() {
if (validator != null) {
this.validationResult.set(validator.validate(getText()));
}
}

///////////////////////////////////////////////////////////////////////////////////////////
Expand Down
Loading

0 comments on commit b341bb6

Please sign in to comment.