Closed evanlinjin closed 1 year ago
eak concept NACK.
If my understanding is up to date we currently use max_satisfaction_weight()
to figure out weight for coin selection which will not use the grinded value. So fixing this won't improve much other than increase the feerate.
It is also not possible to control this on most hardware wallets. If people want less weight I think they should just use taproot addresses rather than demand libraries to have this wacky parameter to save a few bytes.
eak concept NACK.
If my understanding is up to date we currently use
max_satisfaction_weight()
to figure out weight for coin selection which will not use the grinded value. So fixing this won't improve much other than increase the feerate.It is also not possible to control this on most hardware wallets. If people want less weight I think they should just use taproot addresses rather than demand libraries to have this wacky parameter to save a few bytes.
In all else being said, increasing the fee rate slightly is a side-effect most people will be happy with imo.
IIRC bitcoin core is grinding for low R, thus always obtaining len(signature) < 71 bytes
, thus BDK should do the same for privacy reasons ?
(without optimizing fee calculation)
If my understanding is up to date we currently use max_satisfaction_weight() to figure out weight for coin selection which will not use the grinded value.
From the max_satisfaction_weight docs:
All signatures are assumed to be 73 bytes in size, including the length prefix (segwit) or push opcode (pre-segwit) and sighash postfix.
The lenght prefix or push opcode is 1 byte, the sighash postfix is 1 byte, which means that rust-miniscript considers one signature to be 71 bytes in size (i.e., considers them to be grinded).
If we don't want to grind signatures, we should take this into account in the coin selection. This means adding 1 WU per input per signature in segwit inputs, 4WU per input per signature in non-segwit inputs.
If we don't do so we risk returning a transaction with a feerate lower than what the user requested.
I don't think it's easy to account for the extra weight ourselves, we basically have to do minisiscript's job of counting how many signatures can end up in a script in the worst case (for example, if we have 10 keys overall in our descriptor, it's not guaranteed that there's a path that actually contains 10 signatures in the scriptsig/witness).
So here's my proposal, which is a bit of a compromise I think:
SignOptions
to enable/disable signature grinding. By default I would keep it enabled, for the reason @RCasatta described and also because it increases the feerate slightly essentially for free. But being an option, it can still be disabled by the user if they don't want it for whatever reasonFor my part, I have no problem fixing rust-miniscript to add 1 to the signature size estimate.
I would also be open to having a more flexible API that could specify this .. but I've explored this is the past and I'm skeptical that we'd be able to make a good complexity/functionality tradeoff here.
Wait, I might have gotten my math wrong...
The lenght prefix or push opcode is 1 byte, the sighash postfix is 1 byte, which means that rust-miniscript considers one signature to be 71 bytes in size (i.e., considers them to be grinded).
After a bit more research, it seems to me that low-R signatures are 70 bytes long, and high-R signatures are 71 bytes long. Which would mean that rust-miniscript already considers high-R (not grinded) signatures. Does that check out?
@danielabrozzoni and @evanlinjin let me take this up.
@vladimirfomene I personally don't think it will hurt if you get started with changing how our Software "signers" are implemented first.
However, since this is still tagged as discussion, I would first see the opinions of everyone else.
It will be fine to slightly overshoot feerate.
I think this is ready to be worked on. It's a small change on the signer side which gives some pros (Bitcoin Core txs indistinguishable from the bdk ones, and you get some extra priority for your tx without paying additional fees).
I feel like we should have some method in the tx_builder (allow_grinding
or something) so that the user can customize this. @evanlinjin what do you think?
@danielabrozzoni I also think this is ready to be worked on. I think the changes on the signer-side is a "no-brainer" (for the reasons that you have mentioned).
In terms of changing up the TxBuilder
, I think this should be done in a separate PR, and would need more discussion.
In terms of changing up the TxBuilder, I think this should be done in a separate PR, and would need more discussion.
Ok, then I guess we'll just grind by default for now :)
Closing this now that #779 is merged.
Describe the bug
BDK does not do signature grinding for ecdsa signatures.
Expected behavior
BDK should have signature grinding.
Additional context
This is what BDK currently does.
https://github.com/bitcoindevkit/bdk/blob/a1477405d1adebd9a95689af17d3912edf1e57ef/src/wallet/signer.rs#L460-L463
But we have this to use.
https://github.com/rust-bitcoin/rust-secp256k1/blob/7fde3325075f16ec4b8c2c624fee523cc5225047/src/ecdsa/mod.rs#L341-L344
More context
After we are certain that the BDK ECDSA signer(s) implementation uses signature grinding, we should optimize fee-rate calculation to take into consideration of grinding.
Do we need another signer method to inform whether the signer does ecdsa signature grinding?