Allow creating transactions with dust outputs
Add TxBuilder::allow_dust() that skips checking the dust limit
This commit is contained in:
parent
061f15af00
commit
bfd7b2f65d
@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Add capacity to create FeeRate from sats/kvbytes and sats/kwu.
|
- Add capacity to create FeeRate from sats/kvbytes and sats/kwu.
|
||||||
- Rename `as_sat_vb` to `as_sat_per_vb`. Move all `FeeRate` test to `types.rs`.
|
- Rename `as_sat_vb` to `as_sat_per_vb`. Move all `FeeRate` test to `types.rs`.
|
||||||
- Add custom Harware Wallet Signer `HwiSigner` in `src/wallet/harwaresigner/` module.
|
- Add custom Harware Wallet Signer `HwiSigner` in `src/wallet/harwaresigner/` module.
|
||||||
|
- Add `allow_dust` method on `TxBuilder`.
|
||||||
|
|
||||||
## [v0.21.0] - [v0.20.0]
|
## [v0.21.0] - [v0.20.0]
|
||||||
|
|
||||||
@ -22,7 +23,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- New `RpcBlockchain` implementation with various fixes.
|
- New `RpcBlockchain` implementation with various fixes.
|
||||||
- Return balance in separate categories, namely `confirmed`, `trusted_pending`, `untrusted_pending` & `immature`.
|
- Return balance in separate categories, namely `confirmed`, `trusted_pending`, `untrusted_pending` & `immature`.
|
||||||
|
|
||||||
|
|
||||||
## [v0.20.0] - [v0.19.0]
|
## [v0.20.0] - [v0.19.0]
|
||||||
|
|
||||||
- New MSRV set to `1.56.1`
|
- New MSRV set to `1.56.1`
|
||||||
|
@ -790,7 +790,10 @@ where
|
|||||||
let recipients = params.recipients.iter().map(|(r, v)| (r, *v));
|
let recipients = params.recipients.iter().map(|(r, v)| (r, *v));
|
||||||
|
|
||||||
for (index, (script_pubkey, value)) in recipients.enumerate() {
|
for (index, (script_pubkey, value)) in recipients.enumerate() {
|
||||||
if value.is_dust(script_pubkey) && !script_pubkey.is_provably_unspendable() {
|
if !params.allow_dust
|
||||||
|
&& value.is_dust(script_pubkey)
|
||||||
|
&& !script_pubkey.is_provably_unspendable()
|
||||||
|
{
|
||||||
return Err(Error::OutputBelowDustLimit(index));
|
return Err(Error::OutputBelowDustLimit(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5408,6 +5411,30 @@ pub(crate) mod test {
|
|||||||
builder.finish().unwrap();
|
builder.finish().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_allow_dust_limit() {
|
||||||
|
let (wallet, _, _) = get_funded_wallet(get_test_single_sig_cltv());
|
||||||
|
|
||||||
|
let addr = wallet.get_address(New).unwrap();
|
||||||
|
|
||||||
|
let mut builder = wallet.build_tx();
|
||||||
|
|
||||||
|
builder.add_recipient(addr.script_pubkey(), 0);
|
||||||
|
|
||||||
|
assert!(matches!(
|
||||||
|
builder.finish().unwrap_err(),
|
||||||
|
Error::OutputBelowDustLimit(0)
|
||||||
|
));
|
||||||
|
|
||||||
|
let mut builder = wallet.build_tx();
|
||||||
|
|
||||||
|
builder
|
||||||
|
.allow_dust(true)
|
||||||
|
.add_recipient(addr.script_pubkey(), 0);
|
||||||
|
|
||||||
|
assert!(builder.finish().is_ok());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fee_rate_sign_no_grinding_high_r() {
|
fn test_fee_rate_sign_no_grinding_high_r() {
|
||||||
// Our goal is to obtain a transaction with a signature with high-R (71 bytes
|
// Our goal is to obtain a transaction with a signature with high-R (71 bytes
|
||||||
|
@ -148,6 +148,7 @@ pub(crate) struct TxParams {
|
|||||||
pub(crate) include_output_redeem_witness_script: bool,
|
pub(crate) include_output_redeem_witness_script: bool,
|
||||||
pub(crate) bumping_fee: Option<PreviousFee>,
|
pub(crate) bumping_fee: Option<PreviousFee>,
|
||||||
pub(crate) current_height: Option<u32>,
|
pub(crate) current_height: Option<u32>,
|
||||||
|
pub(crate) allow_dust: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
@ -560,6 +561,14 @@ impl<'a, D: BatchDatabase, Cs: CoinSelectionAlgorithm<D>, Ctx: TxBuilderContext>
|
|||||||
self.params.current_height = Some(height);
|
self.params.current_height = Some(height);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set whether or not the dust limit is checked.
|
||||||
|
///
|
||||||
|
/// **Note**: by avoiding a dust limit check you may end up with a transaction that is non-standard.
|
||||||
|
pub fn allow_dust(&mut self, allow_dust: bool) -> &mut Self {
|
||||||
|
self.params.allow_dust = allow_dust;
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, D: BatchDatabase, Cs: CoinSelectionAlgorithm<D>> TxBuilder<'a, D, Cs, CreateTx> {
|
impl<'a, D: BatchDatabase, Cs: CoinSelectionAlgorithm<D>> TxBuilder<'a, D, Cs, CreateTx> {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user