Skip to content

Commit 4152da0

Browse files
authored
Merge branch 'develop' into feat/audit-fixes
2 parents 4d0e333 + 0146ba2 commit 4152da0

File tree

38 files changed

+2338
-1467
lines changed

38 files changed

+2338
-1467
lines changed

.github/workflows/bitcoin-tests.yml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ jobs:
7474
- tests::neon_integrations::min_txs
7575
- tests::neon_integrations::vote_for_aggregate_key_burn_op_test
7676
- tests::neon_integrations::mock_miner_replay
77+
- tests::neon_integrations::listunspent_max_utxos
7778
- tests::epoch_25::microblocks_disabled
7879
- tests::should_succeed_handling_malformed_and_valid_txs
7980
- tests::nakamoto_integrations::simple_neon_integration
@@ -105,6 +106,10 @@ jobs:
105106
- tests::signer::v0::locally_rejected_blocks_overriden_by_global_acceptance
106107
- tests::signer::v0::reorg_locally_accepted_blocks_across_tenures_succeeds
107108
- tests::signer::v0::miner_recovers_when_broadcast_block_delay_across_tenures_occurs
109+
- tests::signer::v0::multiple_miners_with_nakamoto_blocks
110+
- tests::signer::v0::partial_tenure_fork
111+
- tests::signer::v0::mine_2_nakamoto_reward_cycles
112+
- tests::signer::v0::signer_set_rollover
108113
- tests::nakamoto_integrations::stack_stx_burn_op_integration_test
109114
- tests::nakamoto_integrations::check_block_heights
110115
- tests::nakamoto_integrations::clarity_burn_state
@@ -117,10 +122,6 @@ jobs:
117122
- tests::nakamoto_integrations::follower_bootup_across_multiple_cycles
118123
- tests::nakamoto_integrations::utxo_check_on_startup_panic
119124
- tests::nakamoto_integrations::utxo_check_on_startup_recover
120-
- tests::signer::v0::multiple_miners_with_nakamoto_blocks
121-
- tests::signer::v0::partial_tenure_fork
122-
- tests::signer::v0::mine_2_nakamoto_reward_cycles
123-
- tests::signer::v0::signer_set_rollover
124125
# Do not run this one until we figure out why it fails in CI
125126
# - tests::neon_integrations::bitcoin_reorg_flap
126127
# - tests::neon_integrations::bitcoin_reorg_flap_with_follower

.github/workflows/ci.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,29 @@ jobs:
186186
- check-release
187187
uses: ./.github/workflows/bitcoin-tests.yml
188188

