Skip to content

Commit 8693523

Browse files
committed
feat: move tenure extend buffer to signer config
Instead of adding this buffer on the miner-side, this change now makes the signer add this buffer to the time sent to the miner, giving signers the control.
1 parent a38bb0c commit 8693523

File tree

12 files changed

+80
-23
lines changed

12 files changed

+80
-23
lines changed

CHANGELOG.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ and this project adheres to the versioning scheme outlined in the [README.md](RE
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))
1313
- Add `vrf_seed` to the `/v3/sortitions` rpc endpoint
14-
- Add miner configuration option `tenure_extend_buffer_secs` to specify the number of seconds of buffer the miner should wait, after reaching the 70% threshold for tenure extension time, before issuing a tenure extension, to allow for clock skew between the miner and signers
1514

1615
### Changed
1716

stacks-signer/CHANGELOG.md

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

1212
- Introduced the `reorg_attempts_activity_timeout_ms` configuration option for signers which is used to determine the length of time after the last block of a tenure is confirmed that an incoming miner's attempts to reorg it are considered valid miner activity.
13+
- Add signer configuration option `tenure_idle_timeout_buffer_secs` to specify the number of seconds of buffer the signer will add to its tenure extend time that it sends to miners. The idea is to allow for some clock skew between the miner and signers, preventing the case where the miner attempts to tenure extend too early.
1314

1415
### Changed
1516

stacks-signer/src/chainstate.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ pub struct ProposalEvalConfig {
124124
pub tenure_last_block_proposal_timeout: Duration,
125125
/// How much idle time must pass before allowing a tenure extend
126126
pub tenure_idle_timeout: Duration,
127+
/// How much buffer to add to the tenure idle timeout sent to miners to account for clock skew
128+
pub tenure_idle_timeout_buffer: Duration,
127129
/// Time following the last block of the previous tenure's global acceptance that a signer will consider an attempt by
128130
/// the new miner to reorg it as valid towards miner activity
129131
pub reorg_attempts_activity_timeout: Duration,
@@ -137,6 +139,7 @@ impl From<&SignerConfig> for ProposalEvalConfig {
137139
tenure_last_block_proposal_timeout: value.tenure_last_block_proposal_timeout,
138140
tenure_idle_timeout: value.tenure_idle_timeout,
139141
reorg_attempts_activity_timeout: value.reorg_attempts_activity_timeout,
142+
tenure_idle_timeout_buffer: value.tenure_idle_timeout_buffer,
140143
}
141144
}
142145
}

stacks-signer/src/client/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,7 @@ pub(crate) mod tests {
416416
tenure_last_block_proposal_timeout: config.tenure_last_block_proposal_timeout,
417417
block_proposal_validation_timeout: config.block_proposal_validation_timeout,
418418
tenure_idle_timeout: config.tenure_idle_timeout,
419+
tenure_idle_timeout_buffer: config.tenure_idle_timeout_buffer,
419420
block_proposal_max_age_secs: config.block_proposal_max_age_secs,
420421
reorg_attempts_activity_timeout: config.reorg_attempts_activity_timeout,
421422
}

stacks-signer/src/config.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ const DEFAULT_TENURE_LAST_BLOCK_PROPOSAL_TIMEOUT_SECS: u64 = 30;
4242
const DEFAULT_DRY_RUN: bool = false;
4343
const TENURE_IDLE_TIMEOUT_SECS: u64 = 120;
4444
const DEFAULT_REORG_ATTEMPTS_ACTIVITY_TIMEOUT_MS: u64 = 200_000;
45+
/// Default number of seconds to add to the tenure extend time, after computing the idle timeout,
46+
/// to allow for clock skew between the signer and the miner
47+
const DEFAULT_TENURE_IDLE_TIMEOUT_BUFFER_SECS: u64 = 2;
4548

