Skip to content

Commit f251c33

Browse files
authored
Merge pull request #6666 from charans29/feature/add-current-epoch-6658
Feature/add current epoch 6658
2 parents cda6a5e + 28bc737 commit f251c33

File tree

4 files changed

+34
-110
lines changed

4 files changed

+34
-110
lines changed

docs/rpc/components/schemas/pox-info.schema.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ required:
1515
- reward_cycle_length
1616
- contract_versions
1717
- epochs
18+
- current_epoch
1819
properties:
1920
contract_id:
2021
type: string
@@ -27,6 +28,10 @@ properties:
2728
type: integer
2829
minimum: 0
2930
description: The latest Bitcoin chain block height
31+
current_epoch:
32+
type: string
33+
pattern: "^Epoch[0-9]+(_[0-9]+)?$"
34+
description: The ID of the Stacks Epoch that the node is currently in.
3035
pox_activation_threshold_ustx:
3136
type: integer
3237
description:

stacks-signer/src/client/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ pub(crate) mod tests {
302302
network_epoch: 0,
303303
},
304304
],
305+
current_epoch: StacksEpochId::Epoch30,
305306
reward_cycle_length: thread_rng().next_u64(),
306307
rejection_votes_left_required: None,
307308
next_reward_cycle_in: thread_rng().next_u64(),

stacks-signer/src/client/stacks_client.rs

