rest: clean-up for `mempool` endpoints #25760

pull brunoerg wants to merge 1 commits into bitcoin:master from brunoerg:2022-07-rest-improvements changing 1 files +13 −28
  1. brunoerg commented at 12:00 PM on July 31, 2022: contributor

    The functions rest_mempool_info and rest_mempool_contents are similar, the only difference between them is: rest_mempool_info uses MempoolInfoToJSON to get the mempool informations and rest_mempool_contents uses MempoolToJSON, for this reason this PR creates a new function to handle it and reduce duplicated code.

    Also,

    1. Rename strURIPart to str_uri_part.
    2. Rename strJSON to str_json.
  2. fanquake added the label RPC/REST/ZMQ on Jul 31, 2022
  3. stickies-v commented at 2:00 PM on July 31, 2022: contributor

    Concept ACK 029fad6

    Alternatively, you could also only register /rest/mempool/ and inspect the str_uri_part? I think this would allow for slightly more code reduction.

  4. DrahtBot commented at 7:45 PM on July 31, 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:

    • #25756 (rest: Remove support for a number of -deprecatedrest options by stickies-v)
    • #25755 (rest: Use from_blockhash and txdetails query parameters by stickies-v)
    • #25754 (rest: Extend HTTPRequest interface to support querying path (parameters) by stickies-v)
    • #25753 (rest: Move format string from path-like parameter to query parameter by stickies-v)
    • #25412 (rest: add /deploymentinfo endpoint by brunoerg)
    • #21422 (Add feerate histogram to getmempoolinfo by kiminuo)

    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.

  5. brunoerg marked this as ready for review on Aug 1, 2022
  6. brunoerg commented at 9:01 PM on August 2, 2022: contributor

    Alternatively, you could also only register /rest/mempool/ and inspect the str_uri_part? I think this would allow for slightly more code reduction.

    Nice, I had thought about it, but I think str_uri_part wouldn't get me the whole URI but only (in this case) the format, like: '.json'. Am I missing something?

  7. stickies-v commented at 9:22 PM on August 2, 2022: contributor

    http_request_cb passes everything after the endpoint prefix to str_uri_part. If you register the endpoints with prefix /rest/mempool/<info|content>, then indeed only .json would get passed to str_uri_part. If however you just register /rest/mempool/, then everything after that i.e. <info|content>.json would get passed. (plug: #25754 is trying to clean up this interface)

    I don't think the current approach of registering both separately is unreasonable, so this is just a suggestion if you think that implementation makes sense - intuitively it would be my first approach.

  8. brunoerg force-pushed on Aug 3, 2022
  9. brunoerg commented at 12:36 AM on August 3, 2022: contributor

    Nice, @stickies-v. Force-pushed addressing your suggestion.

    It is clearer having only /rest/mempool/, and then check the str_uri_part.

  10. in src/rest.cpp:607 in 001b45fc5e outdated
     628 |      case RESTResponseFormat::JSON: {
     629 | -        UniValue mempoolObject = MempoolToJSON(*mempool, true);
     630 | +        std::string str_json;
     631 | +        if (str_uri_part == "contents.json") {
     632 | +            str_json = MempoolToJSON(*mempool, true).write() + "\n";
     633 | +        } else if (str_uri_part == "info.json") {
    


    stickies-v commented at 10:51 AM on August 3, 2022:

    I'd use param instead of str_uri_part directly because it already has the format string and any query parameters stripped from it, that makes it a bit more resilient.


    brunoerg commented at 6:20 PM on August 3, 2022:

    Done

  11. in src/rest.cpp:614 in 001b45fc5e outdated
     632 | +            str_json = MempoolToJSON(*mempool, true).write() + "\n";
     633 | +        } else if (str_uri_part == "info.json") {
     634 | +            str_json = MempoolInfoToJSON(*mempool).write() + "\n";
     635 | +        } else {
     636 | +            return RESTERR(req, HTTP_BAD_REQUEST, "Error: invalid URI format");
     637 | +        }
    


    stickies-v commented at 10:56 AM on August 3, 2022:

    Ideally this check is done earlier in the code, if an invalid path is provided we shouldn't even be getting the mempool etc first. It also makes bad calls more clear, if you e.g. call GET /rest/mempool/doesntexist you'd get "output format not found (available: json)" as response, whereas "Error: invalid URI format. Expected /rest/mempool/<info|contents>.json" would be more helpful.


    brunoerg commented at 4:07 PM on August 3, 2022:

    Nice, I agree.

  12. stickies-v commented at 11:04 AM on August 3, 2022: contributor

    Nice! I've left a few more suggestions in comments, but I think that's pretty much it from me.

    <details> <summary>Couldn't make suggested code, so here's the diff instead:</summary>

    diff --git a/src/rest.cpp b/src/rest.cpp
    index dd6fe8d8e..3f2ab98a8 100644
    --- a/src/rest.cpp
    +++ b/src/rest.cpp
    @@ -594,20 +594,23 @@ static bool rest_mempool(const std::any& context, HTTPRequest* req, const std::s
     {
         if (!CheckWarmup(req))
             return false;
    -    const CTxMemPool* mempool = GetMemPool(context, req);
    -    if (!mempool) return false;
    +
         std::string param;
         const RESTResponseFormat rf = ParseDataFormat(param, str_uri_part);
    +    if (param != "contents" && param != "info") {
    +        return RESTERR(req, HTTP_BAD_REQUEST, "Error: invalid URI format. Expected /rest/mempool/<info|contents>.json");
    +    }
    +
    +    const CTxMemPool* mempool = GetMemPool(context, req);
    +    if (!mempool) return false;
     
         switch (rf) {
         case RESTResponseFormat::JSON: {
             std::string str_json;
    -        if (str_uri_part == "contents.json") {
    +        if (param == "contents") {
                 str_json = MempoolToJSON(*mempool, true).write() + "\n";
    -        } else if (str_uri_part == "info.json") {
    -            str_json = MempoolInfoToJSON(*mempool).write() + "\n";
             } else {
    -            return RESTERR(req, HTTP_BAD_REQUEST, "Error: invalid URI format");
    +            str_json = MempoolInfoToJSON(*mempool).write() + "\n";
             }
     
             req->WriteHeader("Content-Type", "application/json");
    

    </details>

  13. brunoerg force-pushed on Aug 3, 2022
  14. brunoerg commented at 6:22 PM on August 3, 2022: contributor

    Thanks, @stickies-v for your review! Force-pushed addressing the latest suggestions.

  15. in src/rest.cpp:601 in da0c612c3d outdated
     613 | -        return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: json)");
     614 | -    }
     615 | +    std::string param;
     616 | +    const RESTResponseFormat rf = ParseDataFormat(param, str_uri_part);
     617 | +    if (param != "contents" && param != "info") {
     618 | +        return RESTERR(req, HTTP_BAD_REQUEST, "Error: invalid URI format. Expected /rest/mempool/<info|contents>.json");
    


    stickies-v commented at 6:30 PM on August 3, 2022:

    nit: We already have 3 other instances of this where we don't prefix with "Error:", so maybe best to keep it consistent.

            return RESTERR(req, HTTP_BAD_REQUEST, "Invalid URI format. Expected /rest/mempool/<info|contents>.json");
    

    brunoerg commented at 7:04 PM on August 3, 2022:

    Interesting, there are some places where "Error:" seems to be used. Gonna check it.


    stickies-v commented at 7:06 PM on August 3, 2022:

    Yeah there is, just not for the "Invalid URI format" ones.


    brunoerg commented at 1:23 PM on August 5, 2022:

    Done!

  16. stickies-v approved
  17. stickies-v commented at 6:47 PM on August 3, 2022: contributor

    ACK da0c612c3d69164da19332167c38bfcd1f9777a8 - nice work on removing all the duplicate code!

    Just 1 nit that I didn't see earlier, sorry.

  18. theStack approved
  19. theStack commented at 1:06 PM on August 5, 2022: contributor

    Nice deduplication! 👌

    Code-review ACK da0c612c3d69164da19332167c38bfcd1f9777a8

    Happy to also re-ACK if you decide to take stickies' nit about removing the 'Error' prefix.

  20. rest: clean-up for `mempool` endpoints acbea66589
  21. brunoerg force-pushed on Aug 5, 2022
  22. brunoerg commented at 1:29 PM on August 5, 2022: contributor

    Force-pushed removing the Error: prefix. Thanks, @stickies-v.

  23. stickies-v approved
  24. stickies-v commented at 1:30 PM on August 5, 2022: contributor

    re-ACK acbea66589100fe6ef726f4b2a92ec26132ef17b - verified that just the error message was updated since https://github.com/bitcoin/bitcoin/commit/da0c612c3d69164da19332167c38bfcd1f9777a8

  25. theStack approved
  26. theStack commented at 1:32 PM on August 5, 2022: contributor

    re-ACK acbea66589100fe6ef726f4b2a92ec26132ef17b

  27. in src/rest.cpp:614 in acbea66589
     633 | +        std::string str_json;
     634 | +        if (param == "contents") {
     635 | +            str_json = MempoolToJSON(*mempool, true).write() + "\n";
     636 | +        } else {
     637 | +            str_json = MempoolInfoToJSON(*mempool).write() + "\n";
     638 | +        }
    


    jonatack commented at 1:47 PM on August 5, 2022:

    Maybe reduce temporaries and reassignments here.

         case RESTResponseFormat::JSON: {
    -        std::string str_json;
    -        if (param == "contents") {
    -            str_json = MempoolToJSON(*mempool, true).write() + "\n";
    -        } else {
    -            str_json = MempoolInfoToJSON(*mempool).write() + "\n";
    -        }
    -
             req->WriteHeader("Content-Type", "application/json");
    -        req->WriteReply(HTTP_OK, str_json);
    +        req->WriteReply(HTTP_OK, (param == "contents" ? MempoolToJSON(*mempool, /*verbose=*/true) : MempoolInfoToJSON(*mempool)).write() + "\n");
             return true;
    

    MarcoFalke commented at 2:06 PM on August 5, 2022:

    It could make sense to avoid std::string copies in WriteReply, but maybe for a follow-up?

    edit: I guess that's not possible, as libevent only accepts a (read-only) span, not the memory directly

  28. jonatack commented at 1:47 PM on August 5, 2022: contributor

    Concept ACK

  29. MarcoFalke merged this on Aug 5, 2022
  30. MarcoFalke closed this on Aug 5, 2022

  31. sidhujag referenced this in commit f181013438 on Aug 5, 2022
  32. bitcoin locked this on Aug 23, 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-04-13 15:13 UTC

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