-
Notifications
You must be signed in to change notification settings - Fork 64
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
spend: feerate can be lower than target value #1371
Comments
This is possibly related to #1322. |
I was able to reproduce this on Signet with txid It's a spend from the primary path of a Taproot descriptor, where the primary path is a 2-of-2 multisig, with target feerate 2 sat/vb. The tx weight is 646 and fee 322. Even if calculating the feerate without rounding up the vbytes, this gives 322 / (646/4) = 1.99. |
I think we're currently missing the varint length for This is also mentioned here: |
Perhaps something like this could work: diff --git a/src/descriptors/mod.rs b/src/descriptors/mod.rs
index 818ecb19..6ee1034a 100644
--- a/src/descriptors/mod.rs
+++ b/src/descriptors/mod.rs
@@ -6,6 +6,7 @@ use miniscript::{
secp256k1,
},
descriptor,
+ miniscript::satisfy::Placeholder,
plan::{Assets, CanSign},
psbt::{PsbtInputExt, PsbtOutputExt},
translate_hash_clone, ForEachKey, TranslatePk, Translator,
@@ -270,15 +271,21 @@ impl LianaDescriptor {
.expect("unhardened index");
let witscript_size = der_desc
.explicit_script()
- .map(|s| varint_len(s.len()) + s.len())
- .unwrap_or(0);
+ .map(|s| varint_len(s.len()) + s.len());
// Finally, compute the satisfaction template for the primary path and get its size.
- der_desc
- .plan(&assets)
- .expect("Always satisfiable")
- .witness_size()
- + witscript_size
+ let plan = der_desc.plan(&assets).expect("Always satisfiable");
+ plan.witness_size()
+ + witscript_size.unwrap_or_else(|_| {
+ plan.witness_template()
+ .iter()
+ .map(|elem| match elem {
+ Placeholder::TapScript(s) => varint_len(s.len()),
+ Placeholder::TapControlBlock(cb) => varint_len(cb.serialize().len()),
+ _ => 0,
+ })
+ .sum()
+ })
} else {
// We add one to account for the witness stack size, as the values above give the
// difference in size for a satisfied input that was *already* in a transaction I did a test with this change using the same type of tx as before, and now the fee correctly came to 323 sats. |
I think the change above may be enough to fix the fee issue. There's a separate, less severe issue to do with the estimated satisfied weight of a transaction here: Lines 541 to 557 in cbc46e9
This is used to display the feerate in the GUI. It currently gives the satisfied weight as 642, which, even if we add 2 with the change above, will leave us 2 short. I think this discrepancy may be because when we get the weight of the unsigned tx, it doesn't include the Segwit marker and flag. I think this is because all inputs have empty witnesses, and so the transaction is serialized as non-Segwit: |
…tisig primary path spends 6e74a96 Revert "spend: add 10 sats to fee for 1 sat/vb txs" (Michael Mallan) cf88aca descriptors: fix satisfaction size for Taproot (Michael Mallan) e9c6995 qa: add threshold paramater for multisig descs (Michael Mallan) Pull request description: This is a fix to #1371 and the related #1322. As per #1371 (comment), this adds the varint length for the script and control block elements of a Taproot primary path spend. I think this is what caused #1322 and so I have reverted the change from #1323. ACKs for top commit: edouardparis: utACK 6e74a96 Tree-SHA512: 754e5c2186de853cde9006aeab7989141a4d363b9e3d8adb3f0264bcbca7e3b56a94822d434f6f7d8108e7c0e3023959fa407643e5868082f8981c5ce10b9a1e
The fee of a Taproot (only affects Taproot?) transaction can sometimes be 1 sat lower than required to achieve the target feerate as defined by the coin selection algorithm, i.e. feerate = fee / (weight/4).
Note that #1132 is similar but relates to whether or not the vbytes are rounded up when calculating the feerate.
If we fix this, then we should revert the change from #1323.
The text was updated successfully, but these errors were encountered: