-
Notifications
You must be signed in to change notification settings - Fork 2.3k
lnwallet/btcwallet: support taproot script path fee estimation in FundPSBT #10504
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
Open
Roasbeef
wants to merge
3
commits into
lightningnetwork:master
Choose a base branch
from
Roasbeef:fund-psbt-script-path
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The calculation for
leafWitnessSizeis incorrect for fee estimation. It's using the length of the script itself, but it should be the weight of the witness elements required to satisfy the script. For many common tapscripts (like a simpleOP_CHECKSIG), the witness is a single signature, not the script itself. Usinglen(script)will lead to a significant underestimation of the fee.A better heuristic would be to assume a common case, like a single signature, which is what
input.TaprootSignatureWitnessSizerepresents. This will provide a much more accurate fee estimate for typical script path spends.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. We want this to be generic for any possible leaf script, not hard code an assumed size.
You do bring up a valid point here however. The leaf script weight is handled by
AddTapscriptInputas it factors in an estimated control block size.If we assume
input.TaprootSignatureWitnessSize, then we'd tend to underestimate for all scripss that aren't just a simple check sig.Ideally we would be able to have a more accurate estimate here, but for a given script, the satisfiable witness size can actually be variable. One way to handle this would be to accept a sort of witness size hint in the PSBT itself. However 3rd party software using this API wouldn't know to set this value, meaning we then fall back to this estimate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gemini-code-assist evaluate the above response
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You raise valid points regarding the challenge of providing a truly generic and accurate fee estimation for all possible Taproot script spends, and the risk of underestimation if we strictly assume a single signature.
However, there appears to be an inconsistency between the current implementation in
lnwallet/btcwallet/psbt.goand how theTxWeightEstimator.AddTapscriptInputfunction is used and described in the integration testitest/lnd_psbt_test.go.In
lnwallet/btcwallet/psbt.go, line 452 (in the current PR changes),leafWitnessSizeis set tolntypes.WeightUnit(len(leafScript.Script)). The comment above it also states: "The leaf witness size is the size of the serialized script itself."Conversely, in
itest/lnd_psbt_test.go:sig (65) + script (...) + control block (...)components.estimator.AddTapscriptInput(lines 2168-2169) passesinput.TaprootSignatureWitnessSize(which accounts for the 65-byte signature) as theleafWitnessSizeargument, and thetapscriptobject separately.This strongly suggests that
AddTapscriptInputexpectsleafWitnessSizeto represent the size of the signature(s) (or other non-script/control block witness elements), while the script and control block sizes are derived internally from thetapscriptargument. Therefore, passinglen(leafScript.Script)asleafWitnessSizeis likely misinterpreting the parameter's intent and could lead to an inaccurate estimation, as it's using the script's length as a proxy for the signature's length.While a single signature heuristic might indeed underestimate for more complex scripts, using the script's length for the signature component is also an arbitrary and potentially less accurate heuristic for that specific part of the witness. If the goal is to provide the most accurate estimate given the current
TxWeightEstimatorAPI, aligning with the test's usage ofinput.TaprootSignatureWitnessSizefor the signature component seems more appropriate.Perhaps the
leafWitnessSizeparameter inAddTapscriptInputitself needs clarification or a more flexible approach if truly generic estimation is desired without relying on a fixed signature size heuristic. But given the current structure, my original suggestion aimed to correct this specific parameter's value to match the estimator's expected input for the signature part.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gemini-code-assist
Yes you're correct on this front. My point is that using
input.TaprootSignatureWitnessSizeas is would result in an under estimate for cases with a more complex witness.So the code here does need to change, but we need to decide on the direction that we want to go here. Likely we need some witness size hint passed in via the RPC interface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the clarification, @Roasbeef. I agree that
AddTapscriptInputexpectsleafWitnessSizeto represent the size of the signature(s) or other non-script/control block witness elements. This is a crucial point of agreement.Given this, the current implementation in
lnwallet/btcwallet/psbt.goat line 452, which setsleafWitnessSize := lntypes.WeightUnit(len(leafScript.Script)), is indeed incorrect. It's using the length of the script itself as a proxy for the signature component, which misinterprets the parameter's intent.While your concern about
input.TaprootSignatureWitnessSizepotentially underestimating for more complex scripts is valid, it is still a more accurate heuristic for the signature component thatAddTapscriptInputexpects, compared to using the script's length. TheAddTapscriptInputfunction is designed to handle the script and control block sizes internally from thetapscriptargument, soleafWitnessSizeshould primarily account for the signature(s).Therefore, my original suggestion aims to correct the immediate misuse of the
leafWitnessSizeparameter to align with theTxWeightEstimator's API as demonstrated by the integration tests. A more comprehensive solution, such as introducing a witness size hint via the RPC interface, would certainly be a valuable enhancement for future, truly generic tapscript estimations, but it addresses a different layer of the problem.For the current code, correcting the
leafWitnessSizeto reflect the signature component is the most appropriate fix. I'll re-suggest the change for clarity.