The dust threshold is defined as
discard_feerate is defined as 3 s/vB. It follows that you need to know the
input_weight to calculate an output's dust threshold.
This is easy in the case of P2PKH outputs, because the input has a fixed weight. It is however is impossible in the case of P2SH, P2WSH, and P2TR outputs, because you cannot tell from the address what condition script the recipient encoded in their address to spend the output later. It could be a legacy multisig, wrapped segwit, or some custom construction. In case of P2TR it could be spend per the
keypath or the
scriptpath which would result in different input weights.
Therefore, the Bitcoin Core code only uses two different dust thresholds:
For all native segwit outputs, it uses the weight of the actual output plus the weight of a P2WPKH input. Note that although
nSize += (32 + 4 + 1 + (107 / WITNESS_SCALE_FACTOR) + 4);
should evaluate to 67.75 vB, since
nSize is a
size_t, it actually comes out as 67 vB.
This means for P2WPKH, where an output is 31 vB, the total comes out to 31 vB + 67 vB = 98 vB. This means for P2WPKH dust threshold is 294 satoshis. For P2WSH and P2TR, where outputs are 43 vB, the dust threshold comes out to 330 satoshis.
P2PKH outputs are 34 vB and inputs are 148 vB, so their roundtrip total is 34 vB + 148 vB = 182 vB, and thus the P2PKH dust threshold is 546 satoshis. Since P2SH outputs are only 32 vB for wrapped segwit and all other P2SH outputs, their dust threshold comes out to 540 satoshi.
You can look up address prefixes in this table:
m… is a testnet P2PKH address
2… is a testnet P2SH address