/// <summary> /// Check whether an output amount is considered dust for a given transaction relay fee. /// Transactions with dust outputs are rejected by mempool. /// </summary> /// <param name="amount">Output amount</param> /// <param name="scriptSize">Size of the output script in bytes</param> /// <param name="relayFeePerKb">Mempool relay fee/kB</param> /// <returns>Whether the output is dust</returns> public static bool IsDustAmount(Amount amount, int scriptSize, Amount relayFeePerKb) { // Calculate the total (estimated) cost to the network. This is // calculated using the serialize size of the output plus the serial // size of a transaction input which redeems it. The output is assumed // to be compressed P2PKH as this is the most common script type. Use // the average size of a compressed P2PKH redeem input (165) rather than // the largest possible (Transaction.RedeemPayToPubKeyHashInputSize). var totalSize = 8 + 2 + CompactInt.SerializeSize((ulong)scriptSize) + scriptSize + 165; // Dust is defined as an output value where the total cost to the network // (output size + input size) is greater than 1/3 of the relay fee. return(amount * 1000 / (3 * totalSize) < relayFeePerKb); }
/// <summary> /// Estimates the signed serialize size of an unsigned transaction, assuming all /// inputs spend P2PKH outputs. The estimate is a worst case, so the actual /// serialize size after signing should always be less than or equal to this value. /// </summary> /// <param name="inputCount">Number of P2PKH outputs the transaction will redeem</param> /// <param name="outputs">Transaction output array</param> /// <param name="addChangeOutput">Add the serialize size for an additional P2PKH change output</param> /// <returns>Estimated signed serialize size of the transaction</returns> public static int EstimateSerializeSize(int inputCount, Output[] outputs, bool addChangeOutput) { if (outputs == null) { throw new ArgumentNullException(nameof(outputs)); } var changeSize = 0; var outputCount = outputs.Length; if (addChangeOutput) { changeSize = PayToPubKeyHashOutputSize; outputCount++; } return (12 + (2 * CompactInt.SerializeSize((ulong)inputCount)) + CompactInt.SerializeSize((ulong)outputCount) + inputCount * RedeemPayToPubKeyHashInputSize + outputs.Sum(o => o.SerializeSize) + changeSize); }