189+
190+
p2p-tests:
191+
if: |
192+
needs.check-release.outputs.is_release == 'true' || (
193+
github.event_name == 'workflow_dispatch' ||
194+
github.event_name == 'pull_request' ||
195+
github.event_name == 'merge_group' ||
196+
(
197+
contains('
198+
refs/heads/master
199+
refs/heads/develop
200+
refs/heads/next
201+
', github.event.pull_request.head.ref) &&
202+
github.event_name == 'push'
203+
)
204+
)
205+
name: P2P Tests
206+
needs:
207+
- rustfmt
208+
- create-cache
209+
- check-release
210+
uses: ./.github/workflows/p2p-tests.yml
211+
189212
## Test to run on a tagged release
190213
##
191214
## Runs when:

.github/workflows/p2p-tests.yml

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
## Github workflow to run p2p tests
2+
3+
name: Tests::P2P
4+
5+
on:
6+
workflow_call:
7+
8+
## env vars are transferred to composite action steps
9+
env:
10+
BITCOIND_TEST: 0
11+
RUST_BACKTRACE: full
12+
SEGMENT_DOWNLOAD_TIMEOUT_MINS: 15
13+
TEST_TIMEOUT: 30
14+
15+
concurrency:
16+
group: stackslib-tests-${{ github.head_ref || github.ref || github.run_id}}
17+
## Only cancel in progress if this is for a PR
18+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
19+
20+
jobs:
21+
# p2p integration tests with code coverage
22+
integration-tests:
23+
name: Integration Tests
24+
runs-on: ubuntu-latest
25+
strategy:
26+
## Continue with the test matrix even if we've had a failure
27+
fail-fast: false
28+
## Run a maximum of 32 concurrent tests from the test matrix
29+
max-parallel: 32
30+
matrix:
31+
test-name:
32+
- net::tests::convergence::test_walk_ring_allow_15
33+
- net::tests::convergence::test_walk_ring_15_plain
34+
- net::tests::convergence::test_walk_ring_15_pingback
35+
- net::tests::convergence::test_walk_ring_15_org_biased
36+
- net::tests::convergence::test_walk_line_allowed_15
37+
- net::tests::convergence::test_walk_line_15_plain
38+
- net::tests::convergence::test_walk_line_15_org_biased
39+
- net::tests::convergence::test_walk_line_15_pingback
40+
- net::tests::convergence::test_walk_star_allowed_15
41+
- net::tests::convergence::test_walk_star_15_plain
42+
- net::tests::convergence::test_walk_star_15_pingback
43+
- net::tests::convergence::test_walk_star_15_org_biased
44+
- net::tests::convergence::test_walk_inbound_line_15
45+
steps:
46+
## Setup test environment
47+
- name: Setup Test Environment
48+
id: setup_tests
49+
uses: stacks-network/actions/stacks-core/testenv@main
50+
with:
51+
btc-version: "25.0"
52+
53+
## Increase open file descriptors limit
54+
- name: Increase Open File Descriptors
55+
run: |
56+
sudo prlimit --nofile=4096:4096
57+
58+
## Run test matrix using restored cache of archive file
59+
## - Test will timeout after env.TEST_TIMEOUT minutes
60+
- name: Run Tests
61+
id: run_tests
62+
timeout-minutes: ${{ fromJSON(env.TEST_TIMEOUT) }}
63+
uses: stacks-network/actions/stacks-core/run-tests@main
64+
with:
65+
test-name: ${{ matrix.test-name }}
66+
threads: 1
67+
68+
## Create and upload code coverage file
69+
- name: Code Coverage
70+
id: codecov
71+
uses: stacks-network/actions/codecov@main
72+
with:
73+
test-name: ${{ matrix.test-name }}
74+
75+
check-tests:
76+
name: Check Tests
77+
runs-on: ubuntu-latest
78+
if: always()
79+
needs:
80+
- integration-tests
81+
steps:
82+
- name: Check Tests Status
83+
id: check_tests_status
84+
uses: stacks-network/actions/check-jobs-status@main
85+
with:
86+
jobs: ${{ toJson(needs) }}
87+
summary_print: "true"

.github/workflows/standalone-tests.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ on:
2121
- Atlas Tests
2222
- Bitcoin Tests
2323
- Epoch Tests
24+
- P2P Tests
2425
- Slow Tests
2526
- Stacks-Core Tests
2627
- SBTC Tests
@@ -69,6 +70,23 @@ jobs:
6970
- create-cache
7071
uses: ./.github/workflows/bitcoin-tests.yml
7172

73+
## Runs when:
74+
## either or of the following:
75+
## - workflow is 'Release Tests'
76+
## - workflow is 'CI Tests'
77+
## - workflow is 'P2P Tests'
78+
p2p-tests:
79+
if: |
80+
(
81+
inputs.workflow == 'Release Tests' ||
82+
inputs.workflow == 'CI Tests' ||
83+
inputs.workflow == 'P2P Tests'
84+
)
85+
name: P2P Tests
86+
needs:
87+
- create-cache
88+
uses: ./.github/workflows/p2p-tests.yml
89+
7290
#####################################################
7391
## Runs when:
7492
## either or of the following:

Cargo.lock

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

stacks-signer/src/client/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,4 +603,9 @@ pub(crate) mod tests {
603603
serde_json::to_string(header_types).expect("Failed to serialize tenure tip info");
604604
format!("HTTP/1.1 200 OK\n\n{response_json}")
605605
}
606+
607+
pub fn build_get_last_set_cycle_response(cycle: u64) -> String {
608+
let clarity_value = ClarityValue::okay(ClarityValue::UInt(cycle as u128)).unwrap();
609+
build_read_only_response(&clarity_value)
610+
}
606611
}