Lines changed: 15 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -274,31 +274,7 @@ impl StacksClient {
274274
pub fn get_node_epoch(&self) -> Result<StacksEpochId, ClientError> {
275275
debug!("StacksClient: Getting node epoch");
276276
let pox_info = self.get_pox_data()?;
277-
let burn_block_height = self.get_burn_block_height()?;
278-
279-
let epoch_25 = pox_info
280-
.epochs
281-
.iter()
282-
.find(|epoch| epoch.epoch_id == StacksEpochId::Epoch25)
283-
.ok_or(ClientError::UnsupportedStacksFeature(
284-
"/v2/pox must report epochs".into(),
285-
))?;
286-
287-
let epoch_30 = pox_info
288-
.epochs
289-
.iter()
290-
.find(|epoch| epoch.epoch_id == StacksEpochId::Epoch30)
291-
.ok_or(ClientError::UnsupportedStacksFeature(
292-
"/v2/pox mut report epochs".into(),
293-
))?;
294-
295-
if burn_block_height < epoch_25.start_height {
296-
Ok(StacksEpochId::Epoch24)
297-
} else if burn_block_height < epoch_30.start_height {
298-
Ok(StacksEpochId::Epoch25)
299-
} else {
300-
Ok(StacksEpochId::Epoch30)
301-
}
277+
Ok(pox_info.current_epoch)
302278
}
303279

304280
/// Submit the block proposal to the stacks node. The block will be validated and returned via the HTTP endpoint for Block events.
@@ -553,12 +529,6 @@ impl StacksClient {
553529
Ok(pox_info_data)
554530
}
555531

556-
/// Helper function to retrieve the burn tip height from the stacks node
557-
fn get_burn_block_height(&self) -> Result<u64, ClientError> {
558-
debug!("StacksClient: Getting burn block height");
559-
self.get_peer_info().map(|info| info.burn_block_height)
560-
}
561-
562532
/// Get the current reward cycle info from the stacks node
563533
pub fn get_current_reward_cycle_info(&self) -> Result<RewardCycleInfo, ClientError> {
564534
debug!("StacksClient: Getting current reward cycle info");
@@ -914,17 +884,21 @@ mod tests {
914884
#[test]
915885
fn core_info_call_for_burn_block_height_should_succeed() {
916886
let mock = MockServerClient::new();
917-
let h = spawn(move || mock.client.get_burn_block_height());
887+
let h = spawn(move || mock.client.get_peer_info());
918888
let (response, peer_info) = build_get_peer_info_response(None, None);
919889
write_response(mock.server, response.as_bytes());
920-
let burn_block_height = h.join().unwrap().expect("Failed to deserialize response");
890+
let burn_block_height = h
891+
.join()
892+
.unwrap()
893+
.expect("Failed to deserialize response")
894+
.burn_block_height;
921895
assert_eq!(burn_block_height, peer_info.burn_block_height);
922896
}
923897

924898
#[test]
925899
fn core_info_call_for_burn_block_height_should_fail() {
926900
let mock = MockServerClient::new();
927-
let h = spawn(move || mock.client.get_burn_block_height());
901+
let h = spawn(move || mock.client.get_peer_info());
928902
write_response(
929903
mock.server,
930904
b"HTTP/1.1 200 OK\n\n4e99f99bc4a05437abb8c7d0c306618f45b203196498e2ebe287f10497124958",
@@ -998,85 +972,17 @@ mod tests {
998972
#[test]
999973
fn get_node_epoch_should_succeed() {
1000974
let mock = MockServerClient::new();
1001-
// The burn block height is one BEHIND the activation height of 2.5, therefore is 2.4
1002-
let burn_block_height: u64 = 100;
1003-
let pox_response = build_get_pox_data_response(
1004-
None,
1005-
None,
1006-
Some(burn_block_height.saturating_add(1)),
1007-
None,
1008-
)
1009-
.0;
1010-
let peer_response = build_get_peer_info_response(Some(burn_block_height), None).0;
1011-
let h = spawn(move || mock.client.get_node_epoch());
1012-
write_response(mock.server, pox_response.as_bytes());
1013-
let mock = MockServerClient::from_config(mock.config);
1014-
write_response(mock.server, peer_response.as_bytes());
1015-
let epoch = h.join().unwrap().expect("Failed to deserialize response");
1016-
assert_eq!(epoch, StacksEpochId::Epoch24);
1017975

1018-
// The burn block height is the same as the activation height of 2.5, therefore is 2.5
1019-
let pox_response = build_get_pox_data_response(None, None, Some(burn_block_height), None).0;
1020-
let peer_response = build_get_peer_info_response(Some(burn_block_height), None).0;
1021-
let mock = MockServerClient::from_config(mock.config);
1022-
let h = spawn(move || mock.client.get_node_epoch());
1023-
write_response(mock.server, pox_response.as_bytes());
1024-
let mock = MockServerClient::from_config(mock.config);
1025-
write_response(mock.server, peer_response.as_bytes());
1026-
let epoch = h.join().unwrap().expect("Failed to deserialize response");
1027-
assert_eq!(epoch, StacksEpochId::Epoch25);
1028-
1029-
// The burn block height is the AFTER as the activation height of 2.5 but BEFORE the activation height of 3.0, therefore is 2.5
1030-
let pox_response = build_get_pox_data_response(
1031-
None,
1032-
None,
1033-
Some(burn_block_height.saturating_sub(1)),
1034-
Some(burn_block_height.saturating_add(1)),
1035-
)
1036-
.0;
1037-
let peer_response = build_get_peer_info_response(Some(burn_block_height), None).0;
1038-
let mock = MockServerClient::from_config(mock.config);
1039-
let h = spawn(move || mock.client.get_node_epoch());
1040-
write_response(mock.server, pox_response.as_bytes());
1041-
let mock = MockServerClient::from_config(mock.config);
1042-
write_response(mock.server, peer_response.as_bytes());
1043-
let epoch = h.join().unwrap().expect("Failed to deserialize response");
1044-
assert_eq!(epoch, StacksEpochId::Epoch25);
1045-
1046-
// The burn block height is the AFTER as the activation height of 2.5 and the SAME as the activation height of 3.0, therefore is 3.0
1047-
let pox_response = build_get_pox_data_response(
1048-
None,
1049-
None,
1050-
Some(burn_block_height.saturating_sub(1)),
1051-
Some(burn_block_height),
1052-
)
1053-
.0;
1054-
let peer_response = build_get_peer_info_response(Some(burn_block_height), None).0;
1055-
let mock = MockServerClient::from_config(mock.config);
1056-
let h = spawn(move || mock.client.get_node_epoch());
1057-
write_response(mock.server, pox_response.as_bytes());
1058-
let mock = MockServerClient::from_config(mock.config);
1059-
write_response(mock.server, peer_response.as_bytes());
1060-
let epoch = h.join().unwrap().expect("Failed to deserialize response");
1061-
assert_eq!(epoch, StacksEpochId::Epoch30);
1062-
1063-
// The burn block height is the AFTER as the activation height of 2.5 and AFTER the activation height of 3.0, therefore is 3.0
1064-
let pox_response = build_get_pox_data_response(
1065-
None,
1066-
None,
1067-
Some(burn_block_height.saturating_sub(1)),
1068-
Some(burn_block_height),
1069-
)
1070-
.0;
1071-
let peer_response =
1072-
build_get_peer_info_response(Some(burn_block_height.saturating_add(1)), None).0;
1073-
let mock = MockServerClient::from_config(mock.config);
976+
let expected_epoch = StacksEpochId::Epoch30;
977+
978+
let (pox_response, _) = build_get_pox_data_response(None, None, None, None);
979+
1074980
let h = spawn(move || mock.client.get_node_epoch());
981+
1075982
write_response(mock.server, pox_response.as_bytes());
1076-
let mock = MockServerClient::from_config(mock.config);
1077-
write_response(mock.server, peer_response.as_bytes());
983+
1078984
let epoch = h.join().unwrap().expect("Failed to deserialize response");
1079-
assert_eq!(epoch, StacksEpochId::Epoch30);
985+
assert_eq!(epoch, expected_epoch);
1080986
}
1081987

1082988
#[test]

stackslib/src/net/api/getpoxinfo.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ pub struct RPCPoxInfoData {
111111
pub current_cycle: RPCPoxCurrentCycleInfo,
112112
pub next_cycle: RPCPoxNextCycleInfo,
113113
pub epochs: Vec<RPCPoxEpoch>,
114+
pub current_epoch: StacksEpochId,
114115

115116
// below are included for backwards-compatibility
116117
pub min_amount_ustx: u64,
@@ -354,11 +355,21 @@ impl RPCPoxInfoData {
354355
as u64;
355356

356357
let cur_cycle_pox_active = sortdb.is_pox_active(burnchain, &burnchain_tip)?;
357-
let epochs = SortitionDB::get_stacks_epochs(sortdb.conn())?
358+
let epochs: Vec<RPCPoxEpoch> = SortitionDB::get_stacks_epochs(sortdb.conn())?
358359
.to_vec()
359360
.into_iter()
360361
.map(RPCPoxEpoch::from)
361362
.collect();
363+
let burn_height = burnchain_tip.block_height;
364+
let current_epoch = epochs
365+
.iter()
366+
.fold(StacksEpochId::Epoch10, |acc, epoch_data| {
367+
if burn_height >= epoch_data.start_height {
368+
epoch_data.epoch_id
369+
} else {
370+
acc
371+
}
372+
});
362373

363374
Ok(RPCPoxInfoData {
364375
contract_id: boot_code_id(cur_block_pox_contract, chainstate.mainnet).to_string(),
@@ -388,6 +399,7 @@ impl RPCPoxInfoData {
388399
ustx_until_pox_rejection: rejection_votes_left_required,
389400
},
390401
epochs,
402+
current_epoch,
391403
min_amount_ustx: next_threshold,
392404
prepare_cycle_length,
393405
reward_cycle_id,

0 commit comments

Comments
 (0)