tracing: fix `coin_selection:aps_create_tx_internal` calling logic #25003

pull theStack wants to merge 1 commits into bitcoin:master from theStack:202204-tracing_fix_coin_selection-aps_create_tx_internal_log changing 1 files +4 −3
  1. theStack commented at 2:44 PM on April 27, 2022: contributor

    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. This PR fixes this by moving the tracepoint call and the use_aps boolean variable outside the if body.

  2. fanquake requested review from 0xB10C on Apr 27, 2022
  3. fanquake requested review from achow101 on Apr 27, 2022
  4. theStack force-pushed on Apr 27, 2022
  5. mzumsande commented at 3:19 PM on April 27, 2022: contributor

    Good catch!

    I'm not sure about the original intention (maybe also the documentation is imprecise?), but if aps_create_tx_internal is called irrespective of the second CreateTransactionInternal result now, I don't see a point in having the attempting_aps_create_tx tracepoint anymore.

  6. theStack commented at 4:03 PM on April 27, 2022: contributor

    I'm not sure about the original intention (maybe also the documentation is imprecise?), but if aps_create_tx_internal is called irrespective of the second CreateTransactionInternal result now, I don't see a point in having the attempting_aps_create_tx tracepoint anymore.

    Oh, I didn't see that we have this attempting_aps_create_tx tracepoint to be honest. So there is already an implicit way to see if the second CreateTransactionInternal call failed, and it could indeed be that the documentation is not clear enough. What made me sceptical about the conditional tracepoint call though is the fact that there is a "succeeded" parameter (where currently the result of the first CreateTransactionInternal is passed, i.e. always "true").

    I'd conclude then that we can remove either

    • the attempting_aps_create_tx tracepoint (if this PR is preferred), or
    • the success parameter from the aps_create_tx_internal tracepoint (with an according documentation update, e.g. "is called when completed successfully")
  7. achow101 commented at 4:27 PM on April 27, 2022: member

    I'm not sure about the original intention (maybe also the documentation is imprecise?), but if aps_create_tx_internal is called irrespective of the second CreateTransactionInternal result now, I don't see a point in having the attempting_aps_create_tx tracepoint anymore.

    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 aps_create_tx_internal is seen.

  8. achow101 commented at 4:27 PM on April 27, 2022: member

    ACK 5849fa0ed9049468d7a350e289069522b3a21dbf

  9. DrahtBot added the label Wallet on Apr 27, 2022
  10. DrahtBot commented at 2:03 AM on April 28, 2022: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #25218 (refactor: introduce generic 'Result' classes and connect it to CreateTransaction and GetNewDestination by furszy)

    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.

  11. DrahtBot cross-referenced this on Apr 28, 2022 from issue [Draft / POC] Silent Payments by w0xlt
  12. DrahtBot cross-referenced this on Apr 28, 2022 from issue wallet: return error msg for "too-long-mempool-chain" by furszy
  13. 0xB10C cross-referenced this on Apr 28, 2022 from issue wallet: add tracepoints and algorithm information to coin selection by achow101
  14. in src/wallet/spend.cpp:1009 in 5849fa0ed9 outdated
    1007 |                  tx = tx2;
    1008 |                  nFeeRet = nFeeRet2;
    1009 |                  nChangePosInOut = nChangePosInOut2;
    1010 |              }
    1011 |          }
    1012 | +        TRACE5(coin_selection, aps_create_tx_internal, wallet.GetName().c_str(), use_aps, res2, nFeeRet2, nChangePosInOut2);
    


    furszy commented at 2:49 PM on May 4, 2022:

    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).


    furszy commented at 2:49 PM on May 4, 2022:

    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).


    achow101 commented at 5:04 PM on May 26, 2022:

    It's called coin selection because the tracepoint primarily measures the results of performing coin selection.

  15. furszy approved
  16. furszy commented at 2:50 PM on May 4, 2022: member

    Code ACK 5849fa0e

  17. 0xB10C commented at 7:25 PM on May 4, 2022: contributor

    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.

  18. murchandamus commented at 5:38 PM on May 10, 2022: contributor

    I'm not sure about the original intention (maybe also the documentation is imprecise?), but if aps_create_tx_internal is called irrespective of the second CreateTransactionInternal result now, I don't see a point in having the attempting_aps_create_tx tracepoint anymore.

    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 aps_create_tx_internal is seen.

    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. This results in three different concerns:

    1. This feels like a potential footgun for someone trying to understand coin selection outcomes. They might want to know a) how often partial-spends even occurred in the first place, and b) how often the opportunistic APS protected them from it. From what I understand, they cannot actually learn either of these numbers. Instead, a subscriber of the tracepoint would get an inflated sense of how often they were protected from partial spends.
    2. Since the APS solution is preferred even when it has a slightly worse fee, when the general coin selection result and the opportunistic APS result differ, the APS result may actually have a worse waste score and get preferred for the transaction building, disimproving the outcome for the user even when there was no partial-spend in the original solution.
    3. The coin selection is run twice while that might be completely unnecessary in many cases.

    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.

  19. murchandamus commented at 8:36 PM on May 10, 2022: contributor

    I guess some of those comments would have better fit on #24644, sorry. cc: @achow101 ^

  20. theStack cross-referenced this on May 16, 2022 from issue wallet, refactor: return out-params of CreateTransaction() as optional struct by theStack
  21. achow101 commented at 7:37 PM on May 16, 2022: member

    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.

  22. murchandamus commented at 8:30 PM on May 16, 2022: contributor

    Okay, will re-review.

  23. murchandamus commented at 8:36 PM on May 16, 2022: contributor

    ACK 5849fa0ed9049468d7a350e289069522b3a21dbf, but we really should fix both the APS and the tracepoints logging logic.

  24. murchandamus cross-referenced this on May 16, 2022 from issue Coin Selection tracepoint overreports use of APS by murchandamus
  25. 0xB10C commented at 10:18 PM on May 16, 2022: contributor

    Test interface_usdt_coinselection.py passes for 5849fa0ed9049468d7a350e289069522b3a21dbf.

  26. DrahtBot added the label Needs rebase on May 17, 2022
  27. theStack force-pushed on May 17, 2022
  28. theStack commented at 2:05 PM on May 17, 2022: contributor

    Rebased on master (necessary since #20640 has been merged).

  29. DrahtBot removed the label Needs rebase on May 17, 2022
  30. tracing: fix `coin_selection:aps_create_tx_internal` calling logic
    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.
    6b636730f4
  31. theStack force-pushed on May 17, 2022
  32. murchandamus commented at 4:06 PM on May 17, 2022: contributor

    re-ack: 6b636730f4befee39d57fcfd51298f3015dbf563

  33. in src/wallet/spend.cpp:997 in 6b636730f4
     992 | @@ -993,12 +993,13 @@ std::optional<CreatedTransactionResult> CreateTransaction(
     993 |          tmp_cc.m_avoid_partial_spends = true;
     994 |          bilingual_str error2; // fired and forgotten; if an error occurs, we discard the results
     995 |          std::optional<CreatedTransactionResult> txr_grouped = CreateTransactionInternal(wallet, vecSend, change_pos, error2, tmp_cc, fee_calc_out, sign);
     996 | +        // if fee of this alternative one is within the range of the max fee, we use this one
     997 | +        const bool use_aps{txr_grouped.has_value() ? (txr_grouped->fee <= txr_ungrouped->fee + wallet.m_max_aps_fee) : false};
    


    furszy commented at 2:07 PM on May 19, 2022:

    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).

  34. in src/wallet/spend.cpp:999 in 6b636730f4
     992 | @@ -993,12 +993,13 @@ std::optional<CreatedTransactionResult> CreateTransaction(
     993 |          tmp_cc.m_avoid_partial_spends = true;
     994 |          bilingual_str error2; // fired and forgotten; if an error occurs, we discard the results
     995 |          std::optional<CreatedTransactionResult> txr_grouped = CreateTransactionInternal(wallet, vecSend, change_pos, error2, tmp_cc, fee_calc_out, sign);
     996 | +        // if fee of this alternative one is within the range of the max fee, we use this one
     997 | +        const bool use_aps{txr_grouped.has_value() ? (txr_grouped->fee <= txr_ungrouped->fee + wallet.m_max_aps_fee) : false};
     998 | +        TRACE5(coin_selection, aps_create_tx_internal, wallet.GetName().c_str(), use_aps, txr_grouped.has_value(),
     999 | +               txr_grouped.has_value() ? txr_grouped->fee : 0, txr_grouped.has_value() ? txr_grouped->change_pos : 0);
    


    furszy commented at 2:10 PM on May 19, 2022:

    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).

  35. furszy approved
  36. furszy commented at 2:11 PM on May 19, 2022: member

    re-ACK 6b636730

  37. DrahtBot cross-referenced this on May 26, 2022 from issue refactor: introduce generic 'Result' class and connect it to CreateTransaction and GetNewDestination by furszy
  38. achow101 commented at 5:07 PM on May 26, 2022: member

    ACK 6b636730f4befee39d57fcfd51298f3015dbf563

  39. achow101 merged this on May 26, 2022
  40. achow101 closed this on May 26, 2022

  41. sidhujag referenced this in commit b8ba7a8f31 on May 28, 2022
  42. bitcoin locked this on May 26, 2023

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-05-19 14:52 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me