Skip to content

Commit 1c9596c

Browse files
authored
Merge pull request #5308 from stacks-network/feat/5304
feat: Add tenure-height to the /v2/info endpoint
2 parents eb252e8 + 708bfe5 commit 1c9596c

File tree

11 files changed

+119
-39
lines changed

11 files changed

+119
-39
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ and this project adheres to the versioning scheme outlined in the [README.md](RE
1717
- `get-tenure-info?` added
1818
- `get-block-info?` removed
1919
- Added `/v3/signer/{signer_pubkey}/{reward_cycle}` endpoint
20+
- Added `tenure_height` to `/v2/info` endpoint
2021
- Added optional `timeout_ms` to `events_observer` configuration
2122
- Added support for re-sending events to event observers across restarts
2223

docs/rpc/api/core-node/get-info.example.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"stacks_tip": "b1807a2d3f7f8c7922f7c1d60d7c34145ade05d789640dc7dc9ec1021e07bb54",
1212
"stacks_tip_consensus_hash": "17f76e597bab45646956f38dd39573085d72cbc0",
1313
"unanchored_tip": "0000000000000000000000000000000000000000000000000000000000000000",
14+
"tenure_height": 523,
1415
"exit_at_block_height": null,
1516
"is_fully_synced": false
1617
}

