Skip to content

Commit 9541920

Browse files
authored
Merge branch 'develop' into perf/descendancy-check
2 parents 8a38889 + cbb4fad commit 9541920

File tree

27 files changed

+817
-148
lines changed

27 files changed

+817
-148
lines changed

CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,15 @@ and this project adheres to the versioning scheme outlined in the [README.md](RE
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- Added new `ValidateRejectCode` values to the `/v3/block_proposal` endpoint
13+
1014
### Changed
1115

1216
- Reduce the default `block_rejection_timeout_steps` configuration so that miners will retry faster when blocks fail to reach 70% approved or 30% rejected.
1317
- Added index for `next_ready_nakamoto_block()` which improves block processing performance.
18+
- Added a new field, `parent_burn_block_hash`, to the payload that is included in the `/new_burn_block` event observer payload.
1419

1520
## [3.1.0.0.8]
1621

@@ -26,7 +31,7 @@ and this project adheres to the versioning scheme outlined in the [README.md](RE
2631

2732
- When a miner times out waiting for signatures, it will re-propose the same block instead of building a new block ([#5877](https://github.com/stacks-network/stacks-core/pull/5877))
2833
- Improve tenure downloader trace verbosity applying proper logging level depending on the tenure state ("debug" if unconfirmed, "info" otherwise) ([#5871](https://github.com/stacks-network/stacks-core/issues/5871))
29-
- Remove warning log about missing UTXOs when a node is configured as `miner` with `mock_mining` mode enabled ([#5841](https://github.com/stacks-network/stacks-core/issues/5841))
34+
- Remove warning log about missing UTXOs when a node is configured as `miner` with `mock_mining` mode enabled ([#5841](https://github.com/stacks-network/stacks-core/issues/5841))
3035
- Deprecated the `wait_on_interim_blocks` option in the miner config file. This option is no longer needed, as the miner will always wait for interim blocks to be processed before mining a new block. To wait extra time in between blocks, use the `min_time_between_blocks_ms` option instead. ([#5979](https://github.com/stacks-network/stacks-core/pull/5979))
3136
- Added `empty_mempool_sleep_ms` to the miner config file to control the time to wait in between mining attempts when the mempool is empty. If not set, the default sleep time is 2.5s. ([#5997](https://github.com/stacks-network/stacks-core/pull/5997))
3237

docs/event-dispatcher.md

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ These events are sent to the configured endpoint at two URLs:
2727
This payload includes data related to a newly processed block,
2828
and any events emitted from Stacks transactions during the block.
2929

30-
If the transaction originally comes from the parent microblock stream
30+
If the transaction originally comes from the parent microblock stream
3131
preceding this block, the microblock related fields will be filled in.
3232

3333
If the `raw_tx` field for a particular transaction is "0x00", that indicates
34-
that it is a burnchain operation. A burnchain operation is a transaction that
34+
that it is a burnchain operation. A burnchain operation is a transaction that
3535
is executed on the Stacks network, but was sent through the Bitcoin network.
36-
The Stacks network supports a few specific burnchain operations. You can read
36+
The Stacks network supports a few specific burnchain operations. You can read
3737
more about them [here](https://github.com/stacksgov/sips/blob/main/sips/sip-007/sip-007-stacking-consensus.md#stx-operations-on-bitcoin).
3838
The section below has example json encodings for each of the burnchain operations.
3939

@@ -152,8 +152,8 @@ Example:
152152
}
153153
```
154154

155-
#### Example json values for burnchain operations
156-
- TransferStx
155+
#### Example json values for burnchain operations
156+
- TransferStx
157157
```json
158158
{
159159
"transfer_stx": {
@@ -233,6 +233,8 @@ Example:
233233
```json
234234
{
235235
"burn_block_hash": "0x4eaabcd105865e471f697eff5dd5bd85d47ecb5a26a3379d74fae0ae87c40904",
236+
"consensus_hash": "0x53c166a709a9abd64a92a57f928a8b26aad08992",
237+
"parent_burn_block_hash": "0x6eaebcd105865e471f697eff5dd5bd85d47ecb5a26a3379d74fae0ae87c40904",
236238
"burn_block_height": 331,
237239
"reward_recipients": [
238240
{
@@ -258,8 +260,8 @@ Example:
258260

259261
### `POST /new_microblocks`
260262

261-
This payload includes data related to one or more microblocks that are either emmitted by the
262-
node itself, or received through the network.
263+
This payload includes data related to one or more microblocks that are either emmitted by the
264+
node itself, or received through the network.
263265

264266
Example:
265267

@@ -311,9 +313,9 @@ Example:
311313
}
312314
```
313315

314-
* `burn_block_{}` are the stats related to the burn block that is associated with the stacks
316+
* `burn_block_{}` are the stats related to the burn block that is associated with the stacks
315317
block that precedes this microblock stream.
316-
* Each transaction json object includes information about the microblock the transaction was packaged into.
318+
* Each transaction json object includes information about the microblock the transaction was packaged into.
317319

318320
### `POST /new_mempool_tx`
319321

@@ -384,23 +386,23 @@ Example:
384386
"tx_events": [
385387
{
386388
"Success": {
387-
"txid": "3e04ada5426332bfef446ba0a06d124aace4ade5c11840f541bf88e2e919faf6",
388-
"fee": 0,
389-
"execution_cost": {
390-
"write_length": 0,
391-
"write_count": 0,
392-
"read_length": 0,
393-
"read_count": 0,
389+
"txid": "3e04ada5426332bfef446ba0a06d124aace4ade5c11840f541bf88e2e919faf6",
390+
"fee": 0,
391+
"execution_cost": {
392+
"write_length": 0,
393+
"write_count": 0,
394+
"read_length": 0,
395+
"read_count": 0,
394396
"runtime": 0
395-
},
397+
},
396398
"result": {
397-
"ResponseData":
399+
"ResponseData":
398400
{
399401
"committed": true,
400402
"data": true
401403
}
402404
}
403-
}},
405+
}},
404406
{
405407
"ProcessingError": {
406408
"txid": "eef9f46b20fb637bd07ec92ad3ec175a5a4bdf3e8799259fc5b16a272090d4de",
@@ -432,23 +434,23 @@ Example:
432434
"tx_events": [
433435
{
434436
"Success": {
435-
"txid": "3e04ada5426332bfef446ba0a06d124aace4ade5c11840f541bf88e2e919faf6",
436-
"fee": 0,
437-
"execution_cost": {
438-
"write_length": 10,
439-
"write_count": 10,
440-
"read_length": 20,
441-
"read_count": 10,
437+
"txid": "3e04ada5426332bfef446ba0a06d124aace4ade5c11840f541bf88e2e919faf6",
438+
"fee": 0,
439+
"execution_cost": {
440+
"write_length": 10,
441+
"write_count": 10,
442+
"read_length": 20,
443+
"read_count": 10,
442444
"runtime": 1290
443-
},
445+
},
444446
"result": {
445-
"ResponseData":
447+
"ResponseData":
446448
{
447449
"committed": true,
448450
"data": true
449451
}
450452
}
451-
}},
453+
}},
452454
{
453455
"Skipped": {
454456
"txid": "eef9f46b20fb637bd07ec92ad3ec175a5a4bdf3e8799259fc5b16a272090d4de",

libsigner/src/events.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,7 @@ struct BlockEvent {
605605
#[serde(with = "prefix_hex")]
606606
index_block_hash: StacksBlockId,
607607
#[serde(with = "prefix_opt_hex")]
608+
#[serde(default)]
608609
signer_signature_hash: Option<Sha512Trunc256Sum>,
609610
#[serde(with = "prefix_hex")]
610611
consensus_hash: ConsensusHash,

stacks-signer/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to the versioning scheme outlined in the [README.md](README.md).
77

8+
## [3.1.0.0.8.1]
9+
10+
### Added
11+
12+
- The signer will now check if their associated stacks-node has processed the parent block for a block proposal before submitting that block proposal. If it cannot confirm that the parent block has been processed, it waits a default time of 15s before submitting, configurable via `proposal_wait_for_parent_time_secs` in the signer config.toml.
13+
814
## [3.1.0.0.8.0]
915

1016
### Changed

stacks-signer/src/chainstate.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,8 @@ pub struct ProposalEvalConfig {
141141
/// Time following the last block of the previous tenure's global acceptance that a signer will consider an attempt by
142142
/// the new miner to reorg it as valid towards miner activity
143143
pub reorg_attempts_activity_timeout: Duration,
144+
/// Time to wait before submitting a block proposal to the stacks-node
145+
pub proposal_wait_for_parent_time: Duration,
144146
}
145147

146148
impl From<&SignerConfig> for ProposalEvalConfig {
@@ -152,6 +154,7 @@ impl From<&SignerConfig> for ProposalEvalConfig {
152154
tenure_idle_timeout: value.tenure_idle_timeout,
153155
reorg_attempts_activity_timeout: value.reorg_attempts_activity_timeout,
154156
tenure_idle_timeout_buffer: value.tenure_idle_timeout_buffer,
157+
proposal_wait_for_parent_time: value.proposal_wait_for_parent_time,
155158
}
156159
}
157160
}

stacks-signer/src/client/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,7 @@ pub(crate) mod tests {
418418
tenure_idle_timeout_buffer: config.tenure_idle_timeout_buffer,
419419
block_proposal_max_age_secs: config.block_proposal_max_age_secs,
420420
reorg_attempts_activity_timeout: config.reorg_attempts_activity_timeout,
421+
proposal_wait_for_parent_time: config.proposal_wait_for_parent_time,
421422
}
422423
}
423424

stacks-signer/src/config.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ const DEFAULT_REORG_ATTEMPTS_ACTIVITY_TIMEOUT_MS: u64 = 200_000;
4545
/// Default number of seconds to add to the tenure extend time, after computing the idle timeout,
4646
/// to allow for clock skew between the signer and the miner
4747
const DEFAULT_TENURE_IDLE_TIMEOUT_BUFFER_SECS: u64 = 2;
48+
/// Default time (in ms) to wait before submitting a proposal if we
49+
/// cannot determine that our stacks-node has processed the parent
50+
/// block
51+
const DEFAULT_PROPOSAL_WAIT_TIME_FOR_PARENT_SECS: u64 = 15;
4852

4953
#[derive(thiserror::Error, Debug)]
5054
/// An error occurred parsing the provided configuration
@@ -175,6 +179,9 @@ pub struct SignerConfig {
175179
pub reorg_attempts_activity_timeout: Duration,
176180
/// The running mode for the signer (dry-run or normal)
177181
pub signer_mode: SignerConfigMode,
182+
/// Time to wait before submitting a block proposal to the stacks-node if we cannot
183+
/// determine that the stacks-node has processed the parent
184+
pub proposal_wait_for_parent_time: Duration,
178185
}
179186

180187
/// The parsed configuration for the signer
@@ -221,6 +228,9 @@ pub struct GlobalConfig {
221228
/// Time following the last block of the previous tenure's global acceptance that a signer will consider an attempt by
222229
/// the new miner to reorg it as valid towards miner activity
223230
pub reorg_attempts_activity_timeout: Duration,
231+
/// Time to wait before submitting a block proposal to the stacks-node if we cannot
232+
/// determine that the stacks-node has processed the parent
233+
pub proposal_wait_for_parent_time: Duration,
224234
/// Is this signer binary going to be running in dry-run mode?
225235
pub dry_run: bool,
226236
}
@@ -268,6 +278,8 @@ struct RawConfigFile {
268278
/// Time (in millisecs) following a block's global acceptance that a signer will consider an attempt by a miner
269279
/// to reorg the block as valid towards miner activity
270280
pub reorg_attempts_activity_timeout_ms: Option<u64>,
281+
/// Time to wait (in millisecs) before submitting a block proposal to the stacks-node
282+
pub proposal_wait_for_parent_time_secs: Option<u64>,
271283
/// Is this signer binary going to be running in dry-run mode?
272284
pub dry_run: Option<bool>,
273285
}
@@ -385,6 +397,12 @@ impl TryFrom<RawConfigFile> for GlobalConfig {
385397
.unwrap_or(DEFAULT_TENURE_IDLE_TIMEOUT_BUFFER_SECS),
386398
);
387399

400+
let proposal_wait_for_parent_time = Duration::from_secs(
401+
raw_data
402+
.proposal_wait_for_parent_time_secs
403+
.unwrap_or(DEFAULT_PROPOSAL_WAIT_TIME_FOR_PARENT_SECS),
404+
);
405+
388406
Ok(Self {
389407
node_host: raw_data.node_host,
390408
endpoint,
@@ -405,6 +423,7 @@ impl TryFrom<RawConfigFile> for GlobalConfig {
405423
reorg_attempts_activity_timeout,
406424
dry_run,
407425
tenure_idle_timeout_buffer,
426+
proposal_wait_for_parent_time,
408427
})
409428
}
410429
}

stacks-signer/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ pub trait Signer<T: SignerEventTrait>: Debug + Display {
7878
fn has_unprocessed_blocks(&self) -> bool;
7979
/// Get a reference to the local state machine of the signer
8080
fn get_local_state_machine(&self) -> &LocalStateMachine;
81+
/// Get the number of pending block proposals
82+
fn get_pending_proposals_count(&self) -> u64;
8183
}
8284

8385
/// A wrapper around the running signer type for the signer

stacks-signer/src/runloop.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ pub struct StateInfo {
5656
/// The local state machines for the running signers
5757
/// as a pair of (reward-cycle, state-machine)
5858
pub signer_state_machines: Vec<(u64, Option<LocalStateMachine>)>,
59+
/// The number of pending block proposals for this signer
60+
pub pending_proposals_count: u64,
5961
}
6062

6163
/// The signer result that can be sent across threads
@@ -320,6 +322,7 @@ impl<Signer: SignerTrait<T>, T: StacksMessageCodec + Clone + Send + Debug> RunLo
320322
tenure_idle_timeout_buffer: self.config.tenure_idle_timeout_buffer,
321323
block_proposal_max_age_secs: self.config.block_proposal_max_age_secs,
322324
reorg_attempts_activity_timeout: self.config.reorg_attempts_activity_timeout,
325+
proposal_wait_for_parent_time: self.config.proposal_wait_for_parent_time,
323326
}))
324327
}
325328

@@ -529,6 +532,17 @@ impl<Signer: SignerTrait<T>, T: StacksMessageCodec + Clone + Send + Debug>
529532
)
530533
})
531534
.collect(),
535+
pending_proposals_count: self
536+
.stacks_signers
537+
.values()
538+
.find_map(|signer| {
539+
if let ConfiguredSigner::RegisteredSigner(signer) = signer {
540+
Some(signer.get_pending_proposals_count())
541+
} else {
542+
None
543+
}
544+
})
545+
.unwrap_or(0),
532546
};
533547
info!("Signer status check requested: {state_info:?}");
534548

stacks-signer/src/signerdb.rs

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1215,12 +1215,18 @@ impl SignerDb {
12151215
/// If found, remove it from the pending table.
12161216
pub fn get_and_remove_pending_block_validation(
12171217
&self,
1218-
) -> Result<Option<Sha512Trunc256Sum>, DBError> {
1219-
let qry = "DELETE FROM block_validations_pending WHERE signer_signature_hash = (SELECT signer_signature_hash FROM block_validations_pending ORDER BY added_time ASC LIMIT 1) RETURNING signer_signature_hash";
1218+
) -> Result<Option<(Sha512Trunc256Sum, u64)>, DBError> {
1219+
let qry = "DELETE FROM block_validations_pending WHERE signer_signature_hash = (SELECT signer_signature_hash FROM block_validations_pending ORDER BY added_time ASC LIMIT 1) RETURNING signer_signature_hash, added_time";
12201220
let args = params![];
12211221
let mut stmt = self.db.prepare(qry)?;
1222-
let sighash: Option<String> = stmt.query_row(args, |row| row.get(0)).optional()?;
1223-
Ok(sighash.and_then(|sighash| Sha512Trunc256Sum::from_hex(&sighash).ok()))
1222+
let result: Option<(String, i64)> = stmt
1223+
.query_row(args, |row| Ok((row.get(0)?, row.get(1)?)))
1224+
.optional()?;
1225+
Ok(result.and_then(|(sighash, ts_i64)| {
1226+
let signer_sighash = Sha512Trunc256Sum::from_hex(&sighash).ok()?;
1227+
let ts = u64::try_from(ts_i64).ok()?;
1228+
Some((signer_sighash, ts))
1229+
}))
12241230
}
12251231

12261232
/// Remove a pending block validation
@@ -2183,20 +2189,29 @@ pub mod tests {
21832189
db.insert_pending_block_validation(&Sha512Trunc256Sum([0x03; 32]), 3000)
21842190
.unwrap();
21852191

2186-
let pending_hash = db.get_and_remove_pending_block_validation().unwrap();
2187-
assert_eq!(pending_hash, Some(Sha512Trunc256Sum([0x01; 32])));
2192+
let (pending_hash, _) = db
2193+
.get_and_remove_pending_block_validation()
2194+
.unwrap()
2195+
.unwrap();
2196+
assert_eq!(pending_hash, Sha512Trunc256Sum([0x01; 32]));
21882197

21892198
let pendings = db.get_all_pending_block_validations().unwrap();
21902199
assert_eq!(pendings.len(), 2);
21912200

2192-
let pending_hash = db.get_and_remove_pending_block_validation().unwrap();
2193-
assert_eq!(pending_hash, Some(Sha512Trunc256Sum([0x02; 32])));
2201+
let (pending_hash, _) = db
2202+
.get_and_remove_pending_block_validation()
2203+
.unwrap()
2204+
.unwrap();
2205+
assert_eq!(pending_hash, Sha512Trunc256Sum([0x02; 32]));
21942206

21952207
let pendings = db.get_all_pending_block_validations().unwrap();
21962208
assert_eq!(pendings.len(), 1);
21972209

2198-
let pending_hash = db.get_and_remove_pending_block_validation().unwrap();
2199-
assert_eq!(pending_hash, Some(Sha512Trunc256Sum([0x03; 32])));
2210+
let (pending_hash, _) = db
2211+
.get_and_remove_pending_block_validation()
2212+
.unwrap()
2213+
.unwrap();
2214+
assert_eq!(pending_hash, Sha512Trunc256Sum([0x03; 32]));
22002215

22012216
let pendings = db.get_all_pending_block_validations().unwrap();
22022217
assert!(pendings.is_empty());

0 commit comments

Comments
 (0)