Skip to content

Commit 5a76b47

Browse files
committed
Merge remote-tracking branch 'origin/develop' into feat/add-version-to-block-proposal
2 parents 4572469 + ea79fdc commit 5a76b47

File tree

26 files changed

+1181
-159
lines changed

26 files changed

+1181
-159
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,12 @@ and this project adheres to the versioning scheme outlined in the [README.md](RE
1010
### Added
1111

1212
- The `BlockProposal` StackerDB message serialization struct now includes a `server_version` string, which represents the version of the node that the miner is using. ([#5803](https://github.com/stacks-network/stacks-core/pull/5803))
13+
- Add `vrf_seed` to the `/v3/sortitions` rpc endpoint
1314

1415
### Changed
1516

17+
- Miner will stop waiting for signatures on a block if the Stacks tip advances (causing the block it had proposed to be invalid).
18+
1619
### Fixed
1720

1821
- Error responses to /v2/transactions/fees are once again expressed as JSON ([#4145](https://github.com/stacks-network/stacks-core/issues/4145)).

contrib/tools/block-replay.sh

Lines changed: 471 additions & 0 deletions
Large diffs are not rendered by default.

docs/rpc/api/core-node/get_sortitions.example.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"miner_pk_hash160": "0x6bc51b33e9f3626944eb879147e18111581f8f9b",
1111
"stacks_parent_ch": "0x697357c72da55b759b1d6b721676c92c69f0b490",
1212
"last_sortition_ch": "0x697357c72da55b759b1d6b721676c92c69f0b490",
13-
"committed_block_hash": "0xeea47d6d639c565027110e192e308fb11656183d5c077bcd718d830652800183"
13+
"committed_block_hash": "0xeea47d6d639c565027110e192e308fb11656183d5c077bcd718d830652800183",
14+
"vrf_seed": "0x48b754acc291a5bfad1354ee19bbc471f14af2b21dc7eccc0f929bd16798defe"
1415
}
1516
]

stacks-signer/src/tests/chainstate.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,7 @@ fn check_proposal_refresh() {
559559
stacks_parent_ch: Some(view.cur_sortition.parent_tenure_id),
560560
last_sortition_ch: Some(view.cur_sortition.parent_tenure_id),
561561
committed_block_hash: None,
562+
vrf_seed: None,
562563
},
563564
SortitionInfo {
564565
burn_block_hash: BurnchainHeaderHash([128; 32]),
@@ -572,6 +573,7 @@ fn check_proposal_refresh() {
572573
stacks_parent_ch: Some(view.cur_sortition.parent_tenure_id),
573574
last_sortition_ch: Some(view.cur_sortition.parent_tenure_id),
574575
committed_block_hash: None,
576+
vrf_seed: None,
575577
},
576578
];
577579

stacks-signer/src/v0/signer.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,10 @@ impl SignerTrait<SignerMessage> for Signer {
207207
"block_height" => b.header.chain_length,
208208
"signer_sighash" => %b.header.signer_signature_hash(),
209209
);
210+
#[cfg(any(test, feature = "testing"))]
211+
if self.test_skip_block_broadcast(b) {
212+
return;
213+
}
210214
stacks_client.post_block_until_ok(self, b);
211215
}
212216
SignerMessage::MockProposal(mock_proposal) => {

stackslib/src/burnchains/bitcoin/indexer.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -234,10 +234,7 @@ impl BitcoinIndexer {
234234
true,
235235
false,
236236
)
237-
.expect(&format!(
238-
"Failed to open {:?}",
239-
working_dir_path.to_str().unwrap()
240-
));
237+
.unwrap_or_else(|_| panic!("Failed to open {working_dir_path:?}"));
241238

242239
BitcoinIndexer {
243240
config: BitcoinIndexerConfig::default_regtest(

stackslib/src/burnchains/tests/mod.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -439,10 +439,7 @@ impl TestBurnchainBlock {
439439
// prove on the last-ever sortition's hash to produce the new seed
440440
let proof = miner
441441
.make_proof(&leader_key.public_key, &last_snapshot.sortition_hash)
442-
.expect(&format!(
443-
"FATAL: no private key for {}",
444-
leader_key.public_key.to_hex()
445-
));
442+
.unwrap_or_else(|| panic!("FATAL: no private key for {:?}", leader_key.public_key));
446443

447444
VRFSeed::from_proof(&proof)
448445
});
@@ -655,10 +652,12 @@ impl TestBurnchainBlock {
655652
let parent_hdr = indexer
656653
.read_burnchain_header(self.block_height.saturating_sub(1))
657654
.unwrap()
658-
.expect(&format!(
659-
"BUG: could not read block at height {}",
660-
self.block_height.saturating_sub(1)
661-
));
655+
.unwrap_or_else(|| {
656+
panic!(
657+
"BUG: could not read block at height {}",
658+
self.block_height.saturating_sub(1)
659+
)
660+
});
662661

663662
let now = BURNCHAIN_TEST_BLOCK_TIME;
664663
let block_hash = BurnchainHeaderHash::from_bitcoin_hash(

stackslib/src/chainstate/nakamoto/tests/node.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1344,7 +1344,7 @@ impl TestPeer<'_> {
13441344
);
13451345
}
13461346
Err(e) => {
1347-
panic!("Failure fetching recipient set: {:?}", e);
1347+
panic!("Failure fetching recipient set: {e:?}");
13481348
}
13491349
};
13501350

@@ -1368,16 +1368,11 @@ impl TestPeer<'_> {
13681368
let proof = self
13691369
.miner
13701370
.make_proof(&miner_key.public_key, &tip.sortition_hash)
1371-
.expect(&format!(
1372-
"FATAL: no private key for {}",
1373-
miner_key.public_key.to_hex()
1374-
));
1371+
.unwrap_or_else(|| panic!("FATAL: no private key for {:?}", miner_key.public_key));
13751372
self.sortdb = Some(sortdb);
13761373
debug!(
1377-
"VRF proof made from {} over {}: {}",
1378-
&miner_key.public_key.to_hex(),
1379-
&tip.sortition_hash,
1380-
&proof.to_hex()
1374+
"VRF proof made from {:?} over {}: {proof:?}",
1375+
miner_key.public_key, &tip.sortition_hash
13811376
);
13821377
proof
13831378
}

stackslib/src/chainstate/stacks/boot/pox_2_tests.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -334,10 +334,7 @@ pub fn check_stacking_state_invariants(
334334
.burn_header_height;
335335

336336
let stacking_state_entry = get_stacking_state_pox(peer, tip, stacker, active_pox_contract)
337-
.expect(&format!(
338-
"Invariant violated: reward-cycle entry has stacker field set, but not present in stacker-state (pox_contract = {})",
339-
active_pox_contract,
340-
))
337+
.unwrap_or_else(|| panic!("Invariant violated: reward-cycle entry has stacker field set, but not present in stacker-state (pox_contract = {active_pox_contract})"))
341338
.expect_tuple().unwrap();
342339
let first_cycle = stacking_state_entry
343340
.get("first-reward-cycle")

stackslib/src/chainstate/stacks/boot/pox_4_tests.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8353,9 +8353,9 @@ fn test_scenario_three(use_nakamoto: bool) {
83538353
assert_eq!(amount_locked_actual, amount_locked_expected);
83548354

83558355
// Check Bob signer key
8356-
let signer_key_expected = Value::buff_from(bob.public_key.to_bytes_compressed());
8356+
let signer_key_expected = Value::buff_from(bob.public_key.to_bytes_compressed()).unwrap();
83578357
let signer_key_actual = bob_stack_tx_ok.data_map.get("signer-key").unwrap().clone();
8358-
assert_eq!(signer_key_actual, signer_key_actual);
8358+
assert_eq!(signer_key_actual, signer_key_expected);
83598359

83608360
// 5. Check that David can't delegate-stack-stx Eve if delegation expires during lock period
83618361
let eve_delegate_stx_to_david_err = receipts
@@ -10262,7 +10262,7 @@ fn test_scenario_five(use_nakamoto: bool) {
1026210262
for (idx, (stacker, stacker_lock_period)) in davids_stackers.iter().enumerate() {
1026310263
let (pox_address, first_reward_cycle, lock_period, _indices) =
1026410264
get_stacker_info_pox_4(&mut peer, &stacker.principal)
10265-
.expect(format!("Failed to find stacker {}", idx).as_str());
10265+
.unwrap_or_else(|| panic!("Failed to find stacker {idx}"));
1026610266
assert_eq!(first_reward_cycle, reward_cycle);
1026710267
assert_eq!(pox_address, david.pox_address);
1026810268
assert_eq!(lock_period, *stacker_lock_period);
@@ -10271,7 +10271,7 @@ fn test_scenario_five(use_nakamoto: bool) {
1027110271
for (idx, (stacker, stacker_lock_period)) in eves_stackers.iter().enumerate() {
1027210272
let (pox_address, first_reward_cycle, lock_period, _indices) =
1027310273
get_stacker_info_pox_4(&mut peer, &stacker.principal)
10274-
.expect(format!("Failed to find stacker {}", idx).as_str());
10274+
.unwrap_or_else(|| panic!("Failed to find stacker {idx}"));
1027510275
assert_eq!(first_reward_cycle, reward_cycle);
1027610276
assert_eq!(pox_address, eve.pox_address);
1027710277
assert_eq!(lock_period, *stacker_lock_period);

stackslib/src/chainstate/stacks/tests/mod.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -609,10 +609,7 @@ impl TestStacksNode {
609609
&miner_key.public_key,
610610
&burn_block.parent_snapshot.sortition_hash,
611611
)
612-
.expect(&format!(
613-
"FATAL: no private key for {}",
614-
miner_key.public_key.to_hex()
615-
));
612+
.unwrap_or_else(|| panic!("FATAL: no private key for {:?}", miner_key.public_key));
616613

617614
let (builder, parent_block_snapshot_opt) = match parent_stacks_block {
618615
None => {

stackslib/src/config/mod.rs

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1691,40 +1691,25 @@ pub struct NodeConfig {
16911691
pub stacker_dbs: Vec<QualifiedContractIdentifier>,
16921692
}
16931693

1694-
#[derive(Clone, Debug)]
1694+
#[derive(Clone, Debug, Default)]
16951695
pub enum CostEstimatorName {
1696+
#[default]
16961697
NaivePessimistic,
16971698
}
16981699

1699-
#[derive(Clone, Debug)]
1700+
#[derive(Clone, Debug, Default)]
17001701
pub enum FeeEstimatorName {
1702+
#[default]
17011703
ScalarFeeRate,
17021704
FuzzedWeightedMedianFeeRate,
17031705
}
17041706

1705-
#[derive(Clone, Debug)]
1707+
#[derive(Clone, Debug, Default)]
17061708
pub enum CostMetricName {
1709+
#[default]
17071710
ProportionDotProduct,
17081711
}
17091712

1710-
impl Default for CostEstimatorName {
1711-
fn default() -> Self {
1712-
CostEstimatorName::NaivePessimistic
1713-
}
1714-
}
1715-
1716-
impl Default for FeeEstimatorName {
1717-
fn default() -> Self {
1718-
FeeEstimatorName::ScalarFeeRate
1719-
}
1720-
}
1721-
1722-
impl Default for CostMetricName {
1723-
fn default() -> Self {
1724-
CostMetricName::ProportionDotProduct
1725-
}
1726-
}
1727-
17281713
impl CostEstimatorName {
17291714
fn panic_parse(s: String) -> CostEstimatorName {
17301715
if &s.to_lowercase() == "naive_pessimistic" {

stackslib/src/net/api/getsortition.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@
1616
use std::io::{Read, Seek, SeekFrom, Write};
1717
use std::{fs, io};
1818

19+
use clarity::types::chainstate::VRFSeed;
1920
use regex::{Captures, Regex};
2021
use serde::de::Error as de_Error;
22+
use serde::Serialize;
2123
use stacks_common::codec::{StacksMessageCodec, MAX_MESSAGE_LEN};
2224
use stacks_common::types::chainstate::{
2325
BlockHeaderHash, BurnchainHeaderHash, ConsensusHash, SortitionId, StacksBlockId,
@@ -111,6 +113,9 @@ pub struct SortitionInfo {
111113
/// In Stacks 2.x, this is the winning block.
112114
/// In Stacks 3.x, this is the first block of the parent tenure.
113115
pub committed_block_hash: Option<BlockHeaderHash>,
116+
#[serde(with = "prefix_opt_hex")]
117+
/// This is the VRF seed generated by this sortition
118+
pub vrf_seed: Option<VRFSeed>,
114119
}
115120

116121
impl TryFrom<(&str, &str)> for QuerySpecifier {
@@ -163,12 +168,12 @@ impl GetSortitionHandler {
163168
let is_shadow = chainstate
164169
.nakamoto_blocks_db()
165170
.is_shadow_tenure(&sortition_sn.consensus_hash)?;
166-
let (miner_pk_hash160, stacks_parent_ch, committed_block_hash, last_sortition_ch) =
171+
let (miner_pk_hash160, stacks_parent_ch, committed_block_hash, last_sortition_ch, vrf_seed) =
167172
if !sortition_sn.sortition && !is_shadow {
168173
let handle = sortdb.index_handle(&sortition_sn.sortition_id);
169174
let last_sortition =
170175
handle.get_last_snapshot_with_sortition(sortition_sn.block_height)?;
171-
(None, None, None, Some(last_sortition.consensus_hash))
176+
(None, None, None, Some(last_sortition.consensus_hash), None)
172177
} else if !sortition_sn.sortition && is_shadow {
173178
// this is a shadow tenure.
174179
let parent_tenure_ch = chainstate
@@ -191,6 +196,7 @@ impl GetSortitionHandler {
191196
parent_tenure_start_header.index_block_hash().0,
192197
)),
193198
Some(parent_tenure_ch),
199+
None,
194200
)
195201
} else {
196202
let block_commit = SortitionDB::get_block_commit(sortdb.conn(), &sortition_sn.winning_block_txid, &sortition_sn.sortition_id)?
@@ -236,6 +242,7 @@ impl GetSortitionHandler {
236242
Some(stacks_parent_sn.consensus_hash),
237243
Some(block_commit.block_header_hash),
238244
Some(last_sortition_ch),
245+
Some(block_commit.new_seed),
239246
)
240247
};
241248

@@ -251,6 +258,7 @@ impl GetSortitionHandler {
251258
stacks_parent_ch,
252259
last_sortition_ch,
253260
committed_block_hash,
261+
vrf_seed,
254262
})
255263
}
256264
}

stackslib/src/net/api/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
// You should have received a copy of the GNU General Public License
1515
// along with this program. If not, see <http://www.gnu.org/licenses/>.
1616

17+
use clarity::types::chainstate::VRFSeed;
1718
use clarity::vm::costs::ExecutionCost;
1819
use stacks_common::codec::read_next;
1920
use stacks_common::types::chainstate::{
@@ -239,6 +240,7 @@ macro_rules! impl_hex_deser {
239240
impl_hex_deser!(BurnchainHeaderHash);
240241
impl_hex_deser!(StacksBlockId);
241242
impl_hex_deser!(SortitionId);
243+
impl_hex_deser!(VRFSeed);
242244
impl_hex_deser!(ConsensusHash);
243245
impl_hex_deser!(BlockHeaderHash);
244246
impl_hex_deser!(Hash160);

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use std::collections::BTreeMap;
1717
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
1818

19+
use clarity::types::chainstate::VRFSeed;
1920
use stacks_common::types::chainstate::{BurnchainHeaderHash, ConsensusHash};
2021
use stacks_common::types::net::PeerHost;
2122

@@ -159,6 +160,13 @@ fn response() {
159160
let second_entry: SortitionInfo = serde_json::from_value(info_array[1].clone())
160161
.expect("Response array elements should parse to SortitionInfo");
161162
assert!(first_entry.was_sortition);
163+
assert_eq!(
164+
first_entry.vrf_seed,
165+
Some(
166+
VRFSeed::from_hex("48b754acc291a5bfad1354ee19bbc471f14af2b21dc7eccc0f929bd16798defe")
167+
.unwrap()
168+
)
169+
);
162170
assert!(second_entry.was_sortition);
163171
assert_eq!(
164172
first_entry.last_sortition_ch.as_ref().unwrap(),

stackslib/src/net/chat.rs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,21 +52,12 @@ use crate::net::{
5252
use crate::util_lib::db::{DBConn, Error as db_error};
5353

5454
// did we or did we not successfully send a message?
55-
#[derive(Debug, Clone)]
55+
#[derive(Debug, Clone, Default)]
5656
pub struct NeighborHealthPoint {
5757
pub success: bool,
5858
pub time: u64,
5959
}
6060

61-
impl Default for NeighborHealthPoint {
62-
fn default() -> NeighborHealthPoint {
63-
NeighborHealthPoint {
64-
success: false,
65-
time: 0,
66-
}
67-
}
68-
}
69-
7061
pub const NUM_HEALTH_POINTS: usize = 32;
7162
pub const HEALTH_POINT_LIFETIME: u64 = 12 * 3600; // 12 hours
7263

stackslib/src/net/download/nakamoto/tenure.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -345,10 +345,12 @@ impl TenureStartEnd {
345345
rc,
346346
pox_constants
347347
.block_height_to_reward_cycle(first_burn_height, wt_start.burn_height)
348-
.expect(&format!(
349-
"FATAL: tenure from before system start ({} <= {})",
350-
wt_start.burn_height, first_burn_height
351-
)),
348+
.unwrap_or_else(|| {
349+
panic!(
350+
"FATAL: tenure from before system start ({} <= {first_burn_height})",
351+
wt_start.burn_height
352+
)
353+
}),
352354
wt.processed,
353355
);
354356
tenure_start_end.fetch_end_block = true;

stackslib/src/net/httpcore.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1014,10 +1014,9 @@ impl StacksHttp {
10141014
pub fn set_response_handler(&mut self, request_verb: &str, request_path: &str) {
10151015
let handler_index = self
10161016
.find_response_handler(request_verb, request_path)
1017-
.expect(&format!(
1018-
"FATAL: could not find handler for '{}' '{}'",
1019-
request_verb, request_path
1020-
));
1017+
.unwrap_or_else(|| {
1018+
panic!("FATAL: could not find handler for '{request_verb}' '{request_path}'")
1019+
});
10211020
self.request_handler_index = Some(handler_index);
10221021
}
10231022

0 commit comments

Comments
 (0)