-
Notifications
You must be signed in to change notification settings - Fork 36.2k
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
tracing: fix coin_selection:aps_create_tx_internal
calling logic
#25003
tracing: fix coin_selection:aps_create_tx_internal
calling logic
#25003
Conversation
3c86ed3
to
5849fa0
Compare
Good catch! I'm not sure about the original intention (maybe also the documentation is imprecise?), but if |
Oh, I didn't see that we have this I'd conclude then that we can remove either
|
It helps us know whether the selected_coins tracepoint (that will happen within CreateTransactionInternal) is for the APS CreateTransactionInternal without having to look backwards when |
ACK 5849fa0 |
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
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.
Code ACK 5849fa0
src/wallet/spend.cpp
Outdated
if (use_aps) { | ||
tx = tx2; | ||
nFeeRet = nFeeRet2; | ||
nChangePosInOut = nChangePosInOut2; | ||
} | ||
} | ||
TRACE5(coin_selection, aps_create_tx_internal, wallet.GetName().c_str(), use_aps, res2, nFeeRet2, nChangePosInOut2); |
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.
small off-topic question (that has nothing to do with this PR) is why this trace context is called "coin_selection" when CreateTransactionInternal
could fail for other reasons (like missing solving data, signing, etc).
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.
Changes look good to me, however I'm not too involved with coin selection.
Might make sense for @xekyo to review/comment on this PR too. He's using the coin_selection
tracepoints.
If I understand this correctly, the way this tracepoint is activated, it would log a result as having been produced per APS, whenever the APS result is preferred. Among other things, this would include if there are two equivalent (or even matching) solutions, or if there wasn't any partial-spend concern with the original solution in the first place.
All together, I think both the design for this tracepoint and the design for the opportunistic APS may have the same solution: only run the opportunistic APS if the original selection result includes a partial spend: this would speed up coin selection, remove the potential for disimproving the selection result, and give useful numbers to the subscribers of the tracepoint. While I think this PR improves over the original deployment, if I got the above right, it might be better to remove this tracepoint due to not providing a clear signal instead. |
While I agree the signal is not particularly clear and this could result in some misleading information, the tracepoint is still necessary as sometimes the APS solution is used and is different from the original solution, so it would be even more misleading if we were to only record the original. However, I also agree that we should change how the opportunistic APS works, but that is outside the scope of this PR. |
Okay, will re-review. |
ACK 5849fa0, but we really should fix both the APS and the tracepoints logging logic. |
Test |
5849fa0
to
8148f0d
Compare
Rebased on master (necessary since #20640 has been merged). |
According to the documentation, the tracepoint `coin_selection:aps_create_tx_internal` "Is called when the second `CreateTransactionInternal` with Avoid Partial Spends enabled completes." Currently it is only called if the second call to `CreateTransactionInternal` succeeds, i.e. the third parameter is always `true` and we don't get notified in the case that it fails. Fix this by introducing a boolean variable for the result of the call and moving the tracepoint call outside the if body.
8148f0d
to
6b63673
Compare
re-ack: 6b63673 |
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.
re-ACK 6b63673
src/wallet/spend.cpp
Outdated
if (use_aps) { | ||
tx = tx2; | ||
nFeeRet = nFeeRet2; | ||
nChangePosInOut = nChangePosInOut2; | ||
} | ||
} | ||
TRACE5(coin_selection, aps_create_tx_internal, wallet.GetName().c_str(), use_aps, res2, nFeeRet2, nChangePosInOut2); |
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.
small off-topic question (that has nothing to do with this PR) is why this trace context is called "coin_selection" when CreateTransactionInternal
could fail for other reasons (like missing solving data, signing, etc).
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.
It's called coin selection because the tracepoint primarily measures the results of performing coin selection.
@@ -993,12 +993,13 @@ std::optional<CreatedTransactionResult> CreateTransaction( | |||
tmp_cc.m_avoid_partial_spends = true; | |||
bilingual_str error2; // fired and forgotten; if an error occurs, we discard the results | |||
std::optional<CreatedTransactionResult> txr_grouped = CreateTransactionInternal(wallet, vecSend, change_pos, error2, tmp_cc, fee_calc_out, sign); | |||
// if fee of this alternative one is within the range of the max fee, we use this one | |||
const bool use_aps{txr_grouped.has_value() ? (txr_grouped->fee <= txr_ungrouped->fee + wallet.m_max_aps_fee) : false}; |
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.
nit: could be written as:
const bool use_aps = txr_grouped &&
(txr_grouped->fee <= txr_ungrouped->fee + wallet.m_max_aps_fee);
(removing the optional has_value()
call).
// if fee of this alternative one is within the range of the max fee, we use this one | ||
const bool use_aps{txr_grouped.has_value() ? (txr_grouped->fee <= txr_ungrouped->fee + wallet.m_max_aps_fee) : false}; | ||
TRACE5(coin_selection, aps_create_tx_internal, wallet.GetName().c_str(), use_aps, txr_grouped.has_value(), | ||
txr_grouped.has_value() ? txr_grouped->fee : 0, txr_grouped.has_value() ? txr_grouped->change_pos : 0); |
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.
same code nit here, I don't see a reason to use txr_grouped.has_value()
when there is a cleaner way of doing it with the bool() operator (by default std::optional is set to nullopt).
ACK 6b63673 |
According to the documentation, the tracepoint
coin_selection:aps_create_tx_internal
"Is called when the secondCreateTransactionInternal
with Avoid Partial Spends enabled completes."Currently it is only called if the second call to
CreateTransactionInternal
succeeds, i.e. the third parameter is alwaystrue
and we don't get notified in the case that it fails. This PR fixes this by moving the tracepoint call and theuse_aps
boolean variable outside the if body.