docs/rpc/api/core-node/get-info.schema.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"stacks_tip",
1818
"stacks_tip_consensus_hash",
1919
"unanchored_tip",
20+
"tenure_height",
2021
"exit_at_block_height",
2122
"is_fully_synced"
2223
],
@@ -69,6 +70,10 @@
6970
"type": "string",
7071
"description": "the latest microblock hash if any microblocks were processed. if no microblock has been processed for the current block, a 000.., hex array is returned"
7172
},
73+
"tenure_height": {
74+
"type": "integer",
75+
"description": "the latest Stacks tenure height"
76+
},
7277
"exit_at_block_height": {
7378
"type": "integer",
7479
"description": "the block height at which the testnet network will be reset. not applicable for mainnet"

stacks-signer/src/client/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,7 @@ pub(crate) mod tests {
322322
stacks_tip_consensus_hash: generate_random_consensus_hash(),
323323
unanchored_tip: None,
324324
unanchored_seq: Some(0),
325+
tenure_height: thread_rng().next_u64(),
325326
exit_at_block_height: None,
326327
is_fully_synced: false,
327328
genesis_chainstate_hash: Sha256Sum::zero(),

stackslib/src/net/api/getinfo.rs

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,12 @@ use stacks_common::util::hash::{Hash160, Sha256Sum};
2727
use crate::burnchains::affirmation::AffirmationMap;
2828
use crate::burnchains::Txid;
2929
use crate::chainstate::burn::db::sortdb::SortitionDB;
30+
use crate::chainstate::nakamoto::NakamotoChainState;
3031
use crate::chainstate::stacks::db::StacksChainState;
3132
use crate::core::mempool::MemPoolDB;
3233
use crate::net::http::{
3334
parse_json, Error, HttpRequest, HttpRequestContents, HttpRequestPreamble, HttpResponse,
34-
HttpResponseContents, HttpResponsePayload, HttpResponsePreamble,
35+
HttpResponseContents, HttpResponsePayload, HttpResponsePreamble, HttpServerError,
3536
};
3637
use crate::net::httpcore::{
3738
HttpPreambleExtensions, RPCRequestHandler, StacksHttpRequest, StacksHttpResponse,
@@ -81,6 +82,7 @@ pub struct RPCPeerInfoData {
8182
pub genesis_chainstate_hash: Sha256Sum,
8283
pub unanchored_tip: Option<StacksBlockId>,
8384
pub unanchored_seq: Option<u16>,
85+
pub tenure_height: u64,
8486
pub exit_at_block_height: Option<u64>,
8587
pub is_fully_synced: bool,
8688
#[serde(default)]
@@ -106,6 +108,7 @@ impl RPCPeerInfoData {
106108
chainstate: &StacksChainState,
107109
exit_at_block_height: Option<u64>,
108110
genesis_chainstate_hash: &Sha256Sum,
111+
coinbase_height: u64,
109112
ibd: bool,
110113
) -> RPCPeerInfoData {
111114
let server_version = version_string(
@@ -148,7 +151,7 @@ impl RPCPeerInfoData {
148151
stacks_tip_consensus_hash: network.stacks_tip.consensus_hash.clone(),
149152
unanchored_tip: unconfirmed_tip,
150153
unanchored_seq: unconfirmed_seq,
151-
exit_at_block_height: exit_at_block_height,
154+
exit_at_block_height,
152155
is_fully_synced,
153156
genesis_chainstate_hash: genesis_chainstate_hash.clone(),
154157
node_public_key: Some(public_key_buf),
@@ -169,6 +172,7 @@ impl RPCPeerInfoData {
169172
.map(|cid| format!("{}", cid))
170173
.collect(),
171174
),
175+
tenure_height: coinbase_height,
172176
}
173177
}
174178
}
@@ -217,16 +221,28 @@ impl RPCRequestHandler for RPCPeerInfoRequestHandler {
217221
node: &mut StacksNodeState,
218222
) -> Result<(HttpResponsePreamble, HttpResponseContents), NetError> {
219223
let ibd = node.ibd;
220-
let rpc_peer_info =
224+
225+
let rpc_peer_info: Result<RPCPeerInfoData, StacksHttpResponse> =
221226
node.with_node_state(|network, _sortdb, chainstate, _mempool, rpc_args| {
222-
RPCPeerInfoData::from_network(
227+
let coinbase_height = network.stacks_tip.coinbase_height;
228+
229+
Ok(RPCPeerInfoData::from_network(
223230
network,
224231
chainstate,
225232
rpc_args.exit_at_block_height.clone(),
226233
&rpc_args.genesis_chainstate_hash,
234+
coinbase_height,
227235
ibd,
228-
)
236+
))
229237
});
238+
239+
let rpc_peer_info = match rpc_peer_info {
240+
Ok(rpc_peer_info) => rpc_peer_info,
241+
Err(response) => {
242+
return response.try_into_contents().map_err(NetError::from);
243+
}
244+
};
245+
230246
let mut preamble = HttpResponsePreamble::ok_json(&preamble);
231247
preamble.set_canonical_stacks_tip_height(Some(node.canonical_stacks_tip_height()));
232248
let body = HttpResponseContents::try_from_json(&rpc_peer_info)?;

stackslib/src/net/api/postmempoolquery.rs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,9 @@ impl StacksMemPoolStream {
116116

117117
Self {
118118
tx_query,
119-
last_randomized_txid: last_randomized_txid,
119+
last_randomized_txid,
120120
num_txs: 0,
121-
max_txs: max_txs,
121+
max_txs,
122122
coinbase_height,
123123
corked: false,
124124
finished: false,
@@ -275,14 +275,8 @@ impl RPCRequestHandler for RPCMempoolQueryRequestHandler {
275275
.ok_or(NetError::SendError("`mempool_query` not set".into()))?;
276276
let page_id = self.page_id.take();
277277

278-
let stream_res = node.with_node_state(|network, sortdb, chainstate, mempool, _rpc_args| {
279-
let header = self.get_stacks_chain_tip(&preamble, sortdb, chainstate)
280-
.map_err(|e| StacksHttpResponse::new_error(&preamble, &HttpServerError::new(format!("Failed to load chain tip: {:?}", &e))))?;
281-
282-
let coinbase_height = NakamotoChainState::get_coinbase_height(&mut chainstate.index_conn(), &header.index_block_hash())
283-
.map_err(|e| StacksHttpResponse::new_error(&preamble, &HttpServerError::new(format!("Failed to load coinbase height: {:?}", &e))))?
284-
.unwrap_or(0);
285-
278+
let stream_res = node.with_node_state(|network, _sortdb, _chainstate, mempool, _rpc_args| {
279+
let coinbase_height = network.stacks_tip.coinbase_height;
286280
let max_txs = network.connection_opts.mempool_max_tx_query;
287281
debug!(
288282
"Begin mempool query";

stackslib/src/net/api/tests/getinfo.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ fn test_try_parse_request() {
5050
.try_parse_request(&parsed_preamble.expect_request(), &bytes[offset..])
5151
.unwrap();
5252

53-
// parsed request consumes headers that would not be in a constructed reqeuest
53+
// parsed request consumes headers that would not be in a constructed request
5454
parsed_request.clear_headers();
5555
parsed_request.add_header(
5656
"X-Canonical-Stacks-Tip-Height".to_string(),
@@ -63,10 +63,10 @@ fn test_try_parse_request() {
6363

6464
#[test]
6565
fn test_getinfo_compat() {
66-
let old_getinfo_json = r#"{"peer_version":402653189,"pox_consensus":"b712eb731b613eebae814a8f416c5c15bc8391ec","burn_block_height":727631,"stable_pox_consensus":"53b5ed79842080500d7d83daa36aa1069dedf983","stable_burn_block_height":727624,"server_version":"stacks-node 0.0.1 (feat/faster-inv-generation:68f33190a, release build, linux [x86_64])","network_id":1,"parent_network_id":3652501241,"stacks_tip_height":52537,"stacks_tip":"b3183f2ac588e12319ff0fde78f97e62c92a218d87828c35710c29aaf7adbedc","stacks_tip_consensus_hash":"b712eb731b613eebae814a8f416c5c15bc8391ec","genesis_chainstate_hash":"74237aa39aa50a83de11a4f53e9d3bb7d43461d1de9873f402e5453ae60bc59b","unanchored_tip":"e76f68d607480e9984b4062b2691fb60a88423177898f5780b40ace17ae8982a","unanchored_seq":0,"exit_at_block_height":null,"is_fully_synced":false}"#;
67-
let getinfo_no_pubkey_hash_json = r#"{"peer_version":402653189,"pox_consensus":"b712eb731b613eebae814a8f416c5c15bc8391ec","burn_block_height":727631,"stable_pox_consensus":"53b5ed79842080500d7d83daa36aa1069dedf983","stable_burn_block_height":727624,"server_version":"stacks-node 0.0.1 (feat/faster-inv-generation:68f33190a, release build, linux [x86_64])","network_id":1,"parent_network_id":3652501241,"stacks_tip_height":52537,"stacks_tip":"b3183f2ac588e12319ff0fde78f97e62c92a218d87828c35710c29aaf7adbedc","stacks_tip_consensus_hash":"b712eb731b613eebae814a8f416c5c15bc8391ec","genesis_chainstate_hash":"74237aa39aa50a83de11a4f53e9d3bb7d43461d1de9873f402e5453ae60bc59b","unanchored_tip":"e76f68d607480e9984b4062b2691fb60a88423177898f5780b40ace17ae8982a","unanchored_seq":0,"exit_at_block_height":null,"is_fully_synced":false,"node_public_key":"029b27d345e7bd2a6627262cefe6e97d9bc482f41ec32ec76a7bec391bb441798d"}"#;
68-
let getinfo_no_pubkey_json = r#"{"peer_version":402653189,"pox_consensus":"b712eb731b613eebae814a8f416c5c15bc8391ec","burn_block_height":727631,"stable_pox_consensus":"53b5ed79842080500d7d83daa36aa1069dedf983","stable_burn_block_height":727624,"server_version":"stacks-node 0.0.1 (feat/faster-inv-generation:68f33190a, release build, linux [x86_64])","network_id":1,"parent_network_id":3652501241,"stacks_tip_height":52537,"stacks_tip":"b3183f2ac588e12319ff0fde78f97e62c92a218d87828c35710c29aaf7adbedc","stacks_tip_consensus_hash":"b712eb731b613eebae814a8f416c5c15bc8391ec","genesis_chainstate_hash":"74237aa39aa50a83de11a4f53e9d3bb7d43461d1de9873f402e5453ae60bc59b","unanchored_tip":"e76f68d607480e9984b4062b2691fb60a88423177898f5780b40ace17ae8982a","unanchored_seq":0,"exit_at_block_height":null,"is_fully_synced":false,"node_public_key_hash":"046e6f832a83ff0da4a550907d3a44412cc1e4bf"}"#;
69-
let getinfo_full_json = r#"{"peer_version":402653189,"pox_consensus":"b712eb731b613eebae814a8f416c5c15bc8391ec","burn_block_height":727631,"stable_pox_consensus":"53b5ed79842080500d7d83daa36aa1069dedf983","stable_burn_block_height":727624,"server_version":"stacks-node 0.0.1 (feat/faster-inv-generation:68f33190a, release build, linux [x86_64])","network_id":1,"parent_network_id":3652501241,"stacks_tip_height":52537,"stacks_tip":"b3183f2ac588e12319ff0fde78f97e62c92a218d87828c35710c29aaf7adbedc","stacks_tip_consensus_hash":"b712eb731b613eebae814a8f416c5c15bc8391ec","genesis_chainstate_hash":"74237aa39aa50a83de11a4f53e9d3bb7d43461d1de9873f402e5453ae60bc59b","unanchored_tip":"e76f68d607480e9984b4062b2691fb60a88423177898f5780b40ace17ae8982a","unanchored_seq":0,"exit_at_block_height":null,"is_fully_synced":false,"node_public_key":"029b27d345e7bd2a6627262cefe6e97d9bc482f41ec32ec76a7bec391bb441798d","node_public_key_hash":"046e6f832a83ff0da4a550907d3a44412cc1e4bf"}"#;
66+
let old_getinfo_json = r#"{"peer_version":402653189,"pox_consensus":"b712eb731b613eebae814a8f416c5c15bc8391ec","burn_block_height":727631,"stable_pox_consensus":"53b5ed79842080500d7d83daa36aa1069dedf983","stable_burn_block_height":727624,"server_version":"stacks-node 0.0.1 (feat/faster-inv-generation:68f33190a, release build, linux [x86_64])","network_id":1,"parent_network_id":3652501241,"stacks_tip_height":52537,"stacks_tip":"b3183f2ac588e12319ff0fde78f97e62c92a218d87828c35710c29aaf7adbedc","stacks_tip_consensus_hash":"b712eb731b613eebae814a8f416c5c15bc8391ec","genesis_chainstate_hash":"74237aa39aa50a83de11a4f53e9d3bb7d43461d1de9873f402e5453ae60bc59b","unanchored_tip":"e76f68d607480e9984b4062b2691fb60a88423177898f5780b40ace17ae8982a","unanchored_seq":0,"exit_at_block_height":null,"is_fully_synced":false, "tenure_height": 42}"#;
67+
let getinfo_no_pubkey_hash_json = r#"{"peer_version":402653189,"pox_consensus":"b712eb731b613eebae814a8f416c5c15bc8391ec","burn_block_height":727631,"stable_pox_consensus":"53b5ed79842080500d7d83daa36aa1069dedf983","stable_burn_block_height":727624,"server_version":"stacks-node 0.0.1 (feat/faster-inv-generation:68f33190a, release build, linux [x86_64])","network_id":1,"parent_network_id":3652501241,"stacks_tip_height":52537,"stacks_tip":"b3183f2ac588e12319ff0fde78f97e62c92a218d87828c35710c29aaf7adbedc","stacks_tip_consensus_hash":"b712eb731b613eebae814a8f416c5c15bc8391ec","genesis_chainstate_hash":"74237aa39aa50a83de11a4f53e9d3bb7d43461d1de9873f402e5453ae60bc59b","unanchored_tip":"e76f68d607480e9984b4062b2691fb60a88423177898f5780b40ace17ae8982a","unanchored_seq":0,"exit_at_block_height":null,"is_fully_synced":false,"node_public_key":"029b27d345e7bd2a6627262cefe6e97d9bc482f41ec32ec76a7bec391bb441798d", "tenure_height": 42}"#;
68+
let getinfo_no_pubkey_json = r#"{"peer_version":402653189,"pox_consensus":"b712eb731b613eebae814a8f416c5c15bc8391ec","burn_block_height":727631,"stable_pox_consensus":"53b5ed79842080500d7d83daa36aa1069dedf983","stable_burn_block_height":727624,"server_version":"stacks-node 0.0.1 (feat/faster-inv-generation:68f33190a, release build, linux [x86_64])","network_id":1,"parent_network_id":3652501241,"stacks_tip_height":52537,"stacks_tip":"b3183f2ac588e12319ff0fde78f97e62c92a218d87828c35710c29aaf7adbedc","stacks_tip_consensus_hash":"b712eb731b613eebae814a8f416c5c15bc8391ec","genesis_chainstate_hash":"74237aa39aa50a83de11a4f53e9d3bb7d43461d1de9873f402e5453ae60bc59b","unanchored_tip":"e76f68d607480e9984b4062b2691fb60a88423177898f5780b40ace17ae8982a","unanchored_seq":0,"exit_at_block_height":null,"is_fully_synced":false,"node_public_key_hash":"046e6f832a83ff0da4a550907d3a44412cc1e4bf", "tenure_height": 0}"#;
69+
let getinfo_full_json = r#"{"peer_version":402653189,"pox_consensus":"b712eb731b613eebae814a8f416c5c15bc8391ec","burn_block_height":727631,"stable_pox_consensus":"53b5ed79842080500d7d83daa36aa1069dedf983","stable_burn_block_height":727624,"server_version":"stacks-node 0.0.1 (feat/faster-inv-generation:68f33190a, release build, linux [x86_64])","network_id":1,"parent_network_id":3652501241,"stacks_tip_height":52537,"stacks_tip":"b3183f2ac588e12319ff0fde78f97e62c92a218d87828c35710c29aaf7adbedc","stacks_tip_consensus_hash":"b712eb731b613eebae814a8f416c5c15bc8391ec","genesis_chainstate_hash":"74237aa39aa50a83de11a4f53e9d3bb7d43461d1de9873f402e5453ae60bc59b","unanchored_tip":"e76f68d607480e9984b4062b2691fb60a88423177898f5780b40ace17ae8982a","unanchored_seq":0,"exit_at_block_height":null,"is_fully_synced":false,"node_public_key":"029b27d345e7bd2a6627262cefe6e97d9bc482f41ec32ec76a7bec391bb441798d","node_public_key_hash":"046e6f832a83ff0da4a550907d3a44412cc1e4bf", "tenure_height": 2423}"#;
7070

7171
// they all parse
7272
for json_obj in &[
@@ -102,4 +102,6 @@ fn test_try_make_response() {
102102
Some(1)
103103
);
104104
let resp = response.decode_peer_info().unwrap();
105+
106+
assert_eq!(resp.tenure_height, 1);
105107
}

stackslib/src/net/api/tests/gettenureinfo.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ use stacks_common::types::net::PeerHost;
2525
use stacks_common::types::Address;
2626

2727
use super::test_rpc;
28-
use crate::net::api::getinfo::RPCPeerInfoData;
2928
use crate::net::api::tests::TestRPC;
3029
use crate::net::api::*;
3130
use crate::net::connection::ConnectionOptions;

0 commit comments

Comments
 (0)