4649
#[derive(thiserror::Error, Debug)]
4750
/// An error occurred parsing the provided configuration
@@ -162,6 +165,9 @@ pub struct SignerConfig {
162165
pub block_proposal_validation_timeout: Duration,
163166
/// How much idle time must pass before allowing a tenure extend
164167
pub tenure_idle_timeout: Duration,
168+
/// Amount of buffer time to add to the tenure extend time sent to miners to allow for
169+
/// clock skew
170+
pub tenure_idle_timeout_buffer: Duration,
165171
/// The maximum age of a block proposal in seconds that will be processed by the signer
166172
pub block_proposal_max_age_secs: u64,
167173
/// Time following the last block of the previous tenure's global acceptance that a signer will consider an attempt by
@@ -207,6 +213,9 @@ pub struct GlobalConfig {
207213
pub block_proposal_validation_timeout: Duration,
208214
/// How much idle time must pass before allowing a tenure extend
209215
pub tenure_idle_timeout: Duration,
216+
/// Amount of buffer time to add to the tenure extend time sent to miners to allow for
217+
/// clock skew
218+
pub tenure_idle_timeout_buffer: Duration,
210219
/// The maximum age of a block proposal that will be processed by the signer
211220
pub block_proposal_max_age_secs: u64,
212221
/// Time following the last block of the previous tenure's global acceptance that a signer will consider an attempt by
@@ -251,6 +260,9 @@ struct RawConfigFile {
251260
pub block_proposal_validation_timeout_ms: Option<u64>,
252261
/// How much idle time (in seconds) must pass before a tenure extend is allowed
253262
pub tenure_idle_timeout_secs: Option<u64>,
263+
/// Number of seconds of buffer to add to the tenure extend time sent to miners to allow for
264+
/// clock skew
265+
pub tenure_idle_timeout_buffer_secs: Option<u64>,
254266
/// The maximum age of a block proposal (in secs) that will be processed by the signer.
255267
pub block_proposal_max_age_secs: Option<u64>,
256268
/// Time (in millisecs) following a block's global acceptance that a signer will consider an attempt by a miner
@@ -367,6 +379,12 @@ impl TryFrom<RawConfigFile> for GlobalConfig {
367379

368380
let dry_run = raw_data.dry_run.unwrap_or(DEFAULT_DRY_RUN);
369381

382+
let tenure_idle_timeout_buffer = Duration::from_secs(
383+
raw_data
384+
.tenure_idle_timeout_buffer_secs
385+
.unwrap_or(DEFAULT_TENURE_IDLE_TIMEOUT_BUFFER_SECS),
386+
);
387+
370388
Ok(Self {
371389
node_host: raw_data.node_host,
372390
endpoint,
@@ -386,6 +404,7 @@ impl TryFrom<RawConfigFile> for GlobalConfig {
386404
block_proposal_max_age_secs,
387405
reorg_attempts_activity_timeout,
388406
dry_run,
407+
tenure_idle_timeout_buffer,
389408
})
390409
}
391410
}

stacks-signer/src/runloop.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ impl<Signer: SignerTrait<T>, T: StacksMessageCodec + Clone + Send + Debug> RunLo
314314
tenure_last_block_proposal_timeout: self.config.tenure_last_block_proposal_timeout,
315315
block_proposal_validation_timeout: self.config.block_proposal_validation_timeout,
316316
tenure_idle_timeout: self.config.tenure_idle_timeout,
317+
tenure_idle_timeout_buffer: self.config.tenure_idle_timeout_buffer,
317318
block_proposal_max_age_secs: self.config.block_proposal_max_age_secs,
318319
reorg_attempts_activity_timeout: self.config.reorg_attempts_activity_timeout,
319320
}))

stacks-signer/src/tests/chainstate.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ fn setup_test_environment(
9191
block_proposal_timeout: Duration::from_secs(5),
9292
tenure_last_block_proposal_timeout: Duration::from_secs(30),
9393
tenure_idle_timeout: Duration::from_secs(300),
94+
tenure_idle_timeout_buffer: Duration::from_secs(2),
9495
reorg_attempts_activity_timeout: Duration::from_secs(3),
9596
},
9697
};

