mirror of
https://github.com/bitcoinj/bitcoinj.git
synced 2025-02-25 15:10:18 +01:00
TransactionOutput: Consider the witness discount in getMinNonDustValue().
This commit is contained in:
parent
fb353d744e
commit
25f36872d5
2 changed files with 30 additions and 14 deletions
|
@ -193,10 +193,7 @@ public class TransactionOutput extends ChildMessage {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Gets the minimum value for a txout of this size to be considered non-dust by Bitcoin Core
|
* <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
|
* (and thus relayed). See: CTxOut::IsDust() in Bitcoin Core.</p>
|
||||||
* consume more than a third of its value in fees is not something the Bitcoin system wants to deal with right now,
|
|
||||||
* so we call them "dust outputs" and they're made non standard. The choice of one third is somewhat arbitrary and
|
|
||||||
* may change in future.</p>
|
|
||||||
*
|
*
|
||||||
* <p>You probably should use {@link TransactionOutput#getMinNonDustValue()} which uses
|
* <p>You probably should use {@link TransactionOutput#getMinNonDustValue()} which uses
|
||||||
* a safe fee-per-kb by default.</p>
|
* a safe fee-per-kb by default.</p>
|
||||||
|
@ -204,19 +201,34 @@ public class TransactionOutput extends ChildMessage {
|
||||||
* @param feePerKb The fee required per kilobyte. Note that this is the same as Bitcoin Core's -minrelaytxfee * 3
|
* @param feePerKb The fee required per kilobyte. Note that this is the same as Bitcoin Core's -minrelaytxfee * 3
|
||||||
*/
|
*/
|
||||||
public Coin getMinNonDustValue(Coin feePerKb) {
|
public Coin getMinNonDustValue(Coin feePerKb) {
|
||||||
// A typical output is 33 bytes (pubkey hash + opcodes) and requires an input of 148 bytes to spend so we add
|
// "Dust" is defined in terms of dustRelayFee,
|
||||||
// that together to find out the total amount of data used to transfer this amount of value. Note that this
|
// which has units satoshis-per-kilobyte.
|
||||||
// formula is wrong for anything that's not a P2PKH output, unfortunately, we must follow Bitcoin Core's
|
// If you'd pay more in fees than the value of the output
|
||||||
// wrongness in order to ensure we're considered standard. A better formula would either estimate the
|
// to spend something, then we consider it dust.
|
||||||
// size of data needed to satisfy all different script types, or just hard code 33 below.
|
// A typical spendable non-segwit txout is 34 bytes big, and will
|
||||||
final long size = this.unsafeBitcoinSerialize().length + 148;
|
// need a CTxIn of at least 148 bytes to spend:
|
||||||
|
// so dust is a spendable txout less than
|
||||||
|
// 182*dustRelayFee/1000 (in satoshis).
|
||||||
|
// 546 satoshis at the default rate of 3000 sat/kB.
|
||||||
|
// A typical spendable segwit txout is 31 bytes big, and will
|
||||||
|
// need a CTxIn of at least 67 bytes to spend:
|
||||||
|
// so dust is a spendable txout less than
|
||||||
|
// 98*dustRelayFee/1000 (in satoshis).
|
||||||
|
// 294 satoshis at the default rate of 3000 sat/kB.
|
||||||
|
long size = this.unsafeBitcoinSerialize().length;
|
||||||
|
final Script script = getScriptPubKey();
|
||||||
|
if (ScriptPattern.isP2PKH(script) || ScriptPattern.isP2PK(script) || ScriptPattern.isP2SH(script))
|
||||||
|
size += 32 + 4 + 1 + 107 + 4; // 148
|
||||||
|
else if (ScriptPattern.isP2WH(script))
|
||||||
|
size += 32 + 4 + 1 + (107 / 4) + 4; // 68
|
||||||
|
else
|
||||||
|
return Coin.ZERO;
|
||||||
return feePerKb.multiply(size).divide(1000);
|
return feePerKb.multiply(size).divide(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the minimum value for this output to be considered "not dust", i.e. the transaction will be relayable
|
* Returns the minimum value for this output to be considered "not dust", i.e. the transaction will be relayable
|
||||||
* and mined by default miners. For normal pay to address outputs, this is 2730 satoshis, the same as
|
* and mined by default miners.
|
||||||
* {@link Transaction#MIN_NONDUST_OUTPUT}.
|
|
||||||
*/
|
*/
|
||||||
public Coin getMinNonDustValue() {
|
public Coin getMinNonDustValue() {
|
||||||
return getMinNonDustValue(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(3));
|
return getMinNonDustValue(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(3));
|
||||||
|
|
|
@ -86,7 +86,11 @@ public class TransactionOutputTest extends TestWithWallet {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getMinNonDustValue() throws Exception {
|
public void getMinNonDustValue() throws Exception {
|
||||||
TransactionOutput payToAddressOutput = new TransactionOutput(UNITTEST, null, Coin.COIN, myAddress);
|
TransactionOutput p2pk = new TransactionOutput(UNITTEST, null, Coin.COIN, myKey);
|
||||||
assertEquals(Transaction.MIN_NONDUST_OUTPUT, payToAddressOutput.getMinNonDustValue());
|
assertEquals(Coin.valueOf(576), p2pk.getMinNonDustValue());
|
||||||
|
TransactionOutput p2pkh = new TransactionOutput(UNITTEST, null, Coin.COIN, LegacyAddress.fromKey(UNITTEST, myKey));
|
||||||
|
assertEquals(Coin.valueOf(546), p2pkh.getMinNonDustValue());
|
||||||
|
TransactionOutput p2wpkh = new TransactionOutput(UNITTEST, null, Coin.COIN, SegwitAddress.fromKey(UNITTEST, myKey));
|
||||||
|
assertEquals(Coin.valueOf(294), p2wpkh.getMinNonDustValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue