refactor: wallet: return util::Result from GetReservedDestination methods #25656

pull theStack wants to merge 1 commits into bitcoin:master from theStack:202207-refactor-wallet_use_bresult_for_getreserveddestination changing 5 files +26 −40
  1. theStack commented at 10:16 pm on July 20, 2022: contributor
    This PR is a follow-up to #25218, as suggested in comment #25218 (review). The interfaces of the methods ReserveDestination::GetReservedDestination, {Legacy,Descriptor,}ScriptPubKeyMan::GetReservedDestination are improved by returning util::Result<CTxDestination> instead of bool in order to get rid of the two CTxDestination& and bilingual_str& out-parameters.
  2. fanquake added the label Refactoring on Jul 20, 2022
  3. in src/wallet/spend.cpp:715 in d7c37ed989 outdated
    713+        if (op_dest.HasRes()) {
    714+            dest = op_dest.ReleaseObj();
    715+        } else {
    716+            error = _("Transaction needs a change address, but we can't generate it.") + Untranslated(" ") + op_dest.GetError();
    717         }
    718         scriptChange = GetScriptForDestination(dest);
    


    furszy commented at 10:26 pm on July 20, 2022:

    Can remove the bottom scriptChange = GetScriptForDestination(dest); call if GetReservedDestination failed (no valid destination).

    0auto op_dest = reservedest.GetReservedDestination(true);
    1if (!op_dest) {
    2    error = _("Transaction needs a change address, but we can't generate it.") + Untranslated(" ") + op_dest.GetError();
    3} else {
    4    scriptChange = GetScriptForDestination(op_dest.GetObj());
    5}
    

    theStack commented at 8:00 pm on July 21, 2022:
    Thanks, done. Scrictly speaking moving the scriptChange assignment into the conditional is a bit more than a refactor (it could have been done also before the BResult change), but it also makes sense to not unnecessarily call GetScriptForDestination in the failure case.
  4. in src/wallet/scriptpubkeyman.h:182 in d7c37ed989 outdated
    178@@ -179,7 +179,7 @@ class ScriptPubKeyMan
    179     virtual bool CheckDecryptionKey(const CKeyingMaterial& master_key, bool accept_no_keys = false) { return false; }
    180     virtual bool Encrypt(const CKeyingMaterial& master_key, WalletBatch* batch) { return false; }
    181 
    182-    virtual bool GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool, bilingual_str& error) { return false; }
    183+    virtual BResult<CTxDestination> GetReservedDestination(const OutputType type, bool internal, int64_t& index, CKeyPool& keypool) { return {}; }
    


    furszy commented at 10:30 pm on July 20, 2022:

    Because CTxDestination default value is CNoDestination, this will return a succeed BResult object. Would be better to do:

    0return Untranslated("Not supported");
    

    (same as we are doing for the base GetNewDestination)


    MarcoFalke commented at 5:30 am on July 21, 2022:
    I would have expected for {} to return an empty error message. Is there any way to avoid this confusion at compile time?

    ryanofsky commented at 1:01 pm on July 21, 2022:

    I would have expected for {} to return an empty error message. Is there any way to avoid this confusion at compile time?

    I think the silent conversion of bilingual_str into errors is an anti-feature. Not every translated string is necessarily an error string, and the conversion makes it not possible to use a BResult<bilingual_str> type that returns a normal translated string. #25665 improves this by adding an explicit error contructor


    furszy commented at 2:01 pm on July 21, 2022:

    I would have expected for {} to return an empty error message. Is there any way to avoid this confusion at compile time?

    Yeah @MarcoFalke, my bad here, I shouldn’t had reviewed the PR before sleep…

    As we internally use an std::variant, and the first element is the bilingual_str. The {} will indeed initialize the variant with an empty error message.

    What I tried to say on the message is that I don’t see how empty error strings are useful. The caller cannot know where/why the function failed (which is the main purpose of returning an error string in the first place).

    Thinking out loud without test it: Probably we could prevent this behavior by removing the empty constructor or by asserting that an error string cannot be empty.

    I think the silent conversion of bilingual_str into errors is an anti-feature. Not every translated string is necessarily an error string, and the conversion makes it not possible to use a BResult<bilingual_str> type that returns a normal translated string. #25665 improves this by adding an explicit error contructor

    You know, the initial version that did for the generic CallResult was actually implemented in that way. I was using an OperationResult<T, E> ErrorOut(string) helper function instead of the silent conversion.

    I have 25665 on my review list 👍🏼 . The last time that I checked it (brief check, thus why I haven’t commented yet), I wasn’t so sure about the internal std:.variant removal because every result was going to have the succeed object initialized AND the errors AND warnings in memory. And conceptually, a function can succeed OR fail. Not both.

    But.. will comment there soon :). Need to finish up few other reviews first. Been focused on the nice, and long, #24914 lately.


    theStack commented at 8:03 pm on July 21, 2022:
    Changed to return return Untranslated("Not supported"); for the sake of being consistent with other methods in the same class (GetNewDestination) right now, as suggested by furszy. The discussion here about general improvements to BResults seem to better fit to #25665, this PR is merely a refactor.
  5. in src/wallet/wallet.cpp:2443 in d7c37ed989 outdated
    2442+        if (op_address.HasRes()) {
    2443+            address = op_address.ReleaseObj();
    2444+        } else {
    2445+            return op_address.GetError();
    2446         }
    2447         fInternal = keypool.fInternal;
    


    furszy commented at 10:37 pm on July 20, 2022:

    What about this:

    0const auto& op_address = m_spk_man->GetReservedDestination(type, internal, nIndex, keypool);
    1if (!op_address) return op_address;
    2fInternal = keypool.fInternal;
    3address = op_address.ReleaseObj();
    

    theStack commented at 8:03 pm on July 21, 2022:
    Thanks, done.
  6. DrahtBot commented at 6:47 am on July 21, 2022: contributor

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

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #25616 (refactor: Return util::Result from WalletLoader methods by w0xlt)
    • #25526 (wallet: avoid double keypool TopUp() calls on descriptor wallets by furszy)
    • #25297 (wallet: speedup transactions sync, rescan and load by grouping all independent db writes on a single batched db transaction 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.

  7. theStack force-pushed on Jul 21, 2022
  8. theStack commented at 8:05 pm on July 21, 2022: contributor
    Force-pushed with changes as suggested by @furszy (https://github.com/bitcoin/bitcoin/pull/25656#discussion_r926102164, #25656 (review) (for consistency reasons), #25656 (review)).
  9. furszy approved
  10. furszy commented at 1:18 pm on July 22, 2022: member
    Code review ACK 224e1e1f
  11. DrahtBot added the label Needs rebase on Aug 5, 2022
  12. refactor: wallet: return util::Result from `GetReservedDestination` methods 76b3c37fcb
  13. theStack renamed this:
    refactor: wallet: return BResult from `GetReservedDestination` methods
    refactor: wallet: return util::Result from `GetReservedDestination` methods
    on Aug 5, 2022
  14. theStack force-pushed on Aug 5, 2022
  15. theStack commented at 3:21 pm on August 5, 2022: contributor
    Rebased on master, util::Result is used instead of BResult now accordingly. Also squashed the two commits into one as I think it’s easier to review.
  16. DrahtBot removed the label Needs rebase on Aug 5, 2022
  17. furszy approved
  18. furszy commented at 1:39 pm on August 8, 2022: member
    ACK 76b3c37f
  19. MarcoFalke merged this on Aug 10, 2022
  20. MarcoFalke closed this on Aug 10, 2022

  21. theStack deleted the branch on Aug 10, 2022
  22. jonatack commented at 3:57 pm on August 10, 2022: contributor
    Post-merge ACK
  23. sidhujag referenced this in commit e80a59057a on Aug 10, 2022
  24. bitcoin locked this on Aug 13, 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: 2024-12-22 12:12 UTC

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