allow rest/block/height.json
changes from review, added integration test
This commit is contained in:
parent
7f6daef99b
commit
55f5f2049e
3 changed files with 37 additions and 10 deletions
|
@ -17,10 +17,16 @@ Given a transaction hash: returns a transaction in binary, hex-encoded binary, o
|
||||||
For full TX query capability, one must enable the transaction index via "txindex=1" command line / configuration option.
|
For full TX query capability, one must enable the transaction index via "txindex=1" command line / configuration option.
|
||||||
|
|
||||||
#### Blocks
|
#### Blocks
|
||||||
|
`GET /rest/block/tip.<bin|hex|json>`
|
||||||
`GET /rest/block/<BLOCK-HASH>.<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-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.
|
Given a block hash: returns a block, in binary, hex-encoded binary or JSON formats.
|
||||||
|
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.
|
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.
|
||||||
|
|
||||||
|
|
18
src/rest.cpp
18
src/rest.cpp
|
@ -205,13 +205,25 @@ static bool rest_block(HTTPRequest* req,
|
||||||
const RetFormat rf = ParseDataFormat(hashStr, strURIPart);
|
const RetFormat rf = ParseDataFormat(hashStr, strURIPart);
|
||||||
|
|
||||||
uint256 hash;
|
uint256 hash;
|
||||||
if (!ParseHashStr(hashStr, hash))
|
long int blockHeight = 0;
|
||||||
return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
|
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;
|
CBlock block;
|
||||||
CBlockIndex* pblockindex = nullptr;
|
CBlockIndex* pblockindex = nullptr;
|
||||||
{
|
{
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
|
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);
|
pblockindex = LookupBlockIndex(hash);
|
||||||
if (!pblockindex) {
|
if (!pblockindex) {
|
||||||
return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");
|
return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");
|
||||||
|
|
|
@ -84,7 +84,7 @@ class RESTTest (BitcoinTestFramework):
|
||||||
self.nodes[1].generatetoaddress(100, not_related_address)
|
self.nodes[1].generatetoaddress(100, not_related_address)
|
||||||
self.sync_all()
|
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)
|
txid = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1)
|
||||||
self.sync_all()
|
self.sync_all()
|
||||||
|
@ -200,17 +200,26 @@ class RESTTest (BitcoinTestFramework):
|
||||||
|
|
||||||
self.log.info("Test the /block and /headers URIs")
|
self.log.info("Test the /block and /headers URIs")
|
||||||
bb_hash = self.nodes[0].getbestblockhash()
|
bb_hash = self.nodes[0].getbestblockhash()
|
||||||
|
bb_height = self.nodes[0].getblock(self.nodes[0].getbestblockhash())['height']
|
||||||
|
|
||||||
# Check binary format
|
# Check binary format
|
||||||
response = self.test_rest_request("/block/{}".format(bb_hash), req_type=ReqType.BIN, ret_type=RetType.OBJ)
|
response = self.test_rest_request("/block/{}".format(bb_hash), req_type=ReqType.BIN, ret_type=RetType.OBJ)
|
||||||
assert_greater_than(int(response.getheader('content-length')), 80)
|
assert_greater_than(int(response.getheader('content-length')), 80)
|
||||||
response_bytes = response.read()
|
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
|
# Compare with block header
|
||||||
response_header = self.test_rest_request("/headers/1/{}".format(bb_hash), req_type=ReqType.BIN, ret_type=RetType.OBJ)
|
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')), 80)
|
assert_equal(int(response_header.getheader('content-length')), 112)
|
||||||
response_header_bytes = response_header.read()
|
response_header_bytes = response_header.read()
|
||||||
assert_equal(response_bytes[:80], response_header_bytes)
|
assert_equal(response_bytes[:112], response_header_bytes)
|
||||||
|
|
||||||
# Check block hex format
|
# Check block hex format
|
||||||
response_hex = self.test_rest_request("/block/{}".format(bb_hash), req_type=ReqType.HEX, ret_type=RetType.OBJ)
|
response_hex = self.test_rest_request("/block/{}".format(bb_hash), req_type=ReqType.HEX, ret_type=RetType.OBJ)
|
||||||
|
@ -259,9 +268,9 @@ class RESTTest (BitcoinTestFramework):
|
||||||
|
|
||||||
# Make 3 tx and mine them on node 1
|
# Make 3 tx and mine them on node 1
|
||||||
txs = []
|
txs = []
|
||||||
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, 11))
|
txs.append(self.nodes[0].sendtoaddress(not_related_address, 0.11))
|
||||||
txs.append(self.nodes[0].sendtoaddress(not_related_address, 11))
|
txs.append(self.nodes[0].sendtoaddress(not_related_address, 0.11))
|
||||||
self.sync_all()
|
self.sync_all()
|
||||||
|
|
||||||
# Check that there are exactly 3 transactions in the TX memory pool before generating the block
|
# Check that there are exactly 3 transactions in the TX memory pool before generating the block
|
||||||
|
|
Loading…
Reference in a new issue