Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop' into feat/add-version-t…
Browse files Browse the repository at this point in the history
…o-block-proposal
  • Loading branch information
hstove committed Feb 7, 2025
2 parents 4572469 + ea79fdc commit 5a76b47
Show file tree
Hide file tree
Showing 26 changed files with 1,181 additions and 159 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@ and this project adheres to the versioning scheme outlined in the [README.md](RE
### Added

- 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))
- Add `vrf_seed` to the `/v3/sortitions` rpc endpoint

### Changed

- Miner will stop waiting for signatures on a block if the Stacks tip advances (causing the block it had proposed to be invalid).

### Fixed

- Error responses to /v2/transactions/fees are once again expressed as JSON ([#4145](https://github.com/stacks-network/stacks-core/issues/4145)).
Expand Down
471 changes: 471 additions & 0 deletions contrib/tools/block-replay.sh

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion docs/rpc/api/core-node/get_sortitions.example.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"miner_pk_hash160": "0x6bc51b33e9f3626944eb879147e18111581f8f9b",
"stacks_parent_ch": "0x697357c72da55b759b1d6b721676c92c69f0b490",
"last_sortition_ch": "0x697357c72da55b759b1d6b721676c92c69f0b490",
"committed_block_hash": "0xeea47d6d639c565027110e192e308fb11656183d5c077bcd718d830652800183"
"committed_block_hash": "0xeea47d6d639c565027110e192e308fb11656183d5c077bcd718d830652800183",
"vrf_seed": "0x48b754acc291a5bfad1354ee19bbc471f14af2b21dc7eccc0f929bd16798defe"
}
]
2 changes: 2 additions & 0 deletions stacks-signer/src/tests/chainstate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,7 @@ fn check_proposal_refresh() {
stacks_parent_ch: Some(view.cur_sortition.parent_tenure_id),
last_sortition_ch: Some(view.cur_sortition.parent_tenure_id),
committed_block_hash: None,
vrf_seed: None,
},
SortitionInfo {
burn_block_hash: BurnchainHeaderHash([128; 32]),
Expand All @@ -572,6 +573,7 @@ fn check_proposal_refresh() {
stacks_parent_ch: Some(view.cur_sortition.parent_tenure_id),
last_sortition_ch: Some(view.cur_sortition.parent_tenure_id),
committed_block_hash: None,
vrf_seed: None,
},
];

Expand Down
4 changes: 4 additions & 0 deletions stacks-signer/src/v0/signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,10 @@ impl SignerTrait<SignerMessage> for Signer {
"block_height" => b.header.chain_length,
"signer_sighash" => %b.header.signer_signature_hash(),
);
#[cfg(any(test, feature = "testing"))]
if self.test_skip_block_broadcast(b) {
return;
}
stacks_client.post_block_until_ok(self, b);
}
SignerMessage::MockProposal(mock_proposal) => {
Expand Down
5 changes: 1 addition & 4 deletions stackslib/src/burnchains/bitcoin/indexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,10 +234,7 @@ impl BitcoinIndexer {
true,
false,
)
.expect(&format!(
"Failed to open {:?}",
working_dir_path.to_str().unwrap()
));
.unwrap_or_else(|_| panic!("Failed to open {working_dir_path:?}"));

BitcoinIndexer {
config: BitcoinIndexerConfig::default_regtest(
Expand Down
15 changes: 7 additions & 8 deletions stackslib/src/burnchains/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -439,10 +439,7 @@ impl TestBurnchainBlock {
// prove on the last-ever sortition's hash to produce the new seed
let proof = miner
.make_proof(&leader_key.public_key, &last_snapshot.sortition_hash)
.expect(&format!(
"FATAL: no private key for {}",
leader_key.public_key.to_hex()
));
.unwrap_or_else(|| panic!("FATAL: no private key for {:?}", leader_key.public_key));

VRFSeed::from_proof(&proof)
});
Expand Down Expand Up @@ -655,10 +652,12 @@ impl TestBurnchainBlock {
let parent_hdr = indexer
.read_burnchain_header(self.block_height.saturating_sub(1))
.unwrap()
.expect(&format!(
"BUG: could not read block at height {}",
self.block_height.saturating_sub(1)
));
.unwrap_or_else(|| {
panic!(
"BUG: could not read block at height {}",
self.block_height.saturating_sub(1)
)
});

let now = BURNCHAIN_TEST_BLOCK_TIME;
let block_hash = BurnchainHeaderHash::from_bitcoin_hash(
Expand Down
13 changes: 4 additions & 9 deletions stackslib/src/chainstate/nakamoto/tests/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1344,7 +1344,7 @@ impl TestPeer<'_> {
);
}
Err(e) => {
panic!("Failure fetching recipient set: {:?}", e);
panic!("Failure fetching recipient set: {e:?}");
}
};

Expand All @@ -1368,16 +1368,11 @@ impl TestPeer<'_> {
let proof = self
.miner
.make_proof(&miner_key.public_key, &tip.sortition_hash)
.expect(&format!(
"FATAL: no private key for {}",
miner_key.public_key.to_hex()
));
.unwrap_or_else(|| panic!("FATAL: no private key for {:?}", miner_key.public_key));
self.sortdb = Some(sortdb);
debug!(
"VRF proof made from {} over {}: {}",
&miner_key.public_key.to_hex(),
&tip.sortition_hash,
&proof.to_hex()
"VRF proof made from {:?} over {}: {proof:?}",
miner_key.public_key, &tip.sortition_hash
);
proof
}
Expand Down
5 changes: 1 addition & 4 deletions stackslib/src/chainstate/stacks/boot/pox_2_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,10 +334,7 @@ pub fn check_stacking_state_invariants(
.burn_header_height;

let stacking_state_entry = get_stacking_state_pox(peer, tip, stacker, active_pox_contract)
.expect(&format!(
"Invariant violated: reward-cycle entry has stacker field set, but not present in stacker-state (pox_contract = {})",
active_pox_contract,
))
.unwrap_or_else(|| panic!("Invariant violated: reward-cycle entry has stacker field set, but not present in stacker-state (pox_contract = {active_pox_contract})"))
.expect_tuple().unwrap();
let first_cycle = stacking_state_entry
.get("first-reward-cycle")
Expand Down
8 changes: 4 additions & 4 deletions stackslib/src/chainstate/stacks/boot/pox_4_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8353,9 +8353,9 @@ fn test_scenario_three(use_nakamoto: bool) {
assert_eq!(amount_locked_actual, amount_locked_expected);

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

// 5. Check that David can't delegate-stack-stx Eve if delegation expires during lock period
let eve_delegate_stx_to_david_err = receipts
Expand Down Expand Up @@ -10262,7 +10262,7 @@ fn test_scenario_five(use_nakamoto: bool) {
for (idx, (stacker, stacker_lock_period)) in davids_stackers.iter().enumerate() {
let (pox_address, first_reward_cycle, lock_period, _indices) =
get_stacker_info_pox_4(&mut peer, &stacker.principal)
.expect(format!("Failed to find stacker {}", idx).as_str());
.unwrap_or_else(|| panic!("Failed to find stacker {idx}"));
assert_eq!(first_reward_cycle, reward_cycle);
assert_eq!(pox_address, david.pox_address);
assert_eq!(lock_period, *stacker_lock_period);
Expand All @@ -10271,7 +10271,7 @@ fn test_scenario_five(use_nakamoto: bool) {
for (idx, (stacker, stacker_lock_period)) in eves_stackers.iter().enumerate() {
let (pox_address, first_reward_cycle, lock_period, _indices) =
get_stacker_info_pox_4(&mut peer, &stacker.principal)
.expect(format!("Failed to find stacker {}", idx).as_str());
.unwrap_or_else(|| panic!("Failed to find stacker {idx}"));
assert_eq!(first_reward_cycle, reward_cycle);
assert_eq!(pox_address, eve.pox_address);
assert_eq!(lock_period, *stacker_lock_period);
Expand Down
5 changes: 1 addition & 4 deletions stackslib/src/chainstate/stacks/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -609,10 +609,7 @@ impl TestStacksNode {
&miner_key.public_key,
&burn_block.parent_snapshot.sortition_hash,
)
.expect(&format!(
"FATAL: no private key for {}",
miner_key.public_key.to_hex()
));
.unwrap_or_else(|| panic!("FATAL: no private key for {:?}", miner_key.public_key));

let (builder, parent_block_snapshot_opt) = match parent_stacks_block {
None => {
Expand Down
27 changes: 6 additions & 21 deletions stackslib/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1691,40 +1691,25 @@ pub struct NodeConfig {
pub stacker_dbs: Vec<QualifiedContractIdentifier>,
}

#[derive(Clone, Debug)]
#[derive(Clone, Debug, Default)]
pub enum CostEstimatorName {
#[default]
NaivePessimistic,
}

#[derive(Clone, Debug)]
#[derive(Clone, Debug, Default)]
pub enum FeeEstimatorName {
#[default]
ScalarFeeRate,
FuzzedWeightedMedianFeeRate,
}

#[derive(Clone, Debug)]
#[derive(Clone, Debug, Default)]
pub enum CostMetricName {
#[default]
ProportionDotProduct,
}

impl Default for CostEstimatorName {
fn default() -> Self {
CostEstimatorName::NaivePessimistic
}
}

impl Default for FeeEstimatorName {
fn default() -> Self {
FeeEstimatorName::ScalarFeeRate
}
}

impl Default for CostMetricName {
fn default() -> Self {
CostMetricName::ProportionDotProduct
}
}

impl CostEstimatorName {
fn panic_parse(s: String) -> CostEstimatorName {
if &s.to_lowercase() == "naive_pessimistic" {
Expand Down
12 changes: 10 additions & 2 deletions stackslib/src/net/api/getsortition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@
use std::io::{Read, Seek, SeekFrom, Write};
use std::{fs, io};

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

impl TryFrom<(&str, &str)> for QuerySpecifier {
Expand Down Expand Up @@ -163,12 +168,12 @@ impl GetSortitionHandler {
let is_shadow = chainstate
.nakamoto_blocks_db()
.is_shadow_tenure(&sortition_sn.consensus_hash)?;
let (miner_pk_hash160, stacks_parent_ch, committed_block_hash, last_sortition_ch) =
let (miner_pk_hash160, stacks_parent_ch, committed_block_hash, last_sortition_ch, vrf_seed) =
if !sortition_sn.sortition && !is_shadow {
let handle = sortdb.index_handle(&sortition_sn.sortition_id);
let last_sortition =
handle.get_last_snapshot_with_sortition(sortition_sn.block_height)?;
(None, None, None, Some(last_sortition.consensus_hash))
(None, None, None, Some(last_sortition.consensus_hash), None)
} else if !sortition_sn.sortition && is_shadow {
// this is a shadow tenure.
let parent_tenure_ch = chainstate
Expand All @@ -191,6 +196,7 @@ impl GetSortitionHandler {
parent_tenure_start_header.index_block_hash().0,
)),
Some(parent_tenure_ch),
None,
)
} else {
let block_commit = SortitionDB::get_block_commit(sortdb.conn(), &sortition_sn.winning_block_txid, &sortition_sn.sortition_id)?
Expand Down Expand Up @@ -236,6 +242,7 @@ impl GetSortitionHandler {
Some(stacks_parent_sn.consensus_hash),
Some(block_commit.block_header_hash),
Some(last_sortition_ch),
Some(block_commit.new_seed),
)
};

Expand All @@ -251,6 +258,7 @@ impl GetSortitionHandler {
stacks_parent_ch,
last_sortition_ch,
committed_block_hash,
vrf_seed,
})
}
}
Expand Down
2 changes: 2 additions & 0 deletions stackslib/src/net/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

use clarity::types::chainstate::VRFSeed;
use clarity::vm::costs::ExecutionCost;
use stacks_common::codec::read_next;
use stacks_common::types::chainstate::{
Expand Down Expand Up @@ -239,6 +240,7 @@ macro_rules! impl_hex_deser {
impl_hex_deser!(BurnchainHeaderHash);
impl_hex_deser!(StacksBlockId);
impl_hex_deser!(SortitionId);
impl_hex_deser!(VRFSeed);
impl_hex_deser!(ConsensusHash);
impl_hex_deser!(BlockHeaderHash);
impl_hex_deser!(Hash160);
8 changes: 8 additions & 0 deletions stackslib/src/net/api/tests/getsortition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use std::collections::BTreeMap;
use std::net::{IpAddr, Ipv4Addr, SocketAddr};

use clarity::types::chainstate::VRFSeed;
use stacks_common::types::chainstate::{BurnchainHeaderHash, ConsensusHash};
use stacks_common::types::net::PeerHost;

Expand Down Expand Up @@ -159,6 +160,13 @@ fn response() {
let second_entry: SortitionInfo = serde_json::from_value(info_array[1].clone())
.expect("Response array elements should parse to SortitionInfo");
assert!(first_entry.was_sortition);
assert_eq!(
first_entry.vrf_seed,
Some(
VRFSeed::from_hex("48b754acc291a5bfad1354ee19bbc471f14af2b21dc7eccc0f929bd16798defe")
.unwrap()
)
);
assert!(second_entry.was_sortition);
assert_eq!(
first_entry.last_sortition_ch.as_ref().unwrap(),
Expand Down
11 changes: 1 addition & 10 deletions stackslib/src/net/chat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,21 +52,12 @@ use crate::net::{
use crate::util_lib::db::{DBConn, Error as db_error};

// did we or did we not successfully send a message?
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Default)]
pub struct NeighborHealthPoint {
pub success: bool,
pub time: u64,
}

impl Default for NeighborHealthPoint {
fn default() -> NeighborHealthPoint {
NeighborHealthPoint {
success: false,
time: 0,
}
}
}

pub const NUM_HEALTH_POINTS: usize = 32;
pub const HEALTH_POINT_LIFETIME: u64 = 12 * 3600; // 12 hours

Expand Down
10 changes: 6 additions & 4 deletions stackslib/src/net/download/nakamoto/tenure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,10 +345,12 @@ impl TenureStartEnd {
rc,
pox_constants
.block_height_to_reward_cycle(first_burn_height, wt_start.burn_height)
.expect(&format!(
"FATAL: tenure from before system start ({} <= {})",
wt_start.burn_height, first_burn_height
)),
.unwrap_or_else(|| {
panic!(
"FATAL: tenure from before system start ({} <= {first_burn_height})",
wt_start.burn_height
)
}),
wt.processed,
);
tenure_start_end.fetch_end_block = true;
Expand Down
7 changes: 3 additions & 4 deletions stackslib/src/net/httpcore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1014,10 +1014,9 @@ impl StacksHttp {
pub fn set_response_handler(&mut self, request_verb: &str, request_path: &str) {
let handler_index = self
.find_response_handler(request_verb, request_path)
.expect(&format!(
"FATAL: could not find handler for '{}' '{}'",
request_verb, request_path
));
.unwrap_or_else(|| {
panic!("FATAL: could not find handler for '{request_verb}' '{request_path}'")
});
self.request_handler_index = Some(handler_index);
}

Expand Down
Loading

0 comments on commit 5a76b47

Please sign in to comment.