wallet: Make rpc result structure independent of return value #17155

issue MarcoFalke openend this issue on October 15, 2019
  1. MarcoFalke commented at 7:16 pm on October 15, 2019: member

    I think that the RPC result structure (i.e. the potentially nested JSON types) should not depend on the return value, as this makes the deserialization from json to a language-specific struct harder.

    For example, gettransaction has a key "generated", that can never be false. It either exists (and is true) or does not exists (and is implicitly false).

    generated (and other fields in gettransaction) should be changed to always return the value.

  2. MarcoFalke added the label Wallet on Oct 15, 2019
  3. MarcoFalke added the label RPC/REST/ZMQ on Oct 15, 2019
  4. MarcoFalke added the label good first issue on Oct 15, 2019
  5. MarcoFalke added the label Hacktoberfest on Oct 15, 2019
  6. theStack commented at 8:03 pm on October 15, 2019: member

    Other fields in gettransaction not always present are e.g. blockhash, blockindex and blocktime – they only exist for confirmed transactions, for unconfirmed the trusted field is generated instead (snippet starts one line below yours about generated, by the way):

    https://github.com/bitcoin/bitcoin/blob/e180be49d7d802d05b1850924be97fe27d353ffe/src/wallet/rpcwallet.cpp#L135-L145

    So it doesn’t seem too trivial to solve this (what values should blockhash, blockindex and blocktime get for unconfirmed transactions?). Or is it enough for a first step to approach this just for boolean values?

  7. MarcoFalke commented at 8:33 pm on October 15, 2019: member

    what values should blockhash, blockindex and blocktime get for unconfirmed transactions?

    I think it is fine to solve it by mentioning it in the help text, which is missing right now.

  8. MarcoFalke commented at 8:36 pm on October 15, 2019: member
    Similarly, invovesWatchonly should probably not be included for non-watchonly wallets, but always be included for watchonly wallets. See also slightly related #16383 which changed the fallbacks for RPC inputs when the wallet is watchonly.
  9. theStack commented at 9:13 pm on October 15, 2019: member
    Okay it seems I got something wrong here – is it not the goal to have a fixed result structure, i.e. all fields are always present (basically meaning that there are no conditional .pushKV() calls anymore), to get rid of all “only present if….” fields?
  10. MarcoFalke commented at 10:09 pm on October 15, 2019: member
    You can set blockhash to a JSON-None value to keep the structure static. This will make the RPC response slightly larger, but is preferable I think.
  11. theStack commented at 10:48 pm on October 15, 2019: member

    You can set blockhash to a JSON-None value to keep the structure static. This will make the RPC response slightly larger, but is preferable I think.

    That would make sense. That “JSON-None value” can be created with the empty constructur of UniValue UniValue(), leading to null, as I just found out (as information for anyone wanting to work on this, I’m not sure if I will have time before end of the month).

    What confused me was this part:

    Similarly, invovesWatchonly should probably not be included for non-watchonly wallets, but always be included for watchonly wallets.

    Shouldn’t this field involvesWatchonly also always be generated? Right now it is only add to the response if it is true.

  12. practicalswift commented at 8:51 am on October 16, 2019: contributor
    Concept ACK: making the structure independent of return value makes the life easier for our users and the cost of doing so is essentially zero
  13. nijynot commented at 8:54 am on October 16, 2019: contributor
    I can take a look at this, seems like a good first issue.
  14. laanwj commented at 1:49 pm on October 16, 2019: member
    Concept ACK in general. I can think of only one place where it makes a considerable difference in structure size, and leaving out zero fields was intentional: for the message type statistics in getpeerinfo.
  15. promag commented at 8:41 am on October 17, 2019: member

    I think response schemas dependent of the actual result are fine. Missing keys and null values are things that any JSON RPC client must handle. So it should be fine especially if the result is well documented (and tested).

    But I also don’t mind otherwise. My concern is that we can’t go thru all RPC and make this change lightly - clients are expecting missing keys and we should avoid breaking changes. So we will end up with a non-consistent API anyway. For this reason I also don’t think this is a good first issue.

  16. fjahr commented at 1:24 pm on October 17, 2019: member

    Concept ACK

    I fully agree that static response structures make the lives of people developing against the RPC easier. While responses may be heavier we can overall probably reduce the number of LoC and making this a general rule prevents future discussions whether certain RPC return values could be made conditional, which mostly seems like a waste of energy IMO.

  17. MarcoFalke removed the label Hacktoberfest on Oct 17, 2019
  18. MarcoFalke removed the label good first issue on Oct 17, 2019
  19. ryanofsky commented at 2:43 pm on October 17, 2019: member

    I fully agree that static response structures make the lives of people developing against the RPC easier.

    I think the key advantage of static structures is reduced ambiguity. If field is set conditionally and absent, it’s ambiguous whether the field has no value, or the backend just doesn’t support returning it. It can make it harder than it needs to be write an RPC client that isn’t tied to specific bitcoind version.

  20. MarcoFalke commented at 3:01 pm on October 17, 2019: member

    clients are expecting missing keys and we should avoid breaking changes. So we will end up with a non-consistent API anyway. For this reason I also don’t think this is a good first issue.

    Good point @promag . Removed “good first issue” for now.

  21. MarcoFalke commented at 3:05 pm on October 17, 2019: member
    Also good point by @ryanofsky . A living example for that is #15077 (comment)
  22. sipa commented at 4:10 pm on October 17, 2019: member

    My view is that well-documented cases where values are conditionally present based on other fields are fine (e.g. getaddressinfo only contains the sub-structure that recurses into p2sh when it also indicates you have a p2sh address). That avoids the issue @ryanofsky brings up above where you don’t know if something is not present because the software doesn’t support it, or because it is intended to be missing.

    In other words: I think it would be ideal that fields being missing or not itself should never be used to convey information. But that does not mean that all responses should be completely static.

  23. promag commented at 1:24 am on May 6, 2020: member
    @MarcoFalke and what would be decoded value in gettransaction verbose=false result?
  24. MarcoFalke closed this on May 6, 2020

  25. DrahtBot locked this on Feb 15, 2022

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-07-06 01:12 UTC

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