stacks-signer/src/v0/signer.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,9 @@ impl Signer {
357357
block.header.signer_signature_hash(),
358358
signature,
359359
self.signer_db.calculate_tenure_extend_timestamp(
360-
self.proposal_config.tenure_idle_timeout,
360+
self.proposal_config
361+
.tenure_idle_timeout
362+
.saturating_add(self.proposal_config.tenure_idle_timeout_buffer),
361363
block,
362364
true,
363365
),
@@ -375,7 +377,9 @@ impl Signer {
375377
&self.private_key,
376378
self.mainnet,
377379
self.signer_db.calculate_tenure_extend_timestamp(
378-
self.proposal_config.tenure_idle_timeout,
380+
self.proposal_config
381+
.tenure_idle_timeout
382+
.saturating_add(self.proposal_config.tenure_idle_timeout_buffer),
379383
block,
380384
false,
381385
),
@@ -813,7 +817,9 @@ impl Signer {
813817
&self.private_key,
814818
self.mainnet,
815819
self.signer_db.calculate_tenure_extend_timestamp(
816-
self.proposal_config.tenure_idle_timeout,
820+
self.proposal_config
821+
.tenure_idle_timeout
822+
.saturating_add(self.proposal_config.tenure_idle_timeout_buffer),
817823
&block_info.block,
818824
false,
819825
),

stackslib/src/config/mod.rs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -121,10 +121,6 @@ const DEFAULT_TENURE_TIMEOUT_SECS: u64 = 180;
121121
/// Default percentage of block budget that must be used before attempting a
122122
/// time-based tenure extend
123123
const DEFAULT_TENURE_EXTEND_COST_THRESHOLD: u64 = 50;
124-
/// Default number of seconds to wait after reaching a time when 70% of signers
125-
/// would allow a time-based tenure extend before actually attempting to
126-
/// extend, to allow for clock skew.
127-
const DEFAULT_TENURE_EXTEND_BUFFER_SECS: u64 = 2;
128124

129125
static HELIUM_DEFAULT_CONNECTION_OPTIONS: LazyLock<ConnectionOptions> =
130126
LazyLock::new(|| ConnectionOptions {
@@ -2173,8 +2169,6 @@ pub struct MinerConfig {
21732169
pub tenure_timeout: Duration,
21742170
/// Percentage of block budget that must be used before attempting a time-based tenure extend
21752171
pub tenure_extend_cost_threshold: u64,
2176-
/// Duration defining a buffer period to wait before submitting a time-based tenure extend after reaching the 70% approval time
2177-
pub tenure_extend_buffer_secs: u64,
21782172
/// Define the timeout to apply while waiting for signers responses, based on the amount of rejections
21792173
pub block_rejection_timeout_steps: HashMap<u32, Duration>,
21802174
}
@@ -2216,7 +2210,6 @@ impl Default for MinerConfig {
22162210
tenure_extend_poll_secs: Duration::from_secs(DEFAULT_TENURE_EXTEND_POLL_SECS),
22172211
tenure_timeout: Duration::from_secs(DEFAULT_TENURE_TIMEOUT_SECS),
22182212
tenure_extend_cost_threshold: DEFAULT_TENURE_EXTEND_COST_THRESHOLD,
2219-
tenure_extend_buffer_secs: DEFAULT_TENURE_EXTEND_BUFFER_SECS,
22202213

22212214
block_rejection_timeout_steps: {
22222215
let mut rejections_timeouts_default_map = HashMap::<u32, Duration>::new();
@@ -2623,7 +2616,6 @@ pub struct MinerConfigFile {
26232616
pub tenure_extend_poll_secs: Option<u64>,
26242617
pub tenure_timeout_secs: Option<u64>,
26252618
pub tenure_extend_cost_threshold: Option<u64>,
2626-
pub tenure_extend_buffer_secs: Option<u64>,
26272619
pub block_rejection_timeout_steps: Option<HashMap<String, u64>>,
26282620
}
26292621

@@ -2768,7 +2760,6 @@ impl MinerConfigFile {
27682760
tenure_extend_poll_secs: self.tenure_extend_poll_secs.map(Duration::from_secs).unwrap_or(miner_default_config.tenure_extend_poll_secs),
27692761
tenure_timeout: self.tenure_timeout_secs.map(Duration::from_secs).unwrap_or(miner_default_config.tenure_timeout),
27702762
tenure_extend_cost_threshold: self.tenure_extend_cost_threshold.unwrap_or(miner_default_config.tenure_extend_cost_threshold),
2771-
tenure_extend_buffer_secs: self.tenure_extend_buffer_secs.unwrap_or(miner_default_config.tenure_extend_buffer_secs),
27722763

27732764
block_rejection_timeout_steps: {
27742765
if let Some(block_rejection_timeout_items) = self.block_rejection_timeout_steps {

testnet/stacks-node/src/nakamoto_node/miner.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1352,9 +1352,7 @@ impl BlockMinerThread {
13521352
});
13531353
}
13541354

1355-
let tenure_extend_timestamp = coordinator
1356-
.get_tenure_extend_timestamp()
1357-
.saturating_add(self.config.miner.tenure_extend_buffer_secs);
1355+
let tenure_extend_timestamp = coordinator.get_tenure_extend_timestamp();
13581356
if get_epoch_time_secs() <= tenure_extend_timestamp
13591357
&& self.tenure_change_time.elapsed() <= self.config.miner.tenure_timeout
13601358
{

0 commit comments

Comments
 (0)