stacks-signer/src/client/stacks_client.rs

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use std::net::SocketAddr;
1919
use blockstack_lib::burnchains::Txid;
2020
use blockstack_lib::chainstate::nakamoto::NakamotoBlock;
2121
use blockstack_lib::chainstate::stacks::boot::{
22-
NakamotoSignerEntry, SIGNERS_VOTING_FUNCTION_NAME, SIGNERS_VOTING_NAME,
22+
NakamotoSignerEntry, SIGNERS_NAME, SIGNERS_VOTING_FUNCTION_NAME, SIGNERS_VOTING_NAME,
2323
};
2424
use blockstack_lib::chainstate::stacks::db::StacksBlockHeaderTypes;
2525
use blockstack_lib::chainstate::stacks::{
@@ -162,6 +162,20 @@ impl StacksClient {
162162
Ok(sortition_info)
163163
}
164164

165+
/// Get the last set reward cycle stored within the stackerdb contract
166+
pub fn get_last_set_cycle(&self) -> Result<u128, ClientError> {
167+
let signer_stackerdb_contract_id = boot_code_id(SIGNERS_NAME, self.mainnet);
168+
let function_name_str = "get-last-set-cycle";
169+
let function_name = ClarityName::from(function_name_str);
170+
let value = self.read_only_contract_call(
171+
&signer_stackerdb_contract_id.issuer.clone().into(),
172+
&signer_stackerdb_contract_id.name,
173+
&function_name,
174+
&[],
175+
)?;
176+
Ok(value.expect_result_ok()?.expect_u128()?)
177+
}
178+
165179
/// Retrieve the signer slots stored within the stackerdb contract
166180
pub fn get_stackerdb_signer_slots(
167181
&self,
@@ -450,7 +464,10 @@ impl StacksClient {
450464
"last_sortition" => %last_sortition,
451465
);
452466
let path = self.tenure_forking_info_path(chosen_parent, last_sortition);
453-
let timer = crate::monitoring::new_rpc_call_timer(&path, &self.http_origin);
467+
let timer = crate::monitoring::new_rpc_call_timer(
468+
"/v3/tenures/fork_info/:start/:stop",
469+
&self.http_origin,
470+
);
454471
let send_request = || {
455472
self.stacks_node_client
456473
.get(&path)
@@ -491,7 +508,8 @@ impl StacksClient {
491508
pub fn get_sortition(&self, ch: &ConsensusHash) -> Result<SortitionInfo, ClientError> {
492509
debug!("stacks_node_client: Getting sortition with consensus hash {ch}...");
493510
let path = format!("{}/consensus/{}", self.sortition_info_path(), ch.to_hex());
494-
let timer = crate::monitoring::new_rpc_call_timer(&path, &self.http_origin);
511+
let timer_label = format!("{}/consensus/:consensus_hash", self.sortition_info_path());
512+
let timer = crate::monitoring::new_rpc_call_timer(&timer_label, &self.http_origin);
495513
let send_request = || {
496514
self.stacks_node_client.get(&path).send().map_err(|e| {
497515
warn!("Signer failed to request sortition"; "consensus_hash" => %ch, "err" => ?e);
@@ -561,7 +579,7 @@ impl StacksClient {
561579
) -> Result<Option<Vec<NakamotoSignerEntry>>, ClientError> {
562580
debug!("stacks_node_client: Getting reward set signers for reward cycle {reward_cycle}...");
563581
let timer = crate::monitoring::new_rpc_call_timer(
564-
&self.reward_set_path(reward_cycle),
582+
&format!("{}/v3/stacker_set/:reward_cycle", self.http_origin),
565583
&self.http_origin,
566584
);
567585
let send_request = || {
@@ -581,7 +599,7 @@ impl StacksClient {
581599
backoff::Error::permanent(e.into())
582600
})?;
583601
if error_data.err_type == GetStackersErrors::NOT_AVAILABLE_ERR_TYPE {
584-
Err(backoff::Error::transient(ClientError::NoSortitionOnChain))
602+
Err(backoff::Error::permanent(ClientError::NoSortitionOnChain))
585603
} else {
586604
warn!("Got error response ({status}): {}", error_data.err_msg);
587605
Err(backoff::Error::permanent(ClientError::RequestFailure(
@@ -644,8 +662,8 @@ impl StacksClient {
644662
address: &StacksAddress,
645663
) -> Result<AccountEntryResponse, ClientError> {
646664
debug!("stacks_node_client: Getting account info...");
647-
let timer =
648-
crate::monitoring::new_rpc_call_timer(&self.accounts_path(address), &self.http_origin);
665+
let timer_label = format!("{}/v2/accounts/:principal", self.http_origin);
666+
let timer = crate::monitoring::new_rpc_call_timer(&timer_label, &self.http_origin);
649667
let send_request = || {
650668
self.stacks_node_client
651669
.get(self.accounts_path(address))
@@ -797,7 +815,11 @@ impl StacksClient {
797815
let body =
798816
json!({"sender": self.stacks_address.to_string(), "arguments": args}).to_string();
799817
let path = self.read_only_path(contract_addr, contract_name, function_name);
800-
let timer = crate::monitoring::new_rpc_call_timer(&path, &self.http_origin);
818+
let timer_label = format!(
819+
"{}/v2/contracts/call-read/:principal/{contract_name}/{function_name}",
820+
self.http_origin
821+
);
822+
let timer = crate::monitoring::new_rpc_call_timer(&timer_label, &self.http_origin);
801823
let response = self
802824
.stacks_node_client
803825
.post(path)
@@ -962,11 +984,11 @@ mod tests {
962984
use super::*;
963985
use crate::client::tests::{
964986
build_account_nonce_response, build_get_approved_aggregate_key_response,
965-
build_get_last_round_response, build_get_medium_estimated_fee_ustx_response,
966-
build_get_peer_info_response, build_get_pox_data_response, build_get_round_info_response,
967-
build_get_tenure_tip_response, build_get_vote_for_aggregate_key_response,
968-
build_get_weight_threshold_response, build_read_only_response, write_response,
969-
MockServerClient,
987+
build_get_last_round_response, build_get_last_set_cycle_response,
988+
build_get_medium_estimated_fee_ustx_response, build_get_peer_info_response,
989+
build_get_pox_data_response, build_get_round_info_response, build_get_tenure_tip_response,
990+
build_get_vote_for_aggregate_key_response, build_get_weight_threshold_response,
991+
build_read_only_response, write_response, MockServerClient,
970992
};
971993

972994
#[test]
@@ -1623,4 +1645,14 @@ mod tests {
16231645
write_response(mock.server, response.as_bytes());
16241646
assert_eq!(h.join().unwrap().unwrap(), header);
16251647
}
1648+
1649+
#[test]
1650+
fn get_last_set_cycle_should_succeed() {
1651+
let mock = MockServerClient::new();
1652+
let reward_cycle = thread_rng().next_u64();
1653+
let response = build_get_last_set_cycle_response(reward_cycle);
1654+
let h = spawn(move || mock.client.get_last_set_cycle());
1655+
write_response(mock.server, response.as_bytes());
1656+
assert_eq!(h.join().unwrap().unwrap(), reward_cycle as u128);
1657+
}
16261658
}

0 commit comments

Comments
 (0)