mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-07-31 20:11:23 +00:00
TransactionOutput: New isDust() method, and use it.
This commit is contained in:
@@ -205,6 +205,16 @@ public class TransactionOutput extends ChildMessage {
|
||||
throw new IllegalStateException("Output linked to wrong parent transaction?");
|
||||
}
|
||||
|
||||
/**
|
||||
* Will this transaction be relayable and mined by default miners?
|
||||
*/
|
||||
public boolean isDust() {
|
||||
// Transactions that are OP_RETURN can't be dust regardless of their value.
|
||||
if (getScriptPubKey().isOpReturn())
|
||||
return false;
|
||||
return getValue().isLessThan(getMinNonDustValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Gets the minimum value for a txout of this size to be considered non-dust by Bitcoin Core
|
||||
* (and thus relayed). See: CTxOut::IsDust() in Bitcoin Core. The assumption is that any output that would
|
||||
|
@@ -4119,15 +4119,12 @@ public class Wallet extends BaseTaggableObject
|
||||
for (TransactionOutput output : req.tx.getOutputs()) {
|
||||
if (output.getValue().compareTo(Coin.CENT) < 0) {
|
||||
needAtLeastReferenceFee = true;
|
||||
if (output.getValue().compareTo(output.getMinNonDustValue()) < 0) { // Is transaction a "dust".
|
||||
if (output.getScriptPubKey().isOpReturn()) { // Transactions that are OP_RETURN can't be dust regardless of their value.
|
||||
++opReturnCount;
|
||||
continue;
|
||||
} else {
|
||||
throw new DustySendRequested();
|
||||
}
|
||||
}
|
||||
break;
|
||||
if (output.isDust())
|
||||
throw new DustySendRequested();
|
||||
if (output.getScriptPubKey().isOpReturn())
|
||||
++opReturnCount;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4277,7 +4274,7 @@ public class Wallet extends BaseTaggableObject
|
||||
fee = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;
|
||||
TransactionOutput output = tx.getOutput(0);
|
||||
output.setValue(output.getValue().subtract(fee));
|
||||
return output.getMinNonDustValue().compareTo(output.getValue()) <= 0;
|
||||
return !output.isDust();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5084,11 +5081,11 @@ public class Wallet extends BaseTaggableObject
|
||||
changeAddress = currentChangeAddress();
|
||||
changeOutput = new TransactionOutput(params, req.tx, change, changeAddress);
|
||||
// If the change output would result in this transaction being rejected as dust, just drop the change and make it a fee
|
||||
if (req.ensureMinRequiredFee && change.isLessThan(Transaction.MIN_NONDUST_OUTPUT)) {
|
||||
if (req.ensureMinRequiredFee && changeOutput.isDust()) {
|
||||
// This solution definitely fits in category 3
|
||||
isCategory3 = true;
|
||||
additionalValueForNextCategory = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(
|
||||
Transaction.MIN_NONDUST_OUTPUT.add(Coin.SATOSHI));
|
||||
changeOutput.getMinNonDustValue().add(Coin.SATOSHI));
|
||||
} else {
|
||||
size += changeOutput.unsafeBitcoinSerialize().length + VarInt.sizeOf(req.tx.getOutputs().size()) - VarInt.sizeOf(req.tx.getOutputs().size() - 1);
|
||||
// This solution is either category 1 or 2
|
||||
|
@@ -250,7 +250,7 @@ public abstract class PaymentChannelServerState {
|
||||
|
||||
Wallet.SendRequest req = makeUnsignedChannelContract(newValueToMe);
|
||||
|
||||
if (!fullyUsedUp && refundSize.compareTo(req.tx.getOutput(0).getMinNonDustValue()) < 0)
|
||||
if (!fullyUsedUp && refundSize.isLessThan(req.tx.getOutput(0).getMinNonDustValue()))
|
||||
throw new ValueOutOfRangeException("Attempt to refund negative value or value too small to be accepted by the network");
|
||||
|
||||
// Get the wallet's copy of the contract (ie with confidence information), if this is null, the wallet
|
||||
|
@@ -134,7 +134,7 @@ public class PaymentChannelV1ClientState extends PaymentChannelClientState {
|
||||
// format which one is the change. If we start obfuscating the change output better in future this may
|
||||
// be worth revisiting.
|
||||
TransactionOutput multisigOutput = template.addOutput(totalValue, ScriptBuilder.createMultiSigOutputScript(2, keys));
|
||||
if (multisigOutput.getMinNonDustValue().compareTo(totalValue) > 0)
|
||||
if (multisigOutput.isDust())
|
||||
throw new ValueOutOfRangeException("totalValue too small to use");
|
||||
Wallet.SendRequest req = Wallet.SendRequest.forTx(template);
|
||||
req.coinSelector = AllowUnconfirmedCoinSelector.get();
|
||||
|
@@ -110,7 +110,7 @@ public class PaymentChannelV2ClientState extends PaymentChannelClientState {
|
||||
ScriptBuilder.createCLTVPaymentChannelOutput(BigInteger.valueOf(expiryTime), myKey, serverKey);
|
||||
TransactionOutput transactionOutput = template.addOutput(totalValue,
|
||||
ScriptBuilder.createP2SHOutputScript(redeemScript));
|
||||
if (transactionOutput.getMinNonDustValue().compareTo(totalValue) > 0)
|
||||
if (transactionOutput.isDust())
|
||||
throw new ValueOutOfRangeException("totalValue too small to use");
|
||||
Wallet.SendRequest req = Wallet.SendRequest.forTx(template);
|
||||
req.coinSelector = AllowUnconfirmedCoinSelector.get();
|
||||
|
Reference in New Issue
Block a user