allow rest/block/height.json

changes from review, added integration test
This commit is contained in:
Brannon King 2019-05-13 15:03:42 -06:00 committed by Anthony Fieroni
parent 71acdb839c
commit 0c130f40c7
3 changed files with 35 additions and 9 deletions

View file

@ -24,11 +24,16 @@ By default, this endpoint will only search the mempool.
To query for a confirmed transaction, enable the transaction index via "txindex=1" command line / configuration option.
#### Blocks
`GET /rest/block/tip.<bin|hex|json>`
`GET /rest/block/<BLOCK-HASH>.<bin|hex|json>`
`GET /rest/block/<BLOCK-HEIGHT>.<bin|hex|json>`
`GET /rest/block/notxdetails/tip.<bin|hex|json>`
`GET /rest/block/notxdetails/<BLOCK-HASH>.<bin|hex|json>`
`GET /rest/block/notxdetails/<BLOCK-HEIGHT>.<bin|hex|json>`
Given a block hash: returns a block, in binary, hex-encoded binary or JSON formats.
Responds with 404 if the block doesn't exist.
You can give a block height instead of a hash. Height 0 is not available,
but can be negative to go back that many blocks from the tip.
The HTTP request and response are both handled entirely in-memory, thus making maximum memory usage at least 2.66MB (1 MB max block, plus hex encoding) per request.

View file

@ -202,15 +202,27 @@ static bool rest_block(HTTPRequest* req,
const RetFormat rf = ParseDataFormat(hashStr, strURIPart);
uint256 hash;
if (!ParseHashStr(hashStr, hash))
return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
long int blockHeight = 0;
if (hashStr != "tip") {
blockHeight = hashStr.size() < 12 ? std::strtol(hashStr.c_str(), nullptr, 10) : 0;
if (blockHeight == 0 && !ParseHashStr(hashStr, hash))
return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash or block height: " + hashStr);
}
CBlock block;
CBlockIndex* pblockindex = nullptr;
CBlockIndex* tip = nullptr;
{
LOCK(cs_main);
tip = ::ChainActive().Tip();
if (blockHeight < 0) // negative block heights take us back from current tip
blockHeight += chainActive.Height();
if (blockHeight > 0 && blockHeight <= chainActive.Height())
pblockindex = chainActive[blockHeight];
else if (blockHeight != 0)
return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash or block height: " + hashStr);
else if (hashStr == "tip")
pblockindex = chainActive.Tip();
else
pblockindex = LookupBlockIndex(hash);
if (!pblockindex) {
return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");

View file

@ -86,7 +86,7 @@ class RESTTest (BitcoinTestFramework):
self.nodes[1].generatetoaddress(100, not_related_address)
self.sync_all()
assert_equal(self.nodes[0].getbalance(), 50)
assert_equal(self.nodes[0].getbalance(), 1)
txid = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1)
self.sync_all()
@ -209,6 +209,7 @@ class RESTTest (BitcoinTestFramework):
self.log.info("Test the /block, /blockhashbyheight and /headers URIs")
bb_hash = self.nodes[0].getbestblockhash()
bb_height = self.nodes[0].getblock(self.nodes[0].getbestblockhash())['height']
# Check result if block does not exists
assert_equal(self.test_rest_request('/headers/1/0000000000000000000000000000000000000000000000000000000000000000'), [])
@ -225,6 +226,14 @@ class RESTTest (BitcoinTestFramework):
assert_greater_than(int(response.getheader('content-length')), BLOCK_HEADER_SIZE)
response_bytes = response.read()
response2 = self.test_rest_request("/block/{}".format(bb_height), req_type=ReqType.BIN, ret_type=RetType.OBJ)
response2_bytes = response2.read()
assert_equal(response_bytes, response2_bytes)
response3 = self.test_rest_request("/block/tip", req_type=ReqType.BIN, ret_type=RetType.OBJ)
response3_bytes = response3.read()
assert_equal(response_bytes, response3_bytes)
# Compare with block header
response_header = self.test_rest_request("/headers/1/{}".format(bb_hash), req_type=ReqType.BIN, ret_type=RetType.OBJ)
assert_equal(int(response_header.getheader('content-length')), BLOCK_HEADER_SIZE)
@ -284,9 +293,9 @@ class RESTTest (BitcoinTestFramework):
# Make 3 tx and mine them on node 1
txs = []
txs.append(self.nodes[0].sendtoaddress(not_related_address, 11))
txs.append(self.nodes[0].sendtoaddress(not_related_address, 11))
txs.append(self.nodes[0].sendtoaddress(not_related_address, 11))
txs.append(self.nodes[0].sendtoaddress(not_related_address, 0.11))
txs.append(self.nodes[0].sendtoaddress(not_related_address, 0.11))
txs.append(self.nodes[0].sendtoaddress(not_related_address, 0.11))
self.sync_all()
# Check that there are exactly 3 transactions in the TX memory pool before generating the block