rest: add `/deploymentinfo` endpoint #25412

pull brunoerg wants to merge 4 commits into bitcoin:master from brunoerg:2022-06-rest-deploymentinfo changing 5 files +70 −1
  1. brunoerg commented at 7:51 PM on June 18, 2022: contributor

    #23508 added a new RPC named getdeploymentinfo, it moved the softfork section from getblockchaininfo into this new one. In the REST interface, we have an endpoint named/rest/chaininfo.json (which refers to getblockchaininfo), so, this PR adds a new REST endpoint named /deploymentinfo which refers to getdeploymentinfo.

    You can use it by passing a block hash, e.g: '/rest/deploymentinfo/<BLOCKHASH>.json' or you can use it without passing a block hash to get the 'deploymentinfo' for the last block.

  2. brunoerg force-pushed on Jun 18, 2022
  3. brunoerg force-pushed on Jun 18, 2022
  4. DrahtBot added the label RPC/REST/ZMQ on Jun 18, 2022
  5. in src/rest.cpp:980 in 5d71170c3d outdated
    1000 | @@ -950,6 +1001,7 @@ static const struct {
    1001 |        {"/rest/mempool/contents", rest_mempool_contents},
    1002 |        {"/rest/headers/", rest_headers},
    1003 |        {"/rest/getutxos", rest_getutxos},
    1004 | +      {"/rest/deploymentinfo/", rest_deploymentinfo},
    


    luke-jr commented at 10:47 PM on June 18, 2022:

    This doesn't work with /rest/deploymentinfo.json

    --- a/test/functional/interface_rest.py
    +++ b/test/functional/interface_rest.py
    @@ -380,8 +380,10 @@ class RESTTest (BitcoinTestFramework):
     
             self.log.info("Test the /deploymentinfo URI")
             json_obj = self.test_rest_request(f'/deploymentinfo/{newblockhash[0]}')
    +        assert_equal(json_obj, self.test_rest_request(f'/deploymentinfo'))
             deployment_info = self.nodes[0].getdeploymentinfo(newblockhash[0])
             assert_equal(deployment_info, json_obj)
    +        assert(deployment_info != self.test_rest_request(f'/deploymentinfo/{bb_hash}'))
     
             json_obj = self.test_rest_request('/deploymentinfo/')
             deployment_info = self.nodes[0].getdeploymentinfo()
    

    brunoerg commented at 11:46 AM on June 19, 2022:

    Just noticed that newblockhash[0] and bb_hash are the same, so the assertion: assert(deployment_info != self.test_rest_request(f'/deploymentinfo/{bb_hash}')) would fail.


    brunoerg commented at 11:50 AM on June 19, 2022:

    Fixed /rest/deploymentinfo.json


    luke-jr commented at 2:39 PM on June 19, 2022:

    bb_hash is set to the best block, before newblockhash[0] is mined...


    brunoerg commented at 6:25 PM on June 19, 2022:

    Before?

    newblockhash = self.generate(self.nodes[1], 1) -> L348 bb_hash = self.nodes[0].getbestblockhash() -> L372

  6. in src/rest.cpp:598 in 5d71170c3d outdated
     589 | @@ -590,6 +590,57 @@ static bool rest_chaininfo(const std::any& context, HTTPRequest* req, const std:
     590 |      }
     591 |  }
     592 |  
     593 | +RPCHelpMan getdeploymentinfo();
     594 | +
     595 | +static bool rest_deploymentinfo(const std::any& context, HTTPRequest* req, const std::string& strURIPart)
     596 | +{
     597 | +    if (!CheckWarmup(req))
     598 | +        return false;
    


    luke-jr commented at 10:49 PM on June 18, 2022:
        if (!CheckWarmup(req)) return false;
    
  7. in src/rest.cpp:611 in 5d71170c3d outdated
     606 | +        jsonRequest.context = context;
     607 | +
     608 | +        if (!hashStr.empty()) {
     609 | +            uint256 hash;
     610 | +            if (!ParseHashStr(hashStr, hash))
     611 | +                return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
    


    luke-jr commented at 10:50 PM on June 18, 2022:
                if (!ParseHashStr(hashStr, hash)) {
                    return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
                }
    
  8. in src/rest.cpp:622 in 5d71170c3d outdated
     617 | +            ChainstateManager& chainman = *maybe_chainman;
     618 | +            const CBlockIndex* blockindex = chainman.m_blockman.LookupBlockIndex(hash_bi);
     619 | +            if (!blockindex) {
     620 | +                return RESTERR(req, HTTP_BAD_REQUEST, "Block not found");
     621 | +            }
     622 | +            
    


    luke-jr commented at 10:50 PM on June 18, 2022:
    
    
  9. in src/rest.cpp:625 in 5d71170c3d outdated
     620 | +                return RESTERR(req, HTTP_BAD_REQUEST, "Block not found");
     621 | +            }
     622 | +            
     623 | +            UniValue block_hash(UniValue::VOBJ);
     624 | +            block_hash.pushKV("blockhash", hashStr);
     625 | +        
    


    luke-jr commented at 10:50 PM on June 18, 2022:
    
    
  10. in src/rest.cpp:628 in 5d71170c3d outdated
     623 | +            UniValue block_hash(UniValue::VOBJ);
     624 | +            block_hash.pushKV("blockhash", hashStr);
     625 | +        
     626 | +            jsonRequest.params = block_hash;
     627 | +        } else {
     628 | +            jsonRequest.params = UniValue(UniValue::VARR);
    


    luke-jr commented at 10:51 PM on June 18, 2022:

    Could move this up after jsonRequest.context = context;, and just pushKV directly


    brunoerg commented at 11:38 AM on June 19, 2022:

    Nice, thanks!

  11. in src/rest.cpp:630 in 5d71170c3d outdated
     625 | +        
     626 | +            jsonRequest.params = block_hash;
     627 | +        } else {
     628 | +            jsonRequest.params = UniValue(UniValue::VARR);
     629 | +        }
     630 | +        
    


    luke-jr commented at 10:51 PM on June 18, 2022:
    
    
  12. in src/rest.cpp:641 in 5d71170c3d outdated
     636 | +    }
     637 | +    default: {
     638 | +        return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: json)");
     639 | +    }
     640 | +    }
     641 | +    
    


    luke-jr commented at 10:51 PM on June 18, 2022:
  13. luke-jr changes_requested
  14. brunoerg force-pushed on Jun 19, 2022
  15. brunoerg commented at 11:53 AM on June 19, 2022: contributor

    Force-pushed addressing @luke-jr`s review

  16. in doc/REST-interface.md:89 in c7c4fa2145 outdated
      83 | @@ -84,6 +84,12 @@ Returns various state info regarding block chain processing.
      84 |  Only supports JSON as output format.
      85 |  Refer to the `getblockchaininfo` RPC help for details.
      86 |  
      87 | +#### Deployment info
      88 | +`GET /rest/deploymentinfo/<BLOCKHASH>.json`
    


    w0xlt commented at 1:37 PM on June 19, 2022:

    Maybe it's better to specify that the <BLOCKHASH> parameter is optional and rest/deploymentinfo.json will use the hash of current chain tip.


    brunoerg commented at 6:22 PM on June 19, 2022:

    Nice!

  17. w0xlt approved
  18. in src/rpc/blockchain.cpp:1310 in c7c4fa2145 outdated
    1291 | @@ -1292,7 +1292,7 @@ UniValue DeploymentInfo(const CBlockIndex* blockindex, const ChainstateManager&
    1292 |  }
    1293 |  } // anon namespace
    1294 |  
    1295 | -static RPCHelpMan getdeploymentinfo()
    


    Riahiamirreza commented at 6:16 PM on June 19, 2022:

    Why the RPCHelpMan is not static anymore?


    brunoerg commented at 6:21 PM on June 19, 2022:

    @Riahiamirreza To be able to use it in src/rest.cpp, see getblockchaininfo.

  19. in src/rest.cpp:981 in c7c4fa2145 outdated
     997 | @@ -950,6 +998,8 @@ static const struct {
     998 |        {"/rest/mempool/contents", rest_mempool_contents},
     999 |        {"/rest/headers/", rest_headers},
    1000 |        {"/rest/getutxos", rest_getutxos},
    1001 | +      {"/rest/deploymentinfo/", rest_deploymentinfo},
    1002 | +      {"/rest/deploymentinfo", rest_deploymentinfo},
    


    Riahiamirreza commented at 6:25 PM on June 19, 2022:

    Why this api supports both /rest/deploymentinfo and /rest/deploymentinfo/ while others not. Is this a good idea to add the both to other apis?


    brunoerg commented at 6:33 PM on June 19, 2022:

    This API supports both because getdeploymentinfo can be used by passing or not passing a block hash. So, you can use: /rest/deploymentinfo/BLOCKHASH.json or /rest/deploymentinfo.json if you want to get the information from the current chain tip.

    For other endpoints, passing a BLOCKHASH or a TXID is a must which is not this case.


    stickies-v commented at 4:25 PM on July 22, 2022:

    I would like to reopen this comment. Even though a few other endpoints do the same thing, I think it is bad practice and I would not add the /rest/deploymentinfo endpoint in addition to the regular /rest/deploymentinfo/

    If you want to access the endpoint without providing a blockhash, you can do so already with GET /rest/deploymentinfo/.json. It looks a bit ugly maybe, but that's because the format parameter should be a query parameter in the first place to properly resolve this (which I'll be proposing in a new issue/PR very soon). In the current implementation, people would be able to call GET /rest/deploymentinfoa.json and get Invalid hash: a as response, which is highly intuitive imo and not the API spec.


    brunoerg commented at 11:39 AM on July 23, 2022:

    +0 on this. I don't think it would be a bad practice, in a user perspective I'd prefer: /rest/deploymentinfo.json to get all and /rest/deploymentinfo/<BLOCKHASH>.json to get a specific one. I don't feel myself (as a final user) confortable with /rest/deploymentinfo/.json.

    I agree 100000% with you the format parameter should be a query one, and if you're working on this, maybe we can keep it this way and change it after your PR?


    stickies-v commented at 11:56 AM on July 23, 2022:

    If no one else thinks this is an issue I'm okay to proceed with it, but having something like GET /rest/deploymentinfoa.json resolve to a blockhash of a does not sit well with me. Either way, it doesn't impact the upgrade path with query params I have in mind so from that end I'm not too bothered.

  20. brunoerg force-pushed on Jun 19, 2022
  21. brunoerg commented at 6:30 PM on June 19, 2022: contributor

    Force-pushed addressing @w0xlt's review for documentation.

  22. Riahiamirreza approved
  23. w0xlt approved
  24. DrahtBot commented at 12:09 AM on June 21, 2022: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

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

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    No conflicts as of last run.

  25. in test/functional/interface_rest.py:407 in 06fcbb93f1 outdated
     385 | +        assert_equal(deployment_info, json_obj)
     386 | +
     387 | +        json_obj = self.test_rest_request(f'/deploymentinfo/{newblockhash[0]}')
     388 | +        assert_equal(json_obj, deployment_info)
     389 | +        deployment_info_newblockhash = self.nodes[0].getdeploymentinfo(newblockhash[0])
     390 | +        assert_equal(deployment_info_newblockhash, json_obj)
    


    jonatack commented at 8:24 AM on July 6, 2022:

    suggestions: consistent assert args order, remove unneeded temporary, and define localvar with largest scope first

    @@ -379,13 +379,12 @@ class RESTTest (BitcoinTestFramework):
             assert_equal(blockchain_info, json_obj)
     
             self.log.info("Test the /deploymentinfo URI")
    -
    -        json_obj = self.test_rest_request('/deploymentinfo')
             deployment_info = self.nodes[0].getdeploymentinfo()
    -        assert_equal(deployment_info, json_obj)
    +        assert_equal(deployment_info, self.test_rest_request('/deploymentinfo'))
     
             json_obj = self.test_rest_request(f'/deploymentinfo/{newblockhash[0]}')
    -        assert_equal(json_obj, deployment_info)
    +        assert_equal(deployment_info, json_obj)
    +
             deployment_info_newblockhash = self.nodes[0].getdeploymentinfo(newblockhash[0])
             assert_equal(deployment_info_newblockhash, json_obj)
    

    brunoerg commented at 9:14 PM on July 7, 2022:

    done!

  26. in src/rest.cpp:614 in 06fcbb93f1 outdated
     609 | +            uint256 hash;
     610 | +            if (!ParseHashStr(hashStr, hash)) {
     611 | +                return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
     612 | +            }
     613 | +
     614 | +            LOCK(cs_main);
    


    jonatack commented at 8:26 AM on July 6, 2022:

    I think you can reduce the lock scope to only this line:

    -            const CBlockIndex* blockindex = chainman.m_blockman.LookupBlockIndex(hash_bi);
    +            const CBlockIndex* blockindex{WITH_LOCK(::cs_main, return chainman.m_blockman.LookupBlockIndex(hash_bi))};
    

    (also prefer an absolute reference ::cs_main for new code)


    brunoerg commented at 9:05 PM on July 7, 2022:

    Cool, thanks!

  27. in doc/REST-interface.md:90 in 06fcbb93f1 outdated
      83 | @@ -84,6 +84,13 @@ Returns various state info regarding block chain processing.
      84 |  Only supports JSON as output format.
      85 |  Refer to the `getblockchaininfo` RPC help for details.
      86 |  
      87 | +#### Deployment info
      88 | +`GET /rest/deploymentinfo/<BLOCKHASH>.json`
      89 | +Returns an object containing various state info regarding deployments of consensus changes.
      90 | +BLOCKHASH parameter is optional and `/rest/deploymentinfo.json` will use the hash of current chain tip.
    


    jonatack commented at 8:43 AM on July 6, 2022:

    ideas

     #### Deployment info
    +`GET /rest/deploymentinfo.json`
     `GET /rest/deploymentinfo/<BLOCKHASH>.json`
    -Returns an object containing various state info regarding deployments of consensus changes.
    -BLOCKHASH parameter is optional and `/rest/deploymentinfo.json` will use the hash of current chain tip.
    +Returns an object containing various state info regarding deployments of
    +consensus changes at the current chain tip, or at <BLOCKHASH> if provided.
     Only supports JSON as output format.
     Refer to the `getdeploymentinfo` RPC help for details.
    

    brunoerg commented at 2:02 PM on July 7, 2022:

    Great idea!

  28. in src/rest.cpp:619 in 06fcbb93f1 outdated
     617 | +            if (!maybe_chainman) return false;
     618 | +            ChainstateManager& chainman = *maybe_chainman;
     619 | +            const CBlockIndex* blockindex = chainman.m_blockman.LookupBlockIndex(hash_bi);
     620 | +            if (!blockindex) {
     621 | +                return RESTERR(req, HTTP_BAD_REQUEST, "Block not found");
     622 | +            }
    


    jonatack commented at 9:12 AM on July 6, 2022:

    It looks like this section can be simplified/shortened by removing 3 unneeded temporaries (and reducing the lock scope as mentioned above)

    @@ -610,23 +610,17 @@ static bool rest_deploymentinfo(const std::any& context, HTTPRequest* req, const
                 if (!ParseHashStr(hashStr, hash)) {
                     return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
                 }
    -
    -            LOCK(cs_main);
    -            const uint256 hash_bi(ParseHashV(hashStr, "blockhash"));
    -            ChainstateManager* maybe_chainman = GetChainman(context, req);
    -            if (!maybe_chainman) return false;
    -            ChainstateManager& chainman = *maybe_chainman;
    -            const CBlockIndex* blockindex = chainman.m_blockman.LookupBlockIndex(hash_bi);
    -            if (!blockindex) {
    +            const ChainstateManager* chainman = GetChainman(context, req);
    +            if (!chainman) return false;
    +            if (!WITH_LOCK(::cs_main, return chainman->m_blockman.LookupBlockIndex(ParseHashV(hashStr, "blockhash")))) {
                     return RESTERR(req, HTTP_BAD_REQUEST, "Block not found");
                 }
    -
    -
                 jsonRequest.params.pushKV("blockhash", hashStr);
             }
    

    brunoerg commented at 8:10 PM on July 6, 2022:

    Very nice! Gonna change it!

  29. in src/rest.cpp:628 in 06fcbb93f1 outdated
     623 | +
     624 | +
     625 | +            jsonRequest.params.pushKV("blockhash", hashStr);
     626 | +        }
     627 | +
     628 | +        UniValue deploymentInfoObject = getdeploymentinfo().HandleRequest(jsonRequest);
    


    jonatack commented at 9:15 AM on July 6, 2022:

    hashStr, deploymentInfoObject, strJSON -> could use current naming style for these new localvars (the latter two could also be const)


    brunoerg commented at 8:09 PM on July 6, 2022:

    Interesting.. just had tried to keep same names from other methods, I am gonna change it, thanks!


    jonatack commented at 9:45 AM on July 9, 2022:

    Thanks for updating. Would suggest hashStr -> hash_str (and str_json -> json_str for consistency).

    Edit: can just drop str_json, see #25412 (review).

  30. jonatack commented at 9:18 AM on July 6, 2022: contributor

    Tested concept/approach ACK. I think the first commit removing static ought to be in the second commit, "rest: add `/deploymentinfo", as it is the only reason for removing it. Edit: does this need a release note?

  31. brunoerg force-pushed on Jul 7, 2022
  32. brunoerg commented at 9:15 PM on July 7, 2022: contributor

    Force-pushed addressing @jonatack's review and adding release note.

    Thanks.

  33. brunoerg requested review from jonatack on Jul 8, 2022
  34. in doc/REST-interface.md:93 in 0be3019256 outdated
      83 | @@ -84,6 +84,13 @@ Returns various state info regarding block chain processing.
      84 |  Only supports JSON as output format.
      85 |  Refer to the `getblockchaininfo` RPC help for details.
      86 |  
      87 | +#### Deployment info
      88 | +`GET /rest/deploymentinfo/<BLOCKHASH>.json`
      89 | +Returns an object containing various state info regarding deployments of
      90 | +consensus changes at the current chain tip, or at <BLOCKHASH> if provided.
      91 | +Only supports JSON as output format.
    


    jonatack commented at 9:41 AM on July 9, 2022:

    Is there a reason not to support the hex and bin formats, which most of the other endpoints support?

  35. in doc/REST-interface.md:89 in 0be3019256 outdated
      83 | @@ -84,6 +84,13 @@ Returns various state info regarding block chain processing.
      84 |  Only supports JSON as output format.
      85 |  Refer to the `getblockchaininfo` RPC help for details.
      86 |  
      87 | +#### Deployment info
      88 | +`GET /rest/deploymentinfo/<BLOCKHASH>.json`
    


    jonatack commented at 9:42 AM on July 9, 2022:

    It may be clearer to indicate both endpoints.

     #### Deployment info
    +`GET /rest/deploymentinfo.json`
     `GET /rest/deploymentinfo/<BLOCKHASH>.json`
    
  36. in doc/release-notes-25412.md:1 in 0be3019256 outdated
       0 | @@ -0,0 +1,8 @@
       1 | +Notable changes
    


    jonatack commented at 9:47 AM on July 9, 2022:

    Probably not a "notable change" (maybe the person merging the release notes will edit that, unsure).


    brunoerg commented at 5:19 PM on July 11, 2022:

    Done! and merged the first two commits!

  37. jonatack commented at 9:47 AM on July 9, 2022: contributor

    Would merge the first two commits. A few other comments.

  38. in src/rest.cpp:617 in 0be3019256 outdated
     612 | +            }
     613 | +
     614 | +            const uint256 hash_bi{ParseHashV(hashStr, "blockhash")};
     615 | +            const ChainstateManager* chainman = GetChainman(context, req);
     616 | +            if (!chainman) return false;
     617 | +            if (!WITH_LOCK(::cs_main, return chainman->m_blockman.LookupBlockIndex(hash_bi))) {
    


    jonatack commented at 9:51 AM on July 9, 2022:

    hash_bi is an unnecessary temporary (if you want to keep it, would just name it hash)

    -            const uint256 hash_bi{ParseHashV(hashStr, "blockhash")};
                 const ChainstateManager* chainman = GetChainman(context, req);
                 if (!chainman) return false;
    -            if (!WITH_LOCK(::cs_main, return chainman->m_blockman.LookupBlockIndex(hash_bi))) {
    +            if (!WITH_LOCK(::cs_main, return chainman->m_blockman.LookupBlockIndex(ParseHashV(hashStr, "blockhash")))) {
                     return RESTERR(req, HTTP_BAD_REQUEST, "Block not found");
                 }
    

    brunoerg commented at 5:20 PM on July 11, 2022:

    Addressed it because makes the code cleaner. nice one!

  39. in src/rest.cpp:626 in 0be3019256 outdated
     624 | +
     625 | +        const UniValue deployment_info_object = getdeploymentinfo().HandleRequest(jsonRequest);
     626 | +        const std::string str_json = deployment_info_object.write() + "\n";
     627 | +        req->WriteHeader("Content-Type", "application/json");
     628 | +        req->WriteReply(HTTP_OK, str_json);
     629 | +        return true;
    


    jonatack commented at 9:57 AM on July 9, 2022:

    Looks like this section could be simplified further by dropping two temporaries that add allocations and move operations, are each used only once and don't seem to make the code clearer.

    -        const UniValue deployment_info_object = getdeploymentinfo().HandleRequest(jsonRequest);
    -        const std::string str_json = deployment_info_object.write() + "\n";
             req->WriteHeader("Content-Type", "application/json");
    -        req->WriteReply(HTTP_OK, str_json);
    +        req->WriteReply(HTTP_OK, getdeploymentinfo().HandleRequest(jsonRequest).write() + "\n");
             return true;
    

    brunoerg commented at 5:21 PM on July 11, 2022:

    Nice! Done!

  40. brunoerg force-pushed on Jul 11, 2022
  41. brunoerg commented at 5:21 PM on July 11, 2022: contributor

    Force-pushed addressing @jonatack's review! Thanks for it!

  42. jonatack commented at 12:17 PM on July 14, 2022: contributor

    ACK with the following suggestions

    <details><summary>test improvements</summary><p>

    diff --git a/test/functional/interface_rest.py b/test/functional/interface_rest.py
    index 096794e1e1..1f3cc5f7ba 100755
    --- a/test/functional/interface_rest.py
    +++ b/test/functional/interface_rest.py
    @@ -378,22 +378,33 @@ class RESTTest (BitcoinTestFramework):
             blockchain_info = self.nodes[0].getblockchaininfo()
             assert_equal(blockchain_info, json_obj)
     
    +        # Test compatibility of deprecated and newer endpoints
    +        self.log.info("Test compatibility of deprecated and newer endpoints")
    +        assert_equal(self.test_rest_request(f"/headers/{bb_hash}", query_params={"count": 1}), self.test_rest_request(f"/headers/1/{bb_hash}"))
    +        assert_equal(self.test_rest_request(f"/blockfilterheaders/basic/{bb_hash}", query_params={"count": 1}), self.test_rest_request(f"/blockfilterheaders/basic/5/{bb_hash}"))
    +
             self.log.info("Test the /deploymentinfo URI")
     
             deployment_info = self.nodes[0].getdeploymentinfo()
             assert_equal(deployment_info, self.test_rest_request('/deploymentinfo'))
     
    +        non_existing_blockhash = '42759cde25462784395a337460bde75f58e73d3f08bd31fdc3507cbac856a2c4'
    +        resp = self.test_rest_request(f'/deploymentinfo/{non_existing_blockhash}', ret_type=RetType.OBJ, status=400)
    +        assert_equal(resp.read().decode('utf-8').rstrip(), "Block not found")
    +
    +        resp = self.test_rest_request(f"/deploymentinfo/{INVALID_PARAM}", ret_type=RetType.OBJ, status=400)
    +        assert_equal(resp.read().decode('utf-8').rstrip(), f"Invalid hash: {INVALID_PARAM}")
    +
    +        newblockhash = self.generate(self.nodes[1], 1)
             json_obj = self.test_rest_request(f'/deploymentinfo/{newblockhash[0]}')
    +        assert(deployment_info != json_obj)
    +
    +        deployment_info = self.nodes[0].getdeploymentinfo()
             assert_equal(deployment_info, json_obj)
     
             deployment_info_newblockhash = self.nodes[0].getdeploymentinfo(newblockhash[0])
             assert_equal(deployment_info_newblockhash, json_obj)
     
    -        # Test compatibility of deprecated and newer endpoints
    -        self.log.info("Test compatibility of deprecated and newer endpoints")
    -        assert_equal(self.test_rest_request(f"/headers/{bb_hash}", query_params={"count": 1}), self.test_rest_request(f"/headers/1/{bb_hash}"))
    -        assert_equal(self.test_rest_request(f"/blockfilterheaders/basic/{bb_hash}", query_params={"count": 1}), self.test_rest_request(f"/blockfilterheaders/basic/5/{bb_hash}"))
    -
     
     if __name__ == '__main__':
         RESTTest().main()
    

    </p></details>

    <details><summary>naming style for new code</summary><p>

    diff --git a/src/rest.cpp b/src/rest.cpp
    index d3e878a7bf..c5ea9090e6 100644
    --- a/src/rest.cpp
    +++ b/src/rest.cpp
    @@ -592,12 +592,12 @@ static bool rest_chaininfo(const std::any& context, HTTPRequest* req, const std:
     
     RPCHelpMan getdeploymentinfo();
     
    -static bool rest_deploymentinfo(const std::any& context, HTTPRequest* req, const std::string& strURIPart)
    +static bool rest_deploymentinfo(const std::any& context, HTTPRequest* req, const std::string& uri_part_str)
     {
         if (!CheckWarmup(req)) return false;
     
    -    std::string hashStr;
    -    const RESTResponseFormat rf = ParseDataFormat(hashStr, strURIPart);
    +    std::string hash_str;
    +    const RESTResponseFormat rf = ParseDataFormat(hash_str, uri_part_str);
     
         switch (rf) {
         case RESTResponseFormat::JSON: {
    @@ -605,19 +605,19 @@ static bool rest_deploymentinfo(const std::any& context, HTTPRequest* req, const
             jsonRequest.context = context;
             jsonRequest.params = UniValue(UniValue::VARR);
     
    -        if (!hashStr.empty()) {
    +        if (!hash_str.empty()) {
                 uint256 hash;
    -            if (!ParseHashStr(hashStr, hash)) {
    -                return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
    +            if (!ParseHashStr(hash_str, hash)) {
    +                return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hash_str);
                 }
     
                 const ChainstateManager* chainman = GetChainman(context, req);
                 if (!chainman) return false;
    -            if (!WITH_LOCK(::cs_main, return chainman->m_blockman.LookupBlockIndex(ParseHashV(hashStr, "blockhash")))) {
    +            if (!WITH_LOCK(::cs_main, return chainman->m_blockman.LookupBlockIndex(ParseHashV(hash_str, "blockhash")))) {
                     return RESTERR(req, HTTP_BAD_REQUEST, "Block not found");
                 }
     
    -            jsonRequest.params.pushKV("blockhash", hashStr);
    +            jsonRequest.params.pushKV("blockhash", hash_str);
             }
    

    </p></details>

  43. brunoerg force-pushed on Jul 19, 2022
  44. brunoerg force-pushed on Jul 19, 2022
  45. brunoerg force-pushed on Jul 19, 2022
  46. brunoerg force-pushed on Jul 19, 2022
  47. brunoerg force-pushed on Jul 20, 2022
  48. brunoerg force-pushed on Jul 20, 2022
  49. brunoerg force-pushed on Jul 20, 2022
  50. brunoerg commented at 11:43 PM on July 20, 2022: contributor

    Force-pushed addressing last @jonatack's comment and fixing test. Ready for review!

  51. jonatack commented at 1:47 PM on July 21, 2022: contributor

    ACk c65f82bb6420b1c43a6f39f5b5e31779744a847a

  52. in src/rest.cpp:594 in c65f82bb64 outdated
     589 | @@ -590,6 +590,47 @@ static bool rest_chaininfo(const std::any& context, HTTPRequest* req, const std:
     590 |      }
     591 |  }
     592 |  
     593 | +RPCHelpMan getdeploymentinfo();
    


    stickies-v commented at 4:43 PM on July 22, 2022:

    Any reason you're not declaring this in blockchain.h instead? That seems less messy to me.


    brunoerg commented at 11:38 PM on August 2, 2022:

    There is no specific reason from my side, maybe because of the type RPCHelpMan, gonna check it.


    stickies-v commented at 10:38 AM on August 16, 2022:

    I see now that this was also done for getblockchaininfo(). At the time #7766 was merged, src/rpc/blockchain.h did not yet exist - it was added only with https://github.com/bitcoin/bitcoin/commit/e6dcfeec05d6527ab148550836937ff435e6449c .

    I don't see any reason not to declare it in blockchain.h now though, you'll just have to #include <rpc/util.h> and everything works fine.


    brunoerg commented at 11:44 AM on August 16, 2022:

    Yes, you're right. I'm gonna change it and move getblockchaininfo to there as well


    jonatack commented at 8:43 PM on August 16, 2022:

    Any reason you're not declaring this in blockchain.h instead? That seems less messy to me.

    It looks like the reason was not to needlessly add #include <rpc/util.h> and 400 lines of code to rpc/blockchain.h.


    stickies-v commented at 8:11 AM on August 17, 2022:

    I did not consider that, thanks for the insight @jonatack . Makes sense.

  53. stickies-v commented at 5:06 PM on July 22, 2022: contributor

    Approach ACK c65f82bb6

    Main issue for me is the double endpoint /rest/deploymentinfo and /rest/deploymentinfo/ which I think we should not do, it makes the endpoints ambiguous for imo no good reason. Reasoning in this comment.

    Played around with the endpoint a bit, seems to work as expected, good to have this RPC parity.

  54. in test/functional/interface_rest.py:395 in c65f82bb64 outdated
     390 | +
     391 | +        non_existing_blockhash = '42759cde25462784395a337460bde75f58e73d3f08bd31fdc3507cbac856a2c4'
     392 | +        resp = self.test_rest_request(f'/deploymentinfo/{non_existing_blockhash}', ret_type=RetType.OBJ, status=400)
     393 | +        assert_equal(resp.read().decode('utf-8').rstrip(), "Block not found")
     394 | +
     395 | +        resp = self.test_rest_request(f"/deploymentinfo/{INVALID_PARAM}", ret_type=RetType.OBJ, status=400)
    


    stickies-v commented at 2:14 PM on August 1, 2022:

    I think this test makes more sense without the binary return type, since the endpoint only supports JSON?

            resp = self.test_rest_request(f'/deploymentinfo/{non_existing_blockhash}', status=400)
            assert_equal(resp.read().decode('utf-8').rstrip(), "Block not found")
    
            resp = self.test_rest_request(f"/deploymentinfo/{INVALID_PARAM}", status=400)
    

    brunoerg commented at 5:13 PM on August 15, 2022:

    Let me check but I think if I don't use ret_type=RetType.OBJ here, it will throw an error because it won't be able to decode it.


    stickies-v commented at 10:04 AM on August 16, 2022:

    You're right, my bad. I was confusing ret_type with req_type. Can be marked as resolved, thanks.

  55. stickies-v approved
  56. stickies-v commented at 2:20 PM on August 1, 2022: contributor

    ACK c65f82bb6420b1c43a6f39f5b5e31779744a847a

    I think this PR would benefit from moving the getdeploymentinfo() declaration to blockchain.h and from removing the ret_type=RetType.OBJ as commented here, but neither are blocking imo.

    Edit: happy to ignore my previous comment re double endpoints too, even though it's not my first choice it is in line with the current API organization so it's reasonable to do it this way.

  57. DrahtBot added the label Needs rebase on Aug 5, 2022
  58. brunoerg force-pushed on Aug 15, 2022
  59. brunoerg force-pushed on Aug 15, 2022
  60. DrahtBot removed the label Needs rebase on Aug 15, 2022
  61. brunoerg force-pushed on Aug 16, 2022
  62. in src/rest.cpp:1000 in 8cefefd539 outdated
     996 | @@ -955,4 +997,4 @@ void StopREST()
     997 |      for (const auto& up : uri_prefixes) {
     998 |          UnregisterHTTPHandler(up.prefix, false);
     999 |      }
    1000 | -}
    1001 | +}
    


    w0xlt commented at 3:18 PM on August 16, 2022:

    Is a new line required ?

  63. w0xlt approved
  64. w0xlt commented at 3:21 PM on August 16, 2022: contributor

    reACK 394f177cd3d312a73f173fb8eff49515ce7264af

  65. in src/rpc/blockchain.h:32 in 394f177cd3 outdated
      28 | @@ -28,6 +29,10 @@ struct NodeContext;
      29 |  
      30 |  static constexpr int NUM_GETBLOCKSTATS_PERCENTILES = 5;
      31 |  
      32 | +/** RPC functions used by REST interface */
    


    stickies-v commented at 4:59 PM on August 16, 2022:

    I've often seen feedback that "used by" comments are not maintainable and should not be used, would remove this line? It's quite trivial to check where they're being used.


    brunoerg commented at 5:17 PM on August 16, 2022:

    Makes sense, gonna remove it.

  66. stickies-v approved
  67. brunoerg force-pushed on Aug 16, 2022
  68. brunoerg commented at 5:30 PM on August 16, 2022: contributor

    Force pushed addressing last @stickies-v's comment. Removed the comment in rpc/blockchain.h

    I think now it is ready for a final review. cc: @jonatack @w0xlt

  69. w0xlt approved
  70. in src/rpc/blockchain.h:11 in 9ef5823a3f outdated
       7 | @@ -8,6 +8,7 @@
       8 |  #include <consensus/amount.h>
       9 |  #include <core_io.h>
      10 |  #include <fs.h>
      11 | +#include <rpc/util.h>
    


    jonatack commented at 8:45 PM on August 16, 2022:

    Adding 400 LOC into this file doesn't seem to be an improvement relative to my last ACKed version at https://github.com/bitcoin/bitcoin/commit/c65f82bb6420b1c43a6f39f5b5e31779744a847a.


    brunoerg commented at 9:03 PM on August 16, 2022:

    I'm going to revert it so. Addressed that thinking about keeping the code more organized but you're right about adding 400 LOC.

  71. brunoerg force-pushed on Aug 16, 2022
  72. rest: add `/deploymentinfo` 91497031cb
  73. test: add coverage for `/rest/deploymentinfo` 3e44bee08e
  74. doc: add `/deploymentinfo` in REST-interface 5c96020024
  75. doc: add release note about `/rest/deploymentinfo` a8250e30f1
  76. brunoerg force-pushed on Aug 16, 2022
  77. jonatack commented at 10:48 PM on August 16, 2022: contributor

    re-ACK a8250e30f16f2919ea5aa122b2880b076bd398a3 rebase-only since my last review at c65f82bb

  78. stickies-v approved
  79. brunoerg commented at 4:32 PM on August 23, 2022: contributor

    @w0xlt have in mind a final review here?

  80. achow101 commented at 5:23 PM on October 13, 2022: member

    ACK a8250e30f16f2919ea5aa122b2880b076bd398a3

  81. achow101 merged this on Oct 13, 2022
  82. achow101 closed this on Oct 13, 2022

  83. sidhujag referenced this in commit 151c348370 on Oct 23, 2022
  84. bitcoin locked this on Oct 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: 2026-04-13 15:13 UTC

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