Skip to content

Commit a99a6d1

Browse files
committed
Merge branch 'fix/5285' into feat/shadow-block-tooling
2 parents ad01a76 + 34d658a commit a99a6d1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+1136
-776
lines changed

.github/workflows/bitcoin-tests.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ jobs:
125125
- tests::signer::v0::multiple_miners_with_custom_chain_id
126126
- tests::signer::v0::block_commit_delay
127127
- tests::signer::v0::continue_after_fast_block_no_sortition
128+
- tests::signer::v0::block_validation_response_timeout
128129
- tests::nakamoto_integrations::burn_ops_integration_test
129130
- tests::nakamoto_integrations::check_block_heights
130131
- tests::nakamoto_integrations::clarity_burn_state

stacks-common/src/types/mod.rs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::cmp::Ordering;
22
use std::fmt;
3+
use std::ops::{Deref, DerefMut, Index, IndexMut};
34

45
#[cfg(feature = "canonical")]
56
pub mod sqlite;
@@ -475,3 +476,83 @@ impl<L: PartialEq + Eq> Ord for StacksEpoch<L> {
475476
self.epoch_id.cmp(&other.epoch_id)
476477
}
477478
}
479+
480+
/// A wrapper for holding a list of Epochs, indexable by StacksEpochId
481+
#[derive(Clone, Debug, Default, Deserialize, PartialEq, Eq)]
482+
pub struct EpochList<L: Clone>(Vec<StacksEpoch<L>>);
483+
484+
impl<L: Clone> EpochList<L> {
485+
pub fn new(epochs: &[StacksEpoch<L>]) -> EpochList<L> {
486+
EpochList(epochs.to_vec())
487+
}
488+
489+
pub fn get(&self, index: StacksEpochId) -> Option<&StacksEpoch<L>> {
490+
self.0.get(StacksEpoch::find_epoch_by_id(&self.0, index)?)
491+
}
492+
493+
pub fn get_mut(&mut self, index: StacksEpochId) -> Option<&mut StacksEpoch<L>> {
494+
let index = StacksEpoch::find_epoch_by_id(&self.0, index)?;
495+
self.0.get_mut(index)
496+
}
497+
498+
/// Truncates the list after the given epoch id
499+
pub fn truncate_after(&mut self, epoch_id: StacksEpochId) {
500+
if let Some(index) = StacksEpoch::find_epoch_by_id(&self.0, epoch_id) {
501+
self.0.truncate(index + 1);
502+
}
503+
}
504+
505+
/// Determine which epoch, if any, a given burnchain height falls into.
506+
pub fn epoch_id_at_height(&self, height: u64) -> Option<StacksEpochId> {
507+
StacksEpoch::find_epoch(self, height).map(|idx| self.0[idx].epoch_id)
508+
}
509+
510+
/// Determine which epoch, if any, a given burnchain height falls into.
511+
pub fn epoch_at_height(&self, height: u64) -> Option<StacksEpoch<L>> {
512+
StacksEpoch::find_epoch(self, height).map(|idx| self.0[idx].clone())
513+
}
514+
515+
/// Pushes a new `StacksEpoch` to the end of the list
516+
pub fn push(&mut self, epoch: StacksEpoch<L>) {
517+
if let Some(last) = self.0.last() {
518+
assert!(
519+
epoch.start_height == last.end_height && epoch.epoch_id > last.epoch_id,
520+
"Epochs must be pushed in order"
521+
);
522+
}
523+
self.0.push(epoch);
524+
}
525+
526+
pub fn to_vec(&self) -> Vec<StacksEpoch<L>> {
527+
self.0.clone()
528+
}
529+
}
530+
531+
impl<L: Clone> Index<StacksEpochId> for EpochList<L> {
532+
type Output = StacksEpoch<L>;
533+
fn index(&self, index: StacksEpochId) -> &StacksEpoch<L> {
534+
self.get(index)
535+
.expect("Invalid StacksEpochId: could not find corresponding epoch")
536+
}
537+
}
538+
539+
impl<L: Clone> IndexMut<StacksEpochId> for EpochList<L> {
540+
fn index_mut(&mut self, index: StacksEpochId) -> &mut StacksEpoch<L> {
541+
self.get_mut(index)
542+
.expect("Invalid StacksEpochId: could not find corresponding epoch")
543+
}
544+
}
545+
546+
impl<L: Clone> Deref for EpochList<L> {
547+
type Target = [StacksEpoch<L>];
548+
549+
fn deref(&self) -> &Self::Target {
550+
&self.0
551+
}
552+
}
553+
554+
impl<L: Clone> DerefMut for EpochList<L> {
555+
fn deref_mut(&mut self) -> &mut Self::Target {
556+
&mut self.0
557+
}
558+
}

stacks-signer/src/client/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,7 @@ pub(crate) mod tests {
412412
first_proposal_burn_block_timing: config.first_proposal_burn_block_timing,
413413
block_proposal_timeout: config.block_proposal_timeout,
414414
tenure_last_block_proposal_timeout: config.tenure_last_block_proposal_timeout,
415+
block_proposal_validation_timeout: config.block_proposal_validation_timeout,
415416
}
416417
}
417418

stacks-signer/src/config.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ use crate::client::SignerSlotID;
3535

3636
const EVENT_TIMEOUT_MS: u64 = 5000;
3737
const BLOCK_PROPOSAL_TIMEOUT_MS: u64 = 600_000;
38+
const BLOCK_PROPOSAL_VALIDATION_TIMEOUT_MS: u64 = 120_000;
3839
const DEFAULT_FIRST_PROPOSAL_BURN_BLOCK_TIMING_SECS: u64 = 60;
3940
const DEFAULT_TENURE_LAST_BLOCK_PROPOSAL_TIMEOUT_SECS: u64 = 30;
4041

@@ -132,6 +133,8 @@ pub struct SignerConfig {
132133
/// Time to wait for the last block of a tenure to be globally accepted or rejected
133134
/// before considering a new miner's block at the same height as potentially valid.
134135
pub tenure_last_block_proposal_timeout: Duration,
136+
/// How much time to wait for a block proposal validation response before marking the block invalid
137+
pub block_proposal_validation_timeout: Duration,
135138
}
136139

137140
/// The parsed configuration for the signer
@@ -165,6 +168,9 @@ pub struct GlobalConfig {
165168
/// Time to wait for the last block of a tenure to be globally accepted or rejected
166169
/// before considering a new miner's block at the same height as potentially valid.
167170
pub tenure_last_block_proposal_timeout: Duration,
171+
/// How long to wait for a response from a block proposal validation response from the node
172+
/// before marking that block as invalid and rejecting it
173+
pub block_proposal_validation_timeout: Duration,
168174
}
169175

170176
/// Internal struct for loading up the config file
@@ -187,16 +193,19 @@ struct RawConfigFile {
187193
pub db_path: String,
188194
/// Metrics endpoint
189195
pub metrics_endpoint: Option<String>,
190-
/// How much time must pass in seconds between the first block proposal in a tenure and the next bitcoin block
191-
/// before a subsequent miner isn't allowed to reorg the tenure
196+
/// How much time (in secs) must pass between the first block proposal in a tenure and the next bitcoin block
197+
/// before a subsequent miner isn't allowed to reorg the tenure
192198
pub first_proposal_burn_block_timing_secs: Option<u64>,
193-
/// How much time to wait for a miner to propose a block following a sortition in milliseconds
199+
/// How much time (in millisecs) to wait for a miner to propose a block following a sortition
194200
pub block_proposal_timeout_ms: Option<u64>,
195201
/// An optional custom Chain ID
196202
pub chain_id: Option<u32>,
197203
/// Time in seconds to wait for the last block of a tenure to be globally accepted or rejected
198204
/// before considering a new miner's block at the same height as potentially valid.
199205
pub tenure_last_block_proposal_timeout_secs: Option<u64>,
206+
/// How long to wait (in millisecs) for a response from a block proposal validation response from the node
207+
/// before marking that block as invalid and rejecting it
208+
pub block_proposal_validation_timeout_ms: Option<u64>,
200209
}
201210

202211
impl RawConfigFile {
@@ -282,6 +291,12 @@ impl TryFrom<RawConfigFile> for GlobalConfig {
282291
.unwrap_or(DEFAULT_TENURE_LAST_BLOCK_PROPOSAL_TIMEOUT_SECS),
283292
);
284293

294+
let block_proposal_validation_timeout = Duration::from_millis(
295+
raw_data
296+
.block_proposal_validation_timeout_ms
297+
.unwrap_or(BLOCK_PROPOSAL_VALIDATION_TIMEOUT_MS),
298+
);
299+
285300
Ok(Self {
286301
node_host: raw_data.node_host,
287302
endpoint,
@@ -296,6 +311,7 @@ impl TryFrom<RawConfigFile> for GlobalConfig {
296311
block_proposal_timeout,
297312
chain_id: raw_data.chain_id,
298313
tenure_last_block_proposal_timeout,
314+
block_proposal_validation_timeout,
299315
})
300316
}
301317
}

stacks-signer/src/lib.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,10 +125,7 @@ impl<S: Signer<T> + Send + 'static, T: SignerEventTrait + 'static> SpawnedSigner
125125
);
126126
let (res_send, res_recv) = channel();
127127
let ev = SignerEventReceiver::new(config.network.is_mainnet());
128-
#[cfg(feature = "monitoring_prom")]
129-
{
130-
crate::monitoring::start_serving_monitoring_metrics(config.clone()).ok();
131-
}
128+
crate::monitoring::start_serving_monitoring_metrics(config.clone()).ok();
132129
let runloop = RunLoop::new(config.clone());
133130
let mut signer: RunLoopSigner<S, T> = libsigner::Signer::new(runloop, ev, res_send);
134131
let running_signer = signer.spawn(endpoint).expect("Failed to spawn signer");

stacks-signer/src/monitoring/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ use ::prometheus::HistogramTimer;
1919
#[cfg(feature = "monitoring_prom")]
2020
use slog::slog_error;
2121
#[cfg(not(feature = "monitoring_prom"))]
22-
use slog::slog_warn;
22+
use slog::slog_info;
2323
#[cfg(feature = "monitoring_prom")]
2424
use stacks_common::error;
2525
#[cfg(not(feature = "monitoring_prom"))]
26-
use stacks_common::warn;
26+
use stacks_common::info;
2727

2828
use crate::config::GlobalConfig;
2929

@@ -143,7 +143,7 @@ pub fn start_serving_monitoring_metrics(config: GlobalConfig) -> Result<(), Stri
143143
#[cfg(not(feature = "monitoring_prom"))]
144144
{
145145
if config.metrics_endpoint.is_some() {
146-
warn!("Not starting monitoring metrics server as the monitoring_prom feature is not enabled");
146+
info!("`metrics_endpoint` is configured for the signer, but the monitoring_prom feature is not enabled. Not starting monitoring metrics server.");
147147
}
148148
}
149149
Ok(())

stacks-signer/src/runloop.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,7 @@ impl<Signer: SignerTrait<T>, T: StacksMessageCodec + Clone + Send + Debug> RunLo
284284
db_path: self.config.db_path.clone(),
285285
block_proposal_timeout: self.config.block_proposal_timeout,
286286
tenure_last_block_proposal_timeout: self.config.tenure_last_block_proposal_timeout,
287+
block_proposal_validation_timeout: self.config.block_proposal_validation_timeout,
287288
}))
288289
}
289290

0 commit comments

Comments